|
|
1.1 root 1: /* dgram.c - datagram (CL-mode TS) abstractions */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/compat/RCS/dgram.c,v 7.7 90/07/09 14:31:43 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/compat/RCS/dgram.c,v 7.7 90/07/09 14:31:43 mrose Exp $
9: *
10: *
11: * $Log: dgram.c,v $
12: * Revision 7.7 90/07/09 14:31:43 mrose
13: * sync
14: *
15: * Revision 7.6 90/04/23 00:08:08 mrose
16: * touch-up
17: *
18: * Revision 7.5 90/01/11 18:35:03 mrose
19: * real-sync
20: *
21: * Revision 7.4 89/12/19 17:57:34 mrose
22: * touch-up
23: *
24: * Revision 7.3 89/12/19 15:15:31 mrose
25: * dgram
26: *
27: * Revision 7.2 89/12/17 18:30:11 mrose
28: * foo
29: *
30: * Revision 7.1 89/12/11 16:22:25 mrose
31: * more dgram
32: *
33: * Revision 7.0 89/12/01 10:42:35 mrose
34: * Release 6.0
35: *
36: */
37:
38: /*
39: * NOTICE
40: *
41: * Acquisition, use, and distribution of this module and related
42: * materials are subject to the restrictions of a license agreement.
43: * Consult the Preface in the User's Manual for the full terms of
44: * this agreement.
45: *
46: */
47:
48:
49: /* LINTLIBRARY */
50:
51: #include <errno.h>
52: #include <stdio.h>
53: #include "general.h"
54: #include "manifest.h"
55: #include "tailor.h"
56:
57: #include "dgram.h"
58: #ifdef TCP
59: #include "internet.h"
60: #endif
61: #ifdef TP4
62: #include "tp4.h"
63: #endif
64:
65:
66: #if defined(SOCKETS) && (defined(TCP) || defined(CLTS))
67: #ifndef DEBUG
68: #define action(s,f,i)
69: #endif
70:
71: extern int errno;
72:
73: /* */
74:
75: union sockaddr_un { /* 'cause sizeof (struct sockaddr_iso) == 32 */
76: struct sockaddr sa;
77:
78: #ifdef TCP
79: struct sockaddr_in sin;
80: #endif
81:
82: #ifdef BSD_TP4
83: union sockaddr_osi sosi;
84: #endif
85: };
86:
87:
88: struct dgramblk {
89: int dgram_parent;
90: union sockaddr_un dgram_peer;
91: #ifdef BSD44
92: u_char dgram_addrlen;
93: #endif
94:
95: struct qbuf dgram_queue;
96: };
97:
98:
99: static int maxpeers = 0;
100: static struct dgramblk *peers = NULL;
101:
102: /* */
103:
104: #ifdef TCP
105:
106: /* ARGSUSED */
107:
108: int start_udp_server (sock, backlog, opt1, opt2)
109: struct sockaddr_in *sock;
110: int backlog,
111: opt1,
112: opt2;
113: {
114: register int port;
115: int sd;
116: #ifdef BSD43
117: int onoff;
118: #endif
119: register struct dgramblk *up,
120: *vp;
121:
122: if (peers == NULL) {
123: maxpeers = getdtablesize ();
124: peers = (struct dgramblk *) calloc ((unsigned)maxpeers, sizeof *peers);
125: if (peers == NULL)
126: return NOTOK;
127:
128: for (vp = (up = peers) + maxpeers; up < vp; up++) {
129: up -> dgram_parent = NOTOK;
130: up -> dgram_queue.qb_forw = up -> dgram_queue.qb_back =
131: &up -> dgram_queue;
132: }
133: }
134:
135: if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) == NOTOK)
136: return NOTOK;
137:
138: if (sock -> sin_port != 0) {
139: action ("BIND", sd, (struct sockaddr *) sock);
140:
141: if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK)
142: goto got_socket;
143:
144: (void) close (sd);
145: return NOTOK;
146: }
147: else
148: sock -> sin_family = AF_INET;
149:
150: for (port = IPPORT_RESERVED;; port++) {
151: sock -> sin_port = htons ((u_short) port);
152:
153: action ("BIND", sd, (struct sockaddr *) sock);
154:
155: if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK)
156: break;
157:
158: switch (errno) {
159: case EADDRINUSE:
160: continue;
161:
162: case EADDRNOTAVAIL:
163: default:
164: (void) close (sd);
165: return NOTOK;
166: }
167: }
168:
169: got_socket: ;
170: #ifdef DEBUG
171: {
172: int len = sizeof *sock;
173:
174: action ("FOO1", sd, (struct sockaddr *) sock);
175: if (getsockname (sd, (struct sockaddr *) sock, &len) != NOTOK)
176: action ("FOO2", sd, (struct sockaddr *) sock);
177: }
178: #endif
179:
180: #ifndef BSD43
181: if (opt1)
182: (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0);
183: if (opt2)
184: (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0);
185: #else
186: onoff = 1;
187: if (opt1)
188: (void) setsockopt (sd, SOL_SOCKET, opt1, (char *)&onoff, sizeof onoff);
189: if (opt2)
190: (void) setsockopt (sd, SOL_SOCKET, opt2, (char *)&onoff, sizeof onoff);
191: #endif
192:
193: return (peers[sd].dgram_parent = sd);
194: }
195: #endif
196:
197: /* */
198:
199: #ifdef BSD_TP4
200:
201: /* ARGSUSED */
202:
203: int start_clts_server (sock, backlog, opt1, opt2)
204: union sockaddr_osi *sock;
205: int backlog,
206: opt1,
207: opt2;
208: {
209: int sd;
210: #ifdef BSD43
211: int onoff;
212: #endif
213: u_char *cp;
214: register struct dgramblk *up,
215: *vp;
216: struct sockaddr_iso *ifaddr = &sock -> osi_sockaddr;
217:
218: if (peers == NULL) {
219: maxpeers = getdtablesize ();
220: peers = (struct dgramblk *) calloc ((unsigned)maxpeers, sizeof *peers);
221: if (peers == NULL)
222: return NOTOK;
223:
224: for (vp = (up = peers) + maxpeers; up < vp; up++) {
225: up -> dgram_parent = NOTOK;
226: up -> dgram_queue.qb_forw = up -> dgram_queue.qb_back =
227: &up -> dgram_queue;
228: }
229: }
230:
231: if ((sd = socket (AF_ISO, SOCK_DGRAM, 0)) == NOTOK)
232: return NOTOK;
233:
234: if (ifaddr -> siso_tlen != 0) {
235: action ("BIND", sd, (struct sockaddr *) ifaddr);
236:
237: if (bind (sd, (struct sockaddr *) ifaddr, (int) ifaddr -> siso_len)
238: != NOTOK)
239: goto got_socket;
240:
241: (void) close (sd);
242: return NOTOK;
243: }
244: else
245: ifaddr -> siso_family = AF_ISO;
246:
247: {
248: int pid;
249: u_char *dp,
250: *ep,
251: *fp;
252:
253: pid = getpid ();
254: cp = fp = (u_char *) ifaddr -> siso_data + ifaddr -> siso_nlen;
255: for (ep = (dp = (u_char *) &pid) + sizeof pid; dp < ep; dp++)
256: *cp++ = *dp;
257: ifaddr -> siso_tlen = (cp - fp) + 1;
258: ifaddr -> siso_slen = ifaddr -> siso_plen = 0;
259: ifaddr -> siso_len = sizeof *ifaddr;
260: }
261:
262: for (*cp = 0x00; *cp < 0xff; *cp += 1) {
263: action ("BIND", sd, (struct sockaddr *) ifaddr);
264:
265: if (bind (sd, (struct sockaddr *) ifaddr, (int) ifaddr -> siso_len)
266: != NOTOK)
267: goto got_socket;
268:
269: switch (errno) {
270: case EADDRINUSE:
271: continue;
272:
273: case EADDRNOTAVAIL:
274: default:
275: (void) close (sd);
276: return NOTOK;
277: }
278: }
279: (void) close (sd);
280: errno = EADDRNOTAVAIL;
281: return NOTOK;
282:
283: got_socket: ;
284: #ifdef DEBUG
285: {
286: int len = sizeof *sock;
287:
288: action ("FOO1", sd, ifaddr);
289: if (getsockname (sd, (struct sockaddr *) ifaddr, &len) != NOTOK)
290: action ("FOO2", sd, ifaddr);
291: }
292: #endif
293:
294: #ifndef BSD43
295: if (opt1)
296: (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0);
297: if (opt2)
298: (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0);
299: #else
300: onoff = 1;
301: if (opt1)
302: (void) setsockopt (sd, SOL_SOCKET, opt1, (char *)&onoff, sizeof onoff);
303: if (opt2)
304: (void) setsockopt (sd, SOL_SOCKET, opt2, (char *)&onoff, sizeof onoff);
305: #endif
306:
307: return (peers[sd].dgram_parent = sd);
308: }
309: #endif
310:
311: /* */
312:
313: int join_dgram_aux (fd, sock, newfd)
314: int fd,
315: newfd;
316: struct sockaddr *sock;
317: {
318: int nfds,
319: sd;
320: fd_set ifds;
321: register struct qbuf *qb;
322: register struct dgramblk *up;
323:
324: if (fd < 0 || fd >= maxpeers || peers[fd].dgram_parent != fd) {
325: errno = EINVAL;
326: return NOTOK;
327: }
328:
329: if (newfd) {
330: FD_ZERO (&ifds);
331:
332: nfds = fd + 1;
333: FD_SET (fd, &ifds);
334: if (select_dgram_socket (nfds, &ifds, NULLFD, NULLFD, OK) == NOTOK)
335: return NOTOK;
336:
337: up = &peers[fd];
338: if ((qb = up -> dgram_queue.qb_forw) == &up -> dgram_queue) {
339: errno = EWOULDBLOCK;
340: return NOTOK;
341: }
342:
343: if ((sd = dup (fd)) == NOTOK)
344: return NOTOK;
345:
346: up = &peers[sd];
347: #ifdef BSD44
348: bcopy (qb -> qb_base, (caddr_t) sock,
349: ((struct sockaddr *) qb -> qb_base) -> sa_len);
350: #else
351: *sock = *((struct sockaddr *) qb -> qb_base); /* struct copy */
352: #endif
353:
354: remque (qb);
355: insque (qb, up -> dgram_queue.qb_back);
356: }
357: else
358: up = &peers[fd];
359:
360: up -> dgram_parent = fd;
361: #ifdef BSD44
362: if (sock -> sa_len == 0)
363: sock -> sa_len = sizeof *sock;
364: bcopy ((caddr_t) sock, (caddr_t) &up -> dgram_peer, sock -> sa_len);
365: {
366: struct sockaddr_in *sin;
367:
368: up -> dgram_addrlen = sock -> sa_family != AF_INET ? sock -> sa_len
369: : sizeof *sin - sizeof sin -> sin_zero;
370: }
371: #else
372: up -> dgram_peer.sa = *sock; /* struct copy */
373: #endif
374:
375: action ("JOIN", newfd ? sd : fd, sock);
376:
377: return (newfd ? sd : OK);
378: }
379:
380: /* */
381:
382: int read_dgram_socket (fd, q)
383: int fd;
384: struct qbuf **q;
385: {
386: int nfds;
387: fd_set ifds,
388: mask;
389: register struct qbuf *qb;
390: register struct dgramblk *up;
391:
392: if (fd < 0
393: || fd >= maxpeers
394: || (up = &peers[fd]) -> dgram_parent == NOTOK) {
395: errno = EINVAL;
396: return NOTOK;
397: }
398:
399: if ((qb = up -> dgram_queue.qb_forw) == &up -> dgram_queue) {
400: FD_ZERO (&mask);
401:
402: nfds = fd + 1;
403: FD_SET (fd, &mask);
404: for (ifds = mask;; ifds = mask) {
405: if (select_dgram_socket (nfds, &ifds, NULLFD, NULLFD, NOTOK)
406: == NOTOK)
407: return NOTOK;
408:
409: if ((qb = up -> dgram_queue.qb_forw) != &up -> dgram_queue)
410: break;
411: }
412: }
413:
414: remque (qb);
415: qb -> qb_forw = qb -> qb_back = qb;
416:
417: *q = qb;
418:
419: return qb -> qb_len;
420: }
421:
422: /* */
423:
424: int hack_dgram_socket (fd, sock)
425: int fd;
426: struct sockaddr *sock;
427: {
428: register struct dgramblk *up;
429:
430: if (fd < 0
431: || fd >= maxpeers
432: || (up = &peers[fd]) -> dgram_parent != fd) {
433: errno = EINVAL;
434: return NOTOK;
435: }
436:
437: if (sock == NULL) {
438: bzero ((caddr_t) &up -> dgram_peer, sizeof up -> dgram_peer);
439: return OK;
440: }
441:
442: #ifdef BSD44
443: if (sock -> sa_len == 0)
444: sock -> sa_len = sizeof *sock;
445: bcopy ((caddr_t) sock, (caddr_t) &up -> dgram_peer, sock -> sa_len);
446: up -> dgram_addrlen = 0;
447: #else
448: up -> dgram_peer.sa = *sock; /* struct copy */
449: #endif
450:
451: action ("HACK", fd, sock);
452:
453: return OK;
454: }
455:
456:
457: int write_dgram_socket (fd, qb)
458: int fd;
459: register struct qbuf *qb;
460: {
461: register struct dgramblk *up;
462:
463: if (fd < 0
464: || fd >= maxpeers
465: || (up = &peers[fd]) -> dgram_parent == NOTOK
466: || up -> dgram_peer.sa.sa_family == 0) {
467: errno = EINVAL;
468: return NOTOK;
469: }
470:
471: action ("SENDTO", fd, &up -> dgram_peer.sa);
472:
473: #ifdef BSD44
474: return sendto (fd, qb -> qb_data, qb -> qb_len, NULL,
475: &up -> dgram_peer.sa, (int) up -> dgram_peer.sa.sa_len);
476: #else
477: return sendto (fd, qb -> qb_data, qb -> qb_len, NULL,
478: &up -> dgram_peer.sa, sizeof up -> dgram_peer.sa);
479: #endif
480: }
481:
482:
483: /* */
484:
485: int close_dgram_socket (fd)
486: int fd;
487: {
488: register struct dgramblk *up,
489: *vp;
490:
491: if (fd < 0
492: || fd >= maxpeers
493: || (up = &peers[fd]) -> dgram_parent == NOTOK) {
494: errno = EINVAL;
495: return NOTOK;
496: }
497:
498: action ("CLOSE", fd, &up -> dgram_peer.sa);
499:
500: up -> dgram_parent = NOTOK;
501: bzero ((char *) &up -> dgram_peer, sizeof up -> dgram_peer);
502: QBFREE (&up -> dgram_queue);
503:
504: for (vp = (up = peers) + maxpeers; up < vp; up++)
505: if (up -> dgram_parent == fd)
506: up -> dgram_parent = up - peers;
507:
508: return close (fd);
509: }
510:
511: /* */
512:
513: int select_dgram_socket (nfds, rfds, wfds, efds, secs)
514: int nfds;
515: fd_set *rfds,
516: *wfds,
517: *efds;
518: int secs;
519: {
520: register int fd;
521: int cc,
522: mfds,
523: result;
524: fd_set ifds,
525: jfds;
526: register struct qbuf *qb;
527: register struct dgramblk *up,
528: *vp;
529: struct dgramblk *wp;
530: union sockaddr_un *sock;
531:
532: if (rfds) {
533: jfds = *rfds;
534:
535: if (secs != OK)
536: for (vp = (up = peers) + maxpeers, fd = 0; up < vp; up++, fd++)
537: if (up -> dgram_parent != NOTOK
538: && FD_ISSET (fd, &jfds)
539: && up -> dgram_queue.qb_forw != &up -> dgram_queue) {
540: secs = OK;
541: break;
542: }
543: }
544:
545: if ((result = selsocket (nfds, rfds, wfds, efds, secs)) == NOTOK
546: || rfds == NULLFD)
547: return result;
548:
549: ifds = *rfds;
550: if ((mfds = nfds) > maxpeers)
551: mfds = maxpeers;
552: for (fd = 0, up = peers; fd < mfds; fd++, up++)
553: if (FD_ISSET (fd, &ifds)) {
554: int slen;
555: u_char len;
556: char *data;
557:
558: if (up -> dgram_parent == NOTOK)
559: continue;
560:
561: if ((qb = (struct qbuf *) malloc ((unsigned) (sizeof *qb
562: + (slen
563: = sizeof *sock)
564: + MAXDGRAM)))
565: == NULL)
566: return NOTOK;
567:
568: sock = (union sockaddr_un *) qb -> qb_base;
569: qb -> qb_data = qb -> qb_base + slen;
570: if ((cc = recvfrom (fd, qb -> qb_data, MAXDGRAM, NULL,
571: &sock -> sa, &slen)) == NOTOK) {
572: free ((char *) qb);
573: return NOTOK;
574: }
575: #ifdef BSD44
576: sock -> sa.sa_len = slen;
577: #endif
578: qb -> qb_len = cc;
579:
580: action ("RECVFROM", fd, &sock -> sa);
581:
582: vp = up;
583: data = sock -> sa.sa_data;
584: switch (sock -> sa.sa_family) {
585: case AF_INET: /* XXX: doesn't take into account padding */
586: len = sizeof sock -> sin
587: - sizeof sock -> sin.sin_zero;
588: break;
589:
590: default:
591: #ifdef BSD44
592: len = sock -> sa.sa_len;
593: #else
594: len = sizeof sock -> sa;
595: #endif
596: break;
597: }
598: if (
599: #ifdef BSD44
600: len != up -> dgram_addrlen ||
601: #endif
602: bcmp (data, up -> dgram_peer.sa.sa_data, (int) len)
603: != 0) {
604: for (wp = (vp = peers) + maxpeers; vp < wp; vp++)
605: if (vp != up
606: && vp -> dgram_parent == up -> dgram_parent
607: #ifdef BSD44
608: && len == vp -> dgram_addrlen
609: #endif
610: && bcmp (data, vp -> dgram_peer.sa.sa_data,
611: (int) len) == 0)
612: break;
613: if (vp >= wp
614: && (vp = &peers[up -> dgram_parent])
615: -> dgram_peer.sa.sa_family != 0) {
616: free ((char *) qb);
617: continue;
618: }
619: }
620:
621: insque (qb, vp -> dgram_queue.qb_back);
622: }
623:
624: for (vp = (up = peers) + maxpeers, fd = 0; up < vp; up++, fd++)
625: if (up -> dgram_parent != NOTOK && FD_ISSET (fd, &jfds))
626: if (up -> dgram_queue.qb_forw != &up -> dgram_queue)
627: FD_SET (fd, rfds);
628: else
629: FD_CLR (fd, rfds);
630:
631: result = 0;
632: ifds = *rfds;
633: if (wfds)
634: for (fd = 0; fd < nfds; fd++)
635: if (FD_ISSET (fd, wfds))
636: FD_SET (fd, &ifds);
637: if (efds)
638: for (fd = 0; fd < nfds; fd++)
639: if (FD_ISSET (fd, efds))
640: FD_SET (fd, &ifds);
641: for (fd = 0; fd < nfds; fd++)
642: if (FD_ISSET (fd, &ifds))
643: result++;
644:
645: return result;
646: }
647:
648: /* */
649:
650: #ifdef DEBUG
651:
652: #ifdef TCP
653: #include "isoaddrs.h"
654:
655:
656: static inetprint (sin, bp)
657: struct sockaddr_in *sin;
658: char *bp;
659: {
660: (void) sprintf (bp, "Internet=%s+%d+%d", inet_ntoa (sin -> sin_addr),
661: (int) ntohs (sin -> sin_port), NA_TSET_UDP);
662: }
663: #endif
664:
665: /* */
666:
667: #ifdef CLTS
668: /* prints OSI address using the format described in:
669:
670: "A string encoding of Presentation Address"
671:
672: S.E. Kille, Research Note RN/89/14, February 1989
673: Department of Computer Science
674: University College London
675:
676: */
677:
678: #ifndef SSEL
679: #define SSEL(s) ((s)->siso_tlen + TSEL(s))
680: #define PSEL(s) ((s)->siso_slen + SSEL(s))
681: #endif
682:
683:
684: static isoprint (siso, bp)
685: register struct sockaddr_iso *siso;
686: char *bp;
687: {
688: int didone = 0;
689:
690: if (siso -> siso_plen) {
691: hexprint (bp, siso -> siso_plen, PSEL (siso), "'", "'H");
692: bp += strlen (bp);
693: *bp++ = '/';
694: didone++;
695: }
696: if (siso -> siso_slen || didone) {
697: hexprint (bp, siso -> siso_slen, SSEL (siso), "'", "'H");
698: bp += strlen (bp);
699: *bp++ = '/';
700: didone++;
701: }
702: if (siso -> siso_tlen || didone) {
703: hexprint (bp, siso -> siso_tlen, TSEL (siso), "'", "'H");
704: bp += strlen (bp);
705: *bp++ = '/';
706: didone++;
707: }
708: hexprint (bp, siso -> siso_nlen, siso -> siso_data, "NS+", "");
709: }
710:
711:
712: static hexprint (bp, n, buf, start, stop)
713: char *bp;
714: int n;
715: u_char *buf;
716: char *start,
717: *stop;
718: {
719: register u_char *in = buf, *top = in + n;
720:
721: if (n == 0)
722: return;
723:
724: (void) strcpy (bp, start);
725: bp += strlen (bp);
726:
727: while (in < top) {
728: (void) sprintf (bp, "%02x", *in++ & 0xff);
729: bp += 2;
730: }
731:
732: (void) strcpy (bp, stop);
733: }
734: #endif
735:
736: /* */
737:
738: static struct printent {
739: int p_family;
740: IFP p_function;
741: } ents[] = {
742: #ifdef TCP
743: AF_INET, inetprint,
744: #endif
745:
746: #ifdef CLTS
747: AF_ISO, isoprint,
748: #endif
749:
750: NULL
751: };
752:
753: static action (s, fd, sock)
754: char *s;
755: int fd;
756: struct sockaddr *sock;
757: {
758: char buffer[BUFSIZ];
759: register struct printent *p;
760:
761: if (!(compat_log -> ll_events & LLOG_TRACE))
762: return;
763:
764: for (p = ents; p -> p_family; p++)
765: if (p -> p_family == sock -> sa_family)
766: break;
767: if (!p -> p_family) {
768: DLOG (compat_log, LLOG_EXCEPTIONS,
769: ("unknown dgram address family 0x%x", sock -> sa_family));
770: return;
771: }
772:
773: (void) (*p -> p_function) (sock, buffer);
774:
775: DLOG (compat_log, LLOG_TRACE, ("%-10.10s %d %s", s, fd, buffer));
776: }
777: #endif
778:
779: #else
780:
781: /* */
782:
783: int dgram_dummy () {}
784:
785: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.