|
|
1.1 ! root 1: /* psaprovider.c - PPM: implement the pseudo-presentation protocol */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psaprovider.c,v 7.1 90/07/01 21:05:36 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/psap2-lpp/RCS/psaprovider.c,v 7.1 90/07/01 21:05:36 mrose Exp $ ! 9: * ! 10: * Contributed by The Wollongong Group, Inc. ! 11: * ! 12: * ! 13: * $Log: psaprovider.c,v $ ! 14: * Revision 7.1 90/07/01 21:05:36 mrose ! 15: * pepsy ! 16: * ! 17: * Revision 7.0 89/11/23 22:16:00 mrose ! 18: * Release 6.0 ! 19: * ! 20: */ ! 21: ! 22: /* ! 23: * NOTICE ! 24: * ! 25: * Acquisition, use, and distribution of this module and related ! 26: * materials are subject to the restrictions of a license agreement. ! 27: * Consult the Preface in the User's Manual for the full terms of ! 28: * this agreement. ! 29: * ! 30: */ ! 31: ! 32: ! 33: /* LINTLIBRARY */ ! 34: ! 35: #include <stdio.h> ! 36: #include <signal.h> ! 37: #define LPP ! 38: #include "PS-types.h" ! 39: #include "ppkt.h" ! 40: #include "tailor.h" ! 41: ! 42: /* DATA */ ! 43: ! 44: static int once_only = 0; ! 45: static struct psapblk psapque; ! 46: static struct psapblk *PHead = &psapque; ! 47: ! 48: /* P-DATA.REQUEST */ ! 49: ! 50: int PDataRequest (sd, data, ndata, pi) ! 51: int sd; ! 52: PE *data; ! 53: int ndata; ! 54: struct PSAPindication *pi; ! 55: { ! 56: SBV smask; ! 57: int result; ! 58: register struct psapblk *pb; ! 59: ! 60: if (data == NULL || ndata <= 0 || data[0] == NULLPE || ndata > NPDATA_PS) ! 61: return psaplose (pi, PC_PARAMETER, NULLCP, "bad user data"); ! 62: if (data[0] -> pe_context != PCI_ROSE) ! 63: return psaplose (pi, PC_PARAMETER, NULLCP, ! 64: "wrong context for user data"); ! 65: missingP (pi); ! 66: ! 67: smask = sigioblock (); ! 68: ! 69: psapPsig (pb, sd); ! 70: ! 71: if ((result = PDataRequestAux (pb, data[0], pi)) == NOTOK) ! 72: freepblk (pb); ! 73: ! 74: (void) sigiomask (smask); ! 75: ! 76: return result; ! 77: } ! 78: ! 79: /* */ ! 80: ! 81: static int PDataRequestAux (pb, data, pi) ! 82: register struct psapblk *pb; ! 83: PE data; ! 84: struct PSAPindication *pi; ! 85: { ! 86: int result; ! 87: #ifdef DEBUG ! 88: char *cp; ! 89: #endif ! 90: PE pe; ! 91: PS ps; ! 92: ! 93: pe = NULLPE; ! 94: ! 95: if (pb -> pb_reliability == LOW_QUALITY) { ! 96: struct type_PS_CL__UserData__PDU *pdu; ! 97: ! 98: if ((pdu = (struct type_PS_CL__UserData__PDU *) malloc (sizeof *pdu)) ! 99: == NULL) ! 100: return psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); ! 101: ! 102: pdu -> reference = pb -> pb_reference; ! 103: pdu -> user__data = data; ! 104: ! 105: result = encode_PS_CL__UserData__PDU (&pe, 1, 0, NULLCP, pdu); ! 106: #ifdef DEBUG ! 107: cp = "CL-UserData-PDU"; ! 108: #endif ! 109: ! 110: pdu -> reference = NULL; ! 111: pdu -> user__data = NULLPE; ! 112: free_PS_CL__UserData__PDU (pdu); ! 113: } ! 114: else { ! 115: result = encode_PS_UserData__PDU (&pe, 1, 0, NULLCP, data); ! 116: #ifdef DEBUG ! 117: cp = "UserData-PDU"; ! 118: #endif ! 119: } ! 120: ! 121: if (result != NOTOK) { ! 122: PLOGP (psap2_log,PS_PDUs, pe, cp, 0); ! 123: ! 124: if ((result = pe2ps (ps = pb -> pb_stream, pe)) == NOTOK) ! 125: (void) pslose (pi, ps -> ps_errno); ! 126: else ! 127: result = OK; ! 128: } ! 129: else ! 130: (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", ! 131: PY_pepy); ! 132: ! 133: if (pe) ! 134: pe_free (pe); ! 135: ! 136: return result; ! 137: } ! 138: ! 139: /* P-READ.REQUEST (pseudo; synchronous read) */ ! 140: ! 141: int PReadRequest (sd, px, secs, pi) ! 142: int sd; ! 143: struct PSAPdata *px; ! 144: int secs; ! 145: struct PSAPindication *pi; ! 146: { ! 147: SBV smask; ! 148: int nfds, ! 149: result; ! 150: fd_set mask; ! 151: register struct psapblk *pb; ! 152: struct PSAPabort *pa = &pi -> pi_abort; ! 153: ! 154: missingP (px); ! 155: missingP (pi); ! 156: ! 157: smask = sigioblock (); ! 158: ! 159: psapPsig (pb, sd); ! 160: ! 161: FD_ZERO (&mask); ! 162: FD_SET (pb -> pb_fd, &mask); ! 163: nfds = pb -> pb_fd + 1; ! 164: ! 165: for (;;) { ! 166: fd_set ifds, ! 167: efds; ! 168: register PS ps = pb -> pb_stream; ! 169: ! 170: ifds = mask; /* struct copy */ ! 171: efds = mask; /* struct copy */ ! 172: ! 173: if ((ps -> ps_primeP == NULLIFP || (*ps -> ps_primeP) (ps, 1) == OK) ! 174: && (*pb -> pb_selectfnx) (nfds, &ifds, NULLFD, &efds, secs) ! 175: <= OK) { ! 176: result = psaplose (pi, PC_TIMER, NULLCP, NULLCP); ! 177: break; ! 178: } ! 179: ! 180: if (FD_ISSET (pb -> pb_fd, &ifds) || FD_ISSET (pb -> pb_fd, & efds)) ! 181: if ((result = PReadRequestAux (pb, px, pi)) != NOTOK ! 182: || secs != NOTOK ! 183: || pa -> pa_reason != PC_TIMER) ! 184: break; ! 185: } ! 186: ! 187: if (result == NOTOK && pa -> pa_reason != PC_TIMER) ! 188: freepblk (pb); ! 189: ! 190: (void) sigiomask (smask); ! 191: ! 192: return result; ! 193: } ! 194: ! 195: /* */ ! 196: ! 197: static int PReadRequestAux (pb, px, pi) ! 198: register struct psapblk *pb; ! 199: struct PSAPdata *px; ! 200: struct PSAPindication *pi; ! 201: { ! 202: int result; ! 203: PE pe; ! 204: PS ps; ! 205: struct type_PS_PDUs *pdu; ! 206: struct type_PS_SessionConnectionIdentifier *pref; ! 207: ! 208: if ((pe = ps2pe (ps = pb -> pb_stream)) == NULLPE) ! 209: return pslose (pi, ps -> ps_errno); ! 210: ! 211: pdu = NULL; ! 212: result = decode_PS_PDUs (pe, 1, NULLIP, NULLVP, &pdu); ! 213: ! 214: #ifdef DEBUG ! 215: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) ! 216: pvpdu (psap2_log, print_PS_PDUs_P, pe, "PDU", 1); ! 217: #endif ! 218: ! 219: pe_free (pe); ! 220: ! 221: if (result == NOTOK) { ! 222: if (pb -> pb_reliability == LOW_QUALITY) ! 223: goto bad_ref2; ! 224: ! 225: (void) ppktlose (pb, pi, PC_UNRECOGNIZED, NULLRF, NULLCP, ! 226: "error decoding PDU: %s", PY_pepy); ! 227: goto out; ! 228: } ! 229: ! 230: switch (pdu -> offset) { ! 231: case type_PS_PDUs_releaseRequest: ! 232: { ! 233: register struct PSAPfinish *pf = &pi -> pi_finish; ! 234: register struct type_PS_ReleaseRequest__PDU *rr = ! 235: pdu -> un.releaseRequest; ! 236: ! 237: if (pb -> pb_reliability == LOW_QUALITY ! 238: && refcmp (pb -> pb_reference, (pref = rr -> reference))) { ! 239: bad_ref1: ; ! 240: (void) ppktlose (pb, pi, PC_SESSION, pref, NULLCP, ! 241: "reference mismatch"); ! 242: bad_ref2: ; ! 243: if (pdu) ! 244: free_PS_PDUs (pdu); ! 245: return psaplose (pi, PC_TIMER, NULLCP, NULLCP); ! 246: } ! 247: ! 248: pe = rr -> user__data, rr -> user__data = NULLPE; ! 249: ! 250: pi -> pi_type = PI_FINISH; ! 251: bzero ((char *) pf, sizeof *pf); ! 252: ! 253: (pf -> pf_info[0] = pe) -> pe_context = PCI_ACSE; ! 254: pf -> pf_ninfo = 1; ! 255: ! 256: pb -> pb_flags |= PB_FINN; ! 257: result = DONE; ! 258: } ! 259: break; ! 260: ! 261: case type_PS_PDUs_abort: ! 262: { ! 263: register struct PSAPabort *pa = &pi -> pi_abort; ! 264: register struct type_PS_Abort__PDU *ab = pdu -> un.abort; ! 265: ! 266: if (pb -> pb_reliability == LOW_QUALITY ! 267: && refcmp (pb -> pb_reference, (pref = ab -> reference))) ! 268: goto bad_ref2; ! 269: ! 270: if (ab -> reason) { ! 271: switch (ab -> reason -> parm) { ! 272: case int_PS_Abort__reason_reason__not__specified: ! 273: default: ! 274: result = PC_NOTSPECIFIED; ! 275: break; ! 276: ! 277: case int_PS_Abort__reason_unrecognized__ppdu: ! 278: case int_PS_Abort__reason_unexpected__ppdu: ! 279: case int_PS_Abort__reason_unrecognized__ppdu__parameter: ! 280: result = PC_UNRECOGNIZED ! 281: + (ab -> reason -> parm ! 282: - int_PS_Abort__reason_unrecognized__ppdu); ! 283: break; ! 284: ! 285: case int_PS_Abort__reason_invalid__ppdu__parameter: ! 286: result = PC_INVALID; ! 287: break; ! 288: ! 289: case int_PS_Abort__reason_reference__mismatch: ! 290: result = PC_SESSION; ! 291: break; ! 292: } ! 293: result = psaplose (pi, result, NULLCP, NULLCP); ! 294: break; ! 295: } ! 296: pe = ab -> user__data, ab -> user__data = NULLPE; ! 297: ! 298: pi -> pi_type = PI_ABORT; ! 299: bzero ((char *) pa, sizeof *pa); ! 300: ! 301: pa -> pa_peer = 1; ! 302: pa -> pa_reason = PC_ABORTED; ! 303: (pa -> pa_info[0] = pe) -> pe_context = PCI_ACSE; ! 304: pa -> pa_ninfo = 1; ! 305: ! 306: result = NOTOK; ! 307: } ! 308: break; ! 309: ! 310: case type_PS_PDUs_userData: ! 311: { ! 312: if (pb -> pb_reliability == LOW_QUALITY) ! 313: goto bad_ref2; ! 314: ! 315: pe = pdu -> un.userData, pdu -> un.userData = NULLPE; ! 316: ! 317: bzero ((char *) px, sizeof *px); ! 318: ! 319: px -> px_type = SX_NORMAL; ! 320: (px -> px_info[0] = pe) -> pe_context = PCI_ROSE; ! 321: px -> px_ninfo = 1; ! 322: ! 323: result = OK; ! 324: } ! 325: break; ! 326: ! 327: case type_PS_PDUs_cL__userData: ! 328: { ! 329: register struct type_PS_CL__UserData__PDU *cl = ! 330: pdu -> un.cL__userData; ! 331: ! 332: if (pb -> pb_reliability == LOW_QUALITY ! 333: && refcmp (pb -> pb_reference, (pref = cl -> reference))) ! 334: goto bad_ref1; ! 335: ! 336: pe = cl -> user__data, cl -> user__data = NULLPE; ! 337: ! 338: bzero ((char *) px, sizeof *px); ! 339: ! 340: px -> px_type = SX_NORMAL; ! 341: (px -> px_info[0] = pe) -> pe_context = PCI_ROSE; ! 342: px -> px_ninfo = 1; ! 343: ! 344: result = OK; ! 345: } ! 346: break; ! 347: ! 348: case type_PS_PDUs_connectRequest: ! 349: /* this works 'cause the "reference" is always the FIRST element */ ! 350: result = ppktlose (pb, pi, PC_SESSION, ! 351: pdu -> un.connectRequest -> reference, NULLCP, ! 352: "unexpected PDU %d", pdu -> offset); ! 353: break; ! 354: ! 355: default: ! 356: /* this works 'cause the "reference" is always the FIRST element */ ! 357: result = ppktlose (pb, pi, PC_SESSION, ! 358: pdu -> un.connectResponse -> reference, NULLCP, ! 359: "unexpected PDU %d", pdu -> offset); ! 360: break; ! 361: } ! 362: ! 363: out: ; ! 364: if (pdu) ! 365: free_PS_PDUs (pdu); ! 366: ! 367: return result; ! 368: } ! 369: ! 370: /* define vectors for INDICATION events */ ! 371: ! 372: /* ARGSUSED */ ! 373: ! 374: int PSetIndications (sd, data, tokens, sync, activity, report, finish, ! 375: abort, pi) ! 376: int sd; ! 377: IFP data, ! 378: tokens, ! 379: sync, ! 380: activity, ! 381: report, ! 382: finish, ! 383: abort; ! 384: struct PSAPindication *pi; ! 385: { ! 386: missingP (pi); ! 387: ! 388: return psaplose (pi, PC_OPERATION, NULLCP, NULLCP); ! 389: } ! 390: ! 391: /* INTERNAL */ ! 392: ! 393: struct psapblk *newpblk () { ! 394: register struct psapblk *pb; ! 395: ! 396: pb = (struct psapblk *) calloc (1, sizeof *pb); ! 397: if (pb == NULL) ! 398: return NULL; ! 399: ! 400: pb -> pb_fd = NOTOK; ! 401: ! 402: if (once_only == 0) { ! 403: PHead -> pb_forw = PHead -> pb_back = PHead; ! 404: once_only++; ! 405: } ! 406: ! 407: insque (pb, PHead -> pb_back); ! 408: ! 409: return pb; ! 410: } ! 411: ! 412: ! 413: int freepblk (pb) ! 414: register struct psapblk *pb; ! 415: { ! 416: #ifdef notdef ! 417: register int i; ! 418: register struct PSAPcontext *qp; ! 419: #endif ! 420: ! 421: if (pb == NULL) ! 422: return; ! 423: ! 424: if (pb -> pb_fd != NOTOK && pb -> pb_closefnx) ! 425: (void) (*pb -> pb_closefnx) (pb -> pb_fd); ! 426: ! 427: if (pb -> pb_retry) ! 428: pe_free (pb -> pb_retry); ! 429: if (pb -> pb_response) ! 430: pe_free (pb -> pb_response); ! 431: if (pb -> pb_reference) ! 432: free_PS_SessionConnectionIdentifier (pb -> pb_reference); ! 433: if (pb -> pb_stream) ! 434: ps_free (pb -> pb_stream); ! 435: ! 436: #ifdef notdef /* don't need this stuff */ ! 437: for (qp = pb -> pb_contexts, i = pb -> pb_ncontexts - 1; ! 438: i >= 0; ! 439: qp++, i--) { ! 440: if (qp -> pc_asn) ! 441: oid_free (qp -> pc_asn); ! 442: if (qp -> pc_atn) ! 443: oid_free (qp -> pc_atn); ! 444: } ! 445: if (pb -> pb_asn) ! 446: oid_free (pb -> pb_asn); ! 447: if (pb -> pb_atn) ! 448: oid_free (pb -> pb_atn); ! 449: #endif ! 450: ! 451: if (pb -> pb_ber) ! 452: oid_free (pb -> pb_ber); ! 453: ! 454: remque (pb); ! 455: ! 456: free ((char *) pb); ! 457: } ! 458: ! 459: /* */ ! 460: ! 461: struct psapblk *findpblk (sd) ! 462: register int sd; ! 463: { ! 464: register struct psapblk *pb; ! 465: ! 466: if (once_only == 0) ! 467: return NULL; ! 468: ! 469: for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw) ! 470: if (pb -> pb_fd == sd) ! 471: return pb; ! 472: ! 473: return NULL; ! 474: } ! 475: ! 476: /* */ ! 477: ! 478: int refcmp (ref1, ref2) ! 479: register struct type_PS_SessionConnectionIdentifier *ref1, ! 480: *ref2; ! 481: { ! 482: if (ref1 == NULLRF) ! 483: return (ref2 != NULLRF); ! 484: else ! 485: if (ref2 == NULLRF) ! 486: return 1; ! 487: ! 488: if (qb_cmp (ref1 -> callingSSUserReference, ref2 -> callingSSUserReference) ! 489: || qb_cmp (ref1 -> commonReference, ref2 -> commonReference) ! 490: || qb_cmp (ref1 -> additionalReferenceInformation, ! 491: ref2 -> additionalReferenceInformation)) { ! 492: SLOG (psap2_log, LLOG_EXCEPTIONS, NULLCP, ("reference mismatch")); ! 493: ! 494: return 1; ! 495: } ! 496: ! 497: return 0; ! 498: } ! 499: ! 500: ! 501: static int qb_cmp (qb1, qb2) ! 502: register struct qbuf *qb1, ! 503: *qb2; ! 504: { ! 505: register int i, ! 506: len1, ! 507: len2; ! 508: register char *cp1, ! 509: *cp2; ! 510: register struct qbuf *qp1, ! 511: *qp2; ! 512: ! 513: if (qb1 == NULL) ! 514: return (qb2 != NULL); ! 515: else ! 516: if (qb2 == NULL) ! 517: return 1; ! 518: ! 519: for (qp1 = qb1 -> qb_forw; qp1 != qb1; qp1 = qp1 -> qb_forw) ! 520: if ((len1 = qp1 -> qb_len) > 0) ! 521: break; ! 522: cp1 = qp1 -> qb_data; ! 523: ! 524: for (qp2 = qb2 -> qb_forw; qp2 != qb2; qp2 = qp2 -> qb_forw) ! 525: if ((len2 = qp2 -> qb_len) > 0) ! 526: break; ! 527: cp2 = qp2 -> qb_data; ! 528: ! 529: for (;;) { ! 530: if (qp1 == qb1) ! 531: return (qb2 != qb2); ! 532: else ! 533: if (qp2 == qb2) ! 534: return 1; ! 535: ! 536: if ((i = len1) > len2) ! 537: i = len2; ! 538: if (bcmp (cp1, cp2, i)) ! 539: return 1; ! 540: ! 541: if ((len1 -= i) <= 0) { ! 542: for (qp1 = qp1 -> qb_forw; qp1 != qb1; qp1 = qp1 -> qb_forw) ! 543: if ((len1 = qp1 -> qb_len) > 0) ! 544: break; ! 545: cp1 = qp1 -> qb_data; ! 546: } ! 547: else ! 548: cp1 += i; ! 549: ! 550: if ((len2 -= i) <= 0) { ! 551: for (qp2 = qp2 -> qb_forw; qp2 != qb2; qp2 = qp2 -> qb_forw) ! 552: if ((len2 = qp2 -> qb_len) > 0) ! 553: break; ! 554: cp2 = qp2 -> qb_data; ! 555: } ! 556: else ! 557: cp2 += i; ! 558: } ! 559: } ! 560: ! 561: /* */ ! 562: ! 563: struct SSAPref *pdu2ref (ref) ! 564: register struct type_PS_SessionConnectionIdentifier *ref; ! 565: { ! 566: int i; ! 567: static struct SSAPref sfs; ! 568: register struct SSAPref *sf = &sfs; ! 569: ! 570: pdu2sel (sf -> sr_udata, &i, sizeof sf -> sr_udata, ! 571: ref -> callingSSUserReference); ! 572: sf -> sr_ulen = i; ! 573: ! 574: pdu2sel (sf -> sr_cdata, &i, sizeof sf -> sr_cdata, ! 575: ref -> commonReference); ! 576: sf -> sr_clen = i; ! 577: ! 578: pdu2sel (sf -> sr_adata, &i, sizeof sf -> sr_adata, ! 579: ref -> additionalReferenceInformation); ! 580: sf -> sr_alen = i; ! 581: ! 582: sf -> sr_vlen = 0; ! 583: ! 584: return sf; ! 585: } ! 586: ! 587: /* */ ! 588: ! 589: int pdu2sel (sel, len, i, pb) ! 590: char *sel; ! 591: int *len; ! 592: register int i; ! 593: register struct qbuf *pb; ! 594: { ! 595: register char *cp; ! 596: register struct qbuf *qb; ! 597: ! 598: if (pb == NULL) { ! 599: *len = 0; ! 600: return; ! 601: } ! 602: ! 603: cp = sel; ! 604: for (qb = pb -> qb_forw; qb != pb && i > 0; qb = qb -> qb_forw) { ! 605: if (qb -> qb_len > i) ! 606: qb -> qb_len = i; ! 607: bcopy (qb -> qb_data, cp, qb -> qb_len); ! 608: cp += qb -> qb_len, i -= qb -> qb_len; ! 609: } ! 610: ! 611: *len = cp - sel; ! 612: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.