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: }