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