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