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