|
|
1.1 root 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
8: char copyright[] =
9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)main.c 5.7 (Berkeley) 4/20/86";
15: #endif not lint
16:
17: /*
18: * Routing Table Management Daemon
19: */
20: #include "defs.h"
21: #include <sys/ioctl.h>
22: #include <sys/time.h>
23:
24: #include <net/if.h>
25:
26: #include <errno.h>
27: #include <signal.h>
28: #include <syslog.h>
29:
30: int supplier = -1; /* process should supply updates */
31: int gateway = 0; /* 1 if we are a gateway to parts beyond */
32:
33: struct rip *msg = (struct rip *)packet;
34: int hup();
35:
36: main(argc, argv)
37: int argc;
38: char *argv[];
39: {
40: int cc;
41: struct sockaddr from;
42: u_char retry;
43:
44: argv0 = argv;
45: openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON);
46: setlogmask(LOG_UPTO(LOG_WARNING));
47: sp = getservbyname("router", "udp");
48: if (sp == NULL) {
49: fprintf(stderr, "routed: router/udp: unknown service\n");
50: exit(1);
51: }
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);
57: argv++, argc--;
58: while (argc > 0 && **argv == '-') {
59: if (strcmp(*argv, "-s") == 0) {
60: supplier = 1;
61: argv++, argc--;
62: continue;
63: }
64: if (strcmp(*argv, "-q") == 0) {
65: supplier = 0;
66: argv++, argc--;
67: continue;
68: }
69: if (strcmp(*argv, "-t") == 0) {
70: tracepackets++;
71: setlogmask(LOG_UPTO(LOG_DEBUG));
72: argv++, argc--;
73: continue;
74: }
75: if (strcmp(*argv, "-d") == 0) {
76: setlogmask(LOG_UPTO(LOG_DEBUG));
77: argv++, argc--;
78: continue;
79: }
80: if (strcmp(*argv, "-g") == 0) {
81: gateway = 1;
82: argv++, argc--;
83: continue;
84: }
85: fprintf(stderr,
86: "usage: routed [ -s ] [ -q ] [ -t ] [ -g ]\n");
87: exit(1);
88: }
89: #ifndef DEBUG
90: if (!tracepackets) {
91: int t;
92:
93: if (fork())
94: exit(0);
95: for (t = 0; t < 20; t++)
96: if (t != s)
97: (void) close(t);
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
108: /*
109: * Any extra argument is considered
110: * a tracing log file.
111: */
112: if (argc > 0)
113: traceon(*argv);
114: /*
115: * Collect an initial view of the world by
116: * checking the interface configuration and the gateway kludge
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();
124: if (gateway > 0)
125: rtdefault();
126: if (supplier < 0)
127: supplier = 0;
128: msg->rip_cmd = RIPCMD_REQUEST;
129: msg->rip_vers = RIPVERSION;
130: msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
131: msg->rip_nets[0].rip_metric = HOPCNT_INFINITY;
132: msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC);
133: msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY);
134: toall(sendmsg);
135: signal(SIGALRM, timer);
136: signal(SIGHUP, hup);
137: signal(SIGTERM, hup);
138: timer();
139:
140: for (;;) {
141: int ibits;
142: register int n;
143:
144: ibits = 1 << s;
145: n = select(20, &ibits, 0, 0, 0);
146: if (n < 0)
147: continue;
148: if (ibits & (1 << s))
149: process(s);
150: /* handle ICMP redirects */
151: }
152: }
153:
154: process(fd)
155: int fd;
156: {
157: struct sockaddr from;
158: int fromlen = sizeof (from), cc, omask;
159:
160: cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen);
161: if (cc <= 0) {
162: if (cc < 0 && errno != EINTR)
163: perror("recvfrom");
164: return;
165: }
166: if (fromlen != sizeof (struct sockaddr_in))
167: return;
168: omask = sigblock(sigmask(SIGALRM));
169: rip_input(&from, cc);
170: sigsetmask(omask);
171: }
172:
173: getsocket(domain, type, sin)
174: int domain, type;
175: struct sockaddr_in *sin;
176: {
177: int s, on = 1;
178:
179: if ((s = socket(domain, type, 0)) < 0) {
180: perror("socket");
181: syslog(LOG_ERR, "socket: %m");
182: return (-1);
183: }
184: if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
185: syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
186: close(s);
187: return (-1);
188: }
189: if (bind(s, sin, sizeof (*sin), 0) < 0) {
190: perror("bind");
191: syslog(LOG_ERR, "bind: %m");
192: close(s);
193: return (-1);
194: }
195: return (s);
196: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.