Commit | Line | Data |
---|---|---|
4a10c08d | 1 | /* |
3565c602 KB |
2 | * Copyright (c) 1985 The Regents of the University of California. |
3 | * All rights reserved. | |
4a10c08d | 4 | * |
3565c602 KB |
5 | * This file includes significant work done at Cornell University by |
6 | * Bill Nesheim. That work included by permission. | |
7 | * | |
8 | * Redistribution and use in source and binary forms are permitted | |
9 | * provided that the above copyright notice and this paragraph are | |
10 | * duplicated in all such forms and that any documentation, | |
11 | * advertising materials, and other materials related to such | |
12 | * distribution and use acknowledge that the software was developed | |
13 | * by the University of California, Berkeley. The name of the | |
14 | * University may not be used to endorse or promote products derived | |
15 | * from this software without specific prior written permission. | |
16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
17 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
18 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
4a10c08d KS |
19 | */ |
20 | ||
f6daefea | 21 | #ifndef lint |
4a10c08d | 22 | char copyright[] = |
3565c602 | 23 | "@(#) Copyright (c) 1985 The Regents of the University of California.\n\ |
4a10c08d | 24 | All rights reserved.\n"; |
3565c602 | 25 | #endif /* not lint */ |
4a10c08d KS |
26 | |
27 | #ifndef lint | |
7abf8d65 | 28 | static char sccsid[] = "@(#)main.c 5.7 (Berkeley) %G%"; |
3565c602 | 29 | #endif /* not lint */ |
f6daefea KS |
30 | |
31 | /* | |
32 | * XNS Routing Information Protocol Daemon | |
33 | */ | |
34 | #include "defs.h" | |
35 | #include <sys/ioctl.h> | |
36 | #include <sys/time.h> | |
37 | ||
38 | #include <net/if.h> | |
39 | ||
40 | #include <errno.h> | |
41 | #include <nlist.h> | |
42 | #include <signal.h> | |
7abf8d65 | 43 | #include <paths.h> |
f6daefea KS |
44 | |
45 | int supplier = -1; /* process should supply updates */ | |
46 | extern int gateway; | |
47 | ||
48 | struct rip *msg = (struct rip *) &packet[sizeof (struct idp)]; | |
49 | int hup(), fkexit(); | |
50 | ||
51 | main(argc, argv) | |
52 | int argc; | |
53 | char *argv[]; | |
54 | { | |
48681466 | 55 | int cc; |
f6daefea KS |
56 | struct sockaddr from; |
57 | u_char retry; | |
f6daefea KS |
58 | |
59 | argv0 = argv; | |
60 | argv++, argc--; | |
61 | while (argc > 0 && **argv == '-') { | |
62 | if (strcmp(*argv, "-s") == 0) { | |
63 | supplier = 1; | |
64 | argv++, argc--; | |
65 | continue; | |
66 | } | |
67 | if (strcmp(*argv, "-q") == 0) { | |
68 | supplier = 0; | |
69 | argv++, argc--; | |
70 | continue; | |
71 | } | |
610b111d KS |
72 | if (strcmp(*argv, "-R") == 0) { |
73 | noteremoterequests++; | |
74 | argv++, argc--; | |
75 | continue; | |
76 | } | |
f6daefea KS |
77 | if (strcmp(*argv, "-t") == 0) { |
78 | tracepackets++; | |
79 | argv++, argc--; | |
80 | ftrace = stderr; | |
81 | tracing = 1; | |
82 | continue; | |
83 | } | |
84 | if (strcmp(*argv, "-g") == 0) { | |
85 | gateway = 1; | |
86 | argv++, argc--; | |
87 | continue; | |
88 | } | |
89 | if (strcmp(*argv, "-l") == 0) { | |
90 | gateway = -1; | |
91 | argv++, argc--; | |
92 | continue; | |
93 | } | |
94 | fprintf(stderr, | |
95 | "usage: xnsrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ]\n"); | |
96 | exit(1); | |
97 | } | |
98 | ||
610b111d | 99 | |
f6daefea KS |
100 | #ifndef DEBUG |
101 | if (!tracepackets) { | |
102 | int t; | |
103 | ||
104 | if (fork()) | |
105 | exit(0); | |
106 | for (t = 0; t < 20; t++) | |
107 | (void) close(t); | |
108 | (void) open("/", 0); | |
109 | (void) dup2(0, 1); | |
110 | (void) dup2(0, 2); | |
7abf8d65 | 111 | t = open(_PATH_TTY, 2); |
f6daefea KS |
112 | if (t >= 0) { |
113 | ioctl(t, TIOCNOTTY, (char *)0); | |
114 | (void) close(t); | |
115 | } | |
116 | } | |
117 | #endif | |
610b111d KS |
118 | openlog("XNSrouted", LOG_PID, LOG_DAEMON); |
119 | ||
84f93e8f | 120 | ns_anynet.s_net[0] = -1; ns_anynet.s_net[1] = -1; |
4a10c08d KS |
121 | addr.sns_family = AF_NS; |
122 | addr.sns_port = htons(IDPPORT_RIF); | |
123 | s = getsocket(SOCK_DGRAM, 0, &addr); | |
124 | if (s < 0) | |
125 | exit(1); | |
f6daefea KS |
126 | /* |
127 | * Any extra argument is considered | |
128 | * a tracing log file. | |
129 | */ | |
130 | if (argc > 0) | |
131 | traceon(*argv); | |
132 | /* | |
133 | * Collect an initial view of the world by | |
134 | * snooping in the kernel. Then, send a request packet on all | |
135 | * directly connected networks to find out what | |
136 | * everyone else thinks. | |
137 | */ | |
138 | rtinit(); | |
139 | ifinit(); | |
140 | if (supplier < 0) | |
141 | supplier = 0; | |
142 | /* request the state of the world */ | |
143 | msg->rip_cmd = htons(RIPCMD_REQUEST); | |
84f93e8f | 144 | msg->rip_nets[0].rip_dst = ns_anynet; |
f6daefea KS |
145 | msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); |
146 | toall(sendmsg); | |
147 | signal(SIGALRM, timer); | |
148 | signal(SIGHUP, hup); | |
149 | signal(SIGINT, hup); | |
150 | signal(SIGEMT, fkexit); | |
151 | timer(); | |
152 | ||
f6daefea | 153 | |
610b111d KS |
154 | for (;;) |
155 | process(s); | |
156 | ||
f6daefea KS |
157 | } |
158 | ||
159 | process(fd) | |
160 | int fd; | |
161 | { | |
162 | struct sockaddr from; | |
163 | int fromlen = sizeof (from), cc, omask; | |
164 | struct idp *idp = (struct idp *)packet; | |
165 | ||
166 | cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen); | |
167 | if (cc <= 0) { | |
168 | if (cc < 0 && errno != EINTR) | |
610b111d | 169 | syslog("recvfrom: %m"); |
f6daefea KS |
170 | return; |
171 | } | |
610b111d | 172 | if (tracepackets > 1 && ftrace) { |
4a10c08d | 173 | fprintf(ftrace,"rcv %d bytes on %s ", cc, xns_ntoa(&idp->idp_dna)); |
48681466 | 174 | fprintf(ftrace," from %s\n", xns_ntoa(&idp->idp_sna)); |
f6daefea | 175 | } |
610b111d | 176 | |
84f93e8f KS |
177 | if (noteremoterequests && !ns_neteqnn(idp->idp_sna.x_net, ns_zeronet) |
178 | && !ns_neteq(idp->idp_sna, idp->idp_dna)) | |
179 | { | |
180 | syslog(LOG_ERR, | |
181 | "net of interface (%s) != net on ether (%s)!\n", | |
182 | xns_nettoa(idp->idp_dna.x_net), | |
183 | xns_nettoa(idp->idp_sna.x_net)); | |
f6daefea KS |
184 | } |
185 | ||
4a10c08d | 186 | /* We get the IDP header in front of the RIF packet*/ |
f6daefea | 187 | cc -= sizeof (struct idp); |
f6daefea KS |
188 | #define mask(s) (1<<((s)-1)) |
189 | omask = sigblock(mask(SIGALRM)); | |
190 | rip_input(&from, cc); | |
191 | sigsetmask(omask); | |
192 | } | |
193 | ||
48681466 KS |
194 | getsocket(type, proto, sns) |
195 | int type, proto; | |
196 | struct sockaddr_ns *sns; | |
f6daefea | 197 | { |
48681466 KS |
198 | int domain = sns->sns_family; |
199 | int retry, s, on = 1; | |
f6daefea KS |
200 | |
201 | retry = 1; | |
48681466 | 202 | while ((s = socket(domain, type, proto)) < 0 && retry) { |
610b111d | 203 | syslog("socket: %m"); |
f6daefea KS |
204 | sleep(5 * retry); |
205 | retry <<= 1; | |
206 | } | |
207 | if (retry == 0) | |
208 | return (-1); | |
48681466 | 209 | while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) { |
610b111d | 210 | syslog("bind: %m"); |
f6daefea KS |
211 | sleep(5 * retry); |
212 | retry <<= 1; | |
213 | } | |
214 | if (retry == 0) | |
215 | return (-1); | |
48681466 KS |
216 | if (domain==AF_NS) { |
217 | struct idp idp; | |
218 | if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) { | |
610b111d | 219 | syslog("setsockopt SEE HEADERS: %m"); |
48681466 KS |
220 | exit(1); |
221 | } | |
222 | idp.idp_pt = NSPROTO_RI; | |
223 | if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) { | |
610b111d | 224 | syslog("setsockopt SET HEADER: %m"); |
48681466 KS |
225 | exit(1); |
226 | } | |
227 | } | |
228 | if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { | |
610b111d | 229 | syslog("setsockopt SO_BROADCAST: %m"); |
48681466 KS |
230 | exit(1); |
231 | } | |
f6daefea KS |
232 | return (s); |
233 | } | |
234 | ||
235 | /* | |
236 | * Fork and exit on EMT-- for profiling. | |
237 | */ | |
238 | fkexit() | |
239 | { | |
240 | if (fork() == 0) | |
241 | exit(0); | |
242 | } |