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 = htons(AF_UNSPEC); 131: msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY); 132: toall(sendmsg); 133: signal(SIGALRM, timer); 134: signal(SIGHUP, hup); 135: signal(SIGTERM, hup); 136: timer(); 137: 138: for (;;) { 139: long ibits; 140: register int n; 141: 142: ibits = 1L << s; 143: n = select(20, &ibits, 0, 0, 0); 144: if (n < 0) 145: continue; 146: if (ibits & (1L << s)) 147: process(s); 148: /* handle ICMP redirects */ 149: } 150: } 151: 152: process(fd) 153: int fd; 154: { 155: struct sockaddr from; 156: int fromlen = sizeof (from), cc; 157: long omask; 158: 159: cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen); 160: if (cc <= 0) { 161: if (cc < 0 && errno != EINTR) 162: perror("recvfrom"); 163: return; 164: } 165: if (fromlen != sizeof (struct sockaddr_in)) 166: return; 167: omask = sigblock(sigmask(SIGALRM)); 168: rip_input(&from, cc); 169: sigsetmask(omask); 170: } 171: 172: getsocket(domain, type, sin) 173: int domain, type; 174: struct sockaddr_in *sin; 175: { 176: int s, on = 1; 177: 178: if ((s = socket(domain, type, 0)) < 0) { 179: perror("socket"); 180: syslog(LOG_ERR, "socket: %m"); 181: return (-1); 182: } 183: if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { 184: syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); 185: close(s); 186: return (-1); 187: } 188: if (bind(s, sin, sizeof (*sin), 0) < 0) { 189: perror("bind"); 190: syslog(LOG_ERR, "bind: %m"); 191: close(s); 192: return (-1); 193: } 194: return (s); 195: }