turn COMPAT off
[unix-history] / usr / src / sbin / routed / main.c
CommitLineData
fdd0ed12 1#ifndef lint
5562f0a3 2static char sccsid[] = "@(#)main.c 4.10 (Berkeley) %G%";
fdd0ed12
SL
3#endif
4
5/*
6 * Routing Table Management Daemon
7 */
7fe7fe74 8#include "defs.h"
fdd0ed12 9#include <sys/ioctl.h>
e2feeea9
SL
10#include <sys/time.h>
11
fdd0ed12 12#include <net/if.h>
e2feeea9 13
fdd0ed12
SL
14#include <errno.h>
15#include <nlist.h>
16#include <signal.h>
fdd0ed12
SL
17
18int supplier = -1; /* process should supply updates */
5562f0a3 19extern int gateway;
fdd0ed12
SL
20
21struct rip *msg = (struct rip *)packet;
b7e4f8be 22int hup();
fdd0ed12
SL
23
24main(argc, argv)
25 int argc;
26 char *argv[];
27{
28 int cc;
29 struct sockaddr from;
7fe7fe74
SL
30 u_char retry;
31#ifdef COMPAT
32 int snoroute;
33#endif
fdd0ed12
SL
34
35 argv0 = argv;
fdd0ed12 36 sp = getservbyname("router", "udp");
7fe7fe74
SL
37 if (sp == NULL) {
38 fprintf(stderr, "routed: router/udp: unknown service\n");
fdd0ed12
SL
39 exit(1);
40 }
7fe7fe74
SL
41 addr.sin_family = AF_INET;
42 addr.sin_port = sp->s_port;
43 s = getsocket(AF_INET, SOCK_DGRAM, &addr);
44 if (s < 0)
45 exit(1);
46#ifdef COMPAT
47 bzero(&addr, sizeof (addr));
48 addr.sin_family = AF_INET;
49 addr.sin_port = htons(ntohs(sp->s_port) + 1);
50 snoroute = getsocket(AF_INET, SOCK_DGRAM, &addr);
51 if (snoroute < 0)
52 exit(1);
53#endif
fdd0ed12
SL
54 argv++, argc--;
55 while (argc > 0 && **argv == '-') {
d4b6a849 56 if (strcmp(*argv, "-s") == 0) {
fdd0ed12
SL
57 supplier = 1;
58 argv++, argc--;
59 continue;
60 }
d4b6a849 61 if (strcmp(*argv, "-q") == 0) {
fdd0ed12
SL
62 supplier = 0;
63 argv++, argc--;
64 continue;
65 }
d4b6a849
SL
66 if (strcmp(*argv, "-t") == 0) {
67 tracepackets++;
68 argv++, argc--;
69 continue;
70 }
5562f0a3
MK
71 if (strcmp(*argv, "-g") == 0) {
72 gateway = 1;
73 argv++, argc--;
74 continue;
75 }
76 if (strcmp(*argv, "-l") == 0) {
77 gateway = -1;
78 argv++, argc--;
79 continue;
80 }
81 fprintf(stderr,
82 "usage: routed [ -s ] [ -q ] [ -t ] [ -g ] [ -l ]\n");
fdd0ed12
SL
83 exit(1);
84 }
d4b6a849
SL
85#ifndef DEBUG
86 if (!tracepackets) {
87 int t;
88
89 if (fork())
90 exit(0);
7620381d
SL
91 for (t = 0; t < 20; t++)
92 if (t != s)
93#ifdef COMPAT
55d340a4 94 if (t != snoroute)
7620381d
SL
95#endif
96 (void) close(cc);
d4b6a849
SL
97 (void) open("/", 0);
98 (void) dup2(0, 1);
99 (void) dup2(0, 2);
100 t = open("/dev/tty", 2);
101 if (t >= 0) {
102 ioctl(t, TIOCNOTTY, (char *)0);
103 (void) close(t);
104 }
105 }
106#endif
7fe7fe74
SL
107 /*
108 * Any extra argument is considered
109 * a tracing log file.
110 */
111 if (argc > 0)
112 traceon(*argv);
fdd0ed12
SL
113 /*
114 * Collect an initial view of the world by
115 * snooping in the kernel and the gateway kludge
116 * file. Then, send a request packet on all
117 * directly connected networks to find out what
118 * everyone else thinks.
119 */
120 rtinit();
121 gwkludge();
122 ifinit();
123 if (supplier < 0)
124 supplier = 0;
125 msg->rip_cmd = RIPCMD_REQUEST;
55d340a4 126 msg->rip_vers = RIPVERSION;
fdd0ed12
SL
127 msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
128 msg->rip_nets[0].rip_metric = HOPCNT_INFINITY;
55d340a4
SL
129 msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC);
130 msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY);
fdd0ed12 131 toall(sendmsg);
ce5e9df4 132 signal(SIGALRM, timer);
b7e4f8be 133 signal(SIGHUP, hup);
fdd0ed12
SL
134 timer();
135
fdd0ed12
SL
136 for (;;) {
137 int ibits;
138 register int n;
139
7fe7fe74
SL
140 ibits = 1 << s;
141#ifdef COMPAT
142 ibits |= 1 << snoroute;
143#endif
144 n = select(20, &ibits, 0, 0, 0);
fdd0ed12
SL
145 if (n < 0)
146 continue;
147 if (ibits & (1 << s))
148 process(s);
7fe7fe74 149#ifdef COMPAT
fdd0ed12
SL
150 if (ibits & (1 << snoroute))
151 process(snoroute);
7fe7fe74
SL
152#endif
153 /* handle ICMP redirects */
fdd0ed12
SL
154 }
155}
156
157process(fd)
158 int fd;
159{
fdd0ed12 160 struct sockaddr from;
ce5e9df4 161 int fromlen = sizeof (from), cc, omask;
fdd0ed12 162
7fe7fe74 163 cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen);
fdd0ed12
SL
164 if (cc <= 0) {
165 if (cc < 0 && errno != EINTR)
7fe7fe74 166 perror("recvfrom");
fdd0ed12
SL
167 return;
168 }
7fe7fe74
SL
169 if (fromlen != sizeof (struct sockaddr_in))
170 return;
ce5e9df4
SL
171#define mask(s) (1<<((s)-1))
172 omask = sigblock(mask(SIGALRM));
fdd0ed12 173 rip_input(&from, cc);
ce5e9df4 174 sigsetmask(omask);
fdd0ed12 175}
7fe7fe74
SL
176
177getsocket(domain, type, sin)
178 int domain, type;
179 struct sockaddr_in *sin;
180{
181 int retry, s;
182
183 retry = 1;
184 while ((s = socket(domain, type, 0, 0)) < 0 && retry) {
185 perror("socket");
186 sleep(5 * retry);
187 retry <<= 1;
188 }
189 if (retry == 0)
190 return (-1);
191 while (bind(s, sin, sizeof (*sin), 0) < 0 && retry) {
192 perror("bind");
193 sleep(5 * retry);
194 retry <<= 1;
195 }
196 if (retry == 0)
197 return (-1);
198 return (s);
199}