convert to 4.1c directory layout
[unix-history] / usr / src / sbin / routed / main.c
CommitLineData
fdd0ed12
SL
1#ifndef lint
2static char sccsid[] = "@(#)main.c 4.1 %G%";
3#endif
4
5/*
6 * Routing Table Management Daemon
7 */
8#include "router.h"
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;
26
27 argv0 = argv;
28#ifndef DEBUG
29 if (fork())
30 exit(0);
31 for (cc = 0; cc < 10; cc++)
32 (void) close(cc);
33 (void) open("/", 0);
34 (void) dup2(0, 1);
35 (void) dup2(0, 2);
36 { int t = open("/dev/tty", 2);
37 if (t >= 0) {
38 ioctl(t, TIOCNOTTY, (char *)0);
39 (void) close(t);
40 }
41 }
42#endif
43 if (tracing)
44 traceon("/etc/routerlog");
45
46 /*
47 * We use two sockets. One for which outgoing
48 * packets are routed and for which they're not.
49 * The latter allows us to delete routing table
50 * entries in the kernel for network interfaces
51 * attached to our host which we believe are down
52 * while still polling it to see when/if it comes
53 * back up. With the new ipc interface we'll be
54 * able to specify ``don't route'' as an option
55 * to send, but until then we utilize a second port.
56 */
57 sp = getservbyname("router", "udp");
58 if (sp == 0) {
59 fprintf(stderr, "routed: udp/router: unknown service\n");
60 exit(1);
61 }
62 routingaddr.sin_family = AF_INET;
63 routingaddr.sin_port = htons(sp->s_port);
64 noroutingaddr.sin_family = AF_INET;
65 noroutingaddr.sin_port = htons(sp->s_port + 1);
66again:
67 s = socket(SOCK_DGRAM, 0, &routingaddr, 0);
68 if (s < 0) {
69 perror("socket");
70 sleep(30);
71 goto again;
72 }
73again2:
74 snoroute = socket(SOCK_DGRAM, 0, &noroutingaddr, SO_DONTROUTE);
75 if (snoroute < 0) {
76 perror("socket");
77 sleep(30);
78 goto again2;
79 }
80 argv++, argc--;
81 while (argc > 0 && **argv == '-') {
82 if (!strcmp(*argv, "-s") == 0) {
83 supplier = 1;
84 argv++, argc--;
85 continue;
86 }
87 if (!strcmp(*argv, "-q") == 0) {
88 supplier = 0;
89 argv++, argc--;
90 continue;
91 }
92 goto usage;
93 }
94 if (argc > 0) {
95usage:
96 fprintf(stderr, "usage: routed [ -s ] [ -q ]\n");
97 exit(1);
98 }
99 /*
100 * Collect an initial view of the world by
101 * snooping in the kernel and the gateway kludge
102 * file. Then, send a request packet on all
103 * directly connected networks to find out what
104 * everyone else thinks.
105 */
106 rtinit();
107 gwkludge();
108 ifinit();
109 if (supplier < 0)
110 supplier = 0;
111 msg->rip_cmd = RIPCMD_REQUEST;
112 msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
113 msg->rip_nets[0].rip_metric = HOPCNT_INFINITY;
114 toall(sendmsg);
115 sigset(SIGALRM, timer);
116 timer();
117
118#define INFINITY 1000000
119 for (;;) {
120 int ibits;
121 register int n;
122
123 ibits = (1 << s) | (1 << snoroute);
124 n = select(32, &ibits, 0, INFINITY);
125 if (n < 0)
126 continue;
127 if (ibits & (1 << s))
128 process(s);
129 if (ibits & (1 << snoroute))
130 process(snoroute);
131 }
132}
133
134process(fd)
135 int fd;
136{
137 register int cc;
138 struct sockaddr from;
139
140 cc = receive(fd, &from, packet, sizeof (packet));
141 if (cc <= 0) {
142 if (cc < 0 && errno != EINTR)
143 perror("receive");
144 return;
145 }
146 sighold(SIGALRM);
147 rip_input(&from, cc);
148 sigrelse(SIGALRM);
149}