|
|
1.1 root 1: /*
2: * Copyright (c) 1985 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * Includes material written at Cornell University by Bill Nesheim
7: * with permission of the author.
8: */
9:
10: #ifndef lint
11: char copyright[] =
12: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
13: All rights reserved.\n";
14: #endif not lint
15:
16: #ifndef lint
17: static char sccsid[] = "@(#)main.c 5.5 (Berkeley) 2/14/86";
18: #endif not lint
19:
20: /*
21: * XNS Routing Information Protocol Daemon
22: */
23: #include "defs.h"
24: #include <sys/ioctl.h>
25: #include <sys/time.h>
26:
27: #include <net/if.h>
28:
29: #include <errno.h>
30: #include <nlist.h>
31: #include <signal.h>
32:
33: int supplier = -1; /* process should supply updates */
34: extern int gateway;
35:
36: struct rip *msg = (struct rip *) &packet[sizeof (struct idp)];
37: int hup(), fkexit();
38:
39: main(argc, argv)
40: int argc;
41: char *argv[];
42: {
43: int cc;
44: struct sockaddr from;
45: u_char retry;
46:
47: argv0 = argv;
48: argv++, argc--;
49: while (argc > 0 && **argv == '-') {
50: if (strcmp(*argv, "-s") == 0) {
51: supplier = 1;
52: argv++, argc--;
53: continue;
54: }
55: if (strcmp(*argv, "-q") == 0) {
56: supplier = 0;
57: argv++, argc--;
58: continue;
59: }
60: if (strcmp(*argv, "-R") == 0) {
61: noteremoterequests++;
62: argv++, argc--;
63: continue;
64: }
65: if (strcmp(*argv, "-t") == 0) {
66: tracepackets++;
67: argv++, argc--;
68: ftrace = stderr;
69: tracing = 1;
70: continue;
71: }
72: if (strcmp(*argv, "-g") == 0) {
73: gateway = 1;
74: argv++, argc--;
75: continue;
76: }
77: if (strcmp(*argv, "-l") == 0) {
78: gateway = -1;
79: argv++, argc--;
80: continue;
81: }
82: fprintf(stderr,
83: "usage: xnsrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ]\n");
84: exit(1);
85: }
86:
87:
88: #ifndef DEBUG
89: if (!tracepackets) {
90: int t;
91:
92: if (fork())
93: exit(0);
94: for (t = 0; t < 20; t++)
95: (void) close(t);
96: (void) open("/", 0);
97: (void) dup2(0, 1);
98: (void) dup2(0, 2);
99: t = open("/dev/tty", 2);
100: if (t >= 0) {
101: ioctl(t, TIOCNOTTY, (char *)0);
102: (void) close(t);
103: }
104: }
105: #endif
106: openlog("XNSrouted", LOG_PID, LOG_DAEMON);
107:
108: ns_anynet.s_net[0] = -1; ns_anynet.s_net[1] = -1;
109: addr.sns_family = AF_NS;
110: addr.sns_port = htons(IDPPORT_RIF);
111: s = getsocket(SOCK_DGRAM, 0, &addr);
112: if (s < 0)
113: exit(1);
114: /*
115: * Any extra argument is considered
116: * a tracing log file.
117: */
118: if (argc > 0)
119: traceon(*argv);
120: /*
121: * Collect an initial view of the world by
122: * snooping in the kernel. Then, send a request packet on all
123: * directly connected networks to find out what
124: * everyone else thinks.
125: */
126: rtinit();
127: ifinit();
128: if (supplier < 0)
129: supplier = 0;
130: /* request the state of the world */
131: msg->rip_cmd = htons(RIPCMD_REQUEST);
132: msg->rip_nets[0].rip_dst = ns_anynet;
133: msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
134: toall(sendmsg);
135: signal(SIGALRM, timer);
136: signal(SIGHUP, hup);
137: signal(SIGINT, hup);
138: signal(SIGEMT, fkexit);
139: timer();
140:
141:
142: for (;;)
143: process(s);
144:
145: }
146:
147: process(fd)
148: int fd;
149: {
150: struct sockaddr from;
151: int fromlen = sizeof (from), cc, omask;
152: struct idp *idp = (struct idp *)packet;
153:
154: cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen);
155: if (cc <= 0) {
156: if (cc < 0 && errno != EINTR)
157: syslog("recvfrom: %m");
158: return;
159: }
160: if (tracepackets > 1 && ftrace) {
161: fprintf(ftrace,"rcv %d bytes on %s ", cc, xns_ntoa(&idp->idp_dna));
162: fprintf(ftrace," from %s\n", xns_ntoa(&idp->idp_sna));
163: }
164:
165: if (noteremoterequests && !ns_neteqnn(idp->idp_sna.x_net, ns_zeronet)
166: && !ns_neteq(idp->idp_sna, idp->idp_dna))
167: {
168: syslog(LOG_ERR,
169: "net of interface (%s) != net on ether (%s)!\n",
170: xns_nettoa(idp->idp_dna.x_net),
171: xns_nettoa(idp->idp_sna.x_net));
172: }
173:
174: /* We get the IDP header in front of the RIF packet*/
175: cc -= sizeof (struct idp);
176: #define mask(s) (1<<((s)-1))
177: omask = sigblock(mask(SIGALRM));
178: rip_input(&from, cc);
179: sigsetmask(omask);
180: }
181:
182: getsocket(type, proto, sns)
183: int type, proto;
184: struct sockaddr_ns *sns;
185: {
186: int domain = sns->sns_family;
187: int retry, s, on = 1;
188:
189: retry = 1;
190: while ((s = socket(domain, type, proto)) < 0 && retry) {
191: syslog("socket: %m");
192: sleep(5 * retry);
193: retry <<= 1;
194: }
195: if (retry == 0)
196: return (-1);
197: while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
198: syslog("bind: %m");
199: sleep(5 * retry);
200: retry <<= 1;
201: }
202: if (retry == 0)
203: return (-1);
204: if (domain==AF_NS) {
205: struct idp idp;
206: if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
207: syslog("setsockopt SEE HEADERS: %m");
208: exit(1);
209: }
210: idp.idp_pt = NSPROTO_RI;
211: if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
212: syslog("setsockopt SET HEADER: %m");
213: exit(1);
214: }
215: }
216: if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
217: syslog("setsockopt SO_BROADCAST: %m");
218: exit(1);
219: }
220: return (s);
221: }
222:
223: /*
224: * Fork and exit on EMT-- for profiling.
225: */
226: fkexit()
227: {
228: if (fork() == 0)
229: exit(0);
230: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.