|
|
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.