|
|
1.1 ! root 1: /* psaprovider.c - implement the presentation protocol */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/psap2/RCS/psaprovider.c,v 7.3 90/07/01 21:05:11 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/psap2/RCS/psaprovider.c,v 7.3 90/07/01 21:05:11 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: psaprovider.c,v $ ! 12: * Revision 7.3 90/07/01 21:05:11 mrose ! 13: * pepsy ! 14: * ! 15: * Revision 7.2 90/03/23 17:27:48 mrose ! 16: * update ! 17: * ! 18: * Revision 7.1 89/11/24 16:22:20 mrose ! 19: * sync ! 20: * ! 21: * Revision 7.0 89/11/23 22:14:33 mrose ! 22: * Release 6.0 ! 23: * ! 24: */ ! 25: ! 26: /* ! 27: * NOTICE ! 28: * ! 29: * Acquisition, use, and distribution of this module and related ! 30: * materials are subject to the restrictions of a license agreement. ! 31: * Consult the Preface in the User's Manual for the full terms of ! 32: * this agreement. ! 33: * ! 34: */ ! 35: ! 36: ! 37: /* LINTLIBRARY */ ! 38: ! 39: #include <stdio.h> ! 40: #include <signal.h> ! 41: #include "PS-types.h" ! 42: #include "ppkt.h" ! 43: #include "tailor.h" ! 44: ! 45: /* DATA */ ! 46: ! 47: static int once_only = 0; ! 48: static struct psapblk psapque; ! 49: static struct psapblk *PHead = &psapque; ! 50: ! 51: ! 52: struct pair preq_pairs[] = { ! 53: PR_MANAGEMENT, bit_PS_Presentation__requirements_context__management, ! 54: PR_RESTORATION, bit_PS_Presentation__requirements_restoration, ! 55: 0, 0 ! 56: }; ! 57: ! 58: ! 59: struct pair sreq_pairs[] = { ! 60: SR_HALFDUPLEX, bit_PS_User__session__requirements_half__duplex, ! 61: SR_DUPLEX, bit_PS_User__session__requirements_duplex, ! 62: SR_EXPEDITED, bit_PS_User__session__requirements_expedited__data, ! 63: SR_MINORSYNC, bit_PS_User__session__requirements_minor__synchronize, ! 64: SR_MAJORSYNC, bit_PS_User__session__requirements_major__synchronize, ! 65: SR_RESYNC, bit_PS_User__session__requirements_resynchronize, ! 66: SR_ACTIVITY, bit_PS_User__session__requirements_activity__management, ! 67: SR_NEGOTIATED, bit_PS_User__session__requirements_negotiated__release, ! 68: SR_CAPABILITY, bit_PS_User__session__requirements_capability__data, ! 69: SR_EXCEPTIONS, bit_PS_User__session__requirements_exceptions, ! 70: SR_TYPEDATA, bit_PS_User__session__requirements_typed__data, ! 71: 0, 0 ! 72: }; ! 73: ! 74: /* */ ! 75: ! 76: #define doABORT ss2psabort ! 77: ! 78: ! 79: int DATAser (), TOKENser (), SYNCser (), ACTIVITYser (), REPORTser (), ! 80: FINISHser (), ABORTser (); ! 81: ! 82: ! 83: /* P-[*-]DATA.REQUEST */ ! 84: ! 85: int PDataRequest (sd, data, ndata, pi) ! 86: int sd; ! 87: PE *data; ! 88: int ndata; ! 89: struct PSAPindication *pi; ! 90: { ! 91: return PDataRequestAux (sd, data, ndata, pi, "user", SDataRequest, ! 92: "SDataRequest", "P-DATA user-data", PPDU_TD); ! 93: } ! 94: ! 95: /* */ ! 96: ! 97: int PDataRequestAux (sd, data, ndata, pi, dtype, sfunc, stype, text, ppdu) ! 98: int sd; ! 99: PE *data; ! 100: int ndata; ! 101: struct PSAPindication *pi; ! 102: char *dtype, ! 103: *stype, ! 104: *text; ! 105: IFP sfunc; ! 106: int ppdu; ! 107: { ! 108: SBV smask; ! 109: int i, ! 110: len, ! 111: result; ! 112: char *base, ! 113: *realbase; ! 114: register struct psapblk *pb; ! 115: struct SSAPindication sis; ! 116: register struct SSAPabort *sa = &sis.si_abort; ! 117: register PE *d, ! 118: p; ! 119: ! 120: missingP (data); ! 121: toomuchP (data, ndata, NPDATA, dtype); ! 122: if (ndata <= 0) ! 123: return psaplose (pi, PC_PARAMETER, NULLCP, ! 124: "illegal number of PDVs (%d)", ndata); ! 125: missingP (pi); ! 126: missingP (sfunc); ! 127: missingP (stype); ! 128: missingP (text); ! 129: ! 130: smask = sigioblock (); ! 131: ! 132: psapPsig (pb, sd); ! 133: ! 134: if (ppdu == PPDU_TE) { ! 135: for (d = data, i = 0; i < ndata; i++) ! 136: if ((p = *d++) && p -> pe_context != PE_DFLT_CTX) { ! 137: (void) sigiomask (smask); ! 138: return psaplose (pi, PC_OPERATION, NULLCP, ! 139: "defined context not permited with expedited service"); ! 140: } ! 141: } ! 142: ! 143: if (ppdu == PPDU_TTD && !(pb -> pb_urequirements & SR_TYPEDATA)) { ! 144: (void) sigiomask (smask); ! 145: return psaplose (pi, PC_OPERATION, NULLCP, ! 146: "typed data service unavailable"); ! 147: } ! 148: ! 149: if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, text, ! 150: ppdu)) != OK) ! 151: goto out2; ! 152: ! 153: if ((result = (*sfunc) (sd, base, len, &sis)) == NOTOK) ! 154: if (SC_FATAL (sa -> sa_reason)) ! 155: (void) ss2pslose (pb, pi, stype, sa); ! 156: else { ! 157: (void) ss2pslose (NULLPB, pi, stype, sa); ! 158: goto out1; ! 159: } ! 160: ! 161: out2: ; ! 162: if (result == NOTOK) ! 163: freepblk (pb); ! 164: else ! 165: if (result == DONE) ! 166: result = NOTOK; ! 167: out1: ; ! 168: if (realbase) ! 169: free (realbase); ! 170: else ! 171: if (base) ! 172: free (base); ! 173: ! 174: (void) sigiomask (smask); ! 175: ! 176: return result; ! 177: } ! 178: ! 179: /* P-READ.REQUEST (pseudo) */ ! 180: ! 181: int PReadRequest (sd, px, secs, pi) ! 182: int sd; ! 183: struct PSAPdata *px; ! 184: int secs; ! 185: struct PSAPindication *pi; ! 186: { ! 187: SBV smask; ! 188: int result; ! 189: register struct psapblk *pb; ! 190: ! 191: missingP (px); ! 192: missingP (pi); ! 193: ! 194: smask = sigioblock (); ! 195: ! 196: psapPsig (pb, sd); ! 197: ! 198: result = PReadRequestAux (pb, px, secs, pi); ! 199: ! 200: (void) sigiomask (smask); ! 201: ! 202: return result; ! 203: } ! 204: ! 205: /* */ ! 206: ! 207: static int PReadRequestAux (pb, px, secs, pi) ! 208: register struct psapblk *pb; ! 209: struct PSAPdata *px; ! 210: int secs; ! 211: register struct PSAPindication *pi; ! 212: { ! 213: int result; ! 214: struct SSAPdata sxs; ! 215: register struct SSAPdata *sx = &sxs; ! 216: struct SSAPindication sis; ! 217: register struct SSAPindication *si = &sis; ! 218: ! 219: bzero ((char *) px, sizeof *px); ! 220: bzero ((char *) pi, sizeof *pi); ! 221: ! 222: for (;;) { ! 223: switch (result = SReadRequest (pb -> pb_fd, sx, secs, si)) { ! 224: case NOTOK: ! 225: return doABORT (pb, &si -> si_abort, pi); ! 226: ! 227: case OK: ! 228: return doDATA (pb, sx, px, pi); ! 229: ! 230: case DONE: ! 231: switch (si -> si_type) { ! 232: case SI_TOKEN: ! 233: return doTOKEN (pb, &si -> si_token, pi); ! 234: ! 235: case SI_SYNC: ! 236: return doSYNC (pb, &si -> si_sync, pi); ! 237: ! 238: case SI_ACTIVITY: ! 239: return doACTIVITY (pb, &si -> si_activity, pi); ! 240: ! 241: case SI_REPORT: ! 242: return doREPORT (pb, &si -> si_report, pi); ! 243: ! 244: case SI_FINISH: ! 245: return doFINISH (pb, &si -> si_finish, pi); ! 246: ! 247: default: ! 248: (void) ppktlose (pb, pi, PC_PROTOCOL, PPDU_NONE, ! 249: NULLCP, ! 250: "unknown indication (0x%x) from session", ! 251: si -> si_type); ! 252: break; ! 253: } ! 254: break; ! 255: ! 256: default: ! 257: (void) ppktlose (pb, pi, PC_PROTOCOL, PPDU_NONE, NULLCP, ! 258: "unexpected return from SReadRequest=%d", result); ! 259: break; ! 260: } ! 261: break; ! 262: } ! 263: ! 264: freepblk (pb); ! 265: return NOTOK; ! 266: } ! 267: ! 268: /* */ ! 269: ! 270: static int doDATA (pb, sx, px, pi) ! 271: register struct psapblk *pb; ! 272: register struct SSAPdata *sx; ! 273: register struct PSAPdata *px; ! 274: struct PSAPindication *pi; ! 275: { ! 276: int ppdu, ! 277: result; ! 278: char *text; ! 279: ! 280: switch (px -> px_type = sx -> sx_type) { ! 281: case SX_NORMAL: ! 282: ppdu = PPDU_TD; ! 283: text = "P-DATA user-data"; ! 284: break; ! 285: ! 286: case SX_EXPEDITED: ! 287: ppdu = PPDU_TE; ! 288: text = "P-EXPEDITED-DATA user-data"; ! 289: break; ! 290: ! 291: case SX_CAPDIND: ! 292: ppdu = PPDU_TC; ! 293: goto capd; ! 294: case SX_CAPDCNF: ! 295: ppdu = PPDU_TCC; ! 296: capd: ; ! 297: text = "P-CAPABILITY-DATA user-data"; ! 298: break; ! 299: ! 300: case SX_TYPED: ! 301: ppdu = PPDU_TTD; ! 302: text = "P-TYPED-DATA user-data"; ! 303: break; ! 304: ! 305: default: ! 306: result = ppktlose (pb, pi, PC_PROTOCOL, PPDU_NONE, NULLCP, ! 307: "unknown data indication type=0x%x, %d bytes", ! 308: sx -> sx_type, sx -> sx_cc); ! 309: freepblk (pb); ! 310: goto out; ! 311: } ! 312: ! 313: result = qbuf2info (pb, pi, &sx -> sx_qbuf, sx -> sx_cc, ! 314: px -> px_info, &px -> px_ninfo, text, ppdu); ! 315: ! 316: out: ; ! 317: if (result == NOTOK) ! 318: SXFREE (sx); ! 319: ! 320: return result; ! 321: } ! 322: ! 323: /* */ ! 324: ! 325: static int doTOKEN (pb, st, pi) ! 326: register struct psapblk *pb; ! 327: register struct SSAPtoken *st; ! 328: struct PSAPindication *pi; ! 329: { ! 330: int result; ! 331: register struct PSAPtoken *pt = &pi -> pi_token; ! 332: ! 333: pi -> pi_type = PI_TOKEN; ! 334: ! 335: pt -> pt_type = st -> st_type; ! 336: pt -> pt_tokens = st -> st_tokens; ! 337: pt -> pt_owned = pb -> pb_owned = st -> st_owned; ! 338: ! 339: result = ssdu2info (pb, pi, st -> st_data, st -> st_cc, pt -> pt_info, ! 340: &pt -> pt_ninfo, "P-PLEASE-TOKEN user-data", PPDU_NONE); ! 341: ! 342: STFREE (st); ! 343: ! 344: return (result != NOTOK ? DONE : NOTOK); ! 345: } ! 346: ! 347: /* */ ! 348: ! 349: static int doSYNC (pb, sn, pi) ! 350: register struct psapblk *pb; ! 351: register struct SSAPsync *sn; ! 352: struct PSAPindication *pi; ! 353: { ! 354: int result; ! 355: register struct PSAPsync *pn = &pi -> pi_sync; ! 356: ! 357: pi -> pi_type = PI_SYNC; ! 358: ! 359: pn -> pn_type = sn -> sn_type; ! 360: pn -> pn_options = sn -> sn_options; ! 361: pn -> pn_ssn = sn -> sn_ssn; ! 362: pn -> pn_settings = sn -> sn_settings; ! 363: ! 364: result = ssdu2info (pb, pi, sn -> sn_data, sn -> sn_cc, pn -> pn_info, ! 365: &pn -> pn_ninfo, sn -> sn_type <= SN_MAJORCNF ! 366: ? "P-MAJOR-SYNC user-data" ! 367: : sn -> sn_type <= SN_MINORCNF ! 368: ? "P-MINOR-SYNC user-data" ! 369: : "P-RESYNCHRONIZE user-data", ! 370: sn -> sn_type == SN_RESETIND ! 371: ? PPDU_RS ! 372: : sn -> sn_type == SN_RESETCNF ! 373: ? PPDU_RSA ! 374: : PPDU_NONE); ! 375: ! 376: SNFREE (sn); ! 377: ! 378: return (result != NOTOK ? DONE : NOTOK); ! 379: } ! 380: ! 381: /* */ ! 382: ! 383: static int doACTIVITY (pb, sv, pi) ! 384: register struct psapblk *pb; ! 385: register struct SSAPactivity *sv; ! 386: struct PSAPindication *pi; ! 387: { ! 388: int result; ! 389: register struct PSAPactivity *pv = &pi -> pi_activity; ! 390: ! 391: pi -> pi_type = PI_ACTIVITY; ! 392: ! 393: pv -> pv_type = sv -> sv_type; ! 394: pv -> pv_id = sv -> sv_id; /* struct copy */ ! 395: pv -> pv_oid = sv -> sv_oid; /* struct copy */ ! 396: pv -> pv_connect = sv -> sv_connect; /* struct copy */ ! 397: pv -> pv_ssn = sv -> sv_ssn; ! 398: pv -> pv_reason = sv -> sv_reason; ! 399: ! 400: result = ssdu2info (pb, pi, sv -> sv_data, sv -> sv_cc, pv -> pv_info, ! 401: &pv -> pv_ninfo, sv -> sv_type <= SV_START ! 402: ? "P-ACTIVITY-START user-data" ! 403: : sv -> sv_type <= SV_RESUME ! 404: ? "P-ACTIVITY-RESUME user-data" ! 405: : "P-ACTIVITY-END user-data", PPDU_NONE); ! 406: ! 407: SVFREE (sv); ! 408: ! 409: return (result != NOTOK ? DONE : NOTOK); ! 410: } ! 411: ! 412: /* */ ! 413: ! 414: static int doREPORT (pb, sp, pi) ! 415: register struct psapblk *pb; ! 416: register struct SSAPreport *sp; ! 417: struct PSAPindication *pi; ! 418: { ! 419: int result; ! 420: register struct PSAPreport *pp = &pi -> pi_report; ! 421: ! 422: pi -> pi_type = PI_REPORT; ! 423: ! 424: pp -> pp_peer = sp -> sp_peer; ! 425: pp -> pp_reason = sp -> sp_reason; ! 426: ! 427: result = ssdu2info (pb, pi, sp -> sp_data, sp -> sp_cc, pp -> pp_info, ! 428: &pp -> pp_ninfo, "P-U-EXCEPTION-REPORT user-data", PPDU_NONE); ! 429: ! 430: SPFREE (sp); ! 431: ! 432: return (result != NOTOK ? DONE : NOTOK); ! 433: } ! 434: ! 435: /* */ ! 436: ! 437: static int doFINISH (pb, sf, pi) ! 438: register struct psapblk *pb; ! 439: register struct SSAPfinish *sf; ! 440: struct PSAPindication *pi; ! 441: { ! 442: int result; ! 443: register struct PSAPfinish *pf = &pi -> pi_finish; ! 444: ! 445: pi -> pi_type = PI_FINISH; ! 446: ! 447: result = ssdu2info (pb, pi, sf -> sf_data, sf -> sf_cc, pf -> pf_info, ! 448: &pf -> pf_ninfo, "P-RELEASE user-data", PPDU_NONE); ! 449: ! 450: SFFREE (sf); ! 451: ! 452: if (result == NOTOK) ! 453: return NOTOK; ! 454: ! 455: pb -> pb_flags |= PB_FINN; ! 456: ! 457: return DONE; ! 458: } ! 459: ! 460: /* */ ! 461: ! 462: int ss2psabort (pb, sa, pi) ! 463: register struct psapblk *pb; ! 464: register struct SSAPabort *sa; ! 465: struct PSAPindication *pi; ! 466: { ! 467: int result, ! 468: ppdu; ! 469: register PE pe; ! 470: register struct PSAPabort *pa = &pi -> pi_abort; ! 471: struct type_PS_Abort__type *pdu; ! 472: register struct element_PS_3 *aru; ! 473: register struct type_PS_ARP__PPDU *arp; ! 474: register struct type_PS_User__data *info; ! 475: ! 476: pdu = NULL, pe = NULLPE; ! 477: if (!sa -> sa_peer) { ! 478: if (sa -> sa_reason == SC_TIMER) ! 479: return psaplose (pi, PC_TIMER, NULLCP, NULLCP); ! 480: ! 481: (void) ss2pslose (pb, pi, NULLCP, sa); ! 482: goto out; ! 483: } ! 484: ! 485: if (sa -> sa_cc == 0) { ! 486: (void) psaplose (pi, PC_ABORTED, NULLCP, NULLCP); ! 487: goto out; ! 488: } ! 489: ! 490: bzero ((char *) pi, sizeof *pi); ! 491: pi -> pi_type = PI_ABORT; ! 492: ! 493: if ((pe = ssdu2pe (sa -> sa_info, sa -> sa_cc, NULLCP, &result)) ! 494: == NULLPE) { ! 495: (void) psaplose (pi, result == PS_ERR_NMEM ? PC_CONGEST : PC_PROTOCOL, ! 496: NULLCP, "%s", ps_error (result)); ! 497: goto out; ! 498: } ! 499: ! 500: if (decode_PS_Abort__type (pe, 1, NULLIP, NULLVP, &pdu) == NOTOK) { ! 501: (void) psaplose (pi, PC_UNRECOGNIZED, NULLCP, "%s", PY_pepy); ! 502: goto out; ! 503: } ! 504: ! 505: PLOGP (psap2_log,PS_Abort__type, pe, "Abort-type", 1); ! 506: ! 507: switch (pdu -> offset) { ! 508: default: ! 509: pa -> pa_peer = 1; ! 510: pa -> pa_reason = PC_ABORTED; ! 511: info = NULL, ppdu = PPDU_NONE; ! 512: break; ! 513: ! 514: case type_PS_Abort__type_normal__mode: ! 515: aru = pdu -> un.normal__mode; ! 516: pa -> pa_peer = 1; ! 517: pa -> pa_reason = PC_ABORTED; ! 518: info = aru -> user__data, ppdu = PPDU_ARU; ! 519: break; ! 520: ! 521: case type_PS_Abort__type_provider__abort: ! 522: if ((arp = pdu -> un.provider__abort) -> provider__reason) { ! 523: if ((result = arp -> provider__reason -> parm) == 0) ! 524: result = PC_NOTSPECIFIED; ! 525: else ! 526: result += PC_ABORT_BASE; ! 527: } ! 528: else ! 529: result = PC_NOTSPECIFIED; ! 530: ! 531: (void) psaplose (pi, result, NULLCP, NULLCP); ! 532: info = NULL, ppdu = PPDU_ARP; ! 533: break; ! 534: } ! 535: ! 536: (void) ppdu2info (pb, pi, info, pa -> pa_info, &pa -> pa_ninfo, ppdu); ! 537: ! 538: out: ; ! 539: SAFREE (sa); ! 540: if (pe) ! 541: pe_free (pe); ! 542: if (pdu) ! 543: free_PS_Abort__type (pdu); ! 544: pb -> pb_fd = NOTOK; ! 545: freepblk (pb); ! 546: ! 547: return NOTOK; ! 548: } ! 549: ! 550: /* define vectors for INDICATION events */ ! 551: ! 552: #define e(i) (data ? (i) : NULLIFP) ! 553: ! 554: ! 555: int PSetIndications (sd, data, tokens, sync, activity, report, finish, ! 556: abort, pi) ! 557: int sd; ! 558: IFP data, ! 559: tokens, ! 560: sync, ! 561: activity, ! 562: report, ! 563: finish, ! 564: abort; ! 565: struct PSAPindication *pi; ! 566: { ! 567: SBV smask; ! 568: register struct psapblk *pb; ! 569: struct SSAPindication sis; ! 570: register struct SSAPabort *sa = &sis.si_abort; ! 571: ! 572: if (data || tokens || sync || activity || report || finish || abort) { ! 573: missingP (data); ! 574: missingP (tokens); ! 575: missingP (sync); ! 576: missingP (activity); ! 577: missingP (report); ! 578: missingP (finish); ! 579: missingP (abort); ! 580: } ! 581: ! 582: smask = sigioblock (); ! 583: ! 584: psapPsig (pb, sd); ! 585: ! 586: if (SSetIndications (pb -> pb_fd, e (DATAser), e (TOKENser), ! 587: e (SYNCser), e (ACTIVITYser), e (REPORTser), e (FINISHser), ! 588: e (ABORTser), &sis) == NOTOK) ! 589: switch (sa -> sa_reason) { ! 590: case SC_WAITING: ! 591: (void) sigiomask (smask); ! 592: return psaplose (pi, PC_WAITING, NULLCP, NULLCP); ! 593: ! 594: default: ! 595: (void) ss2pslose (pb, pi, "SSetIndications", sa); ! 596: freepblk (pb); ! 597: (void) sigiomask (smask); ! 598: return NOTOK; ! 599: } ! 600: ! 601: if (pb -> pb_DataIndication = data) ! 602: pb -> pb_flags |= PB_ASYN; ! 603: else ! 604: pb -> pb_flags &= ~PB_ASYN; ! 605: pb -> pb_TokenIndication = tokens; ! 606: pb -> pb_SyncIndication = sync; ! 607: pb -> pb_ActivityIndication = activity; ! 608: pb -> pb_ReportIndication = report; ! 609: pb -> pb_ReleaseIndication = finish; ! 610: pb -> pb_AbortIndication = abort; ! 611: ! 612: (void) sigiomask (smask); ! 613: ! 614: return OK; ! 615: } ! 616: ! 617: #undef e ! 618: ! 619: /* SSAP interface */ ! 620: ! 621: int ss2pslose (pb, pi, event, sa) ! 622: register struct psapblk *pb; ! 623: register struct PSAPindication *pi; ! 624: char *event; ! 625: register struct SSAPabort *sa; ! 626: { ! 627: int reason; ! 628: char *cp, ! 629: buffer[BUFSIZ]; ! 630: ! 631: if (event && SC_FATAL (sa -> sa_reason)) ! 632: SLOG (psap2_log, LLOG_EXCEPTIONS, NULLCP, ! 633: (sa -> sa_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event, ! 634: SErrString (sa -> sa_reason), sa -> sa_cc, sa -> sa_cc, ! 635: sa -> sa_data)); ! 636: ! 637: cp = ""; ! 638: switch (sa -> sa_reason) { ! 639: case SC_SSAPID: ! 640: case SC_SSUSER: ! 641: case SC_ADDRESS: ! 642: reason = PC_ADDRESS; ! 643: break; ! 644: ! 645: case SC_REFUSED: ! 646: reason = PC_REFUSED; ! 647: break; ! 648: ! 649: case SC_CONGEST: ! 650: reason = PC_CONGEST; ! 651: break; ! 652: ! 653: case SC_TRANSPORT: ! 654: case SC_ABORT: ! 655: reason = PC_SESSION; ! 656: break; ! 657: ! 658: default: ! 659: reason = PC_SESSION; ! 660: if (pb == NULLPB) ! 661: switch (sa -> sa_reason) { ! 662: case SC_PARAMETER: ! 663: reason = PC_PARAMETER; ! 664: break; ! 665: ! 666: case SC_OPERATION: ! 667: reason = PC_OPERATION; ! 668: break; ! 669: ! 670: case SC_TIMER: ! 671: reason = PC_TIMER; ! 672: break; ! 673: ! 674: case SC_WAITING: ! 675: reason = PC_WAITING; ! 676: break; ! 677: } ! 678: (void) sprintf (cp = buffer, " (%s at session)", ! 679: SErrString (sa -> sa_reason)); ! 680: break; ! 681: } ! 682: ! 683: if (pb) { ! 684: if (sa -> sa_cc > 0) ! 685: return ppktlose (pb, pi, reason, PPDU_NONE, NULLCP, "%*.*s%s", ! 686: sa -> sa_cc, sa -> sa_cc, sa -> sa_data, cp); ! 687: else ! 688: return ppktlose (pb, pi, reason, PPDU_NONE, NULLCP, "%s", ! 689: *cp ? cp + 1 : cp); ! 690: } ! 691: else { ! 692: if (sa -> sa_cc > 0) ! 693: return psaplose (pi, reason, NULLCP, "%*.*s%s", ! 694: sa -> sa_cc, sa -> sa_cc, sa -> sa_data, cp); ! 695: else ! 696: return psaplose (pi, reason, NULLCP, "%s", ! 697: *cp ? cp + 1 : cp); ! 698: } ! 699: } ! 700: ! 701: /* */ ! 702: ! 703: static int DATAser (sd, sx) ! 704: int sd; ! 705: register struct SSAPdata *sx; ! 706: { ! 707: IFP abort; ! 708: register struct psapblk *pb; ! 709: struct PSAPindication pis; ! 710: register struct PSAPindication *pi = &pis; ! 711: register struct PSAPdata *px = &pi -> pi_data; ! 712: ! 713: if ((pb = findpblk (sd)) == NULL) ! 714: return; ! 715: ! 716: bzero ((char *) px, sizeof *px); ! 717: bzero ((char *) pi, sizeof *pi); ! 718: abort = pb -> pb_AbortIndication; ! 719: ! 720: if (doDATA (pb, sx, px, pi) == NOTOK) ! 721: (*abort) (sd, &pi -> pi_abort); ! 722: else ! 723: (*pb -> pb_DataIndication) (sd, px); ! 724: } ! 725: ! 726: /* */ ! 727: ! 728: static int TOKENser (sd, st) ! 729: int sd; ! 730: register struct SSAPtoken *st; ! 731: { ! 732: IFP abort; ! 733: register struct psapblk *pb; ! 734: struct PSAPindication pis; ! 735: register struct PSAPindication *pi = &pis; ! 736: ! 737: if ((pb = findpblk (sd)) == NULL) ! 738: return; ! 739: ! 740: bzero ((char *) pi, sizeof *pi); ! 741: abort = pb -> pb_AbortIndication; ! 742: ! 743: if (doTOKEN (pb, st, pi) == NOTOK) ! 744: (*abort) (sd, &pi -> pi_abort); ! 745: else ! 746: (*pb -> pb_TokenIndication) (sd, &pi -> pi_token); ! 747: } ! 748: ! 749: /* */ ! 750: ! 751: static int SYNCser (sd, sn) ! 752: int sd; ! 753: register struct SSAPsync *sn; ! 754: { ! 755: IFP abort; ! 756: register struct psapblk *pb; ! 757: struct PSAPindication pis; ! 758: register struct PSAPindication *pi = &pis; ! 759: ! 760: if ((pb = findpblk (sd)) == NULL) ! 761: return; ! 762: ! 763: bzero ((char *) pi, sizeof *pi); ! 764: abort = pb -> pb_AbortIndication; ! 765: ! 766: if (doSYNC (pb, sn, pi) == NOTOK) ! 767: (*abort) (sd, &pi -> pi_abort); ! 768: else ! 769: (*pb -> pb_SyncIndication) (sd, &pi -> pi_sync); ! 770: } ! 771: ! 772: /* */ ! 773: ! 774: static int ACTIVITYser (sd, sv) ! 775: int sd; ! 776: register struct SSAPactivity *sv; ! 777: { ! 778: IFP abort; ! 779: register struct psapblk *pb; ! 780: struct PSAPindication pis; ! 781: register struct PSAPindication *pi = &pis; ! 782: ! 783: if ((pb = findpblk (sd)) == NULL) ! 784: return; ! 785: ! 786: bzero ((char *) pi, sizeof *pi); ! 787: abort = pb -> pb_AbortIndication; ! 788: ! 789: if (doACTIVITY (pb, sv, pi) == NOTOK) ! 790: (*abort) (sd, &pi -> pi_abort); ! 791: else ! 792: (*pb -> pb_ActivityIndication) (sd, &pi -> pi_activity); ! 793: } ! 794: ! 795: /* */ ! 796: ! 797: static int REPORTser (sd, sp) ! 798: int sd; ! 799: register struct SSAPreport *sp; ! 800: { ! 801: IFP abort; ! 802: register struct psapblk *pb; ! 803: struct PSAPindication pis; ! 804: register struct PSAPindication *pi = &pis; ! 805: ! 806: if ((pb = findpblk (sd)) == NULL) ! 807: return; ! 808: ! 809: bzero ((char *) pi, sizeof *pi); ! 810: abort = pb -> pb_AbortIndication; ! 811: ! 812: if (doREPORT (pb, sp, pi) == NOTOK) ! 813: (*abort) (sd, &pi -> pi_abort); ! 814: else ! 815: (*pb -> pb_ReportIndication) (sd, &pi -> pi_report); ! 816: } ! 817: ! 818: /* */ ! 819: ! 820: static int FINISHser (sd, sf) ! 821: int sd; ! 822: register struct SSAPfinish *sf; ! 823: { ! 824: IFP abort; ! 825: register struct psapblk *pb; ! 826: struct PSAPindication pis; ! 827: register struct PSAPindication *pi = &pis; ! 828: ! 829: if ((pb = findpblk (sd)) == NULL) ! 830: return; ! 831: ! 832: bzero ((char *) pi, sizeof *pi); ! 833: abort = pb -> pb_AbortIndication; ! 834: ! 835: if (doFINISH (pb, sf, pi) == NOTOK) ! 836: (*abort) (sd, &pi -> pi_abort); ! 837: else ! 838: (*pb -> pb_ReleaseIndication) (sd, &pi -> pi_finish); ! 839: } ! 840: ! 841: /* */ ! 842: ! 843: static int ABORTser (sd, sa) ! 844: int sd; ! 845: register struct SSAPabort *sa; ! 846: { ! 847: IFP abort; ! 848: register struct psapblk *pb; ! 849: struct PSAPindication pis; ! 850: register struct PSAPindication *pi = &pis; ! 851: ! 852: if ((pb = findpblk (sd)) == NULL) ! 853: return; ! 854: ! 855: bzero ((char *) pi, sizeof *pi); ! 856: abort = pb -> pb_AbortIndication; ! 857: ! 858: (void) doABORT (pb, sa, pi); ! 859: (*abort) (sd, &pi -> pi_abort); ! 860: } ! 861: ! 862: /* INTERNAL */ ! 863: ! 864: struct psapblk *newpblk () { ! 865: register struct psapblk *pb; ! 866: ! 867: pb = (struct psapblk *) calloc (1, sizeof *pb); ! 868: if (pb == NULL) ! 869: return NULL; ! 870: ! 871: pb -> pb_fd = NOTOK; ! 872: ! 873: if (once_only == 0) { ! 874: PHead -> pb_forw = PHead -> pb_back = PHead; ! 875: once_only++; ! 876: } ! 877: ! 878: insque (pb, PHead -> pb_back); ! 879: ! 880: return pb; ! 881: } ! 882: ! 883: ! 884: int freepblk (pb) ! 885: register struct psapblk *pb; ! 886: { ! 887: register int i; ! 888: register struct PSAPcontext *qp; ! 889: ! 890: if (pb == NULL) ! 891: return; ! 892: ! 893: if (pb -> pb_fd != NOTOK) { ! 894: struct SSAPindication sis; ! 895: ! 896: (void) SUAbortRequest (pb -> pb_fd, NULLCP, 0, &sis); ! 897: } ! 898: ! 899: if (pb -> pb_realbase) ! 900: free (pb -> pb_realbase); ! 901: else ! 902: if (pb -> pb_retry) ! 903: free (pb -> pb_retry); ! 904: ! 905: for (qp = pb -> pb_contexts, i = pb -> pb_ncontext - 1; ! 906: i >= 0; ! 907: qp++, i--) { ! 908: if (qp -> pc_asn) ! 909: oid_free (qp -> pc_asn); ! 910: if (qp -> pc_atn) ! 911: oid_free (qp -> pc_atn); ! 912: } ! 913: if (pb -> pb_asn) ! 914: oid_free (pb -> pb_asn); ! 915: if (pb -> pb_atn) ! 916: oid_free (pb -> pb_atn); ! 917: ! 918: if (pb -> pb_ber) ! 919: oid_free (pb -> pb_ber); ! 920: ! 921: remque (pb); ! 922: ! 923: free ((char *) pb); ! 924: } ! 925: ! 926: /* */ ! 927: ! 928: struct psapblk *findpblk (sd) ! 929: register int sd; ! 930: { ! 931: register struct psapblk *pb; ! 932: ! 933: if (once_only == 0) ! 934: return NULL; ! 935: ! 936: for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw) ! 937: if (pb -> pb_fd == sd) ! 938: return pb; ! 939: ! 940: return NULL; ! 941: } ! 942: ! 943: /* */ ! 944: ! 945: struct type_PS_User__data *info2ppdu (pb, pi, data, ndata, ppdu) ! 946: register struct psapblk *pb; ! 947: struct PSAPindication *pi; ! 948: PE *data; ! 949: int ndata, ! 950: ppdu; ! 951: { ! 952: register int i, ! 953: j; ! 954: register PE *d, ! 955: pe; ! 956: register struct qbuf *qb; ! 957: register struct PSAPcontext *qp; ! 958: OID atn; ! 959: struct type_PS_User__data *pdu; ! 960: register struct type_PS_Simply__encoded__data *simple; ! 961: register struct type_PS_Fully__encoded__data **complex, ! 962: *full; ! 963: ! 964: if ((pdu = (struct type_PS_User__data *) calloc (1, sizeof *pdu)) ! 965: == NULL) { ! 966: no_mem: ; ! 967: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); ! 968: goto out; ! 969: } ! 970: ! 971: pdu -> offset = type_PS_User__data_simple; ! 972: for (d = data, i = 0; i < ndata; i++) { ! 973: if ((pe = *d++) == NULLPE) { ! 974: (void) psaplose (pi, PC_PARAMETER, NULLCP, ! 975: "missing %d%s PDV in PSDU", i + 1, ! 976: i == 0 ? "st" : i == 1 ? "nd" : i == 2 ? "rd" : "th"); ! 977: goto out; ! 978: } ! 979: if (pb -> pb_ncontext > 0 ! 980: && pe -> pe_context == PE_DFLT_CTX) { ! 981: if (ppdu != PPDU_TE) { ! 982: (void) psaplose (pi, PC_PARAMETER, NULLCP, ! 983: "default context not permitted"); ! 984: goto out; ! 985: } ! 986: } ! 987: else ! 988: if (ppdu == PPDU_CP ! 989: || (pb -> pb_ncontext > 1 ! 990: && pe -> pe_context != PE_DFLT_CTX)) ! 991: pdu -> offset = type_PS_User__data_complex; ! 992: } ! 993: ! 994: if (pdu -> offset == type_PS_User__data_simple) { ! 995: if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL) ! 996: goto no_mem; ! 997: simple = pdu -> un.simple = qb; ! 998: qb -> qb_forw = qb -> qb_back = qb; ! 999: qb -> qb_data = NULL, qb -> qb_len = 0; ! 1000: ! 1001: j = 0; ! 1002: for (d = data, i = 0; i < ndata; i++) ! 1003: j += ps_get_abs (*d++); ! 1004: qb -> qb_len = j; ! 1005: if ((qb = (struct qbuf *) malloc (sizeof *qb + ((unsigned)j))) == NULL) ! 1006: goto no_mem; ! 1007: qb -> qb_data = qb -> qb_base, qb -> qb_len = j; ! 1008: insque (qb, simple -> qb_back); ! 1009: } ! 1010: else ! 1011: complex = &pdu -> un.complex; ! 1012: ! 1013: for (d = data, i = 0; i < ndata; i++) { ! 1014: pe = *d++; ! 1015: switch (pe -> pe_context) { ! 1016: case PE_DFLT_CTX: ! 1017: atn = pb -> pb_atn; ! 1018: break; ! 1019: ! 1020: default: ! 1021: for (j = 0, qp = pb -> pb_contexts; ! 1022: j < pb -> pb_ncontext; ! 1023: j++, qp++) ! 1024: if (qp -> pc_id == pe -> pe_context) ! 1025: break; ! 1026: if (j >= pb -> pb_ncontext) { ! 1027: (void) psaplose (pi, PC_PARAMETER, NULLCP, ! 1028: "context %d is undefined", pe -> pe_context); ! 1029: goto out; ! 1030: } ! 1031: if (qp -> pc_result != PC_ACCEPT) { ! 1032: (void) psaplose (pi, PC_PARAMETER, NULLCP, ! 1033: "context %d is unsupported", pe -> pe_context); ! 1034: goto out; ! 1035: } ! 1036: atn = qp -> pc_atn; ! 1037: break; ! 1038: } ! 1039: ! 1040: if (!atn_is_ber (pb, atn)) { ! 1041: (void) psaplose (pi, PC_PARAMETER, NULLCP, ! 1042: "ATN not BER for context %d", pe -> pe_context); ! 1043: goto out; ! 1044: } ! 1045: ! 1046: if (pdu -> offset == type_PS_User__data_simple) { ! 1047: if (info2qb (pe, qb, pi) == NULL) ! 1048: goto out; ! 1049: } ! 1050: else { ! 1051: register PE *q; ! 1052: ! 1053: if ((full = (struct type_PS_Fully__encoded__data *) ! 1054: calloc (1, sizeof *full)) == NULL) ! 1055: goto no_mem; ! 1056: *complex = full; ! 1057: complex = &full -> next; ! 1058: if ((full -> PDV__list = (struct type_PS_PDV__list *) ! 1059: calloc (1, sizeof *full -> PDV__list)) ! 1060: == NULL) ! 1061: goto no_mem; ! 1062: full -> PDV__list -> identifier = pe -> pe_context; ! 1063: if ((full -> PDV__list -> presentation__data__values = ! 1064: (struct choice_PS_0 *) ! 1065: calloc (1, sizeof (struct choice_PS_0))) == NULL) ! 1066: goto no_mem; ! 1067: ! 1068: for (q = d, j = i + 1; j < ndata; q++, j++) ! 1069: if ((*q) -> pe_context != pe -> pe_context) ! 1070: break; ! 1071: q--, j--; ! 1072: ! 1073: if (i == j) { ! 1074: full -> PDV__list -> presentation__data__values -> ! 1075: offset = choice_PS_0_single__ASN1__type; ! 1076: (full -> PDV__list -> presentation__data__values -> ! 1077: un.single__ASN1__type = pe) -> pe_refcnt++; ! 1078: } ! 1079: else { ! 1080: register struct qbuf *qb2; ! 1081: ! 1082: full -> PDV__list -> presentation__data__values -> ! 1083: offset = choice_PS_0_octet__aligned; ! 1084: if ((qb2 = (struct qbuf *) malloc (sizeof *qb2)) == NULL) ! 1085: goto no_mem; ! 1086: full -> PDV__list -> presentation__data__values -> ! 1087: un.octet__aligned = qb2; ! 1088: qb2 -> qb_forw = qb2 -> qb_back = qb2; ! 1089: qb2 -> qb_data = NULL, qb2 -> qb_len = 0; ! 1090: for (d--, j++; i < j; i++) { ! 1091: if ((qb = info2qb (*d++, (struct qbuf *) NULL, pi)) ! 1092: == NULL) ! 1093: goto out; ! 1094: qb2 -> qb_len += qb -> qb_len; ! 1095: insque (qb, qb2 -> qb_back); ! 1096: } ! 1097: } ! 1098: } ! 1099: } ! 1100: ! 1101: return pdu; ! 1102: ! 1103: out: ; ! 1104: if (pdu) ! 1105: free_PS_User__data (pdu); ! 1106: ! 1107: return NULL; ! 1108: } ! 1109: ! 1110: /* */ ! 1111: ! 1112: int ppdu2info (pb, pi, info, data, ndata, ppdu) ! 1113: register struct psapblk *pb; ! 1114: struct PSAPindication *pi; ! 1115: struct type_PS_User__data *info; ! 1116: PE *data; ! 1117: int *ndata, ! 1118: ppdu; ! 1119: { ! 1120: register int i, ! 1121: j; ! 1122: int ctx, ! 1123: result; ! 1124: PE pe; ! 1125: register struct type_PS_Fully__encoded__data *full; ! 1126: ! 1127: *ndata = 0; ! 1128: if (info == NULL) ! 1129: return OK; ! 1130: ! 1131: i = 0; ! 1132: switch (info -> offset) { ! 1133: case type_PS_User__data_simple: ! 1134: if (pb -> pb_ncontext < 1 || ppdu == PPDU_TE) ! 1135: ctx = PE_DFLT_CTX; ! 1136: else ! 1137: if (pb -> pb_ncontext > 1) ! 1138: return ppktlose (pb, pi, PC_INVALID, ppdu, NULLCP, ! 1139: "unexpected Simply-encoded-data"); ! 1140: else ! 1141: ctx = pb -> pb_contexts[0].pc_id; ! 1142: while ((result = qb2info (info -> un.simple, &pe)) == PS_ERR_NONE){ ! 1143: if (i++ >= NPDATA) { ! 1144: pe_free (pe); ! 1145: return ppktlose (pb, pi, PC_CONGEST, ppdu, NULLCP, ! 1146: "too much user information"); ! 1147: } ! 1148: (*data++ = pe) -> pe_context = ctx; ! 1149: } ! 1150: if (result != PS_ERR_EOF) ! 1151: return ppktlose (pb, pi, result != PS_ERR_NMEM ? PC_INVALID ! 1152: : PC_CONGEST, ppdu, NULLCP, "%s", ! 1153: ps_error (result)); ! 1154: break; ! 1155: ! 1156: case type_PS_User__data_complex: ! 1157: for (full = info -> un.complex; full; full = full -> next) { ! 1158: struct qbuf *qb; ! 1159: register struct PSAPcontext *qp; ! 1160: register struct type_PS_PDV__list *pdv = full -> PDV__list; ! 1161: ! 1162: ctx = pdv -> identifier; ! 1163: for (j = 0, qp = pb -> pb_contexts; ! 1164: j < pb -> pb_ncontext; ! 1165: j++, qp++) ! 1166: if (qp -> pc_id == ctx) ! 1167: break; ! 1168: if (j >= pb -> pb_ncontext) ! 1169: return ppktlose (pb, pi, PC_INVALID, ppdu, NULLCP, ! 1170: "unexpected use of context %d", ctx); ! 1171: switch (pdv -> presentation__data__values -> offset) { ! 1172: case choice_PS_0_single__ASN1__type: ! 1173: if (i++ >= NPDATA) ! 1174: return ppktlose (pb, pi, PC_CONGEST, ppdu, NULLCP, ! 1175: "too much user information"); ! 1176: pe = pdv -> presentation__data__values -> ! 1177: un.single__ASN1__type; ! 1178: pdv -> presentation__data__values -> ! 1179: un.single__ASN1__type = NULLPE; ! 1180: (*data++ = pe) -> pe_context = ctx; ! 1181: break; ! 1182: ! 1183: case choice_PS_0_octet__aligned: ! 1184: qb = pdv -> presentation__data__values -> ! 1185: un.octet__aligned; ! 1186: while ((result = qb2info (qb, &pe)) == PS_ERR_NONE) { ! 1187: pe -> pe_context = ctx; ! 1188: if (i++ >= NPDATA) { ! 1189: pe_free (pe); ! 1190: return ppktlose (pb, pi, PC_CONGEST, ppdu, ! 1191: NULLCP, ! 1192: "too much user information"); ! 1193: } ! 1194: (*data++ = pe) -> pe_context = ctx; ! 1195: } ! 1196: if (result != PS_ERR_EOF) ! 1197: return ppktlose (pb, pi, result != PS_ERR_NMEM ! 1198: ? PC_INVALID : PC_CONGEST, ppdu, ! 1199: NULLCP, "%s", ps_error (result)); ! 1200: break; ! 1201: ! 1202: default: ! 1203: return ppktlose (pb, pi, PC_INVALID, ppdu, NULLCP, ! 1204: "not expecting non-BER encoding"); ! 1205: } ! 1206: } ! 1207: break; ! 1208: } ! 1209: *ndata = i; ! 1210: ! 1211: return OK; ! 1212: } ! 1213: ! 1214: /* */ ! 1215: ! 1216: #ifndef DEBUG ! 1217: /* ARGSUSED */ ! 1218: #endif ! 1219: ! 1220: int info2ssdu (pb, pi, data, ndata, realbase, base, len, text, ppdu) ! 1221: register struct psapblk *pb; ! 1222: struct PSAPindication *pi; ! 1223: PE *data; ! 1224: int ndata; ! 1225: char **realbase, ! 1226: **base; ! 1227: int *len; ! 1228: char *text; ! 1229: int ppdu; ! 1230: { ! 1231: int result; ! 1232: PE pe; ! 1233: struct type_PS_User__data *info; ! 1234: ! 1235: *realbase = *base = NULLCP, *len = 0; ! 1236: if (data == NULLPEP || ndata <= 0) ! 1237: return OK; ! 1238: ! 1239: if ((info = info2ppdu (pb, pi, data, ndata, ppdu)) == NULL) ! 1240: return (PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE); ! 1241: ! 1242: if (ppdu == PPDU_TTD) { ! 1243: pe = NULLPE; ! 1244: if ((result = encode_PS_User__data (&pe, 1, 0, NULLCP, info)) ! 1245: == NOTOK) { ! 1246: losing: ; ! 1247: free_PS_User__data (info); ! 1248: return psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", ! 1249: PY_pepy); ! 1250: } ! 1251: ! 1252: PLOGP (psap2_log,PS_User__data, pe, text, 0); ! 1253: ! 1254: goto serialize; ! 1255: } ! 1256: else ! 1257: if (ppdu == PPDU_RS || ppdu == PPDU_RSA) { ! 1258: /* this works 'cause RS-PPDU == RSA-PPDU */ ! 1259: struct type_PS_RS__PPDU rss; ! 1260: register struct type_PS_RS__PPDU *rs = &rss; ! 1261: ! 1262: if ((rs -> context__list = silly_list (pb, pi)) == NULL) ! 1263: return (PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE); ! 1264: rs -> user__data = info; ! 1265: ! 1266: pe = NULLPE; ! 1267: if ((result = encode_PS_RS__PPDU (&pe, 1, 0, NULLCP, rs)) ! 1268: == NOTOK) { ! 1269: free_PS_Identifier__list (rs -> context__list); ! 1270: goto losing; ! 1271: } ! 1272: ! 1273: PLOGP (psap2_log,PS_RS__PPDU, pe, text, 0); ! 1274: ! 1275: free_PS_Identifier__list (rs -> context__list); ! 1276: ! 1277: goto serialize; ! 1278: } ! 1279: ! 1280: if (info -> offset == type_PS_User__data_simple) { ! 1281: register struct qbuf *qb; ! 1282: ! 1283: qb = info -> un.simple; ! 1284: *len = qb -> qb_len; ! 1285: ! 1286: qb = qb -> qb_forw; ! 1287: remque (qb); ! 1288: ! 1289: *realbase = (char *) qb, *base = qb -> qb_base; ! 1290: ! 1291: #ifdef DEBUG ! 1292: if (psap2_log -> ll_events & LLOG_PDUS) ! 1293: while (ndata-- > 0) ! 1294: pvpdu (psap2_log, vunknown_P, *data++, text, 0); ! 1295: #endif ! 1296: } ! 1297: else { ! 1298: pe = NULLPE; ! 1299: if (encode_PS_Fully__encoded__data (&pe, 0, 0, NULLCP, ! 1300: info -> un.complex) == NOTOK) ! 1301: goto losing; ! 1302: pe -> pe_class = PE_CLASS_APPL, pe -> pe_id = 1; ! 1303: ! 1304: PLOGP (psap2_log,PS_User__data, pe, text, 0); ! 1305: ! 1306: serialize: ; ! 1307: result = pe2ssdu (pe, base, len); ! 1308: ! 1309: pe_free (pe); ! 1310: ! 1311: if (result == NOTOK) { ! 1312: free_PS_User__data (info); ! 1313: return psaplose (pi, PC_CONGEST, NULLCP, NULLCP); ! 1314: } ! 1315: } ! 1316: free_PS_User__data (info); ! 1317: ! 1318: return OK; ! 1319: } ! 1320: ! 1321: /* */ ! 1322: ! 1323: #ifndef DEBUG ! 1324: /* ARGSUSED */ ! 1325: #endif ! 1326: ! 1327: int ssdu2info (pb, pi, base, len, data, ndata, text, ppdu) ! 1328: register struct psapblk *pb; ! 1329: struct PSAPindication *pi; ! 1330: char *base; ! 1331: int len; ! 1332: PE *data; ! 1333: int *ndata; ! 1334: char *text; ! 1335: int ppdu; ! 1336: { ! 1337: int result; ! 1338: register PE pe; ! 1339: register struct type_PS_User__data *info; ! 1340: ! 1341: *ndata = 0; ! 1342: if (base == NULLCP || len <= 0) ! 1343: return OK; ! 1344: ! 1345: if (ppdu == PPDU_RS || ppdu == PPDU_RSA) { ! 1346: struct type_PS_RS__PPDU *rs;/* this works 'cause RS-PPDU == RSA-PPDU */ ! 1347: ! 1348: if ((pe = ssdu2pe (base, len, NULLCP, &result)) == NULLPE) ! 1349: return ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST ! 1350: : PC_PROTOCOL, ppdu, NULLCP, "%s", ! 1351: ps_error (result)); ! 1352: ! 1353: rs = NULL, info = NULL; ! 1354: result = decode_PS_RS__PPDU (pe, 1, NULLIP, NULLVP, &rs); ! 1355: ! 1356: #ifdef DEBUG ! 1357: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) ! 1358: pvpdu (psap2_log, print_PS_RS__PPDU_P, pe, text, 1); ! 1359: #endif ! 1360: ! 1361: info = rs -> user__data, rs -> user__data = NULL; ! 1362: free_PS_RS__PPDU (rs); ! 1363: ! 1364: goto punch_it; ! 1365: } ! 1366: ! 1367: if ((info = (struct type_PS_User__data *) calloc (1, sizeof *info)) ! 1368: == NULL) { ! 1369: no_mem: ; ! 1370: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); ! 1371: out: ; ! 1372: if (info) ! 1373: free_PS_User__data (info); ! 1374: return NOTOK; ! 1375: } ! 1376: ! 1377: if (pb -> pb_ncontext <= 1 || ppdu == PPDU_TE) { ! 1378: register struct qbuf *qb; ! 1379: ! 1380: info -> offset = type_PS_User__data_simple; ! 1381: ! 1382: if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL) ! 1383: goto no_mem; ! 1384: info -> un.simple = qb; ! 1385: qb -> qb_forw = qb -> qb_back = qb; ! 1386: qb -> qb_data = NULL, qb -> qb_len = len; ! 1387: if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL) ! 1388: goto no_mem; ! 1389: insque (qb, info -> un.simple); ! 1390: qb -> qb_data = base, qb -> qb_len = len; ! 1391: } ! 1392: else { ! 1393: info -> offset = type_PS_User__data_complex; ! 1394: ! 1395: if ((pe = ssdu2pe (base, len, NULLCP, &result)) == NULLPE) { ! 1396: (void) ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST ! 1397: : PC_PROTOCOL, ppdu, NULLCP, "%s", ! 1398: ps_error (result)); ! 1399: goto out; ! 1400: } ! 1401: ! 1402: if (pe -> pe_class != PE_CLASS_APPL ! 1403: || pe -> pe_form != PE_FORM_CONS ! 1404: || pe -> pe_id != 1) { ! 1405: PY_advise (NULLCP, ! 1406: "Fully-encoded-data bad class/form/id: %s/%d/0x%x", ! 1407: pe_classlist[pe -> pe_class], pe -> pe_form, ! 1408: pe -> pe_id); ! 1409: result = NOTOK; ! 1410: } ! 1411: else ! 1412: result = decode_PS_Fully__encoded__data (pe, 0, NULLIP, NULLVP, ! 1413: &info -> un.complex); ! 1414: ! 1415: #ifdef DEBUG ! 1416: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) ! 1417: pvpdu (psap2_log, print_PS_User__data_P, pe, text, 1); ! 1418: #endif ! 1419: ! 1420: punch_it: ; ! 1421: pe_free (pe); ! 1422: ! 1423: if (result == NOTOK) { ! 1424: (void) ppktlose (pb, pi, PC_UNRECOGNIZED, ppdu, NULLCP, "%s", ! 1425: PY_pepy); ! 1426: goto out; ! 1427: } ! 1428: } ! 1429: ! 1430: if ((result = ppdu2info (pb, pi, info, data, ndata, ppdu)) == NOTOK) ! 1431: result = PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE; ! 1432: ! 1433: #ifdef DEBUG ! 1434: if (result == OK ! 1435: && ppdu != PPDU_RS ! 1436: && ppdu != PPDU_RSA ! 1437: && info -> offset == type_PS_User__data_simple ! 1438: && (psap2_log -> ll_events & LLOG_PDUS)) { ! 1439: register int i; ! 1440: ! 1441: for (i = *ndata; i > 0; i--) ! 1442: pvpdu (psap2_log, vunknown_P, *data++, text, 1); ! 1443: } ! 1444: #endif ! 1445: ! 1446: free_PS_User__data (info); ! 1447: ! 1448: return result; ! 1449: } ! 1450: ! 1451: /* */ ! 1452: ! 1453: #ifndef DEBUG ! 1454: /* ARGSUSED */ ! 1455: #endif ! 1456: ! 1457: int qbuf2info (pb, pi, qb, len, data, ndata, text, ppdu) ! 1458: register struct psapblk *pb; ! 1459: struct PSAPindication *pi; ! 1460: struct qbuf *qb; ! 1461: int len; ! 1462: PE *data; ! 1463: int *ndata; ! 1464: char *text; ! 1465: int ppdu; ! 1466: { ! 1467: int result; ! 1468: register PE pe; ! 1469: register struct qbuf *qp; ! 1470: struct type_PS_User__data *info; ! 1471: ! 1472: *ndata = 0; ! 1473: if (qb == NULL || len <= 0) ! 1474: return OK; ! 1475: ! 1476: if (ppdu == PPDU_TTD) { ! 1477: if ((pe = qbuf2pe (qb, len, &result)) == NULLPE) ! 1478: return ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST ! 1479: : PC_PROTOCOL, ppdu, NULLCP, "%s", ! 1480: ps_error (result)); ! 1481: ! 1482: info = NULL; ! 1483: result = decode_PS_User__data (pe, 1, NULLIP, NULLVP, &info); ! 1484: ! 1485: #ifdef DEBUG ! 1486: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) ! 1487: pvpdu (psap2_log, print_PS_User__data_P, pe, text, 1); ! 1488: #endif ! 1489: ! 1490: goto punch_it; ! 1491: } ! 1492: ! 1493: if ((info = (struct type_PS_User__data *) calloc (1, sizeof *info)) ! 1494: == NULL) { ! 1495: no_mem: ; ! 1496: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); ! 1497: goto out; ! 1498: } ! 1499: ! 1500: if (pb -> pb_ncontext <= 1 || ppdu == PPDU_TE) { ! 1501: register struct qbuf *qbp, ! 1502: *qpp; ! 1503: ! 1504: info -> offset = type_PS_User__data_simple; ! 1505: if ((qp = (struct qbuf *) malloc (sizeof *qp)) == NULL) ! 1506: goto no_mem; ! 1507: info -> un.simple = qpp = qp; ! 1508: qp -> qb_forw = qp -> qb_back = qp; ! 1509: qp -> qb_data = NULL, qp -> qb_len = len; ! 1510: for (qp = qb -> qb_forw; qp != qb; qp = qbp) { ! 1511: qbp = qp -> qb_forw; ! 1512: ! 1513: remque (qp); ! 1514: insque (qp, qpp -> qb_back); ! 1515: } ! 1516: } ! 1517: else { ! 1518: info -> offset = type_PS_User__data_complex; ! 1519: ! 1520: if ((pe = qbuf2pe (qb, len, &result)) == NULLPE) { ! 1521: (void) ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST ! 1522: : PC_PROTOCOL, ppdu, NULLCP, "%s", ! 1523: ps_error (result)); ! 1524: goto out; ! 1525: } ! 1526: if (pe -> pe_class != PE_CLASS_APPL ! 1527: || pe -> pe_form != PE_FORM_CONS ! 1528: || pe -> pe_id != 1) { ! 1529: PY_advise (NULLCP, ! 1530: "Fully-encoded-data bad class/form/id: %s/%d/0x%x", ! 1531: pe_classlist[pe -> pe_class], pe -> pe_form, ! 1532: pe -> pe_id); ! 1533: result = NOTOK; ! 1534: } ! 1535: else ! 1536: result = decode_PS_Fully__encoded__data (pe, 0, NULLIP, NULLVP, ! 1537: &info -> un.complex); ! 1538: ! 1539: #ifdef DEBUG ! 1540: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) ! 1541: pvpdu (psap2_log, print_PS_User__data_P, pe, text, 1); ! 1542: #endif ! 1543: ! 1544: punch_it: ; ! 1545: pe_free (pe); ! 1546: ! 1547: if (result == NOTOK) { ! 1548: (void) ppktlose (pb, pi, PC_UNRECOGNIZED, ppdu, NULLCP, "%s", ! 1549: PY_pepy); ! 1550: goto out; ! 1551: } ! 1552: } ! 1553: ! 1554: if ((result = ppdu2info (pb, pi, info, data, ndata, ppdu)) == NOTOK) ! 1555: result = PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE; ! 1556: ! 1557: #ifdef DEBUG ! 1558: if (result == OK ! 1559: && ppdu != PPDU_TTD ! 1560: && info -> offset == type_PS_User__data_simple ! 1561: && (psap2_log -> ll_events & LLOG_PDUS)) { ! 1562: register int i; ! 1563: ! 1564: for (i = *ndata; i > 0; i--) ! 1565: pvpdu (psap2_log, vunknown_P, *data++, text, 1); ! 1566: } ! 1567: #endif ! 1568: ! 1569: free_PS_User__data (info); ! 1570: ! 1571: return result; ! 1572: ! 1573: out: ; ! 1574: if (info) ! 1575: free_PS_User__data (info); ! 1576: ! 1577: return NOTOK; ! 1578: } ! 1579: ! 1580: /* */ ! 1581: ! 1582: struct qbuf *info2qb (pe, qp, pi) ! 1583: register PE pe; ! 1584: register struct qbuf *qp; ! 1585: struct PSAPindication *pi; ! 1586: { ! 1587: int len; ! 1588: register struct qbuf *qb; ! 1589: register PS ps; ! 1590: ! 1591: if ((qb = qp) == NULL) { ! 1592: if ((qb = (struct qbuf *) malloc ((unsigned) sizeof *qb ! 1593: + (len = ps_get_abs (pe)))) ! 1594: == NULL) { ! 1595: no_mem: ; ! 1596: (void) psaplose (pi, PC_CONGEST, NULLCP, NULLCP); ! 1597: goto out; ! 1598: } ! 1599: ! 1600: qb -> qb_data = qb -> qb_base, qb -> qb_len = len; ! 1601: } ! 1602: ! 1603: if ((ps = ps_alloc (str_open)) == NULLPS) ! 1604: goto no_mem; ! 1605: if (str_setup (ps, qb -> qb_data, qb -> qb_len, 1) == NOTOK ! 1606: || pe2ps_aux (ps, pe, 0) == NOTOK) { ! 1607: (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding user-info"); ! 1608: ps_free (ps); ! 1609: goto out; ! 1610: } ! 1611: ! 1612: len = ps -> ps_ptr - ps -> ps_base; ! 1613: if (qp) ! 1614: qp -> qb_data += len, qp -> qb_len -= len; ! 1615: else ! 1616: qb -> qb_len = len; ! 1617: ! 1618: #ifdef DEBUG ! 1619: if (psap_log -> ll_events & LLOG_PDUS) ! 1620: pe2text (psap_log, pe, 0, len); ! 1621: #endif ! 1622: ! 1623: ps_free (ps); ! 1624: ! 1625: return qb; ! 1626: ! 1627: out: ; ! 1628: if (qb && qb != qp) ! 1629: free ((char *) qb); ! 1630: ! 1631: return NULL; ! 1632: } ! 1633: ! 1634: /* */ ! 1635: ! 1636: int qb2info (qb, pe) ! 1637: register struct qbuf *qb; ! 1638: PE *pe; ! 1639: { ! 1640: int result; ! 1641: #ifdef DEBUG ! 1642: int len; ! 1643: #endif ! 1644: PE p; ! 1645: register PS ps; ! 1646: ! 1647: *pe = NULLPE; ! 1648: ! 1649: if ((ps = ps_alloc (qbuf_open)) == NULLPS) ! 1650: return PS_ERR_NMEM; ! 1651: #ifdef DEBUG ! 1652: len = ps -> ps_byteno; ! 1653: #endif ! 1654: if (qbuf_setup (ps, qb) == NOTOK || (p = ps2pe (ps)) == NULLPE) { ! 1655: if ((result = ps -> ps_errno) == PS_ERR_NONE) ! 1656: result = PS_ERR_EOF; ! 1657: } ! 1658: else { ! 1659: result = PS_ERR_NONE; ! 1660: *pe = p; ! 1661: } ! 1662: ! 1663: ps -> ps_addr = NULL; /* so ps_free doesn't free remainder of qbuf */ ! 1664: #ifdef DEBUG ! 1665: len = ps -> ps_byteno - len; ! 1666: #endif ! 1667: ps_free (ps); ! 1668: ! 1669: #ifdef DEBUG ! 1670: if (p && (psap_log -> ll_events & LLOG_PDUS)) ! 1671: pe2text (psap_log, p, 1, len); ! 1672: #endif ! 1673: ! 1674: return result; ! 1675: } ! 1676: ! 1677: /* */ ! 1678: ! 1679: struct type_PS_Identifier__list *silly_list (pb, pi) ! 1680: register struct psapblk *pb; ! 1681: struct PSAPindication *pi; ! 1682: { ! 1683: register int j; ! 1684: register struct PSAPcontext *qp; ! 1685: struct type_PS_Identifier__list *list; ! 1686: register struct type_PS_Identifier__list *lp, ! 1687: **mp; ! 1688: ! 1689: list = NULL; ! 1690: mp = &list; ! 1691: ! 1692: for (j = 0, qp = pb -> pb_contexts; ! 1693: j < pb -> pb_ncontext; ! 1694: j++, qp++) { ! 1695: if ((lp = (struct type_PS_Identifier__list *) ! 1696: calloc (1, sizeof *lp)) == NULL) { ! 1697: no_mem: ; ! 1698: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); ! 1699: free_PS_Identifier__list (list); ! 1700: return NULL; ! 1701: } ! 1702: *mp = lp; ! 1703: mp = &lp -> next; ! 1704: if ((lp -> element_PS_10 = (struct element_PS_11 *) ! 1705: calloc (1, sizeof (struct element_PS_11))) == NULL ! 1706: || (lp -> element_PS_10 -> transfer__syntax = ! 1707: oid_cpy (qp -> pc_atn)) == NULLOID) ! 1708: goto no_mem; ! 1709: lp -> element_PS_10 -> identifier = qp -> pc_id; ! 1710: } ! 1711: ! 1712: return list; ! 1713: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.