rework interface metrics to invert perspective; other misc. fixes
[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
7892134c 14static char sccsid[] = "@(#)main.c 5.11 (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 */
7892134c 32int debug = 0;
fdd0ed12
SL
33
34struct rip *msg = (struct rip *)packet;
7892134c 35int hup(), rtdeleteall();
fdd0ed12
SL
36
37main(argc, argv)
38 int argc;
39 char *argv[];
40{
41 int cc;
42 struct sockaddr from;
7fe7fe74 43 u_char retry;
fdd0ed12
SL
44
45 argv0 = argv;
a349306d 46 openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON);
bb3e151c 47 setlogmask(LOG_WARNING);
fdd0ed12 48 sp = getservbyname("router", "udp");
7fe7fe74
SL
49 if (sp == NULL) {
50 fprintf(stderr, "routed: router/udp: unknown service\n");
fdd0ed12
SL
51 exit(1);
52 }
7fe7fe74
SL
53 addr.sin_family = AF_INET;
54 addr.sin_port = sp->s_port;
55 s = getsocket(AF_INET, SOCK_DGRAM, &addr);
56 if (s < 0)
57 exit(1);
fdd0ed12
SL
58 argv++, argc--;
59 while (argc > 0 && **argv == '-') {
d4b6a849 60 if (strcmp(*argv, "-s") == 0) {
fdd0ed12
SL
61 supplier = 1;
62 argv++, argc--;
63 continue;
64 }
d4b6a849 65 if (strcmp(*argv, "-q") == 0) {
fdd0ed12
SL
66 supplier = 0;
67 argv++, argc--;
68 continue;
69 }
d4b6a849
SL
70 if (strcmp(*argv, "-t") == 0) {
71 tracepackets++;
bb3e151c 72 setlogmask(LOG_DEBUG);
17fe297f
MK
73 argv++, argc--;
74 continue;
75 }
76 if (strcmp(*argv, "-d") == 0) {
7892134c 77 debug++;
bb3e151c 78 setlogmask(LOG_DEBUG);
d4b6a849
SL
79 argv++, argc--;
80 continue;
81 }
5562f0a3
MK
82 if (strcmp(*argv, "-g") == 0) {
83 gateway = 1;
84 argv++, argc--;
85 continue;
86 }
5562f0a3 87 fprintf(stderr,
d002aa8c 88 "usage: routed [ -s ] [ -q ] [ -t ] [ -g ]\n");
fdd0ed12
SL
89 exit(1);
90 }
7892134c 91 if (tracepackets == 0 && debug == 0) {
d4b6a849
SL
92 int t;
93
94 if (fork())
95 exit(0);
7620381d
SL
96 for (t = 0; t < 20; t++)
97 if (t != s)
2b478949 98 (void) close(t);
d4b6a849
SL
99 (void) open("/", 0);
100 (void) dup2(0, 1);
101 (void) dup2(0, 2);
102 t = open("/dev/tty", 2);
103 if (t >= 0) {
104 ioctl(t, TIOCNOTTY, (char *)0);
105 (void) close(t);
106 }
107 }
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();
fdd0ed12 122 ifinit();
34894a1d 123 gwkludge();
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);
7892134c 138 signal(SIGINT, rtdeleteall);
fdd0ed12
SL
139 timer();
140
fdd0ed12
SL
141 for (;;) {
142 int ibits;
143 register int n;
144
7fe7fe74 145 ibits = 1 << s;
7fe7fe74 146 n = select(20, &ibits, 0, 0, 0);
fdd0ed12
SL
147 if (n < 0)
148 continue;
149 if (ibits & (1 << s))
150 process(s);
7fe7fe74 151 /* handle ICMP redirects */
fdd0ed12
SL
152 }
153}
154
155process(fd)
156 int fd;
157{
fdd0ed12 158 struct sockaddr from;
ce5e9df4 159 int fromlen = sizeof (from), cc, omask;
fdd0ed12 160
7fe7fe74 161 cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen);
fdd0ed12
SL
162 if (cc <= 0) {
163 if (cc < 0 && errno != EINTR)
7fe7fe74 164 perror("recvfrom");
fdd0ed12
SL
165 return;
166 }
7fe7fe74
SL
167 if (fromlen != sizeof (struct sockaddr_in))
168 return;
2b478949 169 omask = sigblock(sigmask(SIGALRM));
fdd0ed12 170 rip_input(&from, cc);
ce5e9df4 171 sigsetmask(omask);
fdd0ed12 172}
7fe7fe74
SL
173
174getsocket(domain, type, sin)
175 int domain, type;
176 struct sockaddr_in *sin;
177{
3d42e160 178 int s, on = 1;
7fe7fe74 179
9fe072d4 180 if ((s = socket(domain, type, 0)) < 0) {
7fe7fe74 181 perror("socket");
69b7ef61 182 syslog(LOG_ERR, "socket: %m");
7fe7fe74 183 return (-1);
69b7ef61
MK
184 }
185 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
186 syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
3d42e160
MK
187 close(s);
188 return (-1);
69b7ef61 189 }
34894a1d
MK
190 on = 48*1024;
191 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &on, sizeof (on)) < 0)
192 syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
3d42e160 193 if (bind(s, sin, sizeof (*sin), 0) < 0) {
7fe7fe74 194 perror("bind");
69b7ef61 195 syslog(LOG_ERR, "bind: %m");
3d42e160 196 close(s);
7fe7fe74 197 return (-1);
69b7ef61 198 }
7fe7fe74
SL
199 return (s);
200}