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