|
|
1.1 ! root 1: /* tsapinitiate.c - TPM: initiator */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/tsap/RCS/tsapinitiate.c,v 7.2 90/07/09 14:51:26 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/tsap/RCS/tsapinitiate.c,v 7.2 90/07/09 14:51:26 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: tsapinitiate.c,v $ ! 12: * Revision 7.2 90/07/09 14:51:26 mrose ! 13: * sync ! 14: * ! 15: * Revision 7.1 90/03/23 17:31:34 mrose ! 16: * 8 ! 17: * ! 18: * Revision 7.0 89/11/23 22:30:44 mrose ! 19: * Release 6.0 ! 20: * ! 21: */ ! 22: ! 23: /* ! 24: * NOTICE ! 25: * ! 26: * Acquisition, use, and distribution of this module and related ! 27: * materials are subject to the restrictions of a license agreement. ! 28: * Consult the Preface in the User's Manual for the full terms of ! 29: * this agreement. ! 30: * ! 31: */ ! 32: ! 33: ! 34: /* LINTLIBRARY */ ! 35: ! 36: #include <stdio.h> ! 37: #include <signal.h> ! 38: #include "tpkt.h" ! 39: #include "mpkt.h" ! 40: #include "isoservent.h" ! 41: #include "tailor.h" ! 42: ! 43: ! 44: static struct nsapent { ! 45: int ns_type; ! 46: int ns_stack; ! 47: ! 48: IFP ns_open; ! 49: } nsaps[] = { ! 50: #ifdef TCP ! 51: NA_TCP, TS_TCP, tcpopen, ! 52: #endif ! 53: #ifdef X25 ! 54: NA_X25, TS_X25, x25open, ! 55: #endif ! 56: #ifdef BRIDGE_X25 ! 57: NA_BRG, TS_BRG, bridgeopen, ! 58: #endif ! 59: #ifdef TP4 ! 60: NA_NSAP, TS_TP4, tp4open, ! 61: #endif ! 62: ! 63: NOTOK, TS_NONE, NULL ! 64: }; ! 65: ! 66: ! 67: struct TSAPaddr *newtaddr (), *ta2norm (), *maketsbaddr (); ! 68: ! 69: /* T-(ASYN-)CONNECT.REQUEST */ ! 70: ! 71: int TAsynConnRequest (calling, called, expedited, data, cc, qos, ! 72: tc, td, async) ! 73: struct TSAPaddr *calling, ! 74: *called; ! 75: int expedited, ! 76: cc, ! 77: async; ! 78: char *data; ! 79: struct QOStype *qos; ! 80: struct TSAPconnect *tc; ! 81: struct TSAPdisconnect *td; ! 82: { ! 83: register int n; ! 84: SBV smask; ! 85: int result; ! 86: ! 87: isodetailor (NULLCP, 0); ! 88: ! 89: #ifdef notdef ! 90: missingP (calling); ! 91: #endif ! 92: missingP (called); ! 93: if ((n = called -> ta_naddr) <= 0) ! 94: return tsaplose (td, DR_PARAMETER, NULLCP, ! 95: "no NSAP addresses in called parameter"); ! 96: if (n > NTADDR) ! 97: return tsaplose (td, DR_PARAMETER, NULLCP, ! 98: "too many NSAP addresses in called parameter"); ! 99: ! 100: if ((called = ta2norm (called)) == NULLTA) ! 101: return tsaplose (td, DR_PARAMETER, "invalid called parameter"); ! 102: toomuchP (data, cc, TS_SIZE, "initial"); ! 103: #ifdef notdef ! 104: missingP (qos); ! 105: #endif ! 106: missingP (td); ! 107: ! 108: smask = sigioblock (); ! 109: ! 110: result = TConnRequestAux (calling, called, expedited, data, cc, qos, ! 111: tc, td, async); ! 112: ! 113: (void) sigiomask (smask); ! 114: ! 115: return result; ! 116: } ! 117: ! 118: /* */ ! 119: ! 120: static int TConnRequestAux (calling, called, expedited, data, cc, qos, ! 121: tc, td, async) ! 122: struct TSAPaddr *calling, ! 123: *called; ! 124: char *data; ! 125: int expedited, ! 126: cc, ! 127: async; ! 128: struct QOStype *qos; ! 129: register struct TSAPconnect *tc; ! 130: register struct TSAPdisconnect *td; ! 131: { ! 132: int result; ! 133: register struct tsapblk *tb; ! 134: ! 135: if ((tb = newtblk ()) == NULL) ! 136: return tsaplose (td, DR_CONGEST, NULLCP, "out of memory"); ! 137: ! 138: if (calling == NULLTA) { ! 139: static struct TSAPaddr tas; ! 140: ! 141: calling = &tas; ! 142: bzero ((char *) calling, sizeof *calling); ! 143: } ! 144: #ifdef notdef ! 145: if (called -> ta_selectlen > 0 && calling -> ta_selectlen == 0) { ! 146: calling -> ta_port = htons ((u_short) (0x8000 | (getpid () & 0x7fff))); ! 147: calling -> ta_selectlen = sizeof calling -> ta_port; ! 148: } ! 149: #endif ! 150: ! 151: if (qos) ! 152: tb -> tb_qos = *qos; /* struct copy */ ! 153: ! 154: if ((tb -> tb_calling = (struct TSAPaddr *) ! 155: calloc (1, sizeof *tb -> tb_calling)) == NULL) ! 156: goto no_mem; ! 157: *tb -> tb_calling = *calling; /* struct copy */ ! 158: bcopy (calling -> ta_selector, tb -> tb_initiating.ta_selector, ! 159: tb -> tb_initiating.ta_selectlen = calling -> ta_selectlen); ! 160: ! 161: if ((tb -> tb_called = (struct TSAPaddr *) ! 162: calloc (1, sizeof *tb -> tb_called)) == NULL) ! 163: goto no_mem; ! 164: *tb -> tb_called = *called; /* struct copy */ ! 165: ! 166: if ((tb -> tb_cc = cc) > 0) { ! 167: if ((tb -> tb_data = malloc ((unsigned) cc)) == NULLCP) { ! 168: no_mem: ; ! 169: (void) tsaplose (td, DR_CONGEST, NULLCP, "out of memory"); ! 170: goto out; ! 171: } ! 172: bcopy (data, tb -> tb_data, cc); ! 173: } ! 174: tb -> tb_expedited = expedited; ! 175: ! 176: if ((result = TConnAttempt (tb, td, async)) == NOTOK) { ! 177: #ifdef MGMT ! 178: if (tb -> tb_manfnx) ! 179: (*tb -> tb_manfnx) (OPREQOUTBAD, tb); ! 180: #endif ! 181: goto out; ! 182: } ! 183: ! 184: if (async) { ! 185: tc -> tc_sd = tb -> tb_fd; ! 186: switch (result) { ! 187: case CONNECTING_1: ! 188: case CONNECTING_2: ! 189: return result; ! 190: } ! 191: } ! 192: ! 193: if ((result = (*tb -> tb_retryPfnx) (tb, async, tc, td)) == DONE && !async) ! 194: result = OK; ! 195: return result; ! 196: ! 197: out: ; ! 198: freetblk (tb); ! 199: ! 200: return NOTOK; ! 201: } ! 202: ! 203: /* */ ! 204: ! 205: static int TConnAttempt (tb, td, async) ! 206: struct tsapblk *tb; ! 207: struct TSAPdisconnect *td; ! 208: int async; ! 209: { ! 210: register int n; ! 211: int didone, ! 212: l, ! 213: result; ! 214: register struct TSAPaddr *called, *calling; ! 215: struct TSAPaddr *realcalled; ! 216: register struct NSAPaddr *na, *la; ! 217: struct NSAPaddr *realna; ! 218: register struct TSAPdisconnect *te = td; ! 219: struct TSAPdisconnect tds; ! 220: ! 221: calling = tb -> tb_calling; ! 222: called = tb -> tb_called; ! 223: ! 224: didone = 0; ! 225: for (na = called -> ta_addrs, n = called -> ta_naddr - 1; ! 226: n >= 0; ! 227: na++, n--) { ! 228: register int *ip; ! 229: register char **ap; ! 230: register struct nsapent *ns; ! 231: ! 232: realcalled = called; ! 233: realna = na; ! 234: for (ip = ts_communities; *ip; ip++) ! 235: if (*ip == na -> na_community) ! 236: break; ! 237: if (!*ip) ! 238: continue; ! 239: for (ip = tsb_communities, ap = tsb_addresses; *ip; ip++, ap++) ! 240: if (*ip == na -> na_community) { ! 241: if ((realcalled = maketsbaddr (*ap, na, called)) == NULLTA) ! 242: continue; ! 243: realna = realcalled -> ta_addrs; ! 244: break; ! 245: } ! 246: ! 247: for (la = calling -> ta_addrs, l = calling -> ta_naddr - 1; ! 248: l >= 0; ! 249: la++, l--) ! 250: if (la -> na_community == na -> na_community) ! 251: break; ! 252: if (l < 0) ! 253: la = NULLNA; ! 254: ! 255: for (ns = nsaps; ns -> ns_open; ns++) ! 256: if (ns -> ns_type == realna -> na_stack ! 257: && (ns -> ns_stack & ts_stacks)) ! 258: break; ! 259: if (!ns -> ns_open) ! 260: continue; ! 261: ! 262: didone = 1; ! 263: switch (ns -> ns_type) { ! 264: case NA_NSAP: ! 265: if ((result = (*ns -> ns_open) (tb, calling, la, ! 266: realcalled, realna, ! 267: te, async)) == NOTOK) { ! 268: te = &tds; ! 269: continue; ! 270: } ! 271: break; ! 272: ! 273: default: ! 274: if ((result = (*ns -> ns_open) (tb, la, realna, te, async)) ! 275: == NOTOK) { ! 276: te = &tds; ! 277: continue; ! 278: } ! 279: break; ! 280: } ! 281: break; ! 282: } ! 283: ! 284: if (tb -> tb_fd == NOTOK) { ! 285: if (!didone) ! 286: return tsaplose (td, DR_PARAMETER, NULLCP, ! 287: "no supported NSAP addresses in, nor known TSBridges for, called parameter"); ! 288: ! 289: return NOTOK; ! 290: } ! 291: ! 292: if (la) { ! 293: tb -> tb_initiating.ta_present = 1; ! 294: tb -> tb_initiating.ta_addr = *la; /* struct copy */ ! 295: } ! 296: if (la && la != calling -> ta_addrs) { ! 297: struct NSAPaddr ns; ! 298: ! 299: ns = calling -> ta_addrs[0]; /* struct copy */ ! 300: calling -> ta_addrs[0] = *la; /* .. */ ! 301: *la = ns; /* .. */ ! 302: la = calling -> ta_addrs; /* .. */ ! 303: } ! 304: ! 305: bcopy (realcalled -> ta_selector, tb -> tb_responding.ta_selector, ! 306: tb -> tb_responding.ta_selectlen = realcalled -> ta_selectlen); ! 307: tb -> tb_responding.ta_present = 1; ! 308: tb -> tb_responding.ta_addr = *realna; /* struct copy */ ! 309: ! 310: if ((result = (*tb -> tb_connPfnx) (tb, tb -> tb_expedited, tb -> tb_data, ! 311: tb -> tb_cc, td)) == NOTOK) ! 312: return NOTOK; ! 313: ! 314: if (result == OK) ! 315: result = CONNECTING_1; ! 316: ! 317: return result; ! 318: } ! 319: ! 320: /* T-ASYN-RETRY.REQUEST (pseudo) */ ! 321: ! 322: int TAsynRetryRequest (sd, tc, td) ! 323: int sd; ! 324: struct TSAPconnect *tc; ! 325: struct TSAPdisconnect *td; ! 326: { ! 327: SBV smask; ! 328: int result; ! 329: register struct tsapblk *tb; ! 330: struct TSAPaddr *ta; ! 331: ! 332: missingP (tc); ! 333: missingP (td); ! 334: ! 335: smask = sigioblock (); ! 336: ! 337: if ((tb = findtblk (sd)) == NULL) { ! 338: (void) sigiomask (smask); ! 339: return tsaplose (td, DR_PARAMETER, NULLCP, ! 340: "invalid transport descriptor"); ! 341: } ! 342: if (tb -> tb_flags & TB_CONN) { ! 343: (void) sigiomask (smask); ! 344: return tsaplose (td, DR_OPERATION, NULLCP, ! 345: "transport descriptor connected"); ! 346: } ! 347: ! 348: ta = tb -> tb_called; ! 349: ! 350: switch (result = (*tb -> tb_retryPfnx) (tb, 1, tc, td)) { ! 351: case NOTOK: /* try next nsap in list */ ! 352: if (ta -> ta_naddr <= 1) { ! 353: freetblk (tb); ! 354: break; ! 355: } ! 356: *tb -> tb_called = *newtaddr (ta, &ta -> ta_addrs[1], ! 357: ta -> ta_naddr - 1); /* struct copy */ ! 358: ! 359: switch (result = TConnAttempt (tb, td, 1)) { ! 360: case DONE: ! 361: result = OK; ! 362: /* and fall... */ ! 363: case CONNECTING_1: ! 364: case CONNECTING_2: ! 365: if (tb -> tb_fd != sd) { ! 366: (void) dup2 (tb -> tb_fd, sd); ! 367: (void) close (tb -> tb_fd); ! 368: tb -> tb_fd = sd; ! 369: } ! 370: break; ! 371: ! 372: case NOTOK: ! 373: freetblk (tb); ! 374: break; ! 375: } ! 376: break; ! 377: ! 378: case DONE: ! 379: if (tb -> tb_data) { ! 380: free (tb -> tb_data); ! 381: tb -> tb_data = NULLCP; ! 382: } ! 383: tb -> tb_cc = 0; ! 384: tb -> tb_expedited = 0; ! 385: break; ! 386: ! 387: case CONNECTING_1: ! 388: case CONNECTING_2: ! 389: default: ! 390: break; ! 391: } ! 392: ! 393: (void) sigiomask (smask); ! 394: ! 395: return result; ! 396: } ! 397: ! 398: /* T-ASYN-NEXT.REQUEST (pseudo) */ ! 399: ! 400: int TAsynNextRequest (sd, tc, td) ! 401: int sd; ! 402: struct TSAPconnect *tc; ! 403: struct TSAPdisconnect *td; ! 404: { ! 405: SBV smask; ! 406: int result; ! 407: register struct tsapblk *tb; ! 408: struct TSAPaddr *ta; ! 409: ! 410: missingP (tc); ! 411: missingP (td); ! 412: ! 413: smask = sigioblock (); ! 414: ! 415: if ((tb = findtblk (sd)) == NULL) { ! 416: (void) sigiomask (smask); ! 417: return tsaplose (td, DR_PARAMETER, NULLCP, ! 418: "invalid transport descriptor"); ! 419: } ! 420: if (tb -> tb_flags & TB_CONN) { ! 421: (void) sigiomask (smask); ! 422: return tsaplose (td, DR_OPERATION, NULLCP, ! 423: "transport descriptor connected"); ! 424: } ! 425: ! 426: ta = tb -> tb_called; ! 427: ! 428: /* close previous connection attempt */ ! 429: if (tb -> tb_fd != NOTOK) ! 430: (void) (*tb -> tb_closefnx) (tb -> tb_fd); ! 431: tb -> tb_fd = NOTOK; ! 432: ! 433: if (ta -> ta_naddr <= 1) { ! 434: freetblk (tb); ! 435: (void) sigiomask (smask); ! 436: return tsaplose (td, DR_PARAMETER, NULLCP, "no more NSAPs to try"); ! 437: } ! 438: *tb -> tb_called = *newtaddr (ta, &ta -> ta_addrs[1], ! 439: ta -> ta_naddr - 1); /* struct copy */ ! 440: ! 441: switch (result = TConnAttempt (tb, td, 1)) { ! 442: case DONE: ! 443: result = OK; ! 444: /* and fall... */ ! 445: case CONNECTING_1: ! 446: case CONNECTING_2: ! 447: if (tb -> tb_fd != sd) { ! 448: (void) dup2 (tb -> tb_fd, sd); ! 449: (void) close (tb -> tb_fd); ! 450: tb -> tb_fd = sd; ! 451: } ! 452: break; ! 453: ! 454: case NOTOK: ! 455: freetblk (tb); ! 456: break; ! 457: } ! 458: ! 459: (void) sigiomask (smask); ! 460: ! 461: return result; ! 462: } ! 463: ! 464: /* */ ! 465: ! 466: static struct TSAPaddr *newtaddr (ta, na, n) ! 467: register struct TSAPaddr *ta; ! 468: register struct NSAPaddr *na; ! 469: int n; ! 470: { ! 471: static struct TSAPaddr tzs; ! 472: register struct TSAPaddr *tz = &tzs; ! 473: register struct NSAPaddr *nz = tz -> ta_addrs; ! 474: ! 475: bzero ((char *) tz, sizeof *tz); ! 476: ! 477: if (tz -> ta_selectlen = ta -> ta_selectlen) ! 478: bcopy (ta -> ta_selector, tz -> ta_selector, ta -> ta_selectlen); ! 479: if (na) ! 480: for (tz -> ta_naddr = n; n > 0; n--) ! 481: *nz++ = *na++; /* struct copy */ ! 482: ! 483: return tz; ! 484: } ! 485: ! 486: /* */ ! 487: ! 488: struct TSAPaddr *ta2norm (ta) ! 489: register struct TSAPaddr *ta; ! 490: { ! 491: register int n, ! 492: *ip; ! 493: static struct TSAPaddr tzs; ! 494: register struct TSAPaddr *tz = &tzs; ! 495: register struct NSAPaddr *na, ! 496: *ca; ! 497: ! 498: SLOG (addr_log, LLOG_TRACE, NULLCP, ! 499: ("ta2norm %s", taddr2str (ta))); ! 500: ! 501: for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1; n >= 0; na++, n--) ! 502: if (na -> na_community == 0) { ! 503: SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ! 504: ("ta2norm: empty subnet in NSAP address at offset %d", ! 505: na - ta -> ta_addrs)); ! 506: return NULLTA; ! 507: } ! 508: ! 509: bzero ((char *) tz, sizeof *tz); ! 510: bcopy (ta -> ta_selector, tz -> ta_selector, ! 511: tz -> ta_selectlen = ta -> ta_selectlen); ! 512: ca = tz -> ta_addrs; ! 513: ! 514: for (ip = ts_communities; *ip; ip++) ! 515: for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1; ! 516: n >= 0; ! 517: na++, n--) ! 518: if (*ip == na -> na_community) { ! 519: *ca++ = *na; /* struct copy */ ! 520: tz -> ta_naddr++; ! 521: } ! 522: ! 523: for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1; n >= 0; na++, n--) { ! 524: for (ip = ts_communities; *ip; ip++) ! 525: if (*ip == na -> na_community) ! 526: break; ! 527: if (!*ip) { ! 528: *ca++ = *na; /* struct copy */ ! 529: tz -> ta_naddr++; ! 530: } ! 531: } ! 532: ! 533: SLOG (addr_log, LLOG_TRACE, NULLCP, ! 534: ("ta2norm returns %s", taddr2str (tz))); ! 535: ! 536: return tz; ! 537: } ! 538: ! 539: /* */ ! 540: ! 541: static struct TSAPaddr *maketsbaddr (cp, na, ta) ! 542: char *cp; ! 543: struct NSAPaddr *na; ! 544: struct TSAPaddr *ta; ! 545: { ! 546: static struct TSAPaddr newta; ! 547: register struct TSAPaddr *nta = &newta; ! 548: struct TSAPaddr *taz; ! 549: char *p; ! 550: struct PSAPaddr pas; ! 551: struct PSAPaddr *pa = &pas; ! 552: ! 553: ! 554: if ((taz = str2taddr (cp)) == NULLTA) ! 555: return taz; ! 556: ! 557: *nta = *taz; /* struct copy */ ! 558: bzero ((char *)pa, sizeof *pa); ! 559: pa -> pa_addr.sa_addr.ta_naddr = 1; ! 560: pa -> pa_addr.sa_addr.ta_addrs[0] = *na; ! 561: pa -> pa_addr.sa_addr.ta_selectlen = ta -> ta_selectlen; ! 562: (void) strncpy (pa -> pa_addr.sa_addr.ta_selector, ta -> ta_selector, ! 563: ta -> ta_selectlen); ! 564: if ((p = _paddr2str (pa, NULLNA, -1)) == NULL) ! 565: return NULLTA; ! 566: ! 567: if ((nta -> ta_selectlen = strlen (p)) >= TSSIZE) ! 568: return NULLTA; ! 569: else ! 570: (void) strncpy (nta -> ta_selector, p, TSSIZE); ! 571: nta -> ta_naddr = 1; ! 572: ! 573: return nta; ! 574: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.