Add define for CCI Power 32 - defined (tahoe)
[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
610b111d 17static char sccsid[] = "@(#)main.c 5.4 (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
4a10c08d
KS
108 addr.sns_family = AF_NS;
109 addr.sns_port = htons(IDPPORT_RIF);
110 s = getsocket(SOCK_DGRAM, 0, &addr);
111 if (s < 0)
112 exit(1);
f6daefea
KS
113 /*
114 * Any extra argument is considered
115 * a tracing log file.
116 */
117 if (argc > 0)
118 traceon(*argv);
119 /*
120 * Collect an initial view of the world by
121 * snooping in the kernel. Then, send a request packet on all
122 * directly connected networks to find out what
123 * everyone else thinks.
124 */
125 rtinit();
126 ifinit();
127 if (supplier < 0)
128 supplier = 0;
129 /* request the state of the world */
130 msg->rip_cmd = htons(RIPCMD_REQUEST);
48681466 131 xnnet(msg->rip_nets[0].rip_dst[0]) = htonl(DSTNETS_ALL);
f6daefea
KS
132 msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY);
133 toall(sendmsg);
134 signal(SIGALRM, timer);
135 signal(SIGHUP, hup);
136 signal(SIGINT, hup);
137 signal(SIGEMT, fkexit);
138 timer();
139
f6daefea 140
610b111d
KS
141 for (;;)
142 process(s);
143
f6daefea
KS
144}
145
146process(fd)
147 int fd;
148{
149 struct sockaddr from;
150 int fromlen = sizeof (from), cc, omask;
151 struct idp *idp = (struct idp *)packet;
152
153 cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen);
154 if (cc <= 0) {
155 if (cc < 0 && errno != EINTR)
610b111d 156 syslog("recvfrom: %m");
f6daefea
KS
157 return;
158 }
610b111d 159 if (tracepackets > 1 && ftrace) {
4a10c08d 160 fprintf(ftrace,"rcv %d bytes on %s ", cc, xns_ntoa(&idp->idp_dna));
48681466 161 fprintf(ftrace," from %s\n", xns_ntoa(&idp->idp_sna));
f6daefea 162 }
610b111d
KS
163
164 if (noteremoterequests && ns_netof(idp->idp_sna) &&
165 ns_netof(idp->idp_sna) != ns_netof(idp->idp_dna)) {
166 syslog(LOG_ERR, "net of interface (%d) != net on ether (%d)!\n", ns_netof(idp->idp_dna), ns_netof(idp->idp_sna));
f6daefea
KS
167 }
168
4a10c08d 169 /* We get the IDP header in front of the RIF packet*/
f6daefea 170 cc -= sizeof (struct idp);
f6daefea
KS
171#define mask(s) (1<<((s)-1))
172 omask = sigblock(mask(SIGALRM));
173 rip_input(&from, cc);
174 sigsetmask(omask);
175}
176
48681466
KS
177getsocket(type, proto, sns)
178 int type, proto;
179 struct sockaddr_ns *sns;
f6daefea 180{
48681466
KS
181 int domain = sns->sns_family;
182 int retry, s, on = 1;
f6daefea
KS
183
184 retry = 1;
48681466 185 while ((s = socket(domain, type, proto)) < 0 && retry) {
610b111d 186 syslog("socket: %m");
f6daefea
KS
187 sleep(5 * retry);
188 retry <<= 1;
189 }
190 if (retry == 0)
191 return (-1);
48681466 192 while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) {
610b111d 193 syslog("bind: %m");
f6daefea
KS
194 sleep(5 * retry);
195 retry <<= 1;
196 }
197 if (retry == 0)
198 return (-1);
48681466
KS
199 if (domain==AF_NS) {
200 struct idp idp;
201 if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
610b111d 202 syslog("setsockopt SEE HEADERS: %m");
48681466
KS
203 exit(1);
204 }
205 idp.idp_pt = NSPROTO_RI;
206 if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) {
610b111d 207 syslog("setsockopt SET HEADER: %m");
48681466
KS
208 exit(1);
209 }
210 }
211 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
610b111d 212 syslog("setsockopt SO_BROADCAST: %m");
48681466
KS
213 exit(1);
214 }
f6daefea
KS
215 return (s);
216}
217
218/*
219 * Fork and exit on EMT-- for profiling.
220 */
221fkexit()
222{
223 if (fork() == 0)
224 exit(0);
225}