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