|
|
1.1 ! root 1: /* x25addr.c - X.25 level generic <-> interface address munging */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/compat/RCS/x25addr.c,v 7.3 90/07/09 14:32:30 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/compat/RCS/x25addr.c,v 7.3 90/07/09 14:32:30 mrose Exp $ ! 9: * ! 10: * Contributed by George Michaelson, Julian Onions, and John Pavel ! 11: * ! 12: * ! 13: * $Log: x25addr.c,v $ ! 14: * Revision 7.3 90/07/09 14:32:30 mrose ! 15: * sync ! 16: * ! 17: * Revision 7.2 89/12/11 16:21:42 mrose ! 18: * comments ! 19: * ! 20: * Revision 7.1 89/12/11 01:36:14 mrose ! 21: * SUN_X25_HACK ! 22: * ! 23: * Revision 7.0 89/11/23 21:23:49 mrose ! 24: * Release 6.0 ! 25: * ! 26: */ ! 27: ! 28: /* ! 29: * NOTICE ! 30: * ! 31: * Acquisition, use, and distribution of this module and related ! 32: * materials are subject to the restrictions of a license agreement. ! 33: * Consult the Preface in the User's Manual for the full terms of ! 34: * this agreement. ! 35: * ! 36: */ ! 37: ! 38: ! 39: /* LINTLIBRARY */ ! 40: ! 41: /* ! 42: * for *really* generic address translation ! 43: */ ! 44: ! 45: #include <errno.h> ! 46: #include <stdio.h> ! 47: #include "general.h" ! 48: #include "manifest.h" ! 49: ! 50: #ifdef X25 ! 51: #include "tailor.h" ! 52: #include "tpkt.h" ! 53: #include <sys/file.h> ! 54: #include "x25.h" ! 55: ! 56: #ifndef DEBUG ! 57: #define DEBUG ! 58: #endif ! 59: ! 60: /* */ ! 61: ! 62: /* ! 63: * convert from the generic X25 structure to interface specific ! 64: */ ! 65: /* ARGSUSED */ ! 66: CONN_DB *gen2if (generic, specific, context) ! 67: struct NSAPaddr *generic; ! 68: CONN_DB *specific; ! 69: int context; ! 70: { ! 71: int dtelen; ! 72: char dte[NSAP_DTELEN + 1]; ! 73: #ifdef CAMTEC_CCL ! 74: struct iovec *iov; ! 75: #endif ! 76: ! 77: if (generic == NULLNA ! 78: || specific == (CONN_DB *) 0 ! 79: || generic -> na_stack != NA_X25) ! 80: return (CONN_DB *)0; ! 81: ! 82: if (x25_dnic_prefix && *x25_dnic_prefix) { ! 83: /* need DNIC on local calls? */ ! 84: register int i; ! 85: ! 86: if ( strncmp(generic -> na_dte, x25_dnic_prefix, ! 87: i = strlen(x25_dnic_prefix)) == 0 ) ! 88: { ! 89: if (x25_strip_dnic) bcopy(generic -> na_dte + i, dte, dtelen = ! 90: generic -> na_dtelen - i); ! 91: else bcopy (generic -> na_dte, dte, dtelen = generic -> na_dtelen); ! 92: } ! 93: else ! 94: if (x25_intl_zero) ! 95: { ! 96: bcopy(generic -> na_dte, dte + 1, dtelen = generic-> na_dtelen); ! 97: *dte = '0', dtelen++; ! 98: } ! 99: else bcopy(generic -> na_dte, dte, dtelen = generic -> na_dtelen); ! 100: ! 101: } ! 102: else bcopy (generic -> na_dte, dte, dtelen = generic -> na_dtelen); ! 103: dte[dtelen] = NULL; ! 104: ! 105: #ifdef SUN_X25_HACK ! 106: /* ! 107: * If your X.25 provider expects to receive the subaddress alone ! 108: * on listen requests, and you are using SunLink X.25, you may need ! 109: * to enable SUN_X25_HACK in your config file. This will allow you ! 110: * to use x25_local_dte in isotailor to specify a dte mask to be ! 111: * stripped when listening, and thus use full DTE strings in ! 112: * isoentities and QUIPU EDB files. You will also have to use the ! 113: * tsapd -a <dte> option to specify the listen address in ! 114: * /etc/rc.local and other tsapd startups since by default this equals ! 115: * x25_local_dte and thus will be masked to <null> unless overridden ! 116: * with full DTE + subaddress. ! 117: */ ! 118: ! 119: /* ! 120: * in ADDR_LISTEN context, it may be neccessary to only listen ! 121: * on the sub-address, because certain PTT-provided networks ! 122: * remove the local DTE from incoming CR packets. ! 123: * ! 124: * SunLink X.25 listen asserts whatever DTE it is given as a simple ! 125: * string-compare, and will never receive inbound calls that bear ! 126: * only the sub-address if you assert the full DTE. ! 127: * ! 128: * this behaviour is orthogonal to any requirements to remove DNIC ! 129: * or add a leading 0 on outbound calls, and so needs a separate ! 130: * test. It uses tailor variable x25_local_dte to assert the local ! 131: * DTE *without* subaddress which should be tested for and stripped ! 132: * when detected. ! 133: */ ! 134: ! 135: if ((context == ADDR_LISTEN) && x25_local_dte && *x25_local_dte) ! 136: { ! 137: register int i; ! 138: ! 139: if ( strncmp(generic -> na_dte, x25_local_dte, ! 140: i = strlen(x25_local_dte)) == 0 ) ! 141: { ! 142: bcopy(generic -> na_dte + i, dte, dtelen = ! 143: generic -> na_dtelen - i); ! 144: dte[dtelen] = NULL; ! 145: } ! 146: } ! 147: #endif ! 148: ! 149: DLOG (x25_log, LLOG_DEBUG, ! 150: ("gen2if %s -> %s, %d octets; PID %s", ! 151: generic -> na_dte, dte, dtelen, ! 152: sel2str (generic -> na_pid, (int) generic -> na_pidlen,1))); ! 153: ! 154: ! 155: #ifndef CAMTEC_CCL ! 156: bzero ((char *)specific, sizeof *specific); ! 157: #endif ! 158: ! 159: #ifdef UBC_X25 ! 160: if ((specific -> xaddr_len = dtelen) != 0) { ! 161: bcopy (dte, specific -> xaddr_addr, ! 162: dtelen); ! 163: specific -> xaddr_len = dtelen; ! 164: specific -> xaddr_facilities = 0; ! 165: bcopy (generic -> na_pid, specific -> xaddr_proto, ! 166: generic -> na_pidlen); ! 167: bcopy (generic -> na_cudf, specific -> xaddr_userdata, ! 168: generic -> na_cudflen); ! 169: } ! 170: #endif ! 171: ! 172: #ifdef SUN_X25 ! 173: specific -> hostlen = char2bcd (dte, specific -> host); ! 174: ! 175: /* Zero PID */ ! 176: if (generic -> na_pidlen) { /* non-null PID */ ! 177: if (generic -> na_pidlen > NPSIZE) { ! 178: SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, ! 179: ("PID too long (%d > %d)", generic -> na_pidlen, NPSIZE)); ! 180: return (CONN_DB *)0; ! 181: } else { ! 182: bzero((char *)specific -> data, NPSIZE); ! 183: bcopy (generic -> na_pid, (char *)specific -> data, ! 184: generic -> na_pidlen); ! 185: bcopy (generic -> na_cudf, (char *) specific -> data + NPSIZE, ! 186: generic -> na_cudflen); ! 187: specific -> datalen = generic -> na_pidlen + generic -> na_cudflen; ! 188: } ! 189: } else { /* Null PID (just copy in CUDF, the first four octets of which ! 190: will be the PID in any case) */ ! 191: bcopy (generic -> na_cudf, (char *)specific -> data, ! 192: generic -> na_cudflen); ! 193: specific -> datalen = generic -> na_cudflen; ! 194: } ! 195: #endif ! 196: ! 197: #ifdef CAMTEC_CCL ! 198: switch (context) { ! 199: case ADDR_REMOTE: ! 200: iov = &(specific -> ccl_iovec[0]); ! 201: if (x25_outgoing_port == '#') { ! 202: char *a, *b; ! 203: int i; ! 204: ! 205: iov -> iov_len = dtelen + 4; ! 206: bzero(iov -> iov_base, iov -> iov_len + 1); ! 207: a = iov -> iov_base; ! 208: b = dte; ! 209: *a++ = '#'; ! 210: *a++ = '['; ! 211: for (i = 0; i < dtelen; i++) { ! 212: if (i == 2) *a++ = ':'; ! 213: else if (i == 14) *a++ = ']'; ! 214: *a++ = *b++; ! 215: } ! 216: } ! 217: else { ! 218: iov -> iov_len = dtelen+1; ! 219: bcopy(dte, (iov -> iov_base)+1, dtelen); ! 220: *(iov -> iov_base) = x25_outgoing_port; ! 221: } ! 222: break; ! 223: ! 224: case ADDR_LOCAL: ! 225: iov = &(specific -> ccl_iovec[0]); ! 226: strncpy(iov -> iov_base, generic -> na_dte, generic -> na_dtelen); ! 227: iov -> iov_base[generic -> na_dtelen] = '\0'; ! 228: return (specific); ! 229: ! 230: case ADDR_LISTEN: ! 231: iov = &(specific -> ccl_iovec[0]); ! 232: if (generic -> na_pidlen) ! 233: { /* listen on a PID */ ! 234: register int i; ! 235: iov -> iov_base[0] = 'C'; ! 236: bcopy(generic -> na_pid, iov -> iov_base + 1, ! 237: i = generic -> na_pidlen); ! 238: iov -> iov_len = i + 1; ! 239: } ! 240: else ! 241: if (generic -> na_dtelen < 6) ! 242: { /* listen on a subaddress */ ! 243: register int i; ! 244: iov -> iov_base[0] = 'S'; ! 245: bcopy(generic -> na_dte, iov -> iov_base + 1, ! 246: i = generic -> na_dtelen); ! 247: iov -> iov_len = i + 1; ! 248: } ! 249: else /* full DTE */ ! 250: bcopy(dte, iov -> iov_base, ! 251: iov -> iov_len = dtelen); ! 252: return (specific); ! 253: } ! 254: /* ! 255: * CUDF & PID must be merged. malloc initailly PIDsize space ! 256: * and bzero it. this may be UK net specific action which ! 257: * ensures we do NOT fall foul of listeners which use pid ! 258: * to match as well as "true" cudf & DTE. ! 259: */ ! 260: ! 261: (iov = &(specific -> ccl_iovec[2])) -> iov_len = 0; ! 262: if (generic -> na_faclen != 0) ! 263: bcopy (generic -> na_fac, iov -> iov_base, ! 264: iov -> iov_len = min( generic -> na_faclen, FACSIZE) ); ! 265: iov++; ! 266: if ( (iov -> iov_len = generic -> na_pidlen) != 0) ! 267: bcopy (generic -> na_pid, iov -> iov_base, generic -> na_pidlen); ! 268: ! 269: /* ! 270: * if there is any other user data add that in now... ! 271: * actually cudf is a variable length field so this is ! 272: * all very suspect. ! 273: */ ! 274: ! 275: if (generic -> na_cudflen != 0) ! 276: bcopy(generic -> na_cudf, iov -> iov_base + iov -> iov_len, ! 277: generic -> na_cudflen), iov -> iov_len += generic -> na_cudflen; ! 278: #endif ! 279: ! 280: return(specific); ! 281: } ! 282: ! 283: /* */ ! 284: ! 285: /* ! 286: * convert from interface specific format to generic X.25 structure ! 287: */ ! 288: /* ARGSUSED */ ! 289: struct NSAPaddr *if2gen (generic, specific, context) ! 290: struct NSAPaddr *generic; ! 291: CONN_DB *specific; ! 292: int context; ! 293: { ! 294: int dtelen; ! 295: char dte[NSAP_DTELEN + 1]; ! 296: #ifdef CAMTEC_CCL ! 297: struct iovec *iov; ! 298: #endif ! 299: ! 300: if (generic == NULLNA || specific == (CONN_DB *) 0) ! 301: return NULLNA; ! 302: bzero ((char *)generic, sizeof *generic); ! 303: bzero (dte, sizeof dte); ! 304: dtelen = 0; ! 305: ! 306: generic -> na_stack = NA_X25; ! 307: generic -> na_community = ts_comm_x25_default; ! 308: ! 309: #ifdef UBC_X25 ! 310: if (specific -> xaddr_len != 0) { ! 311: bcopy (specific -> xaddr_addr, dte, specific -> xaddr_len); ! 312: dtelen = specific -> xaddr_len; ! 313: bcopy (specific -> xaddr_proto, generic -> na_pid, ! 314: sizeof(specific -> xaddr_proto)); ! 315: generic -> na_pidlen = sizeof specific -> xaddr_proto; ! 316: bcopy (specific -> xaddr_userdata, generic -> na_cudf, ! 317: sizeof(specific -> xaddr_userdata)); ! 318: generic -> na_cudflen = sizeof specific -> xaddr_userdata; ! 319: } ! 320: #endif ! 321: ! 322: #ifdef SUN_X25 ! 323: dtelen = bcd2char (specific -> host, dte, (int) specific -> hostlen); ! 324: ! 325: if (specific -> datalen > NPSIZE) { /* have some real user data after the PID */ ! 326: bcopy((char *)specific -> data, generic -> na_pid, ! 327: generic -> na_pidlen = NPSIZE); ! 328: bcopy((char *) specific -> data + generic -> na_pidlen, ! 329: generic -> na_cudf, ! 330: generic -> na_cudflen = specific -> datalen - generic -> na_pidlen); ! 331: } ! 332: else { /* PID only */ ! 333: bcopy((char *)specific -> data, generic -> na_pid, ! 334: generic -> na_pidlen = specific -> datalen); ! 335: generic -> na_cudflen = 0; ! 336: } ! 337: ! 338: #endif ! 339: ! 340: #ifdef CAMTEC_CCL ! 341: switch (context) { ! 342: case ADDR_REMOTE: ! 343: ! 344: iov = &(specific -> ccl_iovec[1]); ! 345: if (iov -> iov_len) { ! 346: if (*(iov->iov_base) == '#') { ! 347: char *a; ! 348: ! 349: a = iov -> iov_base; ! 350: while (*a && iov -> iov_len) { ! 351: if (*a == ']') { ! 352: iov -> iov_len--; ! 353: a++; ! 354: break; ! 355: } ! 356: iov -> iov_len--; ! 357: a++; ! 358: } ! 359: if (*a == 0 || iov -> iov_len == 0) ! 360: dtelen = 0; ! 361: else { ! 362: dtelen = iov -> iov_len; ! 363: bcopy (a, dte, dtelen); ! 364: } ! 365: } ! 366: else { ! 367: dtelen = iov -> iov_len - 1; ! 368: bcopy ((iov -> iov_base)+1, dte, ! 369: dtelen); ! 370: } ! 371: } ! 372: else dtelen = 0; ! 373: break; ! 374: ! 375: case ADDR_LOCAL: ! 376: iov = &(specific -> ccl_iovec[0]); ! 377: if (iov -> iov_len) { ! 378: dtelen = iov -> iov_len -1; ! 379: bcopy ((iov -> iov_base)+1, dte, ! 380: dtelen); ! 381: } ! 382: else dtelen = 0; ! 383: break; ! 384: ! 385: case ADDR_LISTEN: ! 386: return NULLNA; ! 387: } ! 388: ! 389: if ( (iov = &(specific -> ccl_iovec[2])) -> iov_len ) ! 390: bcopy( iov -> iov_base, generic -> na_fac, ! 391: generic -> na_faclen = min( iov -> iov_len, FACSIZE)); ! 392: ! 393: if ( ++iov -> iov_len) ! 394: { ! 395: bcopy( iov -> iov_base, generic -> na_pid, ! 396: generic -> na_pidlen = min( iov -> iov_len, NPSIZE)); ! 397: if ( iov -> iov_len > NPSIZE) ! 398: bcopy( iov -> iov_base + NPSIZE, generic -> na_cudf, ! 399: generic -> na_cudflen = min(iov -> iov_len - NPSIZE, CUDFSIZE)); ! 400: } ! 401: #endif ! 402: ! 403: if (x25_dnic_prefix && *x25_dnic_prefix) { ! 404: register int i; ! 405: ! 406: i = 0; ! 407: if (x25_intl_zero && dte[0] == '0' && dte[1] != '0') ! 408: i = 1; ! 409: else ! 410: if (x25_dnic_prefix ! 411: && *x25_dnic_prefix ! 412: && x25_strip_dnic ! 413: && dtelen < 12) /* local call... */ ! 414: bcopy (x25_dnic_prefix, generic -> na_dte, ! 415: generic -> na_dtelen = strlen (x25_dnic_prefix)); ! 416: ! 417: bcopy (dte + i, generic -> na_dte + generic -> na_dtelen, dtelen - i); ! 418: generic -> na_dtelen += dtelen - i; ! 419: } ! 420: else ! 421: bcopy (dte, generic -> na_dte, generic -> na_dtelen = dtelen); ! 422: ! 423: DLOG (x25_log, LLOG_DEBUG, ! 424: ("if2gen %s -> %s, %d octets; PID %s", ! 425: dte, generic -> na_dte, generic -> na_dtelen, ! 426: sel2str (generic -> na_pid, (int) generic -> na_pidlen,1))); ! 427: ! 428: return(generic); ! 429: } ! 430: ! 431: /* */ ! 432: ! 433: #ifdef SUN_X25 ! 434: static int char2bcd (s, d) ! 435: register char *s; ! 436: register u_char *d; ! 437: { ! 438: register int c, ! 439: i; ! 440: ! 441: for (i = 0; *s; i++) { ! 442: if ((c = *s++) >= 'a' && c <= 'f') ! 443: c -= 'a' + 0x0a; ! 444: else ! 445: if (c >= 'A' && c <= 'F') ! 446: c -= 'A' + 0x0a; ! 447: else ! 448: if (c >= '0' && c <= '9') ! 449: c -= '0'; ! 450: else ! 451: c = 0; ! 452: ! 453: if (i & 1) ! 454: *d++ |= c & 0xf; ! 455: else ! 456: *d = (c & 0xf) << 4; ! 457: } ! 458: ! 459: return i; ! 460: } ! 461: ! 462: /* */ ! 463: ! 464: static int bcd2char (s, d, len) ! 465: register u_char *s; ! 466: register char *d; ! 467: int len; ! 468: { ! 469: register int i, ! 470: g; ! 471: ! 472: for (i = 0; i < len; i++) { ! 473: g = s[i >> 1]; ! 474: if ((i & 1) == 0) ! 475: g >>= 4; ! 476: g &= 0xf; ! 477: ! 478: if (g < 0x0a) ! 479: *d++ = g + '0'; ! 480: else ! 481: *d++ = g + 'a' - 0x0a; ! 482: } ! 483: ! 484: *d = NULL; ! 485: ! 486: return len; ! 487: } ! 488: #endif ! 489: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.