date and time created 85/08/16 20:22:41 by sklower
[unix-history] / usr / src / sbin / XNSrouted / main.c
CommitLineData
f6daefea
KS
1#ifndef lint
2static char rcsid[] = "$Header$";
3#endif
4
5/*
6 * XNS Routing Information Protocol Daemon
7 */
8#include "defs.h"
9#include <sys/ioctl.h>
10#include <sys/time.h>
11
12#include <net/if.h>
13
14#include <errno.h>
15#include <nlist.h>
16#include <signal.h>
17
18int supplier = -1; /* process should supply updates */
19extern int gateway;
20
21struct rip *msg = (struct rip *) &packet[sizeof (struct idp)];
22int hup(), fkexit();
23
24main(argc, argv)
25 int argc;
26 char *argv[];
27{
28 struct sockaddr from;
29 u_char retry;
30 int selectbits;
31 struct interface *ifp;
32 extern struct interface *ifnet;
33
34 argv0 = argv;
35 argv++, argc--;
36 while (argc > 0 && **argv == '-') {
37 if (strcmp(*argv, "-s") == 0) {
38 supplier = 1;
39 argv++, argc--;
40 continue;
41 }
42 if (strcmp(*argv, "-q") == 0) {
43 supplier = 0;
44 argv++, argc--;
45 continue;
46 }
47 if (strcmp(*argv, "-t") == 0) {
48 tracepackets++;
49 argv++, argc--;
50 ftrace = stderr;
51 tracing = 1;
52 continue;
53 }
54 if (strcmp(*argv, "-g") == 0) {
55 gateway = 1;
56 argv++, argc--;
57 continue;
58 }
59 if (strcmp(*argv, "-l") == 0) {
60 gateway = -1;
61 argv++, argc--;
62 continue;
63 }
64 fprintf(stderr,
65 "usage: xnsrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ]\n");
66 exit(1);
67 }
68
69#ifndef DEBUG
70 if (!tracepackets) {
71 int t;
72
73 if (fork())
74 exit(0);
75 for (t = 0; t < 20; t++)
76 (void) close(t);
77 (void) open("/", 0);
78 (void) dup2(0, 1);
79 (void) dup2(0, 2);
80 t = open("/dev/tty", 2);
81 if (t >= 0) {
82 ioctl(t, TIOCNOTTY, (char *)0);
83 (void) close(t);
84 }
85 }
86#endif
87 /*
88 * Any extra argument is considered
89 * a tracing log file.
90 */
91 if (argc > 0)
92 traceon(*argv);
93 /*
94 * Collect an initial view of the world by
95 * snooping in the kernel. Then, send a request packet on all
96 * directly connected networks to find out what
97 * everyone else thinks.
98 */
99 rtinit();
100 ifinit();
101 if (supplier < 0)
102 supplier = 0;
103 /* request the state of the world */
104 msg->rip_cmd = htons(RIPCMD_REQUEST);
105 xnnet(msg->rip_nets[0].rip_dst) = htonl(DSTNETS_ALL);
106 msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
107 toall(sendmsg);
108 signal(SIGALRM, timer);
109 signal(SIGHUP, hup);
110 signal(SIGINT, hup);
111 signal(SIGEMT, fkexit);
112 timer();
113
114 /*
115 * Listen for RIF packets on all interfaces
116 */
117 selectbits = 0;
118 for( ifp = ifnet; ifp!=0; ifp = ifp->int_next) {
119 selectbits |= 1 << ifp->int_ripsock[0];
120 selectbits |= 1 << ifp->int_ripsock[1];
121 }
122
123 for (;;) {
124 int ibits;
125 register int n;
126
127 ibits = selectbits;
128 n = select(20, &ibits, 0, 0, 0);
129 if (n < 0) {
130 if(errno != EINTR) {
131 perror("main:select");
132 exit(1);
133 }
134 continue;
135 }
136 for( ifp = ifnet; ifp!=0; ifp = ifp->int_next) {
137 /* take RIF packet off interface */
138 for(n = 0; n < 2; n++)
139 if(ibits & (1 << ifp->int_ripsock[n]))
140 process(ifp->int_ripsock[n]);
141 }
142 }
143}
144
145process(fd)
146 int fd;
147{
148 struct sockaddr from;
149 int fromlen = sizeof (from), cc, omask;
150 struct idp *idp = (struct idp *)packet;
151
152 cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen);
153 if (cc <= 0) {
154 if (cc < 0 && errno != EINTR)
155 perror("recvfrom");
156 return;
157 }
158 /* We get the IDP header in front of the RIF packet*/
159 if (tracepackets > 1) {
160 fprintf(ftrace,"rcv %d bytes on %s ",
161 cc, xns_ntoa(&idp->idp_dst));
162 fprintf(ftrace," from %s\n", xns_ntoa(&idp->idp_src));
163 }
164
165 if (xnnet(idp->idp_src.xn_net) != xnnet(idp->idp_dst.xn_net)) {
166 fprintf(ftrace, "XNSrouted: net of interface (%d) != net on ether (%d)!\n",
167 ntohl(xnnet(idp->idp_dst.xn_net)),
168 ntohs(xnnet(idp->idp_src.xn_net)));
169 }
170
171 cc -= sizeof (struct idp);
172 if (fromlen != sizeof (struct sockaddr_xn))
173 return;
174#define mask(s) (1<<((s)-1))
175 omask = sigblock(mask(SIGALRM));
176 rip_input(&from, cc);
177 sigsetmask(omask);
178}
179
180getsocket(domain, type, proto, sxn)
181 int domain, type, proto;
182 struct sockaddr_xn *sxn;
183{
184 int retry, s;
185
186 retry = 1;
187 while ((s = socket(domain, type, proto, 0)) < 0 && retry) {
188 perror("socket");
189 sleep(5 * retry);
190 retry <<= 1;
191 }
192 if (retry == 0)
193 return (-1);
194 while (bind(s, sxn, sizeof (*sxn), 0) < 0 && retry) {
195 perror("bind");
196 sleep(5 * retry);
197 retry <<= 1;
198 }
199 if (retry == 0)
200 return (-1);
201 return (s);
202}
203
204/*
205 * Fork and exit on EMT-- for profiling.
206 */
207fkexit()
208{
209 if (fork() == 0)
210 exit(0);
211}