|
|
1.1 root 1: /* ssaprespond.c - SPM: responder */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaprespond.c,v 7.1 89/11/27 10:30:46 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/ssap/RCS/ssaprespond.c,v 7.1 89/11/27 10:30:46 mrose Exp $
9: *
10: *
11: * $Log: ssaprespond.c,v $
12: * Revision 7.1 89/11/27 10:30:46 mrose
13: * sync
14: *
15: * Revision 7.0 89/11/23 22:25:38 mrose
16: * Release 6.0
17: *
18: */
19:
20: /*
21: * NOTICE
22: *
23: * Acquisition, use, and distribution of this module and related
24: * materials are subject to the restrictions of a license agreement.
25: * Consult the Preface in the User's Manual for the full terms of
26: * this agreement.
27: *
28: */
29:
30:
31: /* LINTLIBRARY */
32:
33: #include <stdio.h>
34: #include "spkt.h"
35: #include "tailor.h"
36:
37: /* S-CONNECT.INDICATION */
38:
39: int SInit (vecp, vec, ss, si)
40: int vecp;
41: char **vec;
42: struct SSAPstart *ss;
43: struct SSAPindication *si;
44: {
45: int len;
46: register struct ssapblk *sb;
47: register struct ssapkt *s;
48: struct TSAPstart tss;
49: register struct TSAPstart *ts = &tss;
50: struct TSAPdisconnect tds;
51: register struct TSAPdisconnect *td = &tds;
52:
53: isodetailor (NULLCP, 0);
54:
55: if (vecp < 2)
56: return ssaplose (si, SC_PARAMETER, NULLCP,
57: "bad initialization vector");
58: missingP (vec);
59: missingP (ss);
60: missingP (si);
61:
62: if ((sb = newsblk ()) == NULL)
63: return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
64:
65: if (vecp == 2 || TInit (vecp, vec, ts, td) != NOTOK) {
66: int sd;
67: struct TSAPdata txs;
68: register struct TSAPdata *tx = &txs;
69:
70: if (vecp == 2) {
71: if (TRestoreState (vec[1], ts, td) == NOTOK) {
72: (void) ts2sslose (si, "TRestoreState", td);
73: (void) ssaplose (si, SC_PARAMETER, NULLCP,
74: "bad initialization vector");
75: goto out1;
76: }
77: bzero (vec[0], strlen (vec[0]));
78: bzero (vec[1], strlen (vec[1]));
79: *vec = NULL;
80: }
81: else {
82: if (TConnResponse (ts -> ts_sd, &ts -> ts_called,
83: ts -> ts_expedited, NULLCP, 0, NULLQOS, td) == NOTOK) {
84: (void) ts2sslose (si, "TConnResponse", td);
85: (void) TDiscRequest (ts -> ts_sd, NULLCP, 0, td);
86: goto out1;
87: }
88: }
89: sd = ts -> ts_sd;
90:
91: if (TReadRequest (sb -> sb_fd = sd, tx, NOTOK, td) == NOTOK) {
92: (void) ts2sslose (si, "TReadRequest", td);
93: goto out1;
94: }
95:
96: s = tsdu2spkt (&tx -> tx_qbuf, tx -> tx_cc, NULLIP);
97: TXFREE (tx);
98:
99: if (s == NULL || s -> s_errno != SC_ACCEPT) {
100: (void) spktlose (sd, si, (s ? s -> s_errno : SC_CONGEST)
101: | SC_REFUSE, NULLCP, NULLCP);
102: goto out2;
103: }
104:
105: if (s -> s_code != SPDU_CN) {
106: (void) spktlose (sd, si, (s ? s -> s_errno : SC_CONGEST)
107: | SC_REFUSE, NULLCP,
108: "session protocol mangled: expected 0x%x, got 0x%x",
109: SPDU_CN, s -> s_code);
110: goto out2;
111: }
112:
113: if (s -> s_mask & SMASK_CN_VRSN
114: && !(s -> s_cn_version & SB_ALLVRSNS)) {
115: (void) spktlose (sd, si, SC_VERSION | SC_REFUSE, NULLCP,
116: "version mismatch: expecting something in 0x%x, got 0x%x",
117: SB_ALLVRSNS, s -> s_cn_version);
118: goto out2;
119: }
120: }
121: else {
122: int reason;
123:
124: vec += vecp - 2;
125: s = NULL;
126: if ((reason = td -> td_reason) != DR_PARAMETER
127: || TRestoreState (vec[0], ts, td) == NOTOK
128: || (s = str2spkt (vec[1])) == NULL
129: || s -> s_errno != SC_ACCEPT) {
130: if (s)
131: freespkt (s);
132: else
133: (void) ts2sslose (si, reason != DR_PARAMETER ? "TInit"
134: : "TRestoreState", td);
135: (void) ssaplose (si, SC_PARAMETER, NULLCP,
136: "bad initialization vector");
137: goto out1;
138: }
139: bzero (vec[0], strlen (vec[0]));
140: bzero (vec[1], strlen (vec[1]));
141: *vec = NULL;
142: }
143:
144: sb -> sb_fd = ts -> ts_sd;
145: sb -> sb_version =
146: (s -> s_mask & SMASK_CN_VRSN)
147: ? ((s -> s_cn_version & (1 << SB_VRSN2))
148: ? SB_VRSN2 : SB_VRSN1)
149: : s -> s_ulen > SS_SIZE
150: ? SB_VRSN2 : SB_VRSN1;
151: if (ts -> ts_expedited)
152: sb -> sb_flags |= SB_EXPD;
153:
154: bzero ((char *) ss, sizeof *ss);
155: ss -> ss_sd = sb -> sb_fd;
156: if (s -> s_mask & SMASK_CN_REF)
157: ss -> ss_connect = s -> s_cn_reference; /* struct copy */
158: if (s -> s_mask & SMASK_CN_OPT)
159: sb -> sb_options = s -> s_options;
160: if (s -> s_mask & SMASK_CN_ISN)
161: ss -> ss_isn = sb -> sb_V_A = sb -> sb_V_M = s -> s_isn;
162: else
163: ss -> ss_isn = SERIAL_NONE;
164: if (!(s -> s_mask & SMASK_CN_TSDU))
165: s -> s_tsdu_init = s -> s_tsdu_resp = 0;
166: if (s -> s_tsdu_init
167: < (sb -> sb_tsdu_them = GET_TSDU_SIZE (ts -> ts_tsdusize)))
168: sb -> sb_tsdu_them = s -> s_tsdu_init;
169: if (s -> s_tsdu_resp
170: < (sb -> sb_tsdu_us = GET_TSDU_SIZE (ts -> ts_tsdusize)))
171: sb -> sb_tsdu_us = s -> s_tsdu_resp;
172: if (sb -> sb_version >= SB_VRSN2) /* XXX */
173: sb -> sb_tsdu_them = sb -> sb_tsdu_us = 0;
174:
175: if (s -> s_mask & SMASK_CN_SET)
176: sb -> sb_settings = ss -> ss_settings = s -> s_settings;
177: sb -> sb_requirements = (s -> s_mask & SMASK_CN_REQ ? s -> s_cn_require
178: : SR_DEFAULT) & SR_MYREQUIRE;
179: if (!ts -> ts_expedited)
180: sb -> sb_requirements &= ~SR_EXPEDITED;
181: if (!(sb -> sb_requirements & SR_HALFDUPLEX))
182: sb -> sb_requirements &= ~SR_EXCEPTIONS;
183: ss -> ss_requirements = sb -> sb_requirements;
184: ss -> ss_calling.sa_addr = ts -> ts_calling; /* struct copy */
185: if (s -> s_mask & SMASK_CN_CALLING) {
186: if ((len = s -> s_callinglen)
187: > sizeof ss -> ss_calling.sa_selector)
188: len = sizeof ss -> ss_calling.sa_selector;
189: bcopy (s -> s_calling, ss -> ss_calling.sa_selector,
190: ss -> ss_calling.sa_selectlen = len);
191: }
192: sb -> sb_initiating = ss -> ss_calling; /* struct copy */
193: ss -> ss_called.sa_addr = ts -> ts_called; /* struct copy */
194: if (s -> s_mask & SMASK_CN_CALLED) {
195: if ((len = s -> s_calledlen)
196: > sizeof ss -> ss_called.sa_selector)
197: len = sizeof ss -> ss_called.sa_selector;
198: bcopy (s -> s_called, ss -> ss_called.sa_selector,
199: ss -> ss_called.sa_selectlen = len);
200: }
201: sb -> sb_responding = ss -> ss_called; /* struct copy */
202: if ((ss -> ss_ssdusize = sb -> sb_tsdu_us - SSDU_MAGIC) < 0)
203: ss -> ss_ssdusize = ts -> ts_tsdusize - SSDU_MAGIC;
204: ss -> ss_qos = ts -> ts_qos; /* struct copy */
205: ss -> ss_qos.qos_sversion = sb -> sb_version + 1;
206: ss -> ss_qos.qos_extended = (sb -> sb_flags & SB_EXPD) ? 1 : 0;
207: copySPKTdata (s, ss);
208:
209: freespkt (s);
210:
211: return OK;
212:
213: out2: ;
214: freespkt(s);
215:
216: out1: ;
217: freesblk (sb);
218:
219: return NOTOK;
220: }
221:
222: /* S-CONNECT.RESPONSE */
223:
224: #define dotoken(requires,shift,bit,type) \
225: { \
226: if (sb -> sb_requirements & requires) \
227: switch (sb -> sb_settings & (ST_MASK << shift)) { \
228: case ST_CALL_VALUE << shift: \
229: switch (settings & (ST_MASK << shift)) { \
230: case ST_INIT_VALUE << shift: \
231: settings &= ~(ST_MASK << shift); \
232: settings |= ST_INIT_VALUE << shift; \
233: break; \
234: \
235: case ST_RESP_VALUE << shift: \
236: settings &= ~(ST_MASK << shift); \
237: settings |= ST_RESP_VALUE << shift; \
238: sb -> sb_owned |= bit; \
239: break; \
240: \
241: default: \
242: return ssaplose (si, SC_PARAMETER, NULLCP, \
243: "improper choice of %s token setting", type); \
244: } \
245: break; \
246: \
247: case ST_INIT_VALUE << shift: \
248: if ((settings & (ST_MASK << shift)) == (ST_RSVD_VALUE << shift)) \
249: please |= bit; \
250: settings &= ~(ST_MASK << shift); \
251: settings |= ST_INIT_VALUE << shift; \
252: break; \
253: \
254: case ST_RESP_VALUE << shift: \
255: settings &= ~(ST_MASK << shift); \
256: settings |= ST_RESP_VALUE << shift; \
257: sb -> sb_owned |= bit; \
258: break; \
259: } \
260: }
261:
262: /* */
263:
264: int SConnResponse (sd, ref, responding, status, requirements, settings,
265: isn, data, cc, si)
266: int sd;
267: struct SSAPref *ref;
268: struct SSAPaddr *responding;
269: int status,
270: requirements,
271: settings,
272: cc;
273: long isn;
274: char *data;
275: struct SSAPindication *si;
276: {
277: int result,
278: please;
279: register struct ssapkt *s;
280: register struct ssapblk *sb;
281:
282: if ((sb = findsblk (sd)) == NULL || (sb -> sb_flags & SB_CONN))
283: return ssaplose (si, SC_PARAMETER, NULLCP, "invalid session descriptor");
284: missingP (ref);
285: refmuchP (ref);
286: if (ref -> sr_vlen)
287: return ssaplose (si, SC_PARAMETER, NULLCP, "bad format for reference");
288: #ifdef notdef
289: missingP (responding);
290: #endif
291: if (responding)
292: sb -> sb_responding = *responding; /* struct copy */
293: switch (status) {
294: case SC_ACCEPT:
295: if (requirements & ~SR_MYREQUIRE)
296: return ssaplose (si, SC_PARAMETER, NULLCP,
297: "requirements settings not supported");
298: #ifdef notdef /* screwy session protocol... */
299: if (requirements & ~sb -> sb_requirements)
300: return ssaplose (si, SC_PARAMETER, NULLCP,
301: "requirements settings not available");
302: #endif
303: if ((requirements & SR_HALFDUPLEX) && (requirements & SR_DUPLEX))
304: return ssaplose (si, SC_PARAMETER, NULLCP,
305: "half-duplex and duplex services are incompatible");
306: if ((requirements & SR_EXCEPTIONS)
307: && !(requirements & SR_HALFDUPLEX))
308: return ssaplose (si, SC_PARAMETER, NULLCP,
309: "exception service requires half-duplex service");
310: sb -> sb_requirements &= requirements;
311: sb -> sb_owned = 0, please = 0;
312: dotokens ();
313: if (sb -> sb_requirements
314: & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)) {
315: if (!(sb -> sb_requirements & SR_ACTIVITY)
316: || isn != SERIAL_NONE)
317: if (SERIAL_MIN > isn || isn > SERIAL_MAX + 1)
318: return ssaplose (si, SC_PARAMETER, NULLCP,
319: "bad choice for initial serial number");
320: }
321: else
322: if (isn != SERIAL_NONE)
323: return ssaplose (si, SC_PARAMETER, NULLCP,
324: "initial serial number invalid given requirements");
325: break;
326:
327: case SC_NOTSPECIFIED:
328: case SC_CONGESTION:
329: case SC_REJECTED:
330: break;
331:
332: default:
333: return ssaplose (si, SC_PARAMETER, NULLCP, "invalid result");
334: }
335: if (data == NULL)
336: cc = 0;
337: else
338: if (cc > (sb -> sb_version < SB_VRSN2 ? SC_SIZE : ENCLOSE_MAX))
339: return ssaplose (si, SC_PARAMETER, NULLCP,
340: "too much initial user data, %d octets", cc);
341: missingP (si);
342:
343: if (status != SC_ACCEPT) {
344: if ((s = newspkt (SPDU_RF)) == NULL) {
345: (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
346: goto out1;
347: }
348:
349: s -> s_mask |= SMASK_RF_REF;
350: s -> s_rf_reference = *ref; /* struct copy */
351: if (status == SC_REJECTED) {
352: s -> s_mask |= SMASK_RF_REQ;
353: s -> s_rf_require = requirements;
354: }
355: if ((s -> s_rdata = malloc ((unsigned) (s -> s_rlen = 1 + cc)))
356: == NULL) {
357: (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
358: goto out2;
359: }
360: *s -> s_rdata = status & 0xff;
361: if (cc > 0)
362: bcopy (data, s -> s_rdata + 1, cc);
363: result = refuse (sb, s, si);
364: freesblk (sb);
365:
366: return (result != NOTOK && status != SC_ACCEPT ? OK : NOTOK);
367: }
368:
369: if ((s = newspkt (SPDU_AC)) == NULL) {
370: (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
371: goto out1;
372: }
373:
374: s -> s_mask |= SMASK_CN_REF | SMASK_CN_OPT | SMASK_CN_VRSN;
375: s -> s_cn_reference = *ref; /* struct copy */
376: s -> s_options = CR_OPT_NULL;
377: s -> s_cn_version = 1 << sb -> sb_version;
378:
379: if (isn != SERIAL_NONE) {
380: s -> s_mask |= SMASK_CN_ISN;
381: s -> s_isn = isn;
382: }
383:
384: if (sb -> sb_tsdu_us || sb -> sb_tsdu_them) {
385: s -> s_mask |= SMASK_CN_TSDU;
386: s -> s_tsdu_resp = GET_TSDU_SIZE (sb -> sb_tsdu_us);
387: s -> s_tsdu_init = GET_TSDU_SIZE (sb -> sb_tsdu_them);
388: }
389:
390: s -> s_mask |= SMASK_CN_REQ;
391: if ((s -> s_cn_require = sb -> sb_requirements) & SR_TOKENS) {
392: s -> s_mask |= SMASK_CN_SET;
393: s -> s_settings = settings;
394: }
395: if (please) {
396: s -> s_mask |= SMASK_AC_TOKEN;
397: s -> s_ac_token = please;
398: }
399: if (responding) {
400: s -> s_mask |= SMASK_CN_CALLED;
401: bcopy (sb -> sb_responding.sa_selector, s -> s_called,
402: s -> s_calledlen = sb -> sb_responding.sa_selectlen);
403: }
404:
405: if (cc > 0) {
406: s -> s_mask |= SMASK_UDATA_PGI;
407: s -> s_udata = data, s -> s_ulen = cc;
408: }
409: else
410: s -> s_udata = NULL, s -> s_ulen = 0;
411: if ((result = spkt2sd (s, sb -> sb_fd, 0, si)) == NOTOK)
412: freesblk (sb);
413: else
414: sb -> sb_flags |= SB_CONN;
415: s -> s_mask &= ~SMASK_UDATA_PGI;
416: s -> s_udata = NULL, s -> s_ulen = 0;
417:
418: freespkt(s);
419:
420: return result;
421:
422: out2: ;
423: freespkt (s);
424: out1: ;
425: freesblk (sb);
426:
427: return NOTOK;
428: }
429:
430: #undef dotoken
431:
432: /* */
433:
434: static int refuse (sb, s, si)
435: register struct ssapblk *sb;
436: register struct ssapkt *s;
437: register struct SSAPindication *si;
438: {
439: int result;
440: struct TSAPdata txs;
441: register struct TSAPdata *tx = &txs;
442: struct TSAPdisconnect tds;
443: register struct TSAPdisconnect *td = &tds;
444:
445: s -> s_mask |= SMASK_RF_DISC;
446: s -> s_rf_disconnect |= RF_DISC_RELEASE;
447:
448: result = spkt2sd (s, sb -> sb_fd, sb -> sb_flags & SB_EXPD ? 1 : 0, si);
449:
450: freespkt (s);
451: if (result == NOTOK)
452: return NOTOK;
453:
454: switch (TReadRequest (sb -> sb_fd, tx, RF_TIM, td)) {
455: case OK:
456: default: /* what could this be? */
457: TXFREE (tx);
458: break;
459:
460: case NOTOK:
461: sb -> sb_fd = NOTOK;
462: break;
463: }
464:
465: return OK;
466: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.