|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T x
Length: 12285 (0x2ffd) Types: TextFile Names: »x25addr.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/compat/x25addr.c«
/* x25addr.c - X.25 level generic <-> interface address munging */ #ifndef lint static char *rcsid = "$Header: /f/osi/compat/RCS/x25addr.c,v 7.2 89/12/11 16:21:42 mrose Exp $"; #endif /* * $Header: /f/osi/compat/RCS/x25addr.c,v 7.2 89/12/11 16:21:42 mrose Exp $ * * Contributed by George Michaelson, Julian Onions, and John Pavel * * * $Log: x25addr.c,v $ * Revision 7.2 89/12/11 16:21:42 mrose * comments * * Revision 7.1 89/12/11 01:36:14 mrose * SUN_X25_HACK * * Revision 7.0 89/11/23 21:23:49 mrose * Release 6.0 * */ /* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */ /* LINTLIBRARY */ /* * for *really* generic address translation */ #include <errno.h> #include <stdio.h> #include "general.h" #include "manifest.h" #ifdef X25 #include "tailor.h" #include "tpkt.h" #include <sys/file.h> #include "x25.h" #ifndef DEBUG #define DEBUG #endif /* \f */ /* * convert from the generic X25 structure to interface specific */ /* ARGSUSED */ CONN_DB *gen2if (generic, specific, context) struct NSAPaddr *generic; CONN_DB *specific; int context; { int dtelen; char dte[NSAP_DTELEN + 1]; #ifdef CAMTEC_CCL struct iovec *iov; #endif if (generic == NULLNA || specific == (CONN_DB *) 0 || generic -> na_type != NA_X25) return (CONN_DB *)0; if (x25_dnic_prefix && *x25_dnic_prefix) { /* need DNIC on local calls? */ register int i; if ( strncmp(generic -> na_dte, x25_dnic_prefix, i = strlen(x25_dnic_prefix)) == 0 ) { if (x25_strip_dnic) bcopy(generic -> na_dte + i, dte, dtelen = generic -> na_dtelen - i); else bcopy (generic -> na_dte, dte, dtelen = generic -> na_dtelen); } else if (x25_intl_zero) { bcopy(generic -> na_dte, dte + 1, dtelen = generic-> na_dtelen); *dte = '0', dtelen++; } else bcopy(generic -> na_dte, dte, dtelen = generic -> na_dtelen); } else bcopy (generic -> na_dte, dte, dtelen = generic -> na_dtelen); dte[dtelen] = NULL; #ifdef SUN_X25_HACK /* * If your X.25 provider expects to receive the subaddress alone * on listen requests, and you are using SunLink X.25, you may need * to enable SUN_X25_HACK in your config file. This will allow you * to use x25_local_dte in isotailor to specify a dte mask to be * stripped when listening, and thus use full DTE strings in * isoentities and QUIPU EDB files. You will also have to use the * tsapd -a <dte> option to specify the listen address in * /etc/rc.local and other tsapd startups since by default this equals * x25_local_dte and thus will be masked to <null> unless overridden * with full DTE + subaddress. */ /* * in ADDR_LISTEN context, it may be neccessary to only listen * on the sub-address, because certain PTT-provided networks * remove the local DTE from incoming CR packets. * * SunLink X.25 listen asserts whatever DTE it is given as a simple * string-compare, and will never receive inbound calls that bear * only the sub-address if you assert the full DTE. * * this behaviour is orthogonal to any requirements to remove DNIC * or add a leading 0 on outbound calls, and so needs a separate * test. It uses tailor variable x25_local_dte to assert the local * DTE *without* subaddress which should be tested for and stripped * when detected. */ if ((context == ADDR_LISTEN) && x25_local_dte && *x25_local_dte) { register int i; if ( strncmp(generic -> na_dte, x25_local_dte, i = strlen(x25_local_dte)) == 0 ) { bcopy(generic -> na_dte + i, dte, dtelen = generic -> na_dtelen - i); dte[dtelen] = NULL; } } #endif DLOG (x25_log, LLOG_DEBUG, ("gen2if %s -> %s, %d octets; PID %s", generic -> na_dte, dte, dtelen, sel2str (generic -> na_pid, (int) generic -> na_pidlen,1))); #ifndef CAMTEC_CCL bzero ((char *)specific, sizeof *specific); #endif #ifdef UBC_X25 if ((specific -> xaddr_len = dtelen) != 0) { bcopy (dte, specific -> xaddr_addr, dtelen); specific -> xaddr_len = dtelen; specific -> xaddr_facilities = 0; bcopy (generic -> na_pid, specific -> xaddr_proto, generic -> na_pidlen); bcopy (generic -> na_cudf, specific -> xaddr_userdata, generic -> na_cudflen); } #endif #ifdef SUN_X25 specific -> hostlen = char2bcd (dte, specific -> host); /* Zero PID */ if (generic -> na_pidlen) { /* non-null PID */ if (generic -> na_pidlen > NPSIZE) { SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, ("PID too long (%d > %d)", generic -> na_pidlen, NPSIZE)); return (CONN_DB *)0; } else { bzero((char *)specific -> data, NPSIZE); bcopy (generic -> na_pid, (char *)specific -> data, generic -> na_pidlen); bcopy (generic -> na_cudf, (char *) specific -> data + NPSIZE, generic -> na_cudflen); specific -> datalen = generic -> na_pidlen + generic -> na_cudflen; } } else { /* Null PID (just copy in CUDF, the first four octets of which will be the PID in any case) */ bcopy (generic -> na_cudf, (char *)specific -> data, generic -> na_cudflen); specific -> datalen = generic -> na_cudflen; } #endif #ifdef CAMTEC_CCL switch (context) { case ADDR_REMOTE: iov = &(specific -> ccl_iovec[0]); if (x25_outgoing_port == '#') { char *a, *b; int i; iov -> iov_len = dtelen + 4; bzero(iov -> iov_base, iov -> iov_len + 1); a = iov -> iov_base; b = dte; *a++ = '#'; *a++ = '['; for (i = 0; i < dtelen; i++) { if (i == 2) *a++ = ':'; else if (i == 14) *a++ = ']'; *a++ = *b++; } } else { iov -> iov_len = dtelen+1; bcopy(dte, (iov -> iov_base)+1, dtelen); *(iov -> iov_base) = x25_outgoing_port; } break; case ADDR_LOCAL: iov = &(specific -> ccl_iovec[0]); strncpy(iov -> iov_base, generic -> na_dte, generic -> na_dtelen); iov -> iov_base[generic -> na_dtelen] = '\0'; return (specific); case ADDR_LISTEN: iov = &(specific -> ccl_iovec[0]); if (generic -> na_pidlen) { /* listen on a PID */ register int i; iov -> iov_base[0] = 'C'; bcopy(generic -> na_pid, iov -> iov_base + 1, i = generic -> na_pidlen); iov -> iov_len = i + 1; } else if (generic -> na_dtelen < 6) { /* listen on a subaddress */ register int i; iov -> iov_base[0] = 'S'; bcopy(generic -> na_dte, iov -> iov_base + 1, i = generic -> na_dtelen); iov -> iov_len = i + 1; } else /* full DTE */ bcopy(dte, iov -> iov_base, iov -> iov_len = dtelen); return (specific); } /* * CUDF & PID must be merged. malloc initailly PIDsize space * and bzero it. this may be UK net specific action which * ensures we do NOT fall foul of listeners which use pid * to match as well as "true" cudf & DTE. */ (iov = &(specific -> ccl_iovec[2])) -> iov_len = 0; if (generic -> na_faclen != 0) bcopy (generic -> na_fac, iov -> iov_base, iov -> iov_len = min( generic -> na_faclen, FACSIZE) ); iov++; if ( (iov -> iov_len = generic -> na_pidlen) != 0) bcopy (generic -> na_pid, iov -> iov_base, generic -> na_pidlen); /* * if there is any other user data add that in now... * actually cudf is a variable length field so this is * all very suspect. */ if (generic -> na_cudflen != 0) bcopy(generic -> na_cudf, iov -> iov_base + iov -> iov_len, generic -> na_cudflen), iov -> iov_len += generic -> na_cudflen; #endif return(specific); } /* \f */ /* * convert from interface specific format to generic X.25 structure */ /* ARGSUSED */ struct NSAPaddr *if2gen (generic, specific, context) struct NSAPaddr *generic; CONN_DB *specific; int context; { int dtelen; char dte[NSAP_DTELEN + 1]; #ifdef CAMTEC_CCL struct iovec *iov; #endif if (generic == NULLNA || specific == (CONN_DB *) 0) return NULLNA; bzero ((char *)generic, sizeof *generic); bzero (dte, sizeof dte); dtelen = 0; generic -> na_type = NA_X25; generic -> na_subnet = ts_comm_x25_default; #ifdef UBC_X25 if (specific -> xaddr_len != 0) { bcopy (specific -> xaddr_addr, dte, specific -> xaddr_len); dtelen = specific -> xaddr_len; bcopy (specific -> xaddr_proto, generic -> na_pid, sizeof(specific -> xaddr_proto)); generic -> na_pidlen = sizeof specific -> xaddr_proto; bcopy (specific -> xaddr_userdata, generic -> na_cudf, sizeof(specific -> xaddr_userdata)); generic -> na_cudflen = sizeof specific -> xaddr_userdata; } #endif #ifdef SUN_X25 dtelen = bcd2char (specific -> host, dte, (int) specific -> hostlen); if (specific -> datalen > NPSIZE) { /* have some real user data after the PID */ bcopy((char *)specific -> data, generic -> na_pid, generic -> na_pidlen = NPSIZE); bcopy((char *) specific -> data + generic -> na_pidlen, generic -> na_cudf, generic -> na_cudflen = specific -> datalen - generic -> na_pidlen); } else { /* PID only */ bcopy((char *)specific -> data, generic -> na_pid, generic -> na_pidlen = specific -> datalen); generic -> na_cudflen = 0; } #endif #ifdef CAMTEC_CCL switch (context) { case ADDR_REMOTE: iov = &(specific -> ccl_iovec[1]); if (iov -> iov_len) { if (*(iov->iov_base) == '#') { char *a; a = iov -> iov_base; while (*a && iov -> iov_len) { if (*a == ']') { iov -> iov_len--; a++; break; } iov -> iov_len--; a++; } if (*a == 0 || iov -> iov_len == 0) dtelen = 0; else { dtelen = iov -> iov_len; bcopy (a, dte, dtelen); } } else { dtelen = iov -> iov_len - 1; bcopy ((iov -> iov_base)+1, dte, dtelen); } } else dtelen = 0; break; case ADDR_LOCAL: iov = &(specific -> ccl_iovec[0]); if (iov -> iov_len) { dtelen = iov -> iov_len -1; bcopy ((iov -> iov_base)+1, dte, dtelen); } else dtelen = 0; break; case ADDR_LISTEN: return NULLNA; } if ( (iov = &(specific -> ccl_iovec[2])) -> iov_len ) bcopy( iov -> iov_base, generic -> na_fac, generic -> na_faclen = min( iov -> iov_len, FACSIZE)); if ( ++iov -> iov_len) { bcopy( iov -> iov_base, generic -> na_pid, generic -> na_pidlen = min( iov -> iov_len, NPSIZE)); if ( iov -> iov_len > NPSIZE) bcopy( iov -> iov_base + NPSIZE, generic -> na_cudf, generic -> na_cudflen = min(iov -> iov_len - NPSIZE, CUDFSIZE)); } #endif if (x25_dnic_prefix && *x25_dnic_prefix) { register int i; i = 0; if (x25_intl_zero && dte[0] == '0' && dte[1] != '0') i = 1; else if (x25_dnic_prefix && *x25_dnic_prefix && x25_strip_dnic && dtelen < 12) /* local call... */ bcopy (x25_dnic_prefix, generic -> na_dte, generic -> na_dtelen = strlen (x25_dnic_prefix)); bcopy (dte + i, generic -> na_dte + generic -> na_dtelen, dtelen - i); generic -> na_dtelen += dtelen - i; } else bcopy (dte, generic -> na_dte, generic -> na_dtelen = dtelen); DLOG (x25_log, LLOG_DEBUG, ("if2gen %s -> %s, %d octets; PID %s", dte, generic -> na_dte, generic -> na_dtelen, sel2str (generic -> na_pid, (int) generic -> na_pidlen,1))); return(generic); } /* \f */ #ifdef SUN_X25 static int char2bcd (s, d) register char *s; register u_char *d; { register int c, i; for (i = 0; *s; i++) { if ((c = *s++) >= 'a' && c <= 'f') c -= 'a' + 0x0a; else if (c >= 'A' && c <= 'F') c -= 'A' + 0x0a; else if (c >= '0' && c <= '9') c -= '0'; else c = 0; if (i & 1) *d++ |= c & 0xf; else *d = (c & 0xf) << 4; } return i; } /* \f */ static int bcd2char (s, d, len) register u_char *s; register char *d; int len; { register int i, g; for (i = 0; i < len; i++) { g = s[i >> 1]; if ((i & 1) == 0) g >>= 4; g &= 0xf; if (g < 0x0a) *d++ = g + '0'; else *d++ = g + 'a' - 0x0a; } *d = NULL; return len; } #endif #endif