xref: /csrg-svn/sbin/routed/main.c (revision 34566)
121996Sdist /*
2*34566Skarels  * Copyright (c) 1983, 1988 Regents of the University of California.
333489Sbostic  * All rights reserved.
433489Sbostic  *
533489Sbostic  * Redistribution and use in source and binary forms are permitted
633489Sbostic  * provided that this notice is preserved and that due credit is given
733489Sbostic  * to the University of California at Berkeley. The name of the University
833489Sbostic  * may not be used to endorse or promote products derived from this
933489Sbostic  * software without specific prior written permission. This software
1033489Sbostic  * is provided ``as is'' without express or implied warranty.
1121996Sdist  */
1221996Sdist 
139017Ssam #ifndef lint
1421996Sdist char copyright[] =
15*34566Skarels "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
1621996Sdist  All rights reserved.\n";
1733489Sbostic #endif /* not lint */
189017Ssam 
1921996Sdist #ifndef lint
20*34566Skarels static char sccsid[] = "@(#)main.c	5.13 (Berkeley) 05/31/88";
2133489Sbostic #endif /* not lint */
2221996Sdist 
239017Ssam /*
249017Ssam  * Routing Table Management Daemon
259017Ssam  */
2610245Ssam #include "defs.h"
279017Ssam #include <sys/ioctl.h>
2813602Ssam #include <sys/time.h>
2913602Ssam 
309017Ssam #include <net/if.h>
3113602Ssam 
32*34566Skarels #include <sys/errno.h>
33*34566Skarels #include <sys/signal.h>
34*34566Skarels #include <sys/syslog.h>
359017Ssam 
369017Ssam int	supplier = -1;		/* process should supply updates */
3721847Skarels int	gateway = 0;		/* 1 if we are a gateway to parts beyond */
3831220Skarels int	debug = 0;
399017Ssam 
409017Ssam struct	rip *msg = (struct rip *)packet;
41*34566Skarels int	hup(), rtdeleteall(), sigtrace();
429017Ssam 
439017Ssam main(argc, argv)
449017Ssam 	int argc;
459017Ssam 	char *argv[];
469017Ssam {
479017Ssam 	int cc;
489017Ssam 	struct sockaddr from;
4910245Ssam 	u_char retry;
509017Ssam 
519017Ssam 	argv0 = argv;
5224848Seric 	openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON);
5330930Skarels 	setlogmask(LOG_UPTO(LOG_WARNING));
549017Ssam 	sp = getservbyname("router", "udp");
5510245Ssam 	if (sp == NULL) {
5610245Ssam 		fprintf(stderr, "routed: router/udp: unknown service\n");
579017Ssam 		exit(1);
589017Ssam 	}
5910245Ssam 	addr.sin_family = AF_INET;
6010245Ssam 	addr.sin_port = sp->s_port;
6110245Ssam 	s = getsocket(AF_INET, SOCK_DGRAM, &addr);
6210245Ssam 	if (s < 0)
6310245Ssam 		exit(1);
649017Ssam 	argv++, argc--;
659017Ssam 	while (argc > 0 && **argv == '-') {
6610636Ssam 		if (strcmp(*argv, "-s") == 0) {
679017Ssam 			supplier = 1;
689017Ssam 			argv++, argc--;
699017Ssam 			continue;
709017Ssam 		}
7110636Ssam 		if (strcmp(*argv, "-q") == 0) {
729017Ssam 			supplier = 0;
739017Ssam 			argv++, argc--;
749017Ssam 			continue;
759017Ssam 		}
7610636Ssam 		if (strcmp(*argv, "-t") == 0) {
77*34566Skarels 			if (tracehistory == 0)
78*34566Skarels 				tracehistory++;
79*34566Skarels 			else {
80*34566Skarels 				tracehistory = 0;
81*34566Skarels 				tracepackets++;
82*34566Skarels 			}
8330930Skarels 			setlogmask(LOG_UPTO(LOG_DEBUG));
8410636Ssam 			argv++, argc--;
8510636Ssam 			continue;
8610636Ssam 		}
8726341Skarels 		if (strcmp(*argv, "-d") == 0) {
8831220Skarels 			debug++;
8930930Skarels 			setlogmask(LOG_UPTO(LOG_DEBUG));
9026341Skarels 			argv++, argc--;
9126341Skarels 			continue;
9226341Skarels 		}
9316326Skarels 		if (strcmp(*argv, "-g") == 0) {
9416326Skarels 			gateway = 1;
9516326Skarels 			argv++, argc--;
9616326Skarels 			continue;
9716326Skarels 		}
9816326Skarels 		fprintf(stderr,
9921847Skarels 			"usage: routed [ -s ] [ -q ] [ -t ] [ -g ]\n");
1009017Ssam 		exit(1);
1019017Ssam 	}
10231220Skarels 	if (tracepackets == 0 && debug == 0) {
10310636Ssam 		int t;
10410636Ssam 
10510636Ssam 		if (fork())
10610636Ssam 			exit(0);
10710637Ssam 		for (t = 0; t < 20; t++)
10810637Ssam 			if (t != s)
10924761Ssklower 				(void) close(t);
11010636Ssam 		(void) open("/", 0);
11110636Ssam 		(void) dup2(0, 1);
11210636Ssam 		(void) dup2(0, 2);
11310636Ssam 		t = open("/dev/tty", 2);
11410636Ssam 		if (t >= 0) {
11510636Ssam 			ioctl(t, TIOCNOTTY, (char *)0);
11610636Ssam 			(void) close(t);
11710636Ssam 		}
11810636Ssam 	}
1199017Ssam 	/*
12010245Ssam 	 * Any extra argument is considered
12110245Ssam 	 * a tracing log file.
12210245Ssam 	 */
12310245Ssam 	if (argc > 0)
12410245Ssam 		traceon(*argv);
12510245Ssam 	/*
1269017Ssam 	 * Collect an initial view of the world by
12721847Skarels 	 * checking the interface configuration and the gateway kludge
1289017Ssam 	 * file.  Then, send a request packet on all
1299017Ssam 	 * directly connected networks to find out what
1309017Ssam 	 * everyone else thinks.
1319017Ssam 	 */
1329017Ssam 	rtinit();
13330927Skarels 	ifinit();
1349017Ssam 	gwkludge();
13521847Skarels 	if (gateway > 0)
13621847Skarels 		rtdefault();
1379017Ssam 	if (supplier < 0)
1389017Ssam 		supplier = 0;
1399017Ssam 	msg->rip_cmd = RIPCMD_REQUEST;
14012726Ssam 	msg->rip_vers = RIPVERSION;
1419017Ssam 	msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
1429017Ssam 	msg->rip_nets[0].rip_metric = HOPCNT_INFINITY;
14312726Ssam 	msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC);
14412726Ssam 	msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY);
1459017Ssam 	toall(sendmsg);
14613036Ssam 	signal(SIGALRM, timer);
14716314Skarels 	signal(SIGHUP, hup);
14817570Skarels 	signal(SIGTERM, hup);
14931220Skarels 	signal(SIGINT, rtdeleteall);
150*34566Skarels 	signal(SIGUSR1, sigtrace);
151*34566Skarels 	signal(SIGUSR2, sigtrace);
1529017Ssam 	timer();
1539017Ssam 
1549017Ssam 	for (;;) {
1559017Ssam 		int ibits;
1569017Ssam 		register int n;
1579017Ssam 
15810245Ssam 		ibits = 1 << s;
15910245Ssam 		n = select(20, &ibits, 0, 0, 0);
1609017Ssam 		if (n < 0)
1619017Ssam 			continue;
1629017Ssam 		if (ibits & (1 << s))
1639017Ssam 			process(s);
16410245Ssam 		/* handle ICMP redirects */
1659017Ssam 	}
1669017Ssam }
1679017Ssam 
1689017Ssam process(fd)
1699017Ssam 	int fd;
1709017Ssam {
1719017Ssam 	struct sockaddr from;
17213036Ssam 	int fromlen = sizeof (from), cc, omask;
173*34566Skarels 	time_t now;
1749017Ssam 
17510245Ssam 	cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen);
1769017Ssam 	if (cc <= 0) {
1779017Ssam 		if (cc < 0 && errno != EINTR)
17810245Ssam 			perror("recvfrom");
1799017Ssam 		return;
1809017Ssam 	}
18110245Ssam 	if (fromlen != sizeof (struct sockaddr_in))
18210245Ssam 		return;
183*34566Skarels 	if (traceactions && !tracepackets) {
184*34566Skarels 		(void) time(&now);
185*34566Skarels 		curtime = ctime(&now);
186*34566Skarels 	}
18724761Ssklower 	omask = sigblock(sigmask(SIGALRM));
1889017Ssam 	rip_input(&from, cc);
18913036Ssam 	sigsetmask(omask);
1909017Ssam }
19110245Ssam 
19210245Ssam getsocket(domain, type, sin)
19310245Ssam 	int domain, type;
19410245Ssam 	struct sockaddr_in *sin;
19510245Ssam {
19625516Skarels 	int s, on = 1;
19710245Ssam 
19825702Smckusick 	if ((s = socket(domain, type, 0)) < 0) {
19910245Ssam 		perror("socket");
20017570Skarels 		syslog(LOG_ERR, "socket: %m");
20110245Ssam 		return (-1);
20217570Skarels 	}
20317570Skarels 	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
20417570Skarels 		syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
20525516Skarels 		close(s);
20625516Skarels 		return (-1);
20717570Skarels 	}
20830927Skarels 	on = 48*1024;
20930927Skarels 	if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &on, sizeof (on)) < 0)
21030927Skarels 		syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
21125516Skarels 	if (bind(s, sin, sizeof (*sin), 0) < 0) {
21210245Ssam 		perror("bind");
21317570Skarels 		syslog(LOG_ERR, "bind: %m");
21425516Skarels 		close(s);
21510245Ssam 		return (-1);
21617570Skarels 	}
21710245Ssam 	return (s);
21810245Ssam }
219