checkpoint of hacking for mail.cs.berkeley.edu
[unix-history] / usr / src / sbin / 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 *
6ecf3d85 8 * %sccs.include.redist.c%
4a10c08d
KS
9 */
10
f6daefea 11#ifndef lint
4a10c08d 12char 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 18static 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
34int supplier = -1; /* process should supply updates */
35extern int gateway;
36
37struct rip *msg = (struct rip *) &packet[sizeof (struct idp)];
b6a2f0a4 38void hup(), fkexit(), timer();
f6daefea
KS
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 }
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
135process(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
170getsocket(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 214void
f6daefea
KS
215fkexit()
216{
217 if (fork() == 0)
218 exit(0);
219}