new subnets
[unix-history] / usr / src / sbin / routed / main.c
CommitLineData
fdd0ed12 1#ifndef lint
d002aa8c 2static char sccsid[] = "@(#)main.c 4.13 (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 */
d002aa8c 20int gateway = 0; /* 1 if we are a gateway to parts beyond */
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 }
5562f0a3 67 fprintf(stderr,
d002aa8c 68 "usage: routed [ -s ] [ -q ] [ -t ] [ -g ]\n");
fdd0ed12
SL
69 exit(1);
70 }
d4b6a849
SL
71#ifndef DEBUG
72 if (!tracepackets) {
73 int t;
74
75 if (fork())
76 exit(0);
7620381d
SL
77 for (t = 0; t < 20; t++)
78 if (t != s)
7620381d 79 (void) close(cc);
d4b6a849
SL
80 (void) open("/", 0);
81 (void) dup2(0, 1);
82 (void) dup2(0, 2);
83 t = open("/dev/tty", 2);
84 if (t >= 0) {
85 ioctl(t, TIOCNOTTY, (char *)0);
86 (void) close(t);
87 }
88 }
89#endif
7fe7fe74
SL
90 /*
91 * Any extra argument is considered
92 * a tracing log file.
93 */
94 if (argc > 0)
95 traceon(*argv);
fdd0ed12
SL
96 /*
97 * Collect an initial view of the world by
d002aa8c 98 * checking the interface configuration and the gateway kludge
fdd0ed12
SL
99 * file. Then, send a request packet on all
100 * directly connected networks to find out what
101 * everyone else thinks.
102 */
103 rtinit();
104 gwkludge();
105 ifinit();
d002aa8c
MK
106 if (gateway > 0)
107 rtdefault();
fdd0ed12
SL
108 if (supplier < 0)
109 supplier = 0;
110 msg->rip_cmd = RIPCMD_REQUEST;
55d340a4 111 msg->rip_vers = RIPVERSION;
fdd0ed12
SL
112 msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
113 msg->rip_nets[0].rip_metric = HOPCNT_INFINITY;
55d340a4
SL
114 msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC);
115 msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY);
fdd0ed12 116 toall(sendmsg);
ce5e9df4 117 signal(SIGALRM, timer);
b7e4f8be 118 signal(SIGHUP, hup);
69b7ef61 119 signal(SIGTERM, hup);
fdd0ed12
SL
120 timer();
121
fdd0ed12
SL
122 for (;;) {
123 int ibits;
124 register int n;
125
7fe7fe74 126 ibits = 1 << s;
7fe7fe74 127 n = select(20, &ibits, 0, 0, 0);
fdd0ed12
SL
128 if (n < 0)
129 continue;
130 if (ibits & (1 << s))
131 process(s);
7fe7fe74 132 /* handle ICMP redirects */
fdd0ed12
SL
133 }
134}
135
136process(fd)
137 int fd;
138{
fdd0ed12 139 struct sockaddr from;
ce5e9df4 140 int fromlen = sizeof (from), cc, omask;
fdd0ed12 141
7fe7fe74 142 cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen);
fdd0ed12
SL
143 if (cc <= 0) {
144 if (cc < 0 && errno != EINTR)
7fe7fe74 145 perror("recvfrom");
fdd0ed12
SL
146 return;
147 }
7fe7fe74
SL
148 if (fromlen != sizeof (struct sockaddr_in))
149 return;
ce5e9df4
SL
150#define mask(s) (1<<((s)-1))
151 omask = sigblock(mask(SIGALRM));
fdd0ed12 152 rip_input(&from, cc);
ce5e9df4 153 sigsetmask(omask);
fdd0ed12 154}
7fe7fe74
SL
155
156getsocket(domain, type, sin)
157 int domain, type;
158 struct sockaddr_in *sin;
159{
69b7ef61 160 int retry, s, on = 1;
7fe7fe74
SL
161
162 retry = 1;
163 while ((s = socket(domain, type, 0, 0)) < 0 && retry) {
164 perror("socket");
165 sleep(5 * retry);
166 retry <<= 1;
167 }
69b7ef61
MK
168 if (retry == 0) {
169 syslog(LOG_ERR, "socket: %m");
7fe7fe74 170 return (-1);
69b7ef61
MK
171 }
172 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
173 syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
174 exit(1);
175 }
7fe7fe74
SL
176 while (bind(s, sin, sizeof (*sin), 0) < 0 && retry) {
177 perror("bind");
178 sleep(5 * retry);
179 retry <<= 1;
180 }
69b7ef61
MK
181 if (retry == 0) {
182 syslog(LOG_ERR, "bind: %m");
7fe7fe74 183 return (-1);
69b7ef61 184 }
7fe7fe74
SL
185 return (s);
186}