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