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