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