|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.