|
|
1.1 root 1: /* tsapinitiate.c - TPM: initiator */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/tsap/RCS/tsapinitiate.c,v 7.2 90/07/09 14:51:26 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/tsap/RCS/tsapinitiate.c,v 7.2 90/07/09 14:51:26 mrose Exp $
9: *
10: *
11: * $Log: tsapinitiate.c,v $
12: * Revision 7.2 90/07/09 14:51:26 mrose
13: * sync
14: *
15: * Revision 7.1 90/03/23 17:31:34 mrose
16: * 8
17: *
18: * Revision 7.0 89/11/23 22:30:44 mrose
19: * Release 6.0
20: *
21: */
22:
23: /*
24: * NOTICE
25: *
26: * Acquisition, use, and distribution of this module and related
27: * materials are subject to the restrictions of a license agreement.
28: * Consult the Preface in the User's Manual for the full terms of
29: * this agreement.
30: *
31: */
32:
33:
34: /* LINTLIBRARY */
35:
36: #include <stdio.h>
37: #include <signal.h>
38: #include "tpkt.h"
39: #include "mpkt.h"
40: #include "isoservent.h"
41: #include "tailor.h"
42:
43:
44: static struct nsapent {
45: int ns_type;
46: int ns_stack;
47:
48: IFP ns_open;
49: } nsaps[] = {
50: #ifdef TCP
51: NA_TCP, TS_TCP, tcpopen,
52: #endif
53: #ifdef X25
54: NA_X25, TS_X25, x25open,
55: #endif
56: #ifdef BRIDGE_X25
57: NA_BRG, TS_BRG, bridgeopen,
58: #endif
59: #ifdef TP4
60: NA_NSAP, TS_TP4, tp4open,
61: #endif
62:
63: NOTOK, TS_NONE, NULL
64: };
65:
66:
67: struct TSAPaddr *newtaddr (), *ta2norm (), *maketsbaddr ();
68:
69: /* T-(ASYN-)CONNECT.REQUEST */
70:
71: int TAsynConnRequest (calling, called, expedited, data, cc, qos,
72: tc, td, async)
73: struct TSAPaddr *calling,
74: *called;
75: int expedited,
76: cc,
77: async;
78: char *data;
79: struct QOStype *qos;
80: struct TSAPconnect *tc;
81: struct TSAPdisconnect *td;
82: {
83: register int n;
84: SBV smask;
85: int result;
86:
87: isodetailor (NULLCP, 0);
88:
89: #ifdef notdef
90: missingP (calling);
91: #endif
92: missingP (called);
93: if ((n = called -> ta_naddr) <= 0)
94: return tsaplose (td, DR_PARAMETER, NULLCP,
95: "no NSAP addresses in called parameter");
96: if (n > NTADDR)
97: return tsaplose (td, DR_PARAMETER, NULLCP,
98: "too many NSAP addresses in called parameter");
99:
100: if ((called = ta2norm (called)) == NULLTA)
101: return tsaplose (td, DR_PARAMETER, "invalid called parameter");
102: toomuchP (data, cc, TS_SIZE, "initial");
103: #ifdef notdef
104: missingP (qos);
105: #endif
106: missingP (td);
107:
108: smask = sigioblock ();
109:
110: result = TConnRequestAux (calling, called, expedited, data, cc, qos,
111: tc, td, async);
112:
113: (void) sigiomask (smask);
114:
115: return result;
116: }
117:
118: /* */
119:
120: static int TConnRequestAux (calling, called, expedited, data, cc, qos,
121: tc, td, async)
122: struct TSAPaddr *calling,
123: *called;
124: char *data;
125: int expedited,
126: cc,
127: async;
128: struct QOStype *qos;
129: register struct TSAPconnect *tc;
130: register struct TSAPdisconnect *td;
131: {
132: int result;
133: register struct tsapblk *tb;
134:
135: if ((tb = newtblk ()) == NULL)
136: return tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
137:
138: if (calling == NULLTA) {
139: static struct TSAPaddr tas;
140:
141: calling = &tas;
142: bzero ((char *) calling, sizeof *calling);
143: }
144: #ifdef notdef
145: if (called -> ta_selectlen > 0 && calling -> ta_selectlen == 0) {
146: calling -> ta_port = htons ((u_short) (0x8000 | (getpid () & 0x7fff)));
147: calling -> ta_selectlen = sizeof calling -> ta_port;
148: }
149: #endif
150:
151: if (qos)
152: tb -> tb_qos = *qos; /* struct copy */
153:
154: if ((tb -> tb_calling = (struct TSAPaddr *)
155: calloc (1, sizeof *tb -> tb_calling)) == NULL)
156: goto no_mem;
157: *tb -> tb_calling = *calling; /* struct copy */
158: bcopy (calling -> ta_selector, tb -> tb_initiating.ta_selector,
159: tb -> tb_initiating.ta_selectlen = calling -> ta_selectlen);
160:
161: if ((tb -> tb_called = (struct TSAPaddr *)
162: calloc (1, sizeof *tb -> tb_called)) == NULL)
163: goto no_mem;
164: *tb -> tb_called = *called; /* struct copy */
165:
166: if ((tb -> tb_cc = cc) > 0) {
167: if ((tb -> tb_data = malloc ((unsigned) cc)) == NULLCP) {
168: no_mem: ;
169: (void) tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
170: goto out;
171: }
172: bcopy (data, tb -> tb_data, cc);
173: }
174: tb -> tb_expedited = expedited;
175:
176: if ((result = TConnAttempt (tb, td, async)) == NOTOK) {
177: #ifdef MGMT
178: if (tb -> tb_manfnx)
179: (*tb -> tb_manfnx) (OPREQOUTBAD, tb);
180: #endif
181: goto out;
182: }
183:
184: if (async) {
185: tc -> tc_sd = tb -> tb_fd;
186: switch (result) {
187: case CONNECTING_1:
188: case CONNECTING_2:
189: return result;
190: }
191: }
192:
193: if ((result = (*tb -> tb_retryPfnx) (tb, async, tc, td)) == DONE && !async)
194: result = OK;
195: return result;
196:
197: out: ;
198: freetblk (tb);
199:
200: return NOTOK;
201: }
202:
203: /* */
204:
205: static int TConnAttempt (tb, td, async)
206: struct tsapblk *tb;
207: struct TSAPdisconnect *td;
208: int async;
209: {
210: register int n;
211: int didone,
212: l,
213: result;
214: register struct TSAPaddr *called, *calling;
215: struct TSAPaddr *realcalled;
216: register struct NSAPaddr *na, *la;
217: struct NSAPaddr *realna;
218: register struct TSAPdisconnect *te = td;
219: struct TSAPdisconnect tds;
220:
221: calling = tb -> tb_calling;
222: called = tb -> tb_called;
223:
224: didone = 0;
225: for (na = called -> ta_addrs, n = called -> ta_naddr - 1;
226: n >= 0;
227: na++, n--) {
228: register int *ip;
229: register char **ap;
230: register struct nsapent *ns;
231:
232: realcalled = called;
233: realna = na;
234: for (ip = ts_communities; *ip; ip++)
235: if (*ip == na -> na_community)
236: break;
237: if (!*ip)
238: continue;
239: for (ip = tsb_communities, ap = tsb_addresses; *ip; ip++, ap++)
240: if (*ip == na -> na_community) {
241: if ((realcalled = maketsbaddr (*ap, na, called)) == NULLTA)
242: continue;
243: realna = realcalled -> ta_addrs;
244: break;
245: }
246:
247: for (la = calling -> ta_addrs, l = calling -> ta_naddr - 1;
248: l >= 0;
249: la++, l--)
250: if (la -> na_community == na -> na_community)
251: break;
252: if (l < 0)
253: la = NULLNA;
254:
255: for (ns = nsaps; ns -> ns_open; ns++)
256: if (ns -> ns_type == realna -> na_stack
257: && (ns -> ns_stack & ts_stacks))
258: break;
259: if (!ns -> ns_open)
260: continue;
261:
262: didone = 1;
263: switch (ns -> ns_type) {
264: case NA_NSAP:
265: if ((result = (*ns -> ns_open) (tb, calling, la,
266: realcalled, realna,
267: te, async)) == NOTOK) {
268: te = &tds;
269: continue;
270: }
271: break;
272:
273: default:
274: if ((result = (*ns -> ns_open) (tb, la, realna, te, async))
275: == NOTOK) {
276: te = &tds;
277: continue;
278: }
279: break;
280: }
281: break;
282: }
283:
284: if (tb -> tb_fd == NOTOK) {
285: if (!didone)
286: return tsaplose (td, DR_PARAMETER, NULLCP,
287: "no supported NSAP addresses in, nor known TSBridges for, called parameter");
288:
289: return NOTOK;
290: }
291:
292: if (la) {
293: tb -> tb_initiating.ta_present = 1;
294: tb -> tb_initiating.ta_addr = *la; /* struct copy */
295: }
296: if (la && la != calling -> ta_addrs) {
297: struct NSAPaddr ns;
298:
299: ns = calling -> ta_addrs[0]; /* struct copy */
300: calling -> ta_addrs[0] = *la; /* .. */
301: *la = ns; /* .. */
302: la = calling -> ta_addrs; /* .. */
303: }
304:
305: bcopy (realcalled -> ta_selector, tb -> tb_responding.ta_selector,
306: tb -> tb_responding.ta_selectlen = realcalled -> ta_selectlen);
307: tb -> tb_responding.ta_present = 1;
308: tb -> tb_responding.ta_addr = *realna; /* struct copy */
309:
310: if ((result = (*tb -> tb_connPfnx) (tb, tb -> tb_expedited, tb -> tb_data,
311: tb -> tb_cc, td)) == NOTOK)
312: return NOTOK;
313:
314: if (result == OK)
315: result = CONNECTING_1;
316:
317: return result;
318: }
319:
320: /* T-ASYN-RETRY.REQUEST (pseudo) */
321:
322: int TAsynRetryRequest (sd, tc, td)
323: int sd;
324: struct TSAPconnect *tc;
325: struct TSAPdisconnect *td;
326: {
327: SBV smask;
328: int result;
329: register struct tsapblk *tb;
330: struct TSAPaddr *ta;
331:
332: missingP (tc);
333: missingP (td);
334:
335: smask = sigioblock ();
336:
337: if ((tb = findtblk (sd)) == NULL) {
338: (void) sigiomask (smask);
339: return tsaplose (td, DR_PARAMETER, NULLCP,
340: "invalid transport descriptor");
341: }
342: if (tb -> tb_flags & TB_CONN) {
343: (void) sigiomask (smask);
344: return tsaplose (td, DR_OPERATION, NULLCP,
345: "transport descriptor connected");
346: }
347:
348: ta = tb -> tb_called;
349:
350: switch (result = (*tb -> tb_retryPfnx) (tb, 1, tc, td)) {
351: case NOTOK: /* try next nsap in list */
352: if (ta -> ta_naddr <= 1) {
353: freetblk (tb);
354: break;
355: }
356: *tb -> tb_called = *newtaddr (ta, &ta -> ta_addrs[1],
357: ta -> ta_naddr - 1); /* struct copy */
358:
359: switch (result = TConnAttempt (tb, td, 1)) {
360: case DONE:
361: result = OK;
362: /* and fall... */
363: case CONNECTING_1:
364: case CONNECTING_2:
365: if (tb -> tb_fd != sd) {
366: (void) dup2 (tb -> tb_fd, sd);
367: (void) close (tb -> tb_fd);
368: tb -> tb_fd = sd;
369: }
370: break;
371:
372: case NOTOK:
373: freetblk (tb);
374: break;
375: }
376: break;
377:
378: case DONE:
379: if (tb -> tb_data) {
380: free (tb -> tb_data);
381: tb -> tb_data = NULLCP;
382: }
383: tb -> tb_cc = 0;
384: tb -> tb_expedited = 0;
385: break;
386:
387: case CONNECTING_1:
388: case CONNECTING_2:
389: default:
390: break;
391: }
392:
393: (void) sigiomask (smask);
394:
395: return result;
396: }
397:
398: /* T-ASYN-NEXT.REQUEST (pseudo) */
399:
400: int TAsynNextRequest (sd, tc, td)
401: int sd;
402: struct TSAPconnect *tc;
403: struct TSAPdisconnect *td;
404: {
405: SBV smask;
406: int result;
407: register struct tsapblk *tb;
408: struct TSAPaddr *ta;
409:
410: missingP (tc);
411: missingP (td);
412:
413: smask = sigioblock ();
414:
415: if ((tb = findtblk (sd)) == NULL) {
416: (void) sigiomask (smask);
417: return tsaplose (td, DR_PARAMETER, NULLCP,
418: "invalid transport descriptor");
419: }
420: if (tb -> tb_flags & TB_CONN) {
421: (void) sigiomask (smask);
422: return tsaplose (td, DR_OPERATION, NULLCP,
423: "transport descriptor connected");
424: }
425:
426: ta = tb -> tb_called;
427:
428: /* close previous connection attempt */
429: if (tb -> tb_fd != NOTOK)
430: (void) (*tb -> tb_closefnx) (tb -> tb_fd);
431: tb -> tb_fd = NOTOK;
432:
433: if (ta -> ta_naddr <= 1) {
434: freetblk (tb);
435: (void) sigiomask (smask);
436: return tsaplose (td, DR_PARAMETER, NULLCP, "no more NSAPs to try");
437: }
438: *tb -> tb_called = *newtaddr (ta, &ta -> ta_addrs[1],
439: ta -> ta_naddr - 1); /* struct copy */
440:
441: switch (result = TConnAttempt (tb, td, 1)) {
442: case DONE:
443: result = OK;
444: /* and fall... */
445: case CONNECTING_1:
446: case CONNECTING_2:
447: if (tb -> tb_fd != sd) {
448: (void) dup2 (tb -> tb_fd, sd);
449: (void) close (tb -> tb_fd);
450: tb -> tb_fd = sd;
451: }
452: break;
453:
454: case NOTOK:
455: freetblk (tb);
456: break;
457: }
458:
459: (void) sigiomask (smask);
460:
461: return result;
462: }
463:
464: /* */
465:
466: static struct TSAPaddr *newtaddr (ta, na, n)
467: register struct TSAPaddr *ta;
468: register struct NSAPaddr *na;
469: int n;
470: {
471: static struct TSAPaddr tzs;
472: register struct TSAPaddr *tz = &tzs;
473: register struct NSAPaddr *nz = tz -> ta_addrs;
474:
475: bzero ((char *) tz, sizeof *tz);
476:
477: if (tz -> ta_selectlen = ta -> ta_selectlen)
478: bcopy (ta -> ta_selector, tz -> ta_selector, ta -> ta_selectlen);
479: if (na)
480: for (tz -> ta_naddr = n; n > 0; n--)
481: *nz++ = *na++; /* struct copy */
482:
483: return tz;
484: }
485:
486: /* */
487:
488: struct TSAPaddr *ta2norm (ta)
489: register struct TSAPaddr *ta;
490: {
491: register int n,
492: *ip;
493: static struct TSAPaddr tzs;
494: register struct TSAPaddr *tz = &tzs;
495: register struct NSAPaddr *na,
496: *ca;
497:
498: SLOG (addr_log, LLOG_TRACE, NULLCP,
499: ("ta2norm %s", taddr2str (ta)));
500:
501: for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1; n >= 0; na++, n--)
502: if (na -> na_community == 0) {
503: SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
504: ("ta2norm: empty subnet in NSAP address at offset %d",
505: na - ta -> ta_addrs));
506: return NULLTA;
507: }
508:
509: bzero ((char *) tz, sizeof *tz);
510: bcopy (ta -> ta_selector, tz -> ta_selector,
511: tz -> ta_selectlen = ta -> ta_selectlen);
512: ca = tz -> ta_addrs;
513:
514: for (ip = ts_communities; *ip; ip++)
515: for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1;
516: n >= 0;
517: na++, n--)
518: if (*ip == na -> na_community) {
519: *ca++ = *na; /* struct copy */
520: tz -> ta_naddr++;
521: }
522:
523: for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1; n >= 0; na++, n--) {
524: for (ip = ts_communities; *ip; ip++)
525: if (*ip == na -> na_community)
526: break;
527: if (!*ip) {
528: *ca++ = *na; /* struct copy */
529: tz -> ta_naddr++;
530: }
531: }
532:
533: SLOG (addr_log, LLOG_TRACE, NULLCP,
534: ("ta2norm returns %s", taddr2str (tz)));
535:
536: return tz;
537: }
538:
539: /* */
540:
541: static struct TSAPaddr *maketsbaddr (cp, na, ta)
542: char *cp;
543: struct NSAPaddr *na;
544: struct TSAPaddr *ta;
545: {
546: static struct TSAPaddr newta;
547: register struct TSAPaddr *nta = &newta;
548: struct TSAPaddr *taz;
549: char *p;
550: struct PSAPaddr pas;
551: struct PSAPaddr *pa = &pas;
552:
553:
554: if ((taz = str2taddr (cp)) == NULLTA)
555: return taz;
556:
557: *nta = *taz; /* struct copy */
558: bzero ((char *)pa, sizeof *pa);
559: pa -> pa_addr.sa_addr.ta_naddr = 1;
560: pa -> pa_addr.sa_addr.ta_addrs[0] = *na;
561: pa -> pa_addr.sa_addr.ta_selectlen = ta -> ta_selectlen;
562: (void) strncpy (pa -> pa_addr.sa_addr.ta_selector, ta -> ta_selector,
563: ta -> ta_selectlen);
564: if ((p = _paddr2str (pa, NULLNA, -1)) == NULL)
565: return NULLTA;
566:
567: if ((nta -> ta_selectlen = strlen (p)) >= TSSIZE)
568: return NULLTA;
569: else
570: (void) strncpy (nta -> ta_selector, p, TSSIZE);
571: nta -> ta_naddr = 1;
572:
573: return nta;
574: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.