|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983, 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that this notice is preserved and that due credit is given ! 7: * to the University of California at Berkeley. The name of the University ! 8: * may not be used to endorse or promote products derived from this ! 9: * software without specific prior written permission. This software ! 10: * is provided ``as is'' without express or implied warranty. ! 11: */ ! 12: ! 13: #ifndef lint ! 14: char copyright[] = ! 15: "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\ ! 16: All rights reserved.\n"; ! 17: #endif /* not lint */ ! 18: ! 19: #ifndef lint ! 20: static char sccsid[] = "@(#)main.c 5.13 (Berkeley) 5/31/88"; ! 21: #endif /* not lint */ ! 22: ! 23: /* ! 24: * Routing Table Management Daemon ! 25: */ ! 26: #include "defs.h" ! 27: #include <sys/ioctl.h> ! 28: #include <sys/time.h> ! 29: ! 30: #include <net/if.h> ! 31: ! 32: #include <sys/errno.h> ! 33: #include <sys/signal.h> ! 34: #include <sys/syslog.h> ! 35: ! 36: int supplier = -1; /* process should supply updates */ ! 37: int gateway = 0; /* 1 if we are a gateway to parts beyond */ ! 38: int debug = 0; ! 39: ! 40: struct rip *msg = (struct rip *)packet; ! 41: int hup(), rtdeleteall(), sigtrace(); ! 42: ! 43: main(argc, argv) ! 44: int argc; ! 45: char *argv[]; ! 46: { ! 47: int cc; ! 48: struct sockaddr from; ! 49: u_char retry; ! 50: ! 51: argv0 = argv; ! 52: openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON); ! 53: setlogmask(LOG_UPTO(LOG_WARNING)); ! 54: sp = getservbyname("router", "udp"); ! 55: if (sp == NULL) { ! 56: fprintf(stderr, "routed: router/udp: unknown service\n"); ! 57: exit(1); ! 58: } ! 59: addr.sin_family = AF_INET; ! 60: addr.sin_port = sp->s_port; ! 61: s = getsocket(AF_INET, SOCK_DGRAM, &addr); ! 62: if (s < 0) ! 63: exit(1); ! 64: argv++, argc--; ! 65: while (argc > 0 && **argv == '-') { ! 66: if (strcmp(*argv, "-s") == 0) { ! 67: supplier = 1; ! 68: argv++, argc--; ! 69: continue; ! 70: } ! 71: if (strcmp(*argv, "-q") == 0) { ! 72: supplier = 0; ! 73: argv++, argc--; ! 74: continue; ! 75: } ! 76: if (strcmp(*argv, "-t") == 0) { ! 77: if (tracehistory == 0) ! 78: tracehistory++; ! 79: else { ! 80: tracehistory = 0; ! 81: tracepackets++; ! 82: } ! 83: setlogmask(LOG_UPTO(LOG_DEBUG)); ! 84: argv++, argc--; ! 85: continue; ! 86: } ! 87: if (strcmp(*argv, "-d") == 0) { ! 88: debug++; ! 89: setlogmask(LOG_UPTO(LOG_DEBUG)); ! 90: argv++, argc--; ! 91: continue; ! 92: } ! 93: if (strcmp(*argv, "-g") == 0) { ! 94: gateway = 1; ! 95: argv++, argc--; ! 96: continue; ! 97: } ! 98: fprintf(stderr, ! 99: "usage: routed [ -s ] [ -q ] [ -t ] [ -g ]\n"); ! 100: exit(1); ! 101: } ! 102: if (tracepackets == 0 && debug == 0) { ! 103: int t; ! 104: ! 105: if (fork()) ! 106: exit(0); ! 107: for (t = 0; t < 20; t++) ! 108: if (t != s) ! 109: (void) close(t); ! 110: (void) open("/", 0); ! 111: (void) dup2(0, 1); ! 112: (void) dup2(0, 2); ! 113: t = open("/dev/tty", 2); ! 114: if (t >= 0) { ! 115: ioctl(t, TIOCNOTTY, (char *)0); ! 116: (void) close(t); ! 117: } ! 118: } ! 119: /* ! 120: * Any extra argument is considered ! 121: * a tracing log file. ! 122: */ ! 123: if (argc > 0) ! 124: traceon(*argv); ! 125: /* ! 126: * Collect an initial view of the world by ! 127: * checking the interface configuration and the gateway kludge ! 128: * file. Then, send a request packet on all ! 129: * directly connected networks to find out what ! 130: * everyone else thinks. ! 131: */ ! 132: rtinit(); ! 133: ifinit(); ! 134: gwkludge(); ! 135: if (gateway > 0) ! 136: rtdefault(); ! 137: if (supplier < 0) ! 138: supplier = 0; ! 139: msg->rip_cmd = RIPCMD_REQUEST; ! 140: msg->rip_vers = RIPVERSION; ! 141: msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC; ! 142: msg->rip_nets[0].rip_metric = HOPCNT_INFINITY; ! 143: msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC); ! 144: msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY); ! 145: toall(sendmsg); ! 146: signal(SIGALRM, timer); ! 147: signal(SIGHUP, hup); ! 148: signal(SIGTERM, hup); ! 149: signal(SIGINT, rtdeleteall); ! 150: signal(SIGUSR1, sigtrace); ! 151: signal(SIGUSR2, sigtrace); ! 152: timer(); ! 153: ! 154: for (;;) { ! 155: int ibits; ! 156: register int n; ! 157: ! 158: ibits = 1 << s; ! 159: n = select(20, &ibits, 0, 0, 0); ! 160: if (n < 0) ! 161: continue; ! 162: if (ibits & (1 << s)) ! 163: process(s); ! 164: /* handle ICMP redirects */ ! 165: } ! 166: } ! 167: ! 168: process(fd) ! 169: int fd; ! 170: { ! 171: struct sockaddr from; ! 172: int fromlen = sizeof (from), cc, omask; ! 173: time_t now; ! 174: ! 175: cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen); ! 176: if (cc <= 0) { ! 177: if (cc < 0 && errno != EINTR) ! 178: perror("recvfrom"); ! 179: return; ! 180: } ! 181: if (fromlen != sizeof (struct sockaddr_in)) ! 182: return; ! 183: if (traceactions && !tracepackets) { ! 184: (void) time(&now); ! 185: curtime = ctime(&now); ! 186: } ! 187: omask = sigblock(sigmask(SIGALRM)); ! 188: rip_input(&from, cc); ! 189: sigsetmask(omask); ! 190: } ! 191: ! 192: getsocket(domain, type, sin) ! 193: int domain, type; ! 194: struct sockaddr_in *sin; ! 195: { ! 196: int s, on = 1; ! 197: ! 198: if ((s = socket(domain, type, 0)) < 0) { ! 199: perror("socket"); ! 200: syslog(LOG_ERR, "socket: %m"); ! 201: return (-1); ! 202: } ! 203: if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { ! 204: syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); ! 205: close(s); ! 206: return (-1); ! 207: } ! 208: on = 48*1024; ! 209: if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &on, sizeof (on)) < 0) ! 210: syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m"); ! 211: if (bind(s, sin, sizeof (*sin), 0) < 0) { ! 212: perror("bind"); ! 213: syslog(LOG_ERR, "bind: %m"); ! 214: close(s); ! 215: return (-1); ! 216: } ! 217: return (s); ! 218: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.