|
|
1.1 ! root 1: /* psapinitiate.c - PPM: initiator */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psapinitiate.c,v 7.3 90/07/09 14:45:05 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/psap2-lpp/RCS/psapinitiate.c,v 7.3 90/07/09 14:45:05 mrose Exp $ ! 9: * ! 10: * Contributed by The Wollongong Group, Inc. ! 11: * ! 12: * ! 13: * $Log: psapinitiate.c,v $ ! 14: * Revision 7.3 90/07/09 14:45:05 mrose ! 15: * sync ! 16: * ! 17: * Revision 7.2 90/07/01 21:05:24 mrose ! 18: * pepsy ! 19: * ! 20: * Revision 7.1 89/12/01 10:51:43 mrose ! 21: * touch-up ! 22: * ! 23: * Revision 7.0 89/11/23 22:15:53 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: #include <stdio.h> ! 42: #include <signal.h> ! 43: #define LPP ! 44: #include "PS-types.h" ! 45: #include "ppkt.h" ! 46: #include "tailor.h" ! 47: ! 48: /* P-(ASYN-)CONNECT.REQUEST */ ! 49: ! 50: #ifndef notdef ! 51: /* ARGSUSED */ ! 52: #endif ! 53: ! 54: int PAsynConnRequest (calling, called, ctxlist, defctxname, prequirements, ! 55: srequirements, isn, settings, ref, data, ndata, qos, pc, pi, async) ! 56: struct PSAPaddr *calling, ! 57: *called; ! 58: int prequirements, ! 59: srequirements, ! 60: settings, ! 61: ndata, ! 62: async; ! 63: long isn; ! 64: struct PSAPctxlist *ctxlist; ! 65: OID defctxname; ! 66: struct SSAPref *ref; ! 67: PE *data; ! 68: struct QOStype *qos; ! 69: struct PSAPconnect *pc; ! 70: struct PSAPindication *pi; ! 71: { ! 72: SBV smask; ! 73: int result; ! 74: ! 75: isodetailor (NULLCP, 0); ! 76: ! 77: #ifdef notdef ! 78: missingP (calling); ! 79: #endif ! 80: missingP (called); ! 81: if (ctxlist == NULL || ctxlist -> pc_nctx != NPCTX_PS) ! 82: return psaplose (pi, PC_PARAMETER, NULLCP, ! 83: "exactly %d proposed presentation contexts supported", ! 84: NPCTX_PS); ! 85: #ifdef notdef ! 86: if (defctxname) ! 87: return psaplose (pi, PC_PARAMETER, NULLCP, ! 88: "default context name not allowed"); ! 89: #endif ! 90: if (prequirements != PR_KERNEL) ! 91: return psaplose (pi, PC_PARAMETER, NULLCP, ! 92: "presentation requirements settings not supported"); ! 93: ! 94: if (srequirements != SR_DUPLEX) ! 95: return psaplose (pi, PC_PARAMETER, NULLCP, ! 96: "session requirements settings not supported"); ! 97: if (isn != SERIAL_NONE) ! 98: return psaplose (pi, PC_PARAMETER, NULLCP, ! 99: "initial serial number not permitted"); ! 100: if (settings != 0) /* not really an accurate test... */ ! 101: return psaplose (pi, PC_PARAMETER, NULLCP, ! 102: "initial token settings not permitted"); ! 103: missingP (ref); ! 104: if (ref -> sr_ulen > SREF_USER_SIZE ! 105: || ref -> sr_ulen <= 2 ! 106: || ref -> sr_clen > SREF_COMM_SIZE ! 107: || ref -> sr_clen <= 2 ! 108: || ref -> sr_alen > SREF_ADDT_SIZE ! 109: || ref -> sr_alen == 1 ! 110: || ref -> sr_vlen > 0) ! 111: return psaplose (pi, PC_PARAMETER, NULLCP, "bad format for reference"); ! 112: if (data == NULL || ndata <= 0 || data[0] == NULLPE || ndata > NPDATA_PS) ! 113: return psaplose (pi, PC_PARAMETER, NULLCP, "bad initial user data"); ! 114: if (data[0] -> pe_context != PCI_ACSE) ! 115: return psaplose (pi, PC_PARAMETER, NULLCP, ! 116: "wrong context for initial user data"); ! 117: missingP (pc); ! 118: missingP (pi); ! 119: ! 120: smask = sigioblock (); ! 121: ! 122: result = PConnRequestAux (calling, called, ctxlist, ref, data[0], qos, ! 123: pc, pi, async); ! 124: ! 125: (void) sigiomask (smask); ! 126: ! 127: return result; ! 128: } ! 129: ! 130: /* */ ! 131: ! 132: static int PConnRequestAux (calling, called, ctxlist, ref, data, qos, pc, pi, ! 133: async) ! 134: struct PSAPaddr *calling, ! 135: *called; ! 136: struct PSAPctxlist *ctxlist; ! 137: struct SSAPref *ref; ! 138: PE data; ! 139: struct QOStype *qos; ! 140: struct PSAPconnect *pc; ! 141: struct PSAPindication *pi; ! 142: int async; ! 143: { ! 144: int result; ! 145: OID asn; ! 146: register struct psapblk *pb; ! 147: register struct type_PS_ConnectRequest__PDU *pdu; ! 148: register struct type_PS_SessionConnectionIdentifier *pref; ! 149: ! 150: if ((pb = newpblk ()) == NULL) ! 151: return psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); ! 152: ! 153: if ((pref = (struct type_PS_SessionConnectionIdentifier *) ! 154: malloc (sizeof *pref)) == NULL) { ! 155: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); ! 156: goto out1; ! 157: } ! 158: pb -> pb_reference = pref; ! 159: pdu = NULL; ! 160: if ((pref -> callingSSUserReference = str2qb (ref -> sr_udata + 2, ! 161: (int) ref -> sr_ulen - 2, 1)) ! 162: == NULL ! 163: || (pref -> commonReference = str2qb (ref -> sr_cdata + 2, ! 164: (int) ref -> sr_clen - 2, 1)) ! 165: == NULL) { ! 166: no_mem: ; ! 167: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); ! 168: goto out2; ! 169: } ! 170: if (ref -> sr_alen > 0) { ! 171: if ((pref -> additionalReferenceInformation ! 172: = str2qb (ref -> sr_adata + 2, ! 173: (int) ref -> sr_alen - 2, 1)) ! 174: == NULL) ! 175: goto no_mem; ! 176: } ! 177: else ! 178: pref -> additionalReferenceInformation = NULL; ! 179: ! 180: if ((pb -> pb_ber = ode2oid (DFLT_ATN)) == NULLOID) { ! 181: (void) psaplose (pi, PC_ABSTRACT, NULLCP, "%s: unknown", DFLT_ATN); ! 182: goto out2; ! 183: } ! 184: if ((pb -> pb_ber = oid_cpy (pb -> pb_ber)) == NULLOID) ! 185: goto no_mem; ! 186: ! 187: asn = NULLOID; ! 188: { ! 189: register int i; ! 190: register struct PSAPcontext *pp, ! 191: *qp; ! 192: ! 193: i = ctxlist -> pc_nctx - 1; ! 194: for (pp = ctxlist -> pc_ctx, qp = pb -> pb_contexts; ! 195: i >= 0; ! 196: i--, pp++, qp++) { ! 197: switch (qp -> pc_id = pp -> pc_id) { ! 198: case PCI_ROSE: ! 199: asn = pp -> pc_asn; /* and fall */ ! 200: case PCI_ACSE: ! 201: break; ! 202: ! 203: default: ! 204: (void) psaplose (pi, PC_PARAMETER, NULLCP, ! 205: "illegal value for PCI (%d)", ! 206: pp -> pc_id); ! 207: goto out2; ! 208: } ! 209: ! 210: if (pp -> pc_asn == NULLOID) { ! 211: (void) psaplose (pi, PC_PARAMETER, NULLCP, ! 212: "no abstract syntax name given for context %d", ! 213: pp -> pc_id); ! 214: goto out2; ! 215: } ! 216: ! 217: if (pp -> pc_atn && !atn_is_ok (pb, pp -> pc_atn)) { ! 218: (void) psaplose (pi, PC_TRANSFER, NULLCP, ! 219: "unknown transfer syntax given for context %d", ! 220: pp -> pc_id); ! 221: goto out2; ! 222: } ! 223: ! 224: qp -> pc_result = PC_ACCEPT; ! 225: ! 226: pb -> pb_ncontext++; ! 227: } ! 228: } ! 229: if (asn == NULLOID) { ! 230: (void) psaplose (pi, PC_PARAMETER, NULLCP, "PCI for SASE not present"); ! 231: goto out2; ! 232: } ! 233: ! 234: if ((pdu = (struct type_PS_ConnectRequest__PDU *) malloc (sizeof *pdu)) ! 235: == NULL) ! 236: goto no_mem; ! 237: ! 238: pdu -> version = int_PS_version_version__1; ! 239: pdu -> reference = pref; ! 240: if (calling && calling -> pa_selectlen > 0) { ! 241: if ((pdu -> calling = str2qb (calling -> pa_selector, ! 242: calling -> pa_selectlen, 1)) == NULL) ! 243: goto no_mem; ! 244: } ! 245: else ! 246: pdu -> calling = NULL; ! 247: ! 248: if (called -> pa_selectlen > 0) { ! 249: if ((pdu -> called = str2qb (called -> pa_selector, ! 250: called -> pa_selectlen, 1)) == NULL) ! 251: goto no_mem; ! 252: } ! 253: else ! 254: pdu -> called = NULL; ! 255: ! 256: if ((pdu -> asn = oid_cpy (asn)) == NULLOID) ! 257: goto no_mem; ! 258: ! 259: pdu -> user__data = data; ! 260: ! 261: pb -> pb_retry = NULLPE; ! 262: result = encode_PS_ConnectRequest__PDU (&pb -> pb_retry, 1, 0, NULLCP, ! 263: pdu); ! 264: ! 265: pdu -> reference = NULL; ! 266: pdu -> user__data = NULLPE; ! 267: free_PS_ConnectRequest__PDU (pdu); ! 268: pdu = NULL; ! 269: ! 270: if (result == NOTOK) { ! 271: (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", ! 272: PY_pepy); ! 273: goto out1; ! 274: } ! 275: ! 276: if ((result = PConnRequestAux2 (pb, calling ? &calling -> pa_addr.sa_addr ! 277: : NULLTA, ! 278: &called -> pa_addr.sa_addr, qos, ! 279: pi, async)) == NOTOK) ! 280: goto out1; ! 281: ! 282: if (async && result == OK) { ! 283: pc -> pc_sd = pb -> pb_fd; ! 284: return result; ! 285: } ! 286: if ((result = PAsynRetryAux (pb, pc, pi)) == DONE && !async) ! 287: result = OK; ! 288: return result; ! 289: ! 290: out2: ; ! 291: if (pdu) { ! 292: pdu -> reference = NULL; ! 293: pdu -> user__data = NULLPE; ! 294: free_PS_ConnectRequest__PDU (pdu); ! 295: } ! 296: ! 297: out1: ; ! 298: freepblk (pb); ! 299: ! 300: return NOTOK; ! 301: } ! 302: ! 303: /* */ ! 304: ! 305: #define QOS_RELIABLE_DFLT HIGH_QUALITY ! 306: ! 307: ! 308: int tcpopen (), udpopen (); ! 309: ! 310: static struct nsapent { ! 311: int ns_reliability; ! 312: int ns_tset; ! 313: ! 314: IFP ns_open; ! 315: } nsaps[] = { ! 316: HIGH_QUALITY, NA_TSET_TCP, tcpopen, ! 317: LOW_QUALITY, NA_TSET_UDP, udpopen, ! 318: ! 319: NULL ! 320: }; ! 321: ! 322: ! 323: static int PConnRequestAux2 (pb, calling, called, qos, pi, async) ! 324: struct psapblk *pb; ! 325: struct TSAPaddr *calling, ! 326: *called; ! 327: struct QOStype *qos; ! 328: struct PSAPindication *pi; ! 329: int async; ! 330: { ! 331: int reliability, ! 332: result; ! 333: register int n = called -> ta_naddr - 1; ! 334: register struct NSAPaddr *na = called -> ta_addrs; ! 335: ! 336: reliability = qos ? qos -> qos_reliability : QOS_RELIABLE_DFLT; ! 337: ! 338: for (; n >= 0; na++, n--) { ! 339: register int l; ! 340: register struct NSAPaddr *la; ! 341: register struct nsapent *ns; ! 342: ! 343: if (na -> na_stack != NA_TCP) ! 344: continue; ! 345: ! 346: if (na -> na_tset == 0) ! 347: na -> na_tset = NA_TSET_TCP; ! 348: ! 349: for (ns = nsaps; ns -> ns_open; ns++) ! 350: if (ns -> ns_reliability == reliability ! 351: && (ns -> ns_tset & na -> na_tset)) ! 352: break; ! 353: if (!ns -> ns_open) ! 354: continue; ! 355: ! 356: if (calling) { ! 357: for (l = calling -> ta_naddr - 1, la = calling -> ta_addrs; ! 358: l >= 0; ! 359: la++, l--) { ! 360: if (la -> na_stack != NA_TCP) ! 361: continue; ! 362: if (ns -> ns_tset & la -> na_tset) ! 363: break; ! 364: } ! 365: if (l < 0) ! 366: la = NULLNA; ! 367: } ! 368: else ! 369: la = NULLNA; ! 370: ! 371: if ((result = (*ns -> ns_open) (pb, la, na, pi, async)) != NOTOK) ! 372: break; ! 373: } ! 374: ! 375: { ! 376: register struct TSAPaddr *ta = &pb -> pb_responding.pa_addr.sa_addr; ! 377: ! 378: ta -> ta_addrs[0] = *na; /* struct copy */ ! 379: ta -> ta_naddr = 1; ! 380: } ! 381: ! 382: return (pb -> pb_fd != NOTOK ? result : NOTOK); ! 383: } ! 384: ! 385: /* P-ASYN-RETRY.REQUEST (pseudo) */ ! 386: ! 387: int PAsynRetryRequest (sd, pc, pi) ! 388: int sd; ! 389: struct PSAPconnect *pc; ! 390: struct PSAPindication *pi; ! 391: { ! 392: SBV smask; ! 393: int result; ! 394: register struct psapblk *pb; ! 395: ! 396: missingP (pc); ! 397: missingP (pi); ! 398: ! 399: smask = sigioblock (); ! 400: ! 401: if ((pb = findpblk (sd)) == NULL) { ! 402: (void) sigiomask (smask); ! 403: return psaplose (pi, PC_PARAMETER, NULLCP, ! 404: "invalid presentation descriptor"); ! 405: } ! 406: if (pb -> pb_flags & PB_CONN) { ! 407: (void) sigiomask (smask); ! 408: return psaplose (pi, PC_OPERATION, NULLCP, ! 409: "presentation descriptor connected"); ! 410: } ! 411: ! 412: switch (result = (*pb -> pb_retryfnx) (pb, pi)) { ! 413: case NOTOK: ! 414: pb -> pb_fd = NOTOK; ! 415: freepblk (pb); ! 416: break; ! 417: ! 418: case OK: ! 419: break; ! 420: ! 421: case DONE: ! 422: result = PAsynRetryAux (pb, pc, pi); ! 423: break; ! 424: } ! 425: ! 426: (void) sigiomask (smask); ! 427: ! 428: return result; ! 429: } ! 430: ! 431: /* */ ! 432: ! 433: static int PAsynRetryAux (pb, pc, pi) ! 434: register struct psapblk *pb; ! 435: struct PSAPconnect *pc; ! 436: struct PSAPindication *pi; ! 437: { ! 438: int result; ! 439: PE pe; ! 440: struct type_PS_PDUs *pdu; ! 441: ! 442: pdu = NULL; ! 443: result = decode_PS_PDUs (pb -> pb_response, 1, NULLIP, NULLVP, &pdu); ! 444: ! 445: #ifdef DEBUG ! 446: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) ! 447: pvpdu (psap2_log, print_PS_PDUs_P, pb -> pb_response, "PDU", 1); ! 448: #endif ! 449: ! 450: if (pb -> pb_retry) { ! 451: pe_free (pb -> pb_retry); ! 452: pb -> pb_retry = NULLPE; ! 453: } ! 454: ! 455: pe_free (pb -> pb_response); ! 456: pb -> pb_response = NULL; ! 457: ! 458: if (result == NOTOK) { ! 459: (void) ppktlose (pb, pi, PC_UNRECOGNIZED, NULLRF, NULLCP, ! 460: "error decoding PDU: %s", PY_pepy); ! 461: goto out; ! 462: } ! 463: ! 464: bzero ((char *) pc, sizeof *pc); ! 465: ! 466: switch (pdu -> offset) { ! 467: case type_PS_PDUs_connectResponse: ! 468: { ! 469: register struct type_PS_ConnectResponse__PDU *cr = ! 470: pdu -> un.connectResponse; ! 471: ! 472: if (pb -> pb_reliability == LOW_QUALITY ! 473: && refcmp (pb -> pb_reference, cr -> reference)) { ! 474: result = ppktlose (pb, pi, PC_SESSION, cr -> reference, ! 475: NULLCP, "reference mismatch"); ! 476: goto out; ! 477: } ! 478: ! 479: if (cr -> reason == NULL) { ! 480: pb -> pb_flags |= PB_CONN; ! 481: ! 482: pc -> pc_sd = pb -> pb_fd; ! 483: pc -> pc_result = PC_ACCEPT; ! 484: pc -> pc_qos.qos_reliability = pb -> pb_reliability; ! 485: pc -> pc_qos.qos_sversion = 2; ! 486: } ! 487: else { ! 488: pc -> pc_sd = NOTOK; ! 489: pc -> pc_result = cr -> reason -> parm; ! 490: } ! 491: ! 492: pdu2sel (pb -> pb_responding.pa_selector, ! 493: &pb -> pb_responding.pa_selectlen, ! 494: sizeof pb -> pb_responding.pa_selector, ! 495: cr -> responding); ! 496: pc -> pc_responding = pb -> pb_responding; /* struct copy */ ! 497: ! 498: pc -> pc_defctxresult = pb -> pb_result = PC_ACCEPT; ! 499: { ! 500: register int i; ! 501: register struct PSAPcontext *pp, ! 502: *qp; ! 503: ! 504: i = pb -> pb_ncontext; ! 505: for (pp = pb -> pb_contexts, qp = pc -> pc_ctxlist.pc_ctx; ! 506: i >= 0; ! 507: i--, pp++, qp++) { ! 508: qp -> pc_id = pp -> pc_id; ! 509: qp -> pc_asn = qp -> pc_atn = NULLOID; ! 510: qp -> pc_result = PC_ACCEPT; ! 511: } ! 512: pc -> pc_ctxlist.pc_nctx = pb -> pb_ncontext; ! 513: } ! 514: ! 515: pc -> pc_prequirements = PR_KERNEL; ! 516: pc -> pc_srequirements = SR_DUPLEX; ! 517: ! 518: pc -> pc_isn = SERIAL_NONE; ! 519: ! 520: pc -> pc_connect = *pdu2ref (pb -> pb_reference); /* struct copy */ ! 521: ! 522: pe = cr -> user__data, cr -> user__data = NULLPE; ! 523: if (pc -> pc_info[0] = pe) { ! 524: pe -> pe_context = PCI_ACSE; ! 525: pc -> pc_ninfo = 1; ! 526: } ! 527: ! 528: free_PS_PDUs (pdu); ! 529: ! 530: return DONE; ! 531: } ! 532: ! 533: case type_PS_PDUs_abort: ! 534: { ! 535: register struct PSAPabort *pa = &pi -> pi_abort; ! 536: register struct type_PS_Abort__PDU *ab = pdu -> un.abort; ! 537: ! 538: if (pb -> pb_reliability == LOW_QUALITY ! 539: && refcmp (pb -> pb_reference, ab -> reference)) { ! 540: result = psaplose (pi, PC_SESSION, NULLCP, ! 541: "reference mismatch"); ! 542: goto out; ! 543: } ! 544: ! 545: if (ab -> reason) { ! 546: switch (ab -> reason -> parm) { ! 547: case int_PS_Abort__reason_reason__not__specified: ! 548: default: ! 549: result = PC_NOTSPECIFIED; ! 550: break; ! 551: ! 552: case int_PS_Abort__reason_unrecognized__ppdu: ! 553: case int_PS_Abort__reason_unexpected__ppdu: ! 554: case int_PS_Abort__reason_unrecognized__ppdu__parameter: ! 555: result = PC_UNRECOGNIZED ! 556: + (ab -> reason -> parm ! 557: - int_PS_Abort__reason_unrecognized__ppdu); ! 558: break; ! 559: ! 560: case int_PS_Abort__reason_invalid__ppdu__parameter: ! 561: result = PC_INVALID; ! 562: break; ! 563: ! 564: case int_PS_Abort__reason_reference__mismatch: ! 565: result = PC_SESSION; ! 566: break; ! 567: } ! 568: result = psaplose (pi, result, NULLCP, NULLCP); ! 569: goto out; ! 570: } ! 571: pe = ab -> user__data, ab -> user__data = NULLPE; ! 572: ! 573: pi -> pi_type = PI_ABORT; ! 574: bzero ((char *) pa, sizeof *pa); ! 575: ! 576: pa -> pa_peer = 1; ! 577: pa -> pa_reason = PC_ABORTED; ! 578: if (pa -> pa_info[0] = pe) { ! 579: pe -> pe_context = PCI_ACSE; ! 580: pa -> pa_ninfo = 1; ! 581: } ! 582: ! 583: pc -> pc_sd = NOTOK; ! 584: pc -> pc_result = PC_ABORTED; ! 585: ! 586: result = DONE; ! 587: } ! 588: break; ! 589: ! 590: default: ! 591: /* this works 'cause the "reference" is always the FIRST element */ ! 592: result = ppktlose (pb, pi, PC_SESSION, ! 593: pdu -> un.connectResponse -> reference, NULLCP, ! 594: "unexpected PDU %d", pdu -> offset); ! 595: break; ! 596: } ! 597: ! 598: out: ; ! 599: if (pdu) ! 600: free_PS_PDUs (pdu); ! 601: freepblk (pb); ! 602: ! 603: return result; ! 604: } ! 605: ! 606: /* P-ASYN-NEXT.REQUEST (pseudo) */ ! 607: ! 608: /* ARGSUSED */ ! 609: ! 610: int PAsynNextRequest (sd, pc, pi) ! 611: int sd; ! 612: struct PSAPconnect *pc; ! 613: struct PSAPindication *pi; ! 614: { ! 615: return psaplose (pi, PC_OPERATION, NULLCP, ! 616: "operation not supported with lightweight presentation"); ! 617: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.