Commit | Line | Data |
---|---|---|
4a10c08d KS |
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 | ||
f6daefea | 10 | #ifndef lint |
4a10c08d KS |
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.3 (Berkeley) %G%"; | |
18 | #endif not lint | |
f6daefea KS |
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> | |
48681466 | 32 | #include <syslog.h> |
f6daefea KS |
33 | |
34 | int supplier = -1; /* process should supply updates */ | |
35 | extern int gateway; | |
36 | ||
37 | struct rip *msg = (struct rip *) &packet[sizeof (struct idp)]; | |
38 | int hup(), fkexit(); | |
39 | ||
40 | main(argc, argv) | |
41 | int argc; | |
42 | char *argv[]; | |
43 | { | |
48681466 | 44 | int cc; |
f6daefea KS |
45 | struct sockaddr from; |
46 | u_char retry; | |
f6daefea KS |
47 | |
48 | argv0 = argv; | |
49 | argv++, argc--; | |
50 | while (argc > 0 && **argv == '-') { | |
51 | if (strcmp(*argv, "-s") == 0) { | |
52 | supplier = 1; | |
53 | argv++, argc--; | |
54 | continue; | |
55 | } | |
56 | if (strcmp(*argv, "-q") == 0) { | |
57 | supplier = 0; | |
58 | argv++, argc--; | |
59 | continue; | |
60 | } | |
61 | if (strcmp(*argv, "-t") == 0) { | |
62 | tracepackets++; | |
63 | argv++, argc--; | |
64 | ftrace = stderr; | |
65 | tracing = 1; | |
66 | continue; | |
67 | } | |
68 | if (strcmp(*argv, "-g") == 0) { | |
69 | gateway = 1; | |
70 | argv++, argc--; | |
71 | continue; | |
72 | } | |
73 | if (strcmp(*argv, "-l") == 0) { | |
74 | gateway = -1; | |
75 | argv++, argc--; | |
76 | continue; | |
77 | } | |
78 | fprintf(stderr, | |
79 | "usage: xnsrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ]\n"); | |
80 | exit(1); | |
81 | } | |
82 | ||
83 | #ifndef DEBUG | |
84 | if (!tracepackets) { | |
85 | int t; | |
86 | ||
87 | if (fork()) | |
88 | exit(0); | |
89 | for (t = 0; t < 20; t++) | |
90 | (void) close(t); | |
91 | (void) open("/", 0); | |
92 | (void) dup2(0, 1); | |
93 | (void) dup2(0, 2); | |
94 | t = open("/dev/tty", 2); | |
95 | if (t >= 0) { | |
96 | ioctl(t, TIOCNOTTY, (char *)0); | |
97 | (void) close(t); | |
98 | } | |
99 | } | |
100 | #endif | |
4a10c08d KS |
101 | addr.sns_family = AF_NS; |
102 | addr.sns_port = htons(IDPPORT_RIF); | |
103 | s = getsocket(SOCK_DGRAM, 0, &addr); | |
104 | if (s < 0) | |
105 | exit(1); | |
f6daefea KS |
106 | /* |
107 | * Any extra argument is considered | |
108 | * a tracing log file. | |
109 | */ | |
110 | if (argc > 0) | |
111 | traceon(*argv); | |
112 | /* | |
113 | * Collect an initial view of the world by | |
114 | * snooping in the kernel. Then, send a request packet on all | |
115 | * directly connected networks to find out what | |
116 | * everyone else thinks. | |
117 | */ | |
118 | rtinit(); | |
119 | ifinit(); | |
120 | if (supplier < 0) | |
121 | supplier = 0; | |
122 | /* request the state of the world */ | |
123 | msg->rip_cmd = htons(RIPCMD_REQUEST); | |
48681466 | 124 | xnnet(msg->rip_nets[0].rip_dst[0]) = htonl(DSTNETS_ALL); |
f6daefea KS |
125 | msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); |
126 | toall(sendmsg); | |
127 | signal(SIGALRM, timer); | |
128 | signal(SIGHUP, hup); | |
129 | signal(SIGINT, hup); | |
130 | signal(SIGEMT, fkexit); | |
131 | timer(); | |
132 | ||
f6daefea KS |
133 | |
134 | for (;;) { | |
135 | int ibits; | |
136 | register int n; | |
137 | ||
48681466 | 138 | /*ibits = 1 << s; |
f6daefea | 139 | n = select(20, &ibits, 0, 0, 0); |
48681466 | 140 | if (n < 0) |
f6daefea | 141 | continue; |
48681466 KS |
142 | if (ibits & (1 << s)) */ |
143 | process(s); | |
144 | /* handle ICMP redirects */ | |
f6daefea KS |
145 | } |
146 | } | |
147 | ||
148 | process(fd) | |
149 | int fd; | |
150 | { | |
151 | struct sockaddr from; | |
152 | int fromlen = sizeof (from), cc, omask; | |
153 | struct idp *idp = (struct idp *)packet; | |
154 | ||
155 | cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen); | |
156 | if (cc <= 0) { | |
157 | if (cc < 0 && errno != EINTR) | |
158 | perror("recvfrom"); | |
159 | return; | |
160 | } | |
f6daefea | 161 | if (tracepackets > 1) { |
4a10c08d | 162 | fprintf(ftrace,"rcv %d bytes on %s ", cc, xns_ntoa(&idp->idp_dna)); |
48681466 | 163 | fprintf(ftrace," from %s\n", xns_ntoa(&idp->idp_sna)); |
f6daefea | 164 | } |
4a10c08d KS |
165 | if (tracepackets > 0) { |
166 | if (ns_netof(idp->idp_sna) != ns_netof(idp->idp_dna)) { | |
167 | fprintf(ftrace, | |
168 | "XNSrouted: net of interface (%d) ", | |
169 | ns_netof(idp->idp_dna)); | |
170 | fprintf(ftrace, | |
171 | "!= net on ether (%d)!\n", ns_netof(idp->idp_sna)); | |
172 | } | |
173 | if (fromlen != sizeof (struct sockaddr_ns)) | |
174 | fprintf(ftrace, "fromlen is %d instead of %d\n", | |
175 | fromlen, sizeof (struct sockaddr_ns)); | |
f6daefea KS |
176 | } |
177 | ||
4a10c08d | 178 | /* We get the IDP header in front of the RIF packet*/ |
f6daefea | 179 | cc -= sizeof (struct idp); |
f6daefea KS |
180 | #define mask(s) (1<<((s)-1)) |
181 | omask = sigblock(mask(SIGALRM)); | |
182 | rip_input(&from, cc); | |
183 | sigsetmask(omask); | |
184 | } | |
185 | ||
48681466 KS |
186 | getsocket(type, proto, sns) |
187 | int type, proto; | |
188 | struct sockaddr_ns *sns; | |
f6daefea | 189 | { |
48681466 KS |
190 | int domain = sns->sns_family; |
191 | int retry, s, on = 1; | |
f6daefea KS |
192 | |
193 | retry = 1; | |
48681466 | 194 | while ((s = socket(domain, type, proto)) < 0 && retry) { |
f6daefea KS |
195 | perror("socket"); |
196 | sleep(5 * retry); | |
197 | retry <<= 1; | |
198 | } | |
199 | if (retry == 0) | |
200 | return (-1); | |
48681466 | 201 | while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) { |
f6daefea KS |
202 | perror("bind"); |
203 | sleep(5 * retry); | |
204 | retry <<= 1; | |
205 | } | |
206 | if (retry == 0) | |
207 | return (-1); | |
48681466 KS |
208 | if (domain==AF_NS) { |
209 | struct idp idp; | |
210 | if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) { | |
211 | perror("setsockopt SEE HEADERS"); | |
212 | exit(1); | |
213 | } | |
214 | idp.idp_pt = NSPROTO_RI; | |
215 | if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) { | |
216 | perror("setsockopt SET HEADERS"); | |
217 | exit(1); | |
218 | } | |
219 | } | |
220 | if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { | |
221 | perror("setsockopt SO_BROADCAST"); | |
222 | exit(1); | |
223 | } | |
f6daefea KS |
224 | return (s); |
225 | } | |
226 | ||
227 | /* | |
228 | * Fork and exit on EMT-- for profiling. | |
229 | */ | |
230 | fkexit() | |
231 | { | |
232 | if (fork() == 0) | |
233 | exit(0); | |
234 | } |