|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)main.c 4.8 (Berkeley) 7/1/83"; ! 3: #endif ! 4: ! 5: /* ! 6: * Routing Table Management Daemon ! 7: */ ! 8: #include "defs.h" ! 9: #include <sys/ioctl.h> ! 10: #include <sys/time.h> ! 11: ! 12: #include <net/if.h> ! 13: ! 14: #include <errno.h> ! 15: #include <nlist.h> ! 16: #include <signal.h> ! 17: ! 18: int supplier = -1; /* process should supply updates */ ! 19: ! 20: struct rip *msg = (struct rip *)packet; ! 21: ! 22: main(argc, argv) ! 23: int argc; ! 24: char *argv[]; ! 25: { ! 26: int cc; ! 27: struct sockaddr from; ! 28: u_char retry; ! 29: #ifdef COMPAT ! 30: int snoroute; ! 31: #endif ! 32: ! 33: argv0 = argv; ! 34: sp = getservbyname("router", "udp"); ! 35: if (sp == NULL) { ! 36: fprintf(stderr, "routed: router/udp: unknown service\n"); ! 37: exit(1); ! 38: } ! 39: addr.sin_family = AF_INET; ! 40: addr.sin_port = sp->s_port; ! 41: s = getsocket(AF_INET, SOCK_DGRAM, &addr); ! 42: if (s < 0) ! 43: exit(1); ! 44: #ifdef COMPAT ! 45: bzero(&addr, sizeof (addr)); ! 46: addr.sin_family = AF_INET; ! 47: addr.sin_port = htons(ntohs(sp->s_port) + 1); ! 48: snoroute = getsocket(AF_INET, SOCK_DGRAM, &addr); ! 49: if (snoroute < 0) ! 50: exit(1); ! 51: #endif ! 52: argv++, argc--; ! 53: while (argc > 0 && **argv == '-') { ! 54: if (strcmp(*argv, "-s") == 0) { ! 55: supplier = 1; ! 56: argv++, argc--; ! 57: continue; ! 58: } ! 59: if (strcmp(*argv, "-q") == 0) { ! 60: supplier = 0; ! 61: argv++, argc--; ! 62: continue; ! 63: } ! 64: if (strcmp(*argv, "-t") == 0) { ! 65: tracepackets++; ! 66: argv++, argc--; ! 67: continue; ! 68: } ! 69: fprintf(stderr, "usage: routed [ -s ] [ -q ] [ -t ]\n"); ! 70: exit(1); ! 71: } ! 72: #ifndef DEBUG ! 73: if (!tracepackets) { ! 74: int t; ! 75: ! 76: if (fork()) ! 77: exit(0); ! 78: for (t = 0; t < 20; t++) ! 79: if (t != s) ! 80: #ifdef COMPAT ! 81: if (t != snoroute) ! 82: #endif ! 83: (void) close(cc); ! 84: (void) open("/", 0); ! 85: (void) dup2(0, 1); ! 86: (void) dup2(0, 2); ! 87: t = open("/dev/tty", 2); ! 88: if (t >= 0) { ! 89: ioctl(t, TIOCNOTTY, (char *)0); ! 90: (void) close(t); ! 91: } ! 92: } ! 93: #endif ! 94: /* ! 95: * Any extra argument is considered ! 96: * a tracing log file. ! 97: */ ! 98: if (argc > 0) ! 99: traceon(*argv); ! 100: /* ! 101: * Collect an initial view of the world by ! 102: * snooping in the kernel and the gateway kludge ! 103: * file. Then, send a request packet on all ! 104: * directly connected networks to find out what ! 105: * everyone else thinks. ! 106: */ ! 107: rtinit(); ! 108: gwkludge(); ! 109: ifinit(); ! 110: if (supplier < 0) ! 111: supplier = 0; ! 112: msg->rip_cmd = RIPCMD_REQUEST; ! 113: msg->rip_vers = RIPVERSION; ! 114: msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC; ! 115: msg->rip_nets[0].rip_metric = HOPCNT_INFINITY; ! 116: msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC); ! 117: msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY); ! 118: toall(sendmsg); ! 119: signal(SIGALRM, timer); ! 120: timer(); ! 121: ! 122: for (;;) { ! 123: int ibits; ! 124: register int n; ! 125: ! 126: ibits = 1 << s; ! 127: #ifdef COMPAT ! 128: ibits |= 1 << snoroute; ! 129: #endif ! 130: n = select(20, &ibits, 0, 0, 0); ! 131: if (n < 0) ! 132: continue; ! 133: if (ibits & (1 << s)) ! 134: process(s); ! 135: #ifdef COMPAT ! 136: if (ibits & (1 << snoroute)) ! 137: process(snoroute); ! 138: #endif ! 139: /* handle ICMP redirects */ ! 140: } ! 141: } ! 142: ! 143: process(fd) ! 144: int fd; ! 145: { ! 146: struct sockaddr from; ! 147: int fromlen = sizeof (from), cc, omask; ! 148: ! 149: cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen); ! 150: if (cc <= 0) { ! 151: if (cc < 0 && errno != EINTR) ! 152: perror("recvfrom"); ! 153: return; ! 154: } ! 155: if (fromlen != sizeof (struct sockaddr_in)) ! 156: return; ! 157: #define mask(s) (1<<((s)-1)) ! 158: omask = sigblock(mask(SIGALRM)); ! 159: rip_input(&from, cc); ! 160: sigsetmask(omask); ! 161: } ! 162: ! 163: getsocket(domain, type, sin) ! 164: int domain, type; ! 165: struct sockaddr_in *sin; ! 166: { ! 167: int retry, s; ! 168: ! 169: retry = 1; ! 170: while ((s = socket(domain, type, 0, 0)) < 0 && retry) { ! 171: perror("socket"); ! 172: sleep(5 * retry); ! 173: retry <<= 1; ! 174: } ! 175: if (retry == 0) ! 176: return (-1); ! 177: while (bind(s, sin, sizeof (*sin), 0) < 0 && retry) { ! 178: perror("bind"); ! 179: sleep(5 * retry); ! 180: retry <<= 1; ! 181: } ! 182: if (retry == 0) ! 183: return (-1); ! 184: return (s); ! 185: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.