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 | * | |
6ecf3d85 | 8 | * %sccs.include.redist.c% |
4a10c08d KS |
9 | */ |
10 | ||
f6daefea | 11 | #ifndef lint |
4a10c08d | 12 | char copyright[] = |
3565c602 | 13 | "@(#) Copyright (c) 1985 The Regents of the University of California.\n\ |
4a10c08d | 14 | All rights reserved.\n"; |
3565c602 | 15 | #endif /* not lint */ |
4a10c08d KS |
16 | |
17 | #ifndef lint | |
b6a2f0a4 | 18 | static char sccsid[] = "@(#)main.c 5.11 (Berkeley) %G%"; |
3565c602 | 19 | #endif /* not lint */ |
f6daefea KS |
20 | |
21 | /* | |
22 | * XNS Routing Information Protocol Daemon | |
23 | */ | |
24 | #include "defs.h" | |
f6daefea KS |
25 | #include <sys/time.h> |
26 | ||
27 | #include <net/if.h> | |
28 | ||
29 | #include <errno.h> | |
30 | #include <nlist.h> | |
31 | #include <signal.h> | |
7abf8d65 | 32 | #include <paths.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)]; | |
b6a2f0a4 | 38 | void hup(), fkexit(), timer(); |
f6daefea KS |
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 | } | |
610b111d KS |
61 | if (strcmp(*argv, "-R") == 0) { |
62 | noteremoterequests++; | |
63 | argv++, argc--; | |
64 | continue; | |
65 | } | |
f6daefea KS |
66 | if (strcmp(*argv, "-t") == 0) { |
67 | tracepackets++; | |
68 | argv++, argc--; | |
69 | ftrace = stderr; | |
70 | tracing = 1; | |
71 | continue; | |
72 | } | |
73 | if (strcmp(*argv, "-g") == 0) { | |
74 | gateway = 1; | |
75 | argv++, argc--; | |
76 | continue; | |
77 | } | |
78 | if (strcmp(*argv, "-l") == 0) { | |
79 | gateway = -1; | |
80 | argv++, argc--; | |
81 | continue; | |
82 | } | |
83 | fprintf(stderr, | |
84 | "usage: xnsrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ]\n"); | |
85 | exit(1); | |
86 | } | |
87 | ||
610b111d | 88 | |
f6daefea | 89 | #ifndef DEBUG |
43d42ac6 MK |
90 | if (!tracepackets) |
91 | daemon(0, 0); | |
f6daefea | 92 | #endif |
610b111d KS |
93 | openlog("XNSrouted", LOG_PID, LOG_DAEMON); |
94 | ||
84f93e8f | 95 | ns_anynet.s_net[0] = -1; ns_anynet.s_net[1] = -1; |
4a10c08d | 96 | addr.sns_family = AF_NS; |
0b7e1339 | 97 | addr.sns_len = sizeof(addr); |
4a10c08d KS |
98 | addr.sns_port = htons(IDPPORT_RIF); |
99 | s = getsocket(SOCK_DGRAM, 0, &addr); | |
100 | if (s < 0) | |
101 | exit(1); | |
f6daefea KS |
102 | /* |
103 | * Any extra argument is considered | |
104 | * a tracing log file. | |
105 | */ | |
106 | if (argc > 0) | |
107 | traceon(*argv); | |
108 | /* | |
109 | * Collect an initial view of the world by | |
110 | * snooping in the kernel. Then, send a request packet on all | |
111 | * directly connected networks to find out what | |
112 | * everyone else thinks. | |
113 | */ | |
114 | rtinit(); | |
115 | ifinit(); | |
116 | if (supplier < 0) | |
117 | supplier = 0; | |
118 | /* request the state of the world */ | |
119 | msg->rip_cmd = htons(RIPCMD_REQUEST); | |
84f93e8f | 120 | msg->rip_nets[0].rip_dst = ns_anynet; |
f6daefea | 121 | msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); |
b6a2f0a4 | 122 | toall(sndmsg); |
f6daefea KS |
123 | signal(SIGALRM, timer); |
124 | signal(SIGHUP, hup); | |
125 | signal(SIGINT, hup); | |
126 | signal(SIGEMT, fkexit); | |
127 | timer(); | |
128 | ||
f6daefea | 129 | |
610b111d KS |
130 | for (;;) |
131 | process(s); | |
132 | ||
f6daefea KS |
133 | } |
134 | ||
135 | process(fd) | |
136 | int fd; | |
137 | { | |
138 | struct sockaddr from; | |
139 | int fromlen = sizeof (from), cc, omask; | |
140 | struct idp *idp = (struct idp *)packet; | |
141 | ||
142 | cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen); | |
143 | if (cc <= 0) { | |
144 | if (cc < 0 && errno != EINTR) | |
b6a2f0a4 | 145 | syslog(LOG_ERR, "recvfrom: %m"); |
f6daefea KS |
146 | return; |
147 | } | |
610b111d | 148 | if (tracepackets > 1 && ftrace) { |
4a10c08d | 149 | fprintf(ftrace,"rcv %d bytes on %s ", cc, xns_ntoa(&idp->idp_dna)); |
48681466 | 150 | fprintf(ftrace," from %s\n", xns_ntoa(&idp->idp_sna)); |
f6daefea | 151 | } |
610b111d | 152 | |
84f93e8f KS |
153 | if (noteremoterequests && !ns_neteqnn(idp->idp_sna.x_net, ns_zeronet) |
154 | && !ns_neteq(idp->idp_sna, idp->idp_dna)) | |
155 | { | |
156 | syslog(LOG_ERR, | |
157 | "net of interface (%s) != net on ether (%s)!\n", | |
158 | xns_nettoa(idp->idp_dna.x_net), | |
159 | xns_nettoa(idp->idp_sna.x_net)); | |
f6daefea KS |
160 | } |
161 | ||
4a10c08d | 162 | /* We get the IDP header in front of the RIF packet*/ |
f6daefea | 163 | cc -= sizeof (struct idp); |
f6daefea KS |
164 | #define mask(s) (1<<((s)-1)) |
165 | omask = sigblock(mask(SIGALRM)); | |
166 | rip_input(&from, cc); | |
167 | sigsetmask(omask); | |
168 | } | |
169 | ||
48681466 KS |
170 | getsocket(type, proto, sns) |
171 | int type, proto; | |
172 | struct sockaddr_ns *sns; | |
f6daefea | 173 | { |
48681466 KS |
174 | int domain = sns->sns_family; |
175 | int retry, s, on = 1; | |
f6daefea KS |
176 | |
177 | retry = 1; | |
48681466 | 178 | while ((s = socket(domain, type, proto)) < 0 && retry) { |
b6a2f0a4 | 179 | syslog(LOG_ERR, "socket: %m"); |
f6daefea KS |
180 | sleep(5 * retry); |
181 | retry <<= 1; | |
182 | } | |
183 | if (retry == 0) | |
184 | return (-1); | |
b6a2f0a4 KB |
185 | while (bind(s, (struct sockaddr *)sns, sizeof (*sns)) < 0 && retry) { |
186 | syslog(LOG_ERR, "bind: %m"); | |
f6daefea KS |
187 | sleep(5 * retry); |
188 | retry <<= 1; | |
189 | } | |
190 | if (retry == 0) | |
191 | return (-1); | |
48681466 KS |
192 | if (domain==AF_NS) { |
193 | struct idp idp; | |
194 | if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) { | |
b6a2f0a4 | 195 | syslog(LOG_ERR, "setsockopt SEE HEADERS: %m"); |
48681466 KS |
196 | exit(1); |
197 | } | |
198 | idp.idp_pt = NSPROTO_RI; | |
199 | if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) { | |
b6a2f0a4 | 200 | syslog(LOG_ERR, "setsockopt SET HEADER: %m"); |
48681466 KS |
201 | exit(1); |
202 | } | |
203 | } | |
204 | if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { | |
b6a2f0a4 | 205 | syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); |
48681466 KS |
206 | exit(1); |
207 | } | |
f6daefea KS |
208 | return (s); |
209 | } | |
210 | ||
211 | /* | |
212 | * Fork and exit on EMT-- for profiling. | |
213 | */ | |
b6a2f0a4 | 214 | void |
f6daefea KS |
215 | fkexit() |
216 | { | |
217 | if (fork() == 0) | |
218 | exit(0); | |
219 | } |