|
|
1.1 ! root 1: /* tsdu2spkt.c - read/write a SPDU to a TSDU */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/ssap/RCS/tsdu2spkt.c,v 7.0 89/11/23 22:25:55 mrose Rel $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/ssap/RCS/tsdu2spkt.c,v 7.0 89/11/23 22:25:55 mrose Rel $ ! 9: * ! 10: * ! 11: * $Log: tsdu2spkt.c,v $ ! 12: * Revision 7.0 89/11/23 22:25:55 mrose ! 13: * Release 6.0 ! 14: * ! 15: */ ! 16: ! 17: /* ! 18: * NOTICE ! 19: * ! 20: * Acquisition, use, and distribution of this module and related ! 21: * materials are subject to the restrictions of a license agreement. ! 22: * Consult the Preface in the User's Manual for the full terms of ! 23: * this agreement. ! 24: * ! 25: */ ! 26: ! 27: ! 28: /* LINTLIBRARY */ ! 29: ! 30: #include <stdio.h> ! 31: #include "spkt.h" ! 32: #include "tailor.h" ! 33: ! 34: /* */ ! 35: ! 36: struct local_buf { ! 37: char *top; /* Top of buffer */ ! 38: char *ptr; /* Pointer to working buffer */ ! 39: int pgi; /* Offset of last PGI li */ ! 40: int left; /* Number of bytes left */ ! 41: int li; /* Running spdu length */ ! 42: int allocli; /* Allocated li */ ! 43: int len; /* Current buffer size */ ! 44: }; ! 45: ! 46: /* */ ! 47: ! 48: #define PMASK_NODATA 0x000000 ! 49: #define PMASK_CN_ID 0x000001 /* 1: Connection ID */ ! 50: #define PMASK_CN_ITEMS 0x000002 /* 5: Connect/Accept Item */ ! 51: #define PMASK_SYNC 0x000004 /* 15: Sync Type Item */ ! 52: #define PMASK_TOKEN 0x000008 /* 16: Token Item */ ! 53: #define PMASK_TDISC 0x000010 /* 17: Transport Disc */ ! 54: #define PMASK_USER_REQ 0x000020 /* 20: Session User Req */ ! 55: #define PMASK_VERSION 0x000040 /* 22: Version Number */ ! 56: #define PMASK_PREPARE 0x000080 /* 24: Prepare type */ ! 57: #define PMASK_ENCLOSE 0x000100 /* 25: Enclosure Item */ ! 58: #define PMASK_TOKEN_SET 0x000200 /* 26: Token Setting Item */ ! 59: #define PMASK_RESYNC 0x000400 /* 27: Resync type */ ! 60: #define PMASK_LINK 0x000800 /* 33: Linking information */ ! 61: #define PMASK_ACT_ID 0x001000 /* 41: Activity ID */ ! 62: #define PMASK_SERIAL 0x002000 /* 42: Serial Number */ ! 63: #define PMASK_MIA_DATA 0x004000 /* 46: MIA User Data */ ! 64: #define PMASK_REFLECT 0x008000 /* 49: Reflect parameter */ ! 65: #define PMASK_REASON 0x010000 /* 50: Refusal Reason */ ! 66: #define PMASK_SSAP_CALLING 0x020000 /* 51: Calling SSAP ID */ ! 67: #define PMASK_SSAP_CALLED 0x040000 /* 52: Called SSAP ID */ ! 68: #define PMASK_UDATA 0x080000 /* 193: User data */ ! 69: #define PMASK_XDATA 0x100000 /* 194: Extended user data */ ! 70: ! 71: #define PMASK_VARLEN 0x800000 /* PI is Variable Len */ ! 72: #define PMASK_NOTSUPPORTED -1 /* Type not supported */ ! 73: ! 74: ! 75: static int si_table[] = { ! 76: PMASK_REFLECT, /* 0x00: SPDU_ER */ ! 77: PMASK_ENCLOSE /* 0x01: SPDU_GT & SPDU_DT */ ! 78: | PMASK_TOKEN, ! 79: PMASK_TOKEN /* 0x02: SPDU_PT */ ! 80: | PMASK_ENCLOSE ! 81: | PMASK_UDATA, ! 82: PMASK_NOTSUPPORTED, /* 0x03 */ ! 83: PMASK_NOTSUPPORTED, /* 0x04 */ ! 84: PMASK_NODATA, /* 0x05: SPDU_EX */ ! 85: PMASK_NOTSUPPORTED, /* 0x06 */ ! 86: PMASK_PREPARE, /* 0x07: SPDU_PR */ ! 87: PMASK_ENCLOSE /* 0x08: SPDU_NF */ ! 88: | PMASK_UDATA, ! 89: PMASK_TDISC /* 0x09: SPDU_FN */ ! 90: | PMASK_ENCLOSE ! 91: | PMASK_UDATA, ! 92: PMASK_ENCLOSE /* 0x0a: SPDU_DN */ ! 93: | PMASK_UDATA, ! 94: PMASK_NOTSUPPORTED, /* 0x0b */ ! 95: PMASK_CN_ID /* 0x0c: SPDU_RF */ ! 96: | PMASK_TDISC ! 97: | PMASK_USER_REQ ! 98: | PMASK_VERSION ! 99: | PMASK_ENCLOSE ! 100: | PMASK_REASON, ! 101: PMASK_CN_ID /* 0x0d: SPDU_CN */ ! 102: | PMASK_CN_ITEMS ! 103: | PMASK_USER_REQ ! 104: | PMASK_VERSION ! 105: | PMASK_SSAP_CALLING ! 106: | PMASK_SSAP_CALLED ! 107: | PMASK_UDATA ! 108: | PMASK_XDATA, ! 109: PMASK_CN_ID /* 0x0e: SPDU_AC */ ! 110: | PMASK_CN_ITEMS ! 111: | PMASK_USER_REQ ! 112: | PMASK_VERSION ! 113: | PMASK_SSAP_CALLING ! 114: | PMASK_TOKEN ! 115: | PMASK_ENCLOSE ! 116: | PMASK_SSAP_CALLED ! 117: | PMASK_UDATA, ! 118: PMASK_NOTSUPPORTED, /* 0x0f */ ! 119: PMASK_NOTSUPPORTED, /* 0x10 */ ! 120: PMASK_NOTSUPPORTED, /* 0x11 */ ! 121: PMASK_NOTSUPPORTED, /* 0x12 */ ! 122: PMASK_NOTSUPPORTED, /* 0x13 */ ! 123: PMASK_NOTSUPPORTED, /* 0x14 */ ! 124: PMASK_NODATA, /* 0x15: SPDU_GTC */ ! 125: PMASK_NODATA, /* 0x16: SPDU_GTA */ ! 126: PMASK_NOTSUPPORTED, /* 0x17 */ ! 127: PMASK_NOTSUPPORTED, /* 0x18 */ ! 128: PMASK_TDISC /* 0x19: SPDU_AB & SPDU_AI */ ! 129: | PMASK_REFLECT ! 130: | PMASK_REASON ! 131: | PMASK_ENCLOSE ! 132: | PMASK_UDATA, ! 133: PMASK_NODATA, /* 0x1a: SPDU_AA & SPDU_AIA */ ! 134: PMASK_NOTSUPPORTED, /* 0x1b */ ! 135: PMASK_NOTSUPPORTED, /* 0x1c */ ! 136: PMASK_LINK /* 0x1d: SPDU_AR */ ! 137: | PMASK_ACT_ID ! 138: | PMASK_ENCLOSE ! 139: | PMASK_SERIAL ! 140: | PMASK_UDATA, ! 141: PMASK_NOTSUPPORTED, /* 0x1e */ ! 142: PMASK_NOTSUPPORTED, /* 0x1f */ ! 143: PMASK_NOTSUPPORTED, /* 0x20 */ ! 144: PMASK_ENCLOSE, /* 0x21: SPDU_TD */ ! 145: PMASK_TOKEN_SET /* 0x22: SPDU_RA */ ! 146: | PMASK_ENCLOSE ! 147: | PMASK_SERIAL ! 148: | PMASK_UDATA, ! 149: PMASK_NOTSUPPORTED, /* 0x23 */ ! 150: PMASK_NOTSUPPORTED, /* 0x24 */ ! 151: PMASK_NOTSUPPORTED, /* 0x25 */ ! 152: PMASK_NOTSUPPORTED, /* 0x26 */ ! 153: PMASK_NOTSUPPORTED, /* 0x27 */ ! 154: PMASK_NOTSUPPORTED, /* 0x28 */ ! 155: PMASK_SYNC /* 0x29: SPDU_MAP & SPDU_AE */ ! 156: | PMASK_ENCLOSE ! 157: | PMASK_SERIAL ! 158: | PMASK_UDATA, ! 159: PMASK_ENCLOSE /* 0x2a: SPDU_MAA & SPDU_AEA */ ! 160: | PMASK_SERIAL ! 161: | PMASK_UDATA, ! 162: PMASK_NOTSUPPORTED, /* 0x2b */ ! 163: PMASK_NOTSUPPORTED, /* 0x2c */ ! 164: PMASK_ENCLOSE /* 0x2d: SPDU_AS */ ! 165: | PMASK_ACT_ID ! 166: | PMASK_UDATA, ! 167: PMASK_NOTSUPPORTED, /* 0x2e */ ! 168: PMASK_NOTSUPPORTED, /* 0x2f */ ! 169: PMASK_ENCLOSE /* 0x30: SPDU_ED */ ! 170: | PMASK_REASON ! 171: | PMASK_UDATA, ! 172: PMASK_SYNC /* 0x31: SPDU_MIP */ ! 173: | PMASK_ENCLOSE ! 174: | PMASK_SERIAL ! 175: | PMASK_UDATA, ! 176: PMASK_ENCLOSE /* 0x32: SPDU_MIA */ ! 177: | PMASK_SERIAL ! 178: | PMASK_MIA_DATA, ! 179: PMASK_NOTSUPPORTED, /* 0x33 */ ! 180: PMASK_NOTSUPPORTED, /* 0x34 */ ! 181: PMASK_TOKEN_SET /* 0x35: SPDU_RS */ ! 182: | PMASK_ENCLOSE ! 183: | PMASK_RESYNC ! 184: | PMASK_SERIAL ! 185: | PMASK_UDATA, ! 186: PMASK_NOTSUPPORTED, /* 0x36 */ ! 187: PMASK_NOTSUPPORTED, /* 0x37 */ ! 188: PMASK_NOTSUPPORTED, /* 0x38 */ ! 189: PMASK_REASON, /* 0x39: SPDU_AD */ ! 190: PMASK_NODATA, /* 0x3a: SPDU_ADA */ ! 191: PMASK_NOTSUPPORTED, /* 0x3b */ ! 192: PMASK_NOTSUPPORTED, /* 0x3c */ ! 193: PMASK_ENCLOSE /* 0x3d: SPDU_CD */ ! 194: | PMASK_UDATA, ! 195: PMASK_ENCLOSE /* 0x3e: SPDU_CDA */ ! 196: | PMASK_UDATA ! 197: }; ! 198: #define SI_TABLE_LEN ((sizeof si_table) / (sizeof si_table[0])) ! 199: ! 200: /* */ ! 201: ! 202: #define PGI_CN_ID 1 ! 203: #define PI_CALLED_SS 9 ! 204: #define PI_CALLING_SS 10 ! 205: #define PI_COMMON_REF 11 ! 206: #define PI_ADD_INFO 12 ! 207: #define PGI_CN_ITEMS 5 ! 208: #define PI_PROTOCOL_OPT 19 ! 209: #define PI_TSDU_MAXSIZ 21 ! 210: #define PI_VERSION 22 ! 211: #define PI_ISN 23 ! 212: #define PI_TOKEN_SET 26 ! 213: #define PI_ISN2 55 ! 214: #define PI_SYNC 15 ! 215: #define PI_TOKEN 16 ! 216: #define PI_TDISC 17 ! 217: #define PI_USER_REQ 20 ! 218: #define PI_PREPARE 24 ! 219: #define PI_ENCLOSE 25 ! 220: #define PI_RESYNC 27 ! 221: #define PGI_AR_LINK 33 ! 222: #define PI_AR_CALLED 9 ! 223: #define PI_AR_CALLING 10 ! 224: #define PI_AR_COMMON 11 ! 225: #define PI_AR_ADDT 12 ! 226: #define PI_AR_OLD 41 ! 227: #define PI_AR_SERIAL 42 ! 228: #define PI_ACT_ID 41 ! 229: #define PI_SERIAL 42 ! 230: #define PI_MIA_DATA 46 ! 231: #define PI_REFLECT 49 ! 232: #define PI_REASON 50 ! 233: #define PI_SSAP_CALLING 51 ! 234: #define PI_SSAP_CALLED 52 ! 235: #define PI_UDATA 193 ! 236: #define PI_XDATA 194 ! 237: ! 238: ! 239: static int pi_table[] = { ! 240: 0, /* 0x00 */ ! 241: PMASK_VARLEN | PMASK_CN_ID, /* 0x01: Connection ID */ ! 242: 0, 0, 0, /* 0x02-04 */ ! 243: PMASK_VARLEN | PMASK_CN_ITEMS, /* 0x05: Connect/Accept Item */ ! 244: 0, 0, 0, /* 0x06-08 */ ! 245: PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x09: Called Session SS */ ! 246: PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x0a: Calling Session SS */ ! 247: PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x0b: Common Reference */ ! 248: PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x0c: Additional Info */ ! 249: 0, 0, /* 0x0d-0e */ ! 250: PMASK_SYNC, /* 0x0f: Sync Type Item */ ! 251: PMASK_TOKEN, /* 0x10: Token Item */ ! 252: PMASK_TDISC, /* 0x11: Transport Disc */ ! 253: 0, /* 0x12 */ ! 254: PMASK_CN_ITEMS, /* 0x13: Protocol Option */ ! 255: PMASK_USER_REQ, /* 0x14: Session User Req */ ! 256: PMASK_VARLEN | PMASK_CN_ITEMS, /* 0x15: TSDU Max Size */ ! 257: PMASK_VERSION, /* 0x16: Version Number */ ! 258: PMASK_VARLEN | PMASK_CN_ITEMS, /* 0x17: Initial Serial Num */ ! 259: PMASK_PREPARE, /* 0x18: Prepare Type */ ! 260: PMASK_ENCLOSE, /* 0x19: Enclosure Item */ ! 261: PMASK_CN_ITEMS | PMASK_TOKEN_SET, /* 0x1a: Token setting item */ ! 262: PMASK_RESYNC, /* 0x1b: Resync type */ ! 263: 0, 0, 0, 0, 0, /* 0x1c-20 */ ! 264: PMASK_VARLEN | PMASK_LINK, /* 0x21: Activity Link */ ! 265: 0, 0, 0, 0, 0, 0, 0, /* 0x22-28 */ ! 266: PMASK_VARLEN | PMASK_ACT_ID, /* 0x29: Activity ID */ ! 267: PMASK_VARLEN | PMASK_SERIAL, /* 0x2a: Serial Number */ ! 268: 0, 0, 0, /* 0x2b-2d */ ! 269: PMASK_VARLEN | PMASK_MIA_DATA, /* 0x2e: MIA User Data */ ! 270: 0, 0, /* 0x2f-30 */ ! 271: PMASK_VARLEN | PMASK_REFLECT, /* 0x31: Reflect parameter */ ! 272: PMASK_VARLEN | PMASK_REASON, /* 0x32: Refusal Reason */ ! 273: PMASK_VARLEN | PMASK_SSAP_CALLING, /* 0x33: Calling SSAP ID */ ! 274: PMASK_VARLEN | PMASK_SSAP_CALLED, /* 0x34: Called SSAP ID */ ! 275: 0, 0, /* 0x35-36 */ ! 276: PMASK_VARLEN | PMASK_CN_ITEMS /* 0x17: 2nd initial s/n */ ! 277: }; ! 278: #define PI_TABLE_LEN ((sizeof pi_table) / (sizeof pi_table[0])) ! 279: ! 280: /* */ ! 281: ! 282: static int pi_length[PI_TABLE_LEN] = { ! 283: 0, /* 0x00 */ ! 284: SREF_USER_SIZE /* 0x01: Connection ID */ ! 285: + SREF_COMM_SIZE ! 286: + SREF_ADDT_SIZE ! 287: + 6, ! 288: 0, 0, 0, /* 0x02-04 */ ! 289: 1 + 4 + 1 + 6 + 1 + 10, /* 0x05: Connect/Accept Item */ ! 290: 0, 0, 0, /* 0x06-08 */ ! 291: SREF_USER_SIZE, /* 0x09: Called Session SS */ ! 292: SREF_USER_SIZE, /* 0x0a: Calling Session SS */ ! 293: SREF_COMM_SIZE, /* 0x0b: Common Reference */ ! 294: SREF_ADDT_SIZE, /* 0x0c: Additional Info */ ! 295: 0, 0, /* 0x0d-0e */ ! 296: 1, /* 0x0f: Sync Type Item */ ! 297: 1, /* 0x10: Token Item */ ! 298: 1, /* 0x11: Transport Disc */ ! 299: 0, /* 0x12 */ ! 300: 1, /* 0x13: Protocol Option */ ! 301: 2, /* 0x14: Session User Req */ ! 302: 4, /* 0x15: TSDU Max Size */ ! 303: 1, /* 0x16: Version Number */ ! 304: SIZE_CN_ISN, /* 0x17: Initial Serial Num */ ! 305: 1, /* 0x18: Prepare Type */ ! 306: 1, /* 0x19: Enclosure Item */ ! 307: 1, /* 0x1a: Token setting item */ ! 308: 1, /* 0x1b: Resync type */ ! 309: 0, 0, 0, 0, 0, /* 0x1c-20 */ ! 310: 2 * SREF_USER_SIZE /* 0x21: Activity Link */ ! 311: + SREF_COMM_SIZE ! 312: + SREF_ADDT_SIZE ! 313: + SID_DATA_SIZE ! 314: + SIZE_CN_ISN ! 315: + 6 * 2, ! 316: 0, 0, 0, 0, 0, 0, 0, /* 0x22-28 */ ! 317: SID_DATA_SIZE, /* 0x29: Activity ID */ ! 318: SIZE_CN_ISN, /* 0x2a: Serial Number */ ! 319: 0, 0, 0, /* 0x2b-2d */ ! 320: SEGMENT_MAX /* MIA_SIZE */, /* 0x2e: MIA User Data */ ! 321: 0, 0, /* 0x2f-30 */ ! 322: SEGMENT_MAX, /* 0x31: Reflect parameter */ ! 323: RF_SIZE, /* 0x32: Refusal Reason */ ! 324: SSSIZE, /* 0x33: Calling SSAP ID */ ! 325: SSSIZE, /* 0x34: Called SSAP ID */ ! 326: 0, 0, /* 0x35-36 */ ! 327: SIZE_CN_ISN, /* 0x37: 2nd initial s/n */ ! 328: }; ! 329: ! 330: /* */ ! 331: ! 332: #define If_Set(flag) if (s -> s_mask & (flag)) ! 333: #define If_Reset(flag) if (!(s -> s_mask & (flag))) ! 334: #define Set(flag) s -> s_mask |= (flag) ! 335: #define Reset(flag) s -> s_mask &= ~(flag) ! 336: ! 337: #define Put_Item(code,value) \ ! 338: put2spdu((code), pi_length[(code)], (value), &c) ! 339: ! 340: #define Put_Ref(r,code) \ ! 341: { \ ! 342: start_pgi (PGI_CN_ID, &c); \ ! 343: if (r.sr_ulen) \ ! 344: put2spdu (code, (int) r.sr_ulen, r.sr_udata, &c); \ ! 345: if (r.sr_clen) \ ! 346: put2spdu (PI_COMMON_REF, (int) r.sr_clen, r.sr_cdata, &c); \ ! 347: if (r.sr_alen) \ ! 348: put2spdu (PI_ADD_INFO, (int) r.sr_alen, r.sr_adata, &c); \ ! 349: end_pgi (&c); \ ! 350: } ! 351: ! 352: #define Put_SSN(code,ssn) \ ! 353: { \ ! 354: if ((ssn) > SERIAL_MAX + 1) { \ ! 355: if (c.len) \ ! 356: free (c.top); \ ! 357: s -> s_errno = SC_PROTOCOL; \ ! 358: return NOTOK; \ ! 359: } \ ! 360: (void) sprintf (isn, "%lu", (ssn)); \ ! 361: put2spdu ((code), strlen (isn), isn, &c); \ ! 362: } ! 363: ! 364: /* this used to check ! 365: ! 366: if (s -> s_ulen > (csize)) { ! 367: if (c.len) ! 368: free (c.top); ! 369: s -> s_errno = SC_PROTOCOL; ! 370: return NOTOK; ! 371: } ! 372: ! 373: but with version 2 session, there's really no point... */ ! 374: ! 375: #define Put_UData(csize) \ ! 376: { \ ! 377: if (s -> s_udata) { \ ! 378: put2spdu (PI_UDATA, s -> s_ulen, s -> s_udata, &c); \ ! 379: } \ ! 380: } ! 381: ! 382: #define Put_XData(csize) \ ! 383: { \ ! 384: if (s -> s_udata) { \ ! 385: put2spdu (s -> s_ulen > csize ? PI_XDATA : PI_UDATA, s -> s_ulen, \ ! 386: s -> s_udata, &c); \ ! 387: } \ ! 388: } ! 389: ! 390: #define Put_MData(csize) \ ! 391: { \ ! 392: if (s -> s_udata) { \ ! 393: put2spdu (PI_MIA_DATA, s -> s_ulen, s -> s_udata, &c); \ ! 394: } \ ! 395: } ! 396: ! 397: /* */ ! 398: ! 399: static start_spdu (s, c, basesize) ! 400: struct ssapkt *s; ! 401: struct local_buf *c; ! 402: int basesize; ! 403: { ! 404: if (s -> s_udata) ! 405: switch (s -> s_code) { ! 406: case SPDU_DT: /* caller responsible for this... */ ! 407: case SPDU_EX: ! 408: case SPDU_TD: ! 409: break; ! 410: ! 411: default: ! 412: if (s -> s_ulen) ! 413: basesize += s -> s_ulen + (s -> s_ulen > 254 ? 4 : 2); ! 414: break; ! 415: } ! 416: ! 417: switch (s -> s_code) { ! 418: case SPDU_CN: ! 419: case SPDU_AC: ! 420: If_Set (SMASK_CN_REF) { ! 421: basesize += 2; ! 422: if (s -> s_cn_reference.sr_ulen) ! 423: basesize += 2 + s -> s_cn_reference.sr_ulen; ! 424: if (s -> s_cn_reference.sr_clen) ! 425: basesize += 2 + s -> s_cn_reference.sr_clen; ! 426: if (s -> s_cn_reference.sr_alen) ! 427: basesize += 2 + s -> s_cn_reference.sr_alen; ! 428: } ! 429: If_Set (SMASK_CN_CALLING) ! 430: basesize += s -> s_callinglen + 2; ! 431: If_Set (SMASK_CN_CALLED) ! 432: basesize += s -> s_calledlen + 2; ! 433: break; ! 434: ! 435: case SPDU_RF: ! 436: If_Set (SMASK_RF_REF) { ! 437: basesize += 2; ! 438: if (s -> s_rf_reference.sr_ulen) ! 439: basesize += 2 + s -> s_rf_reference.sr_ulen; ! 440: if (s -> s_rf_reference.sr_clen) ! 441: basesize += 2 + s -> s_rf_reference.sr_clen; ! 442: if (s -> s_rf_reference.sr_alen) ! 443: basesize += 2 + s -> s_rf_reference.sr_alen; ! 444: } ! 445: break; ! 446: ! 447: case SPDU_AR: ! 448: basesize += 2; ! 449: If_Set (SMASK_AR_REF) { ! 450: if (s -> s_ar_reference.sr_ulen) ! 451: basesize += 2 + s -> s_ar_reference.sr_ulen; ! 452: if (s -> s_ar_reference.sr_clen) ! 453: basesize += 2 + s -> s_ar_reference.sr_clen; ! 454: if (s -> s_ar_reference.sr_alen) ! 455: basesize += 2 + s -> s_ar_reference.sr_alen; ! 456: if (s -> s_ar_reference.sr_vlen) ! 457: basesize += 2 + s -> s_ar_reference.sr_vlen; ! 458: } ! 459: break; ! 460: } ! 461: ! 462: if (basesize < 254) ! 463: basesize = 254; ! 464: c -> li = c -> pgi = 0; ! 465: c -> len = basesize + ((basesize > 254) ? 4 : 2); ! 466: if ((c -> top = malloc ((unsigned) c -> len)) == NULL) { ! 467: c -> len = 0; ! 468: s -> s_errno = SC_CONGEST; ! 469: } ! 470: else ! 471: s -> s_errno = SC_ACCEPT; ! 472: if ((c -> allocli = c -> left = basesize) > 254) ! 473: c -> ptr = c -> top + 4; ! 474: else ! 475: c -> ptr = c -> top + 2; ! 476: } ! 477: ! 478: /* */ ! 479: ! 480: static int end_spdu (code, c) ! 481: unsigned char code; ! 482: struct local_buf *c; ! 483: { ! 484: if (c -> len) { ! 485: if (c -> allocli > 254) { ! 486: if (c -> li < 255) { ! 487: bcopy ((c -> top + 2), c -> top, (c -> len - c -> left)); ! 488: *(c -> top + 1) = c -> li; ! 489: c -> len = c -> li + 2; ! 490: } ! 491: else { ! 492: *(c -> top + 1) = 255; ! 493: *(c -> top + 2) = (c -> li >> 8) & 0xff; ! 494: *(c -> top + 3) = c -> li & 0xff; ! 495: c -> len = c -> li + 4; ! 496: } ! 497: } ! 498: else { ! 499: *(c -> top + 1) = c -> li; ! 500: c -> len = c -> ptr - c -> top; ! 501: } ! 502: *c -> top = code; ! 503: return OK; ! 504: } ! 505: ! 506: return NOTOK; ! 507: } ! 508: ! 509: /* */ ! 510: ! 511: static start_pgi (code, c) ! 512: unsigned char code; ! 513: struct local_buf *c; ! 514: { ! 515: put2spdu ((int) code, 0, NULLCP, c); ! 516: if (c -> len) ! 517: c -> pgi = (c -> ptr - c -> top - 1); ! 518: } ! 519: ! 520: ! 521: static end_pgi (c) ! 522: struct local_buf *c; ! 523: { ! 524: if (c -> len) ! 525: *(c -> top + c -> pgi) = (c -> len - c -> left) - (c -> pgi + 1); ! 526: } ! 527: ! 528: /* */ ! 529: ! 530: static put2spdu (code, li, value, c) ! 531: int code; ! 532: int li; ! 533: char *value; ! 534: struct local_buf *c; ! 535: { ! 536: int cl = li; ! 537: char *p1, ! 538: *p2; ! 539: ! 540: if (c -> len) { ! 541: cl += (li < 255) ? 2 : 4; ! 542: if (c -> left >= cl) ! 543: c -> left -= cl; ! 544: else { ! 545: /* XXX: this clause of Dwight's is all WRONG, WRONG, WRONG. I think we ! 546: should make start_spdu() smarter, if necessary and change this to ! 547: ! 548: c -> len = 0; ! 549: return; ! 550: */ ! 551: char *cp; ! 552: ! 553: if (c -> allocli < 255) ! 554: cl += 2; ! 555: cp = realloc (c -> top, (unsigned) (c -> len += cl)); ! 556: if (cp == NULL) { ! 557: c -> len = 0; ! 558: return; ! 559: } ! 560: c -> ptr = (c -> top = cp) + (c -> len - c -> left); ! 561: if (c -> allocli < 255) { ! 562: c -> allocli += cl; ! 563: cl = c -> len - c -> left + 2; ! 564: for (p1 = c -> ptr, p2 = p1 + 2; cl; cl--) ! 565: *p2-- = *p1--; ! 566: c -> pgi += 2; ! 567: c -> left -= 2; ! 568: } ! 569: } ! 570: *c -> ptr++ = code & 0xff; ! 571: if (li < 255) { ! 572: *c -> ptr++ = li; ! 573: c -> li += 2 + li; ! 574: } ! 575: else { ! 576: *c -> ptr++ = 255; ! 577: *c -> ptr++ = (li >> 8) & 0xff; ! 578: *c -> ptr++ = li & 0xff; ! 579: c -> li += 4 + li; ! 580: } ! 581: ! 582: bcopy (value, c -> ptr, li); ! 583: c -> ptr += li; ! 584: } ! 585: } ! 586: ! 587: /* */ ! 588: ! 589: int spkt2tsdu (s, base, len) ! 590: register struct ssapkt *s; ! 591: char **base; ! 592: int *len; ! 593: { ! 594: struct local_buf c; ! 595: char isn[SIZE_CN_ISN + 1]; ! 596: ! 597: c.len = 0; ! 598: switch (s -> s_code) { ! 599: case SPDU_CN: ! 600: start_spdu (s, &c, CN_BASE_SIZE); ! 601: If_Set (SMASK_CN_REF) ! 602: Put_Ref (s -> s_cn_reference, PI_CALLING_SS); ! 603: If_Set (SMASK_CN_OPT | SMASK_CN_TSDU | SMASK_CN_VRSN | SMASK_CN_ISN ! 604: | SMASK_CN_SET) { ! 605: start_pgi (PGI_CN_ITEMS, &c); ! 606: If_Set (SMASK_CN_OPT) ! 607: Put_Item (PI_PROTOCOL_OPT, (char *) &s -> s_options); ! 608: If_Set (SMASK_CN_TSDU) { ! 609: u_long tsdu_maxsize = (s -> s_tsdu_init & 0xffff) << 16 ! 610: | s -> s_tsdu_resp & 0xffff; ! 611: tsdu_maxsize = htonl (tsdu_maxsize); ! 612: Put_Item (PI_TSDU_MAXSIZ, (char *) &tsdu_maxsize); ! 613: } ! 614: If_Set (SMASK_CN_VRSN) ! 615: Put_Item (PI_VERSION, (char *) &s -> s_cn_version); ! 616: If_Set (SMASK_CN_ISN) ! 617: Put_SSN (PI_ISN, s -> s_isn); ! 618: If_Set (SMASK_CN_SET) ! 619: Put_Item (PI_TOKEN_SET, (char *) &s -> s_settings); ! 620: end_pgi (&c); ! 621: } ! 622: If_Set (SMASK_CN_REQ) { ! 623: u_short requirements = htons (s -> s_cn_require); ! 624: Put_Item (PI_USER_REQ, (char *) &requirements); ! 625: } ! 626: If_Set (SMASK_CN_CALLING) ! 627: put2spdu (PI_SSAP_CALLING, s -> s_callinglen, ! 628: s -> s_calling, &c); ! 629: If_Set (SMASK_CN_CALLED) ! 630: put2spdu (PI_SSAP_CALLED, s -> s_calledlen, ! 631: s -> s_called, &c); ! 632: Put_XData (CN_SIZE); ! 633: break; ! 634: ! 635: case SPDU_AC: ! 636: start_spdu (s, &c, AC_BASE_SIZE); ! 637: If_Set (SMASK_CN_REF) ! 638: Put_Ref (s -> s_cn_reference, PI_CALLED_SS); ! 639: If_Set (SMASK_CN_OPT | SMASK_CN_TSDU | SMASK_CN_VRSN | SMASK_CN_ISN ! 640: | SMASK_CN_SET) { ! 641: start_pgi (PGI_CN_ITEMS, &c); ! 642: If_Set (SMASK_CN_OPT) ! 643: Put_Item (PI_PROTOCOL_OPT, (char *) &s -> s_options); ! 644: If_Set (SMASK_CN_TSDU) { ! 645: u_long tsdu_maxsize = (s -> s_tsdu_init & 0xffff) << 16 ! 646: | s -> s_tsdu_resp & 0xffff; ! 647: tsdu_maxsize = htonl (tsdu_maxsize); ! 648: Put_Item (PI_TSDU_MAXSIZ, (char *) &tsdu_maxsize); ! 649: } ! 650: If_Set (SMASK_CN_VRSN) ! 651: Put_Item (PI_VERSION, (char *) &s -> s_cn_version); ! 652: If_Set (SMASK_CN_ISN) ! 653: Put_SSN (PI_ISN, s -> s_isn); ! 654: If_Set (SMASK_CN_SET) ! 655: Put_Item (PI_TOKEN_SET, (char *) &s -> s_settings); ! 656: end_pgi (&c); ! 657: } ! 658: If_Set (SMASK_AC_TOKEN) ! 659: Put_Item (PI_TOKEN, (char *) &s -> s_ac_token); ! 660: If_Set (SMASK_CN_REQ) { ! 661: u_short requirements = htons (s -> s_cn_require); ! 662: Put_Item (PI_USER_REQ, (char *) &requirements); ! 663: } ! 664: If_Set (SMASK_CN_CALLING) ! 665: put2spdu (PI_SSAP_CALLING, s -> s_callinglen, ! 666: s -> s_calling, &c); ! 667: If_Set (SMASK_CN_CALLED) ! 668: put2spdu (PI_SSAP_CALLED, s -> s_calledlen, ! 669: s -> s_called, &c); ! 670: If_Set (SMASK_ENCLOSE) ! 671: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 672: Put_UData (AC_SIZE); ! 673: break; ! 674: ! 675: case SPDU_RF: ! 676: start_spdu (s, &c, RF_BASE_SIZE); ! 677: If_Set (SMASK_RF_REF) ! 678: Put_Ref (s -> s_rf_reference, PI_CALLED_SS); ! 679: If_Set (SMASK_RF_DISC) ! 680: Put_Item (PI_TDISC, (char *) &s -> s_rf_disconnect); ! 681: If_Set (SMASK_RF_REQ) { ! 682: u_short requirements = htons (s -> s_rf_require); ! 683: Put_Item (PI_USER_REQ, (char *) &requirements); ! 684: } ! 685: If_Set (SMASK_RF_VRSN) ! 686: Put_Item (PI_VERSION, (char *) &s -> s_rf_version); ! 687: if (s -> s_rlen > RF_SIZE) { ! 688: if (c.len) ! 689: free (c.top); ! 690: s -> s_errno = SC_PROTOCOL; ! 691: return NOTOK; ! 692: } ! 693: If_Set (SMASK_ENCLOSE) ! 694: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 695: if (s -> s_rlen > 0) ! 696: put2spdu (PI_REASON, s -> s_rlen, s -> s_rdata, &c); ! 697: break; ! 698: ! 699: case SPDU_FN: ! 700: start_spdu (s, &c, FN_BASE_SIZE); ! 701: If_Set (SMASK_FN_DISC) ! 702: Put_Item (PI_TDISC, (char *) &s -> s_fn_disconnect); ! 703: If_Set (SMASK_ENCLOSE) ! 704: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 705: Put_UData (FN_SIZE); ! 706: break; ! 707: ! 708: case SPDU_DN: ! 709: start_spdu (s, &c, DN_BASE_SIZE); ! 710: If_Set (SMASK_ENCLOSE) ! 711: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 712: Put_UData (DN_SIZE); ! 713: break; ! 714: ! 715: case SPDU_NF: ! 716: start_spdu (s, &c, NF_BASE_SIZE); ! 717: If_Set (SMASK_ENCLOSE) ! 718: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 719: Put_UData (NF_SIZE); ! 720: break; ! 721: ! 722: case SPDU_AB: ! 723: #ifdef notdef ! 724: case SPDU_AI: /* aka SPDU_AB */ ! 725: #endif ! 726: If_Set (SMASK_SPDU_AB) { ! 727: start_spdu (s, &c, AB_BASE_SIZE); ! 728: If_Reset (SMASK_AB_DISC) { ! 729: s -> s_errno = SC_PROTOCOL; ! 730: break; ! 731: } ! 732: Put_Item (PI_TDISC, (char *) &s -> s_ab_disconnect); ! 733: If_Set (SMASK_AB_REFL) ! 734: put2spdu (PI_REFLECT, AB_REFL_SIZE, ! 735: (char *) s -> s_reflect, &c); ! 736: If_Set (SMASK_ENCLOSE) ! 737: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 738: Put_UData (AB_SIZE); ! 739: break; ! 740: } ! 741: start_spdu (s, &c, AI_BASE_SIZE); ! 742: If_Set (SMASK_AI_REASON) ! 743: put2spdu (PI_REASON, 1, (char *) &s -> s_ai_reason, &c); ! 744: break; ! 745: ! 746: case SPDU_AA: ! 747: #ifdef notdef ! 748: case SPDU_AIA: /* aka SPDU_AA */ ! 749: #endif ! 750: If_Set (SMASK_SPDU_AA) { ! 751: start_spdu (s, &c, AA_BASE_SIZE); ! 752: break; ! 753: } ! 754: start_spdu (s, &c, AIA_BASE_SIZE); ! 755: break; ! 756: ! 757: case SPDU_GT: ! 758: #ifdef notdef ! 759: case SPDU_DT: /* aka SPDU_GT */ ! 760: #endif ! 761: If_Set (SMASK_SPDU_GT) { ! 762: start_spdu (s, &c, GT_BASE_SIZE); ! 763: If_Set (SMASK_GT_TOKEN) ! 764: Put_Item (PI_TOKEN, (char *) &s -> s_gt_token); ! 765: break; ! 766: } /* else fall */ ! 767: start_spdu (s, &c, DT_BASE_SIZE); ! 768: If_Set (SMASK_ENCLOSE) ! 769: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 770: /* NB: caller responsible for mapping s -> s_udata to user info */ ! 771: break; ! 772: ! 773: case SPDU_TD: ! 774: start_spdu (s, &c, TD_BASE_SIZE); ! 775: If_Set (SMASK_ENCLOSE) ! 776: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 777: /* NB: caller responsible for mapping s -> s_udata to user info */ ! 778: break; ! 779: ! 780: case SPDU_EX: ! 781: start_spdu (s, &c, EX_BASE_SIZE); ! 782: /* NB: caller responsible for mapping s -> s_udata to user info */ ! 783: break; ! 784: ! 785: case SPDU_CD: ! 786: start_spdu (s, &c, CD_BASE_SIZE); ! 787: If_Set (SMASK_ENCLOSE) ! 788: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 789: Put_UData (CD_SIZE); ! 790: break; ! 791: ! 792: case SPDU_CDA: ! 793: start_spdu (s, &c, CDA_BASE_SIZE); ! 794: If_Set (SMASK_ENCLOSE) ! 795: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 796: Put_UData (CDA_SIZE); ! 797: break; ! 798: ! 799: case SPDU_PT: ! 800: start_spdu (s, &c, PT_BASE_SIZE); ! 801: If_Set (SMASK_PT_TOKEN) ! 802: Put_Item (PI_TOKEN, (char *) &s -> s_pt_token); ! 803: If_Set (SMASK_ENCLOSE) ! 804: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 805: Put_UData (PT_SIZE); ! 806: break; ! 807: ! 808: case SPDU_GTC: ! 809: start_spdu (s, &c, GTC_BASE_SIZE); ! 810: break; ! 811: ! 812: case SPDU_GTA: ! 813: start_spdu (s, &c, GTA_BASE_SIZE); ! 814: break; ! 815: ! 816: case SPDU_MIP: ! 817: start_spdu (s, &c, MIP_BASE_SIZE); ! 818: If_Set (SMASK_MIP_SYNC) ! 819: Put_Item (PI_SYNC, (char *) &s -> s_mip_sync); ! 820: If_Reset (SMASK_MIP_SERIAL) { ! 821: s -> s_errno = SC_PROTOCOL; ! 822: break; ! 823: } ! 824: Put_SSN (PI_SERIAL, s -> s_mip_serial); ! 825: If_Set (SMASK_ENCLOSE) ! 826: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 827: Put_UData (MIP_SIZE); ! 828: break; ! 829: ! 830: case SPDU_MAP: ! 831: #ifdef notdef ! 832: case SPDU_AE: /* aka SPDU_MAP */ ! 833: #endif ! 834: If_Set (SMASK_MAP_SYNC) { ! 835: start_spdu (s, &c, MAP_BASE_SIZE); ! 836: Put_Item (PI_SYNC, (char *) &s -> s_map_sync); ! 837: } ! 838: else ! 839: start_spdu (s, &c, AE_BASE_SIZE); ! 840: If_Reset (SMASK_MAP_SERIAL) { ! 841: s -> s_errno = SC_PROTOCOL; ! 842: break; ! 843: } ! 844: Put_SSN (PI_SERIAL, s -> s_map_serial); ! 845: If_Set (SMASK_ENCLOSE) ! 846: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 847: Put_UData (MAP_SIZE); ! 848: break; ! 849: ! 850: case SPDU_MIA: ! 851: start_spdu (s, &c, MIA_BASE_SIZE); ! 852: If_Reset (SMASK_MIA_SERIAL) { ! 853: s -> s_errno = SC_PROTOCOL; ! 854: break; ! 855: } ! 856: Put_SSN (PI_SERIAL, s -> s_mia_serial); ! 857: If_Set (SMASK_ENCLOSE) ! 858: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 859: Put_MData (MIA_SIZE); ! 860: break; ! 861: ! 862: case SPDU_MAA: ! 863: #ifdef notdef ! 864: case SPDU_AEA: /* aka SPDU_MAA */ ! 865: #endif ! 866: start_spdu (s, &c, MAA_BASE_SIZE); ! 867: If_Reset (SMASK_MAA_SERIAL) { ! 868: s -> s_errno = SC_PROTOCOL; ! 869: break; ! 870: } ! 871: Put_SSN (PI_SERIAL, s -> s_maa_serial); ! 872: If_Set (SMASK_ENCLOSE) ! 873: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 874: Put_UData (MAA_SIZE); ! 875: break; ! 876: ! 877: case SPDU_RS: ! 878: start_spdu (s, &c, RS_BASE_SIZE); ! 879: If_Set (SMASK_RS_SET) ! 880: Put_Item (PI_TOKEN_SET, (char *) &s -> s_rs_settings); ! 881: If_Reset (SMASK_RS_TYPE) { ! 882: s -> s_errno = SC_PROTOCOL; ! 883: break; ! 884: } ! 885: Put_Item (PI_RESYNC, (char *) &s -> s_rs_type); ! 886: If_Reset (SMASK_RS_SSN) { ! 887: s -> s_errno = SC_PROTOCOL; ! 888: break; ! 889: } ! 890: Put_SSN (PI_SERIAL, s -> s_rs_serial); ! 891: If_Set (SMASK_ENCLOSE) ! 892: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 893: Put_UData (RS_SIZE); ! 894: break; ! 895: ! 896: case SPDU_RA: ! 897: start_spdu (s, &c, RA_BASE_SIZE); ! 898: If_Set (SMASK_RA_SET) ! 899: Put_Item (PI_TOKEN_SET, (char *) &s -> s_ra_settings); ! 900: If_Reset (SMASK_RA_SSN) { ! 901: s -> s_errno = SC_PROTOCOL; ! 902: break; ! 903: } ! 904: Put_SSN (PI_SERIAL, s -> s_ra_serial); ! 905: If_Set (SMASK_ENCLOSE) ! 906: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 907: Put_UData (RA_SIZE); ! 908: break; ! 909: ! 910: case SPDU_PR: ! 911: start_spdu (s, &c, PR_BASE_SIZE); ! 912: If_Reset (SMASK_PR_TYPE) { ! 913: s -> s_errno = SC_PROTOCOL; ! 914: break; ! 915: } ! 916: Put_Item (PI_PREPARE, (char *) &s -> s_pr_type); ! 917: break; ! 918: ! 919: case SPDU_ER: /* we don't do these! */ ! 920: s -> s_errno = SC_PROTOCOL; ! 921: break; ! 922: ! 923: case SPDU_ED: ! 924: start_spdu (s, &c, ED_BASE_SIZE); ! 925: If_Reset (SMASK_ED_REASON) { ! 926: s -> s_errno = SC_PROTOCOL; ! 927: break; ! 928: } ! 929: put2spdu (PI_REASON, 1, (char *) &s -> s_ed_reason, &c); ! 930: If_Set (SMASK_ENCLOSE) ! 931: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 932: Put_UData (ED_SIZE); ! 933: break; ! 934: ! 935: case SPDU_AS: ! 936: start_spdu (s, &c, AS_BASE_SIZE); ! 937: If_Reset (SMASK_AS_ID) { ! 938: s -> s_errno = SC_PROTOCOL; ! 939: break; ! 940: } ! 941: put2spdu (PI_ACT_ID, (int) s -> s_as_id.sd_len, ! 942: s -> s_as_id.sd_data, &c); ! 943: If_Set (SMASK_ENCLOSE) ! 944: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 945: Put_UData (AS_SIZE); ! 946: break; ! 947: ! 948: case SPDU_AR: ! 949: start_spdu (s, &c, AR_BASE_SIZE); ! 950: start_pgi (PGI_AR_LINK, &c); ! 951: If_Set (SMASK_AR_REF) { ! 952: if (s -> s_ar_reference.sr_called_len) ! 953: put2spdu (PI_AR_CALLED, ! 954: (int) s -> s_ar_reference.sr_called_len, ! 955: s -> s_ar_reference.sr_called, &c); ! 956: if (s -> s_ar_reference.sr_calling_len) ! 957: put2spdu (PI_AR_CALLING, ! 958: (int) s -> s_ar_reference.sr_calling_len, ! 959: s -> s_ar_reference.sr_calling, &c); ! 960: if (s -> s_ar_reference.sr_clen) ! 961: put2spdu (PI_AR_COMMON, (int) s -> s_ar_reference.sr_clen, ! 962: s -> s_ar_reference.sr_cdata, &c); ! 963: if (s -> s_ar_reference.sr_alen) ! 964: put2spdu (PI_AR_ADDT, (int) s -> s_ar_reference.sr_alen, ! 965: s -> s_ar_reference.sr_adata, &c); ! 966: } ! 967: If_Reset (SMASK_AR_OID) { ! 968: s -> s_errno = SC_PROTOCOL; ! 969: break; ! 970: } ! 971: put2spdu (PI_ACT_ID, (int) s -> s_ar_oid.sd_len, ! 972: s -> s_ar_oid.sd_data, &c); ! 973: If_Reset (SMASK_AR_SSN) { ! 974: s -> s_errno = SC_PROTOCOL; ! 975: break; ! 976: } ! 977: Put_SSN (PI_SERIAL, s -> s_ar_serial); ! 978: end_pgi (&c); ! 979: If_Reset (SMASK_AR_ID) { ! 980: s -> s_errno = SC_PROTOCOL; ! 981: break; ! 982: } ! 983: put2spdu (PI_ACT_ID, (int) s -> s_ar_id.sd_len, ! 984: s -> s_ar_id.sd_data, &c); ! 985: If_Set (SMASK_ENCLOSE) ! 986: Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose); ! 987: Put_UData (AR_SIZE); ! 988: break; ! 989: ! 990: case SPDU_AD: ! 991: start_spdu (s, &c, AD_BASE_SIZE); ! 992: If_Set (SMASK_AD_REASON) ! 993: put2spdu (PI_REASON, 1, (char *) &s -> s_ad_reason, &c); ! 994: break; ! 995: ! 996: case SPDU_ADA: ! 997: start_spdu (s, &c, ADA_BASE_SIZE); ! 998: break; ! 999: ! 1000: default: ! 1001: s -> s_errno = SC_PROTOCOL; ! 1002: break; ! 1003: } ! 1004: ! 1005: if ((end_spdu (s -> s_code, &c) == NOTOK) || (s -> s_errno != SC_ACCEPT)) { ! 1006: if (s -> s_errno == SC_ACCEPT) ! 1007: s -> s_errno = SC_CONGEST; ! 1008: if (c.len) { ! 1009: free (c.top); ! 1010: c.len = 0; ! 1011: } ! 1012: *base = NULL; ! 1013: *len = 0; ! 1014: } ! 1015: else { ! 1016: *base = c.top; ! 1017: *len = c.len; ! 1018: s -> s_li = c.li; ! 1019: } ! 1020: ! 1021: #ifdef DEBUG ! 1022: if (ssap_log -> ll_events & LLOG_PDUS) ! 1023: spkt2text (ssap_log, s, 0); ! 1024: #endif ! 1025: ! 1026: return c.len ? OK : NOTOK; ! 1027: } ! 1028: ! 1029: /* */ ! 1030: ! 1031: static u_long str2ssn (s, n) ! 1032: register char *s; ! 1033: register int n; ! 1034: { ! 1035: register u_long u; ! 1036: ! 1037: for (u = 0L; n > 0; n--) ! 1038: u = u * 10 + *s++ - '0'; ! 1039: ! 1040: return u; ! 1041: } ! 1042: ! 1043: /* */ ! 1044: ! 1045: /* this is used to pull PCI, not user data... */ ! 1046: ! 1047: #define advance(n) \ ! 1048: if (base >= xbase) { \ ! 1049: if ((base = pullqb (qb, (n))) == NULL) { \ ! 1050: s -> s_errno = SC_PROTOCOL; \ ! 1051: break; \ ! 1052: } \ ! 1053: xbase = base + (n); \ ! 1054: nread += (n); \ ! 1055: } \ ! 1056: else ! 1057: ! 1058: static char *pullqb (qb, n) ! 1059: struct qbuf *qb; ! 1060: int n; ! 1061: { ! 1062: register int i; ! 1063: int once; ! 1064: register char *cp; ! 1065: register struct qbuf *qp; ! 1066: static char *buffer = NULL; ! 1067: ! 1068: if (n > SEGMENT_MAX) ! 1069: return NULLCP; ! 1070: ! 1071: for (once = 1, cp = buffer, qp = NULL; n > 0; once = 0, cp += i, n -= i) { ! 1072: if (qp == NULL && (qp = qb -> qb_forw) == qb) ! 1073: return NULLCP; ! 1074: ! 1075: i = min (qp -> qb_len, n); ! 1076: if (once && i == n) { /* special case */ ! 1077: cp = qp -> qb_data; ! 1078: qp -> qb_data += i, qp -> qb_len -= i; ! 1079: return cp; ! 1080: } ! 1081: ! 1082: if (buffer == NULL) { ! 1083: if ((buffer = malloc ((unsigned) SEGMENT_MAX)) == NULL) ! 1084: return NULLCP; ! 1085: cp = buffer; ! 1086: } ! 1087: bcopy (qp -> qb_data, cp, i); ! 1088: ! 1089: qp -> qb_data += i, qp -> qb_len -= i; ! 1090: if (qp -> qb_len <= 0) { ! 1091: remque (qp); ! 1092: ! 1093: free ((char *) qp); ! 1094: qp = NULL; ! 1095: } ! 1096: } ! 1097: ! 1098: return buffer; ! 1099: } ! 1100: ! 1101: /* */ ! 1102: ! 1103: struct ssapkt *tsdu2spkt (qb, len, cc) ! 1104: struct qbuf *qb; ! 1105: int len, ! 1106: *cc; ! 1107: { ! 1108: register int li; ! 1109: int cat0, ! 1110: nread, ! 1111: pktlen, ! 1112: pgilen, ! 1113: pmask, ! 1114: xlen; ! 1115: register char *base; ! 1116: char *xbase; ! 1117: unsigned char code, ! 1118: si; ! 1119: register struct ssapkt *s; ! 1120: ! 1121: if (cc) { ! 1122: cat0 = *cc; ! 1123: *cc = 0; ! 1124: } ! 1125: else ! 1126: cat0 = 1; ! 1127: if ((base = pullqb (qb, nread = 2)) == NULL ! 1128: || (s = newspkt ((int) (si = *base++))) == NULL) ! 1129: return NULLSPKT; ! 1130: ! 1131: if (*((u_char *) base) == 255) { ! 1132: if ((base = pullqb (qb, 2)) == NULL) { ! 1133: s -> s_errno = SC_PROTOCOL; ! 1134: return s; ! 1135: } ! 1136: nread += 2; ! 1137: s -> s_li = ! 1138: (*((u_char *) base) << 8) + *((u_char *) (base + 1)); ! 1139: } ! 1140: else ! 1141: s -> s_li = *((u_char *) base); ! 1142: pgilen = pktlen = s -> s_li; ! 1143: ! 1144: if (cat0) ! 1145: switch (si) { ! 1146: case SPDU_GT: ! 1147: Set (SMASK_SPDU_GT); ! 1148: break; ! 1149: ! 1150: case SPDU_AB: ! 1151: Set (SMASK_SPDU_AB); ! 1152: break; ! 1153: ! 1154: case SPDU_AA: ! 1155: Set (SMASK_SPDU_AA); ! 1156: break; ! 1157: ! 1158: default: ! 1159: break; ! 1160: } ! 1161: ! 1162: if ((si >= SI_TABLE_LEN) ! 1163: || ((pmask = si_table[si]) == PMASK_NOTSUPPORTED)) { ! 1164: s -> s_errno = SC_PROTOCOL; ! 1165: return s; ! 1166: } ! 1167: if (len < pktlen + nread) { ! 1168: s -> s_errno = SC_PROTOCOL; ! 1169: return s; ! 1170: } ! 1171: ! 1172: s -> s_errno = SC_ACCEPT; ! 1173: xbase = base; ! 1174: while (pktlen && (s -> s_errno == SC_ACCEPT)) { ! 1175: advance (2); ! 1176: code = *base++; ! 1177: if (*((u_char *) base) == 255) { ! 1178: base++; ! 1179: advance (2); ! 1180: li = (*((u_char *) base) << 8) + *((u_char *) (base + 1)); ! 1181: xlen = 2; ! 1182: } ! 1183: else { ! 1184: li = *((u_char *) base); ! 1185: xlen = 1; ! 1186: } ! 1187: base += xlen; ! 1188: if (xlen > 1) ! 1189: xlen += 2; ! 1190: else ! 1191: xlen++; ! 1192: switch (code) { ! 1193: case PI_UDATA: ! 1194: if (!(pmask & PMASK_UDATA)) ! 1195: s -> s_errno = SC_PROTOCOL; ! 1196: break; ! 1197: ! 1198: case PI_XDATA: ! 1199: if (!(pmask & PMASK_XDATA)) ! 1200: s -> s_errno = SC_PROTOCOL; ! 1201: break; ! 1202: ! 1203: default: ! 1204: if (code >= PI_TABLE_LEN || !(pmask & pi_table[code])) ! 1205: s -> s_errno = SC_PROTOCOL; ! 1206: break; ! 1207: } ! 1208: if (s -> s_errno != SC_ACCEPT) ! 1209: break; ! 1210: if (!pgilen) ! 1211: pgilen = pktlen; ! 1212: pktlen -= (xlen + li); ! 1213: if (li > (pgilen -= xlen)) { ! 1214: s -> s_errno = SC_PROTOCOL; ! 1215: break; ! 1216: } ! 1217: pgilen -= li; ! 1218: if (li) ! 1219: advance (li); ! 1220: if (code < PI_TABLE_LEN) { ! 1221: if (li) { ! 1222: if (pi_table[code] & PMASK_VARLEN) { ! 1223: if (li > pi_length[code]) { ! 1224: s -> s_errno = SC_PROTOCOL; ! 1225: break; ! 1226: } ! 1227: } ! 1228: else ! 1229: if (li != pi_length[code]) { ! 1230: s -> s_errno = SC_PROTOCOL; ! 1231: break; ! 1232: } ! 1233: } ! 1234: } ! 1235: ! 1236: switch (code) { ! 1237: case PGI_AR_LINK: ! 1238: Set (SMASK_AR_OID);/* HACK! */ ! 1239: goto do_pgi; ! 1240: ! 1241: case PGI_CN_ID: ! 1242: Set (SMASK_CN_REF);/* fall */ ! 1243: case PGI_CN_ITEMS: ! 1244: do_pgi: ; ! 1245: pktlen += li; ! 1246: pgilen = li; ! 1247: li = 0; ! 1248: break; ! 1249: ! 1250: case PI_CALLED_SS: ! 1251: case PI_CALLING_SS: ! 1252: #ifdef notdef ! 1253: case PI_AR_CALLED: ! 1254: case PI_AR_CALLING: ! 1255: #endif ! 1256: switch (si) { ! 1257: case SPDU_CN: ! 1258: case SPDU_AC: ! 1259: s -> s_cn_reference.sr_ulen = li; ! 1260: bcopy (base, s -> s_cn_reference.sr_udata, li); ! 1261: Set (SMASK_CN_REF); ! 1262: break; ! 1263: case SPDU_RF: ! 1264: s -> s_rf_reference.sr_ulen = li; ! 1265: bcopy (base, s -> s_rf_reference.sr_udata, li); ! 1266: Set (SMASK_RF_REF); ! 1267: break; ! 1268: case SPDU_AR: ! 1269: switch (code) { ! 1270: case PI_AR_CALLED: ! 1271: s -> s_ar_reference.sr_called_len = li; ! 1272: bcopy (base, s -> s_ar_reference.sr_called, ! 1273: li); ! 1274: Set (SMASK_AR_REF); ! 1275: break; ! 1276: case PI_AR_CALLING: ! 1277: s -> s_ar_reference.sr_calling_len = li; ! 1278: bcopy (base, s -> s_ar_reference.sr_calling, ! 1279: li); ! 1280: Set (SMASK_AR_REF); ! 1281: break; ! 1282: default: ! 1283: s -> s_errno = SC_PROTOCOL; ! 1284: break; ! 1285: } ! 1286: break; ! 1287: default: ! 1288: s -> s_errno = SC_PROTOCOL; ! 1289: break; ! 1290: } ! 1291: base += li; ! 1292: break; ! 1293: ! 1294: case PI_COMMON_REF: ! 1295: #ifdef notdef ! 1296: case PI_AR_COMMON: ! 1297: #endif ! 1298: switch (si) { ! 1299: case SPDU_CN: ! 1300: case SPDU_AC: ! 1301: s -> s_cn_reference.sr_clen = li; ! 1302: bcopy (base, s -> s_cn_reference.sr_cdata, li); ! 1303: Set (SMASK_CN_REF); ! 1304: break; ! 1305: case SPDU_RF: ! 1306: s -> s_rf_reference.sr_clen = li; ! 1307: bcopy (base, s -> s_rf_reference.sr_cdata, li); ! 1308: Set (SMASK_RF_REF); ! 1309: break; ! 1310: case SPDU_AR: ! 1311: s -> s_ar_reference.sr_clen = li; ! 1312: bcopy (base, s -> s_ar_reference.sr_cdata, li); ! 1313: Set (SMASK_AR_REF); ! 1314: break; ! 1315: default: ! 1316: s -> s_errno = SC_PROTOCOL; ! 1317: break; ! 1318: } ! 1319: base += li; ! 1320: break; ! 1321: ! 1322: case PI_ADD_INFO: ! 1323: #ifdef notdef ! 1324: case PI_AR_ADDT: ! 1325: #endif ! 1326: switch (si) { ! 1327: case SPDU_CN: ! 1328: case SPDU_AC: ! 1329: s -> s_cn_reference.sr_alen = li; ! 1330: bcopy (base, s -> s_cn_reference.sr_adata, li); ! 1331: Set (SMASK_CN_REF); ! 1332: break; ! 1333: case SPDU_RF: ! 1334: s -> s_rf_reference.sr_alen = li; ! 1335: bcopy (base, s -> s_rf_reference.sr_adata, li); ! 1336: Set (SMASK_RF_REF); ! 1337: break; ! 1338: case SPDU_AR: ! 1339: s -> s_ar_reference.sr_alen = li; ! 1340: bcopy (base, s -> s_ar_reference.sr_adata, li); ! 1341: Set (SMASK_AR_REF); ! 1342: break; ! 1343: default: ! 1344: s -> s_errno = SC_PROTOCOL; ! 1345: break; ! 1346: } ! 1347: base += li; ! 1348: break; ! 1349: ! 1350: case PI_PROTOCOL_OPT: ! 1351: if ((s -> s_options = *base++) & ~CR_OPT_MASK) ! 1352: s -> s_errno = SC_PROTOCOL; ! 1353: else ! 1354: Set (SMASK_CN_OPT); ! 1355: break; ! 1356: ! 1357: case PI_TSDU_MAXSIZ: ! 1358: { ! 1359: u_long tsdu_maxsize; ! 1360: bcopy (base, (char *) &tsdu_maxsize, ! 1361: pi_length[PI_TSDU_MAXSIZ]); ! 1362: tsdu_maxsize = ntohl (tsdu_maxsize); ! 1363: s -> s_tsdu_init = (tsdu_maxsize >> 16) & 0xffff; ! 1364: s -> s_tsdu_resp = tsdu_maxsize & 0xffff; ! 1365: Set (SMASK_CN_TSDU); ! 1366: } ! 1367: base += pi_length[PI_TSDU_MAXSIZ]; ! 1368: break; ! 1369: ! 1370: case PI_VERSION: ! 1371: switch (si) { ! 1372: case SPDU_CN: ! 1373: case SPDU_AC: ! 1374: s -> s_cn_version = *base++; ! 1375: Set (SMASK_CN_VRSN); ! 1376: break; ! 1377: case SPDU_RF: ! 1378: s -> s_rf_version = *base++; ! 1379: Set (SMASK_RF_VRSN); ! 1380: break; ! 1381: default: ! 1382: s -> s_errno = SC_PROTOCOL; ! 1383: break; ! 1384: } ! 1385: break; ! 1386: ! 1387: case PI_SYNC: ! 1388: switch (si) { ! 1389: case SPDU_MIP: ! 1390: if ((s -> s_mip_sync = *base++) & ~MIP_SYNC_MASK) ! 1391: s -> s_errno = SC_PROTOCOL; ! 1392: else ! 1393: Set (SMASK_MIP_SYNC); ! 1394: break; ! 1395: case SPDU_MAP: ! 1396: if ((s -> s_map_sync = *base++) & ~MAP_SYNC_MASK) ! 1397: s -> s_errno = SC_PROTOCOL; ! 1398: else ! 1399: Set (SMASK_MAP_SYNC); ! 1400: break; ! 1401: } ! 1402: break; ! 1403: ! 1404: case PI_TOKEN_SET: ! 1405: switch (si) { ! 1406: case SPDU_CN: ! 1407: case SPDU_AC: ! 1408: s -> s_settings = *base++; ! 1409: Set (SMASK_CN_SET); ! 1410: break; ! 1411: case SPDU_RS: ! 1412: s -> s_rs_settings = *base++; ! 1413: Set (SMASK_RS_SET); ! 1414: break; ! 1415: case SPDU_RA: ! 1416: s -> s_ra_settings = *base++; ! 1417: Set (SMASK_RA_SET); ! 1418: break; ! 1419: default: ! 1420: s -> s_errno = SC_PROTOCOL; ! 1421: break; ! 1422: } ! 1423: break; ! 1424: ! 1425: case PI_TOKEN: ! 1426: switch (si) { ! 1427: case SPDU_AC: ! 1428: s -> s_ac_token = *base++; ! 1429: Set (SMASK_AC_TOKEN); ! 1430: break; ! 1431: case SPDU_GT: ! 1432: If_Reset (SMASK_SPDU_GT) { ! 1433: s -> s_errno = SC_PROTOCOL; ! 1434: break; ! 1435: } ! 1436: s -> s_gt_token = *base++; ! 1437: Set (SMASK_GT_TOKEN); ! 1438: break; ! 1439: case SPDU_PT: ! 1440: s -> s_pt_token = *base++; ! 1441: Set (SMASK_PT_TOKEN); ! 1442: break; ! 1443: default: ! 1444: s -> s_errno = SC_PROTOCOL; ! 1445: break; ! 1446: } ! 1447: break; ! 1448: ! 1449: case PI_TDISC: ! 1450: switch (si) { ! 1451: case SPDU_RF: ! 1452: if ((s -> s_rf_disconnect = *base++) & ~RF_DISC_MASK) ! 1453: s -> s_errno = SC_PROTOCOL; ! 1454: else ! 1455: Set (SMASK_RF_DISC); ! 1456: break; ! 1457: case SPDU_FN: ! 1458: if ((s -> s_fn_disconnect = *base++) & ~FN_DISC_MASK) ! 1459: s -> s_errno = SC_PROTOCOL; ! 1460: else ! 1461: Set (SMASK_FN_DISC); ! 1462: break; ! 1463: case SPDU_AB: ! 1464: If_Reset (SMASK_SPDU_AB) { ! 1465: s -> s_errno = SC_PROTOCOL; ! 1466: break; ! 1467: } ! 1468: if ((s -> s_ab_disconnect = *base++) & ~AB_DISC_MASK) ! 1469: s -> s_errno = SC_PROTOCOL; ! 1470: else ! 1471: Set (SMASK_AB_DISC); ! 1472: break; ! 1473: default: ! 1474: s -> s_errno = SC_PROTOCOL; ! 1475: break; ! 1476: } ! 1477: break; ! 1478: ! 1479: case PI_USER_REQ: ! 1480: { ! 1481: u_short requirements; ! 1482: bcopy (base, (char *) &requirements, 2); ! 1483: requirements = ntohs (requirements); ! 1484: if (si != SPDU_RF) { ! 1485: s -> s_cn_require = requirements; ! 1486: Set (SMASK_CN_REQ); ! 1487: } ! 1488: else { ! 1489: s -> s_rf_require = requirements; ! 1490: Set (SMASK_RF_REQ); ! 1491: } ! 1492: } ! 1493: base += 2; ! 1494: break; ! 1495: ! 1496: case PI_ISN: ! 1497: switch (si) { ! 1498: case SPDU_CN: ! 1499: case SPDU_AC: ! 1500: s -> s_isn = str2ssn (base, li); ! 1501: Set (SMASK_CN_ISN); ! 1502: break; ! 1503: default: ! 1504: s -> s_errno = SC_PROTOCOL; ! 1505: break; ! 1506: } ! 1507: case PI_ISN2: /* not supported yet */ ! 1508: base += li; ! 1509: break; ! 1510: ! 1511: case PI_ENCLOSE: ! 1512: if ((si == SPDU_DT && (s -> s_mask & SMASK_SPDU_GT)) ! 1513: || (si == SPDU_AI && !(s -> s_mask & SMASK_SPDU_AB))) { ! 1514: s -> s_errno = SC_PROTOCOL; ! 1515: break; ! 1516: } ! 1517: if ((s -> s_enclose = *base++) & ~ENCL_MASK) ! 1518: s -> s_errno = SC_PROTOCOL; ! 1519: else ! 1520: Set (SMASK_ENCLOSE); ! 1521: break; ! 1522: ! 1523: case PI_RESYNC: ! 1524: s -> s_rs_type = *base++; ! 1525: if (SYNC_OK (s -> s_rs_type)) ! 1526: Set (SMASK_RS_TYPE); ! 1527: else ! 1528: s -> s_errno = SC_PROTOCOL; ! 1529: break; ! 1530: ! 1531: case PI_ACT_ID: ! 1532: switch (si) { ! 1533: case SPDU_AS: ! 1534: s -> s_as_id.sd_len = li; ! 1535: bcopy (base, s -> s_as_id.sd_data, li); ! 1536: Set (SMASK_AS_ID); ! 1537: break; ! 1538: ! 1539: case SPDU_AR: ! 1540: if ((s -> s_mask & SMASK_AR_OID) ! 1541: && s -> s_ar_oid.sd_len == 0) { ! 1542: s -> s_ar_oid.sd_len = li; ! 1543: bcopy (base, s -> s_ar_oid.sd_data, li); ! 1544: } ! 1545: else { ! 1546: s -> s_ar_id.sd_len = li; ! 1547: bcopy (base, s -> s_ar_id.sd_data, li); ! 1548: Set (SMASK_AR_ID); ! 1549: } ! 1550: break; ! 1551: ! 1552: default: ! 1553: s -> s_errno = SC_PROTOCOL; ! 1554: break; ! 1555: } ! 1556: base += li; ! 1557: break; ! 1558: ! 1559: case PI_SERIAL: ! 1560: switch (si) { ! 1561: case SPDU_MIP: ! 1562: s -> s_mip_serial = str2ssn (base, li); ! 1563: Set (SMASK_MIP_SERIAL); ! 1564: break; ! 1565: case SPDU_MAP: ! 1566: s -> s_map_serial = str2ssn (base, li); ! 1567: Set (SMASK_MAP_SERIAL); ! 1568: break; ! 1569: case SPDU_MIA: ! 1570: s -> s_mia_serial = str2ssn (base, li); ! 1571: Set (SMASK_MIA_SERIAL); ! 1572: break; ! 1573: case SPDU_MAA: ! 1574: s -> s_maa_serial = str2ssn (base, li); ! 1575: Set (SMASK_MAA_SERIAL); ! 1576: break; ! 1577: case SPDU_RS: ! 1578: s -> s_rs_serial = str2ssn (base, li); ! 1579: Set (SMASK_RS_SSN); ! 1580: break; ! 1581: case SPDU_RA: ! 1582: s -> s_ra_serial = str2ssn (base, li); ! 1583: Set (SMASK_RA_SSN); ! 1584: break; ! 1585: case SPDU_AR: ! 1586: s -> s_ar_serial = str2ssn (base, li); ! 1587: Set (SMASK_AR_SSN); ! 1588: break; ! 1589: default: ! 1590: s -> s_errno = SC_PROTOCOL; ! 1591: break; ! 1592: } ! 1593: base += li; ! 1594: break; ! 1595: ! 1596: case PI_MIA_DATA: ! 1597: case PI_UDATA: ! 1598: case PI_XDATA: ! 1599: Set (SMASK_UDATA_PGI); ! 1600: if (!li) ! 1601: break; ! 1602: if (si == SPDU_AB && !(s -> s_mask & SMASK_SPDU_AB)) { ! 1603: s -> s_errno = SC_PROTOCOL; ! 1604: break; ! 1605: } ! 1606: else ! 1607: if (li > (code != PI_XDATA ? SEGMENT_MAX : CONNECT_MAX)) { ! 1608: s -> s_errno = SC_PROTOCOL; ! 1609: break; ! 1610: } ! 1611: s -> s_udata = malloc ((unsigned) (s -> s_ulen = li)); ! 1612: if (s -> s_udata == NULL) { ! 1613: s -> s_errno = SC_CONGEST; ! 1614: break; ! 1615: } ! 1616: bcopy (base, s -> s_udata, li); ! 1617: base += li; ! 1618: break; ! 1619: ! 1620: case PI_REASON: ! 1621: switch (si) { ! 1622: case SPDU_RF: ! 1623: s -> s_rdata = malloc ((unsigned) (s -> s_rlen = li)); ! 1624: if (s -> s_rdata == NULL) { ! 1625: s -> s_errno = SC_CONGEST; ! 1626: break; ! 1627: } ! 1628: bcopy (base, s -> s_rdata, li); ! 1629: base += li; ! 1630: break; ! 1631: case SPDU_ED: ! 1632: s -> s_ed_reason = *base++; ! 1633: if (li == 1 && SP_OK (s -> s_ed_reason)) ! 1634: Set (SMASK_ED_REASON); ! 1635: else ! 1636: s -> s_errno = SC_PROTOCOL; ! 1637: break; ! 1638: case SPDU_AI: ! 1639: If_Set (SMASK_SPDU_AB) { ! 1640: s -> s_errno = SC_PROTOCOL; ! 1641: break; ! 1642: } ! 1643: s -> s_ai_reason = *base++; ! 1644: if (li == 1 && SP_OK (s -> s_ai_reason)) ! 1645: Set (SMASK_AI_REASON); ! 1646: else ! 1647: s -> s_errno = SC_PROTOCOL; ! 1648: break; ! 1649: case SPDU_AD: ! 1650: s -> s_ad_reason = *base++; ! 1651: if (li == 1 && SP_OK (s -> s_ad_reason)) ! 1652: Set (SMASK_AD_REASON); ! 1653: else ! 1654: s -> s_errno = SC_PROTOCOL; ! 1655: break; ! 1656: default: ! 1657: s -> s_errno = SC_PROTOCOL; ! 1658: break; ! 1659: } ! 1660: break; ! 1661: ! 1662: case PI_REFLECT: ! 1663: switch (si) { ! 1664: case SPDU_AB: ! 1665: If_Reset (SMASK_SPDU_AB) { ! 1666: s -> s_errno = SC_PROTOCOL; ! 1667: break; ! 1668: } ! 1669: if (li > AB_REFL_SIZE) { ! 1670: s -> s_errno = SC_PROTOCOL; ! 1671: break; ! 1672: } ! 1673: bcopy (base, (char *) s -> s_reflect, li); ! 1674: Set (SMASK_AB_REFL); ! 1675: break; ! 1676: case SPDU_ER: ! 1677: s -> s_udata = malloc ((unsigned) (s -> s_ulen = li)); ! 1678: if (s -> s_udata == NULL) { ! 1679: s -> s_errno = SC_CONGEST; ! 1680: break; ! 1681: } ! 1682: bcopy (base, s -> s_udata, li); ! 1683: break; ! 1684: default: ! 1685: s -> s_errno = SC_PROTOCOL; ! 1686: break; ! 1687: } ! 1688: base += li; ! 1689: break; ! 1690: ! 1691: case PI_SSAP_CALLING: ! 1692: bcopy (base, s -> s_calling, s -> s_callinglen = li); ! 1693: Set (SMASK_CN_CALLING); ! 1694: base += li; ! 1695: break; ! 1696: ! 1697: case PI_SSAP_CALLED: ! 1698: bcopy (base, s -> s_called, s -> s_calledlen = li); ! 1699: Set (SMASK_CN_CALLED); ! 1700: base += li; ! 1701: break; ! 1702: ! 1703: case PI_PREPARE: ! 1704: if ((s -> s_pr_type = *base++) > PR_MAX) ! 1705: s -> s_errno = SC_PROTOCOL; ! 1706: else ! 1707: Set (SMASK_PR_TYPE); ! 1708: break; ! 1709: ! 1710: default: ! 1711: s -> s_errno = SC_PROTOCOL; ! 1712: break; ! 1713: } ! 1714: } ! 1715: /* NB: caller responsible for mapping user info to s -> s_qbuf */ ! 1716: ! 1717: if (cc) ! 1718: *cc = nread; ! 1719: { /* "dangling" qbuf */ ! 1720: register struct qbuf *qp; ! 1721: ! 1722: if ((qp = qb -> qb_forw) != qb && qp -> qb_len <= 0) { ! 1723: remque (qp); ! 1724: ! 1725: free ((char *) qp); ! 1726: } ! 1727: } ! 1728: ! 1729: switch (s -> s_code) { ! 1730: case SPDU_AB: ! 1731: If_Set (SMASK_SPDU_AB) { ! 1732: If_Reset (SMASK_AB_DISC) ! 1733: s -> s_errno = SC_PROTOCOL; ! 1734: } ! 1735: break; ! 1736: ! 1737: case SPDU_MIP: ! 1738: If_Reset (SMASK_MIP_SERIAL) ! 1739: s -> s_errno = SC_PROTOCOL; ! 1740: break; ! 1741: ! 1742: case SPDU_MAP: ! 1743: If_Reset (SMASK_MAP_SERIAL) ! 1744: s -> s_errno = SC_PROTOCOL; ! 1745: break; ! 1746: ! 1747: case SPDU_MIA: ! 1748: If_Reset (SMASK_MIA_SERIAL) ! 1749: s -> s_errno = SC_PROTOCOL; ! 1750: break; ! 1751: ! 1752: case SPDU_MAA: ! 1753: If_Reset (SMASK_MAA_SERIAL) ! 1754: s -> s_errno = SC_PROTOCOL; ! 1755: break; ! 1756: ! 1757: case SPDU_RS: ! 1758: If_Reset (SMASK_RS_TYPE) ! 1759: s -> s_errno = SC_PROTOCOL; ! 1760: If_Reset (SMASK_RS_SSN) ! 1761: s -> s_errno = SC_PROTOCOL; ! 1762: break; ! 1763: ! 1764: case SPDU_RA: ! 1765: If_Reset (SMASK_RA_SSN) ! 1766: s -> s_errno = SC_PROTOCOL; ! 1767: break; ! 1768: ! 1769: case SPDU_PR: ! 1770: If_Reset (SMASK_PR_TYPE) ! 1771: s -> s_errno = SC_PROTOCOL; ! 1772: break; ! 1773: ! 1774: case SPDU_ED: ! 1775: If_Reset (SMASK_ED_REASON) ! 1776: s -> s_errno = SC_PROTOCOL; ! 1777: break; ! 1778: ! 1779: case SPDU_AS: ! 1780: If_Reset (SMASK_AS_ID) ! 1781: s -> s_errno = SC_PROTOCOL; ! 1782: break; ! 1783: ! 1784: case SPDU_AR: ! 1785: If_Reset (SMASK_AR_OID) ! 1786: s -> s_errno = SC_PROTOCOL; ! 1787: If_Reset (SMASK_AR_SSN) ! 1788: s -> s_errno = SC_PROTOCOL; ! 1789: If_Reset (SMASK_AR_ID) ! 1790: s -> s_errno = SC_PROTOCOL; ! 1791: break; ! 1792: } ! 1793: ! 1794: #ifdef DEBUG ! 1795: if (ssap_log -> ll_events & LLOG_PDUS) ! 1796: spkt2text (ssap_log, s, 1); ! 1797: #endif ! 1798: ! 1799: return s; ! 1800: } ! 1801: ! 1802: /* */ ! 1803: ! 1804: struct ssapkt *newspkt (code) ! 1805: int code; ! 1806: { ! 1807: register struct ssapkt *s; ! 1808: ! 1809: s = (struct ssapkt *) calloc (1, sizeof *s); ! 1810: if (s == NULL) ! 1811: return NULL; ! 1812: ! 1813: s -> s_code = code; ! 1814: s -> s_qbuf.qb_forw = s -> s_qbuf.qb_back = &s -> s_qbuf; ! 1815: ! 1816: return s; ! 1817: } ! 1818: ! 1819: ! 1820: int freespkt (s) ! 1821: register struct ssapkt *s; ! 1822: { ! 1823: if (s == NULL) ! 1824: return; ! 1825: ! 1826: switch (s -> s_code) { ! 1827: case SPDU_RF: ! 1828: if (s -> s_rdata) ! 1829: free (s -> s_rdata);/* and fall... */ ! 1830: ! 1831: default: ! 1832: if (s -> s_udata) ! 1833: free (s -> s_udata); ! 1834: QBFREE (&s -> s_qbuf); ! 1835: break; ! 1836: } ! 1837: ! 1838: free ((char *) s); ! 1839: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.