use syslog instead of perror, ignore remote requests unless specifically asked,
[unix-history] / usr / src / sbin / XNSrouted / main.c
CommitLineData
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
11char 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
17static 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
34int supplier = -1; /* process should supply updates */
35extern int gateway;
36
37struct rip *msg = (struct rip *) &packet[sizeof (struct idp)];
38int hup(), fkexit();
39
40main(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
148process(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
186getsocket(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 */
230fkexit()
231{
232 if (fork() == 0)
233 exit(0);
234}