interim support for ISO
[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 *
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
7abf8d65 28static 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
45int supplier = -1; /* process should supply updates */
46extern int gateway;
47
48struct rip *msg = (struct rip *) &packet[sizeof (struct idp)];
49int hup(), fkexit();
50
51main(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
159process(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
194getsocket(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 */
238fkexit()
239{
240 if (fork() == 0)
241 exit(0);
242}