|
|
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 provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)main.c 5.21 (Berkeley) 6/29/90"; ! 28: #endif /* not lint */ ! 29: ! 30: /* ! 31: * Routing Table Management Daemon ! 32: */ ! 33: #include "defs.h" ! 34: #include <sys/ioctl.h> ! 35: #include <sys/file.h> ! 36: ! 37: #include <net/if.h> ! 38: ! 39: #include <sys/errno.h> ! 40: #include <sys/signal.h> ! 41: #include <sys/syslog.h> ! 42: #include "pathnames.h" ! 43: ! 44: int supplier = -1; /* process should supply updates */ ! 45: int gateway = 0; /* 1 if we are a gateway to parts beyond */ ! 46: int debug = 0; ! 47: int bufspace = 127*1024; /* max. input buffer size to request */ ! 48: ! 49: struct rip *msg = (struct rip *)packet; ! 50: int hup(), rtdeleteall(), sigtrace(); ! 51: ! 52: main(argc, argv) ! 53: int argc; ! 54: char *argv[]; ! 55: { ! 56: int n, cc, nfd, omask, tflags = 0; ! 57: struct sockaddr from; ! 58: struct timeval *tvp, waittime; ! 59: struct itimerval itval; ! 60: register struct rip *query = msg; ! 61: fd_set ibits; ! 62: u_char retry; ! 63: ! 64: argv0 = argv; ! 65: #if BSD >= 43 ! 66: openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON); ! 67: setlogmask(LOG_UPTO(LOG_WARNING)); ! 68: #else ! 69: openlog("routed", LOG_PID); ! 70: #define LOG_UPTO(x) (x) ! 71: #define setlogmask(x) (x) ! 72: #endif ! 73: sp = getservbyname("router", "udp"); ! 74: if (sp == NULL) { ! 75: fprintf(stderr, "routed: router/udp: unknown service\n"); ! 76: exit(1); ! 77: } ! 78: addr.sin_family = AF_INET; ! 79: addr.sin_port = sp->s_port; ! 80: s = getsocket(AF_INET, SOCK_DGRAM, &addr); ! 81: if (s < 0) ! 82: exit(1); ! 83: argv++, argc--; ! 84: while (argc > 0 && **argv == '-') { ! 85: if (strcmp(*argv, "-s") == 0) { ! 86: supplier = 1; ! 87: argv++, argc--; ! 88: continue; ! 89: } ! 90: if (strcmp(*argv, "-q") == 0) { ! 91: supplier = 0; ! 92: argv++, argc--; ! 93: continue; ! 94: } ! 95: if (strcmp(*argv, "-t") == 0) { ! 96: tflags++; ! 97: setlogmask(LOG_UPTO(LOG_DEBUG)); ! 98: argv++, argc--; ! 99: continue; ! 100: } ! 101: if (strcmp(*argv, "-d") == 0) { ! 102: debug++; ! 103: setlogmask(LOG_UPTO(LOG_DEBUG)); ! 104: argv++, argc--; ! 105: continue; ! 106: } ! 107: if (strcmp(*argv, "-g") == 0) { ! 108: gateway = 1; ! 109: argv++, argc--; ! 110: continue; ! 111: } ! 112: fprintf(stderr, ! 113: "usage: routed [ -s ] [ -q ] [ -t ] [ -g ]\n"); ! 114: exit(1); ! 115: } ! 116: ! 117: if (debug == 0) ! 118: daemon(0, 0); ! 119: /* ! 120: * Any extra argument is considered ! 121: * a tracing log file. ! 122: */ ! 123: if (argc > 0) ! 124: traceon(*argv); ! 125: while (tflags-- > 0) ! 126: bumploglevel(); ! 127: ! 128: (void) gettimeofday(&now, (struct timezone *)NULL); ! 129: /* ! 130: * Collect an initial view of the world by ! 131: * checking the interface configuration and the gateway kludge ! 132: * file. Then, send a request packet on all ! 133: * directly connected networks to find out what ! 134: * everyone else thinks. ! 135: */ ! 136: rtinit(); ! 137: ifinit(); ! 138: gwkludge(); ! 139: if (gateway > 0) ! 140: rtdefault(); ! 141: if (supplier < 0) ! 142: supplier = 0; ! 143: query->rip_cmd = RIPCMD_REQUEST; ! 144: query->rip_vers = RIPVERSION; ! 145: if (sizeof(query->rip_nets[0].rip_dst.sa_family) > 1) /* XXX */ ! 146: query->rip_nets[0].rip_dst.sa_family = htons((u_short)AF_UNSPEC); ! 147: else ! 148: query->rip_nets[0].rip_dst.sa_family = AF_UNSPEC; ! 149: query->rip_nets[0].rip_metric = htonl((u_long)HOPCNT_INFINITY); ! 150: toall(sendmsg); ! 151: signal(SIGALRM, timer); ! 152: signal(SIGHUP, hup); ! 153: signal(SIGTERM, hup); ! 154: signal(SIGINT, rtdeleteall); ! 155: signal(SIGUSR1, sigtrace); ! 156: signal(SIGUSR2, sigtrace); ! 157: itval.it_interval.tv_sec = TIMER_RATE; ! 158: itval.it_value.tv_sec = TIMER_RATE; ! 159: itval.it_interval.tv_usec = 0; ! 160: itval.it_value.tv_usec = 0; ! 161: srandom(getpid()); ! 162: if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0) ! 163: syslog(LOG_ERR, "setitimer: %m\n"); ! 164: ! 165: FD_ZERO(&ibits); ! 166: nfd = s + 1; /* 1 + max(fd's) */ ! 167: for (;;) { ! 168: FD_SET(s, &ibits); ! 169: /* ! 170: * If we need a dynamic update that was held off, ! 171: * needupdate will be set, and nextbcast is the time ! 172: * by which we want select to return. Compute time ! 173: * until dynamic update should be sent, and select only ! 174: * until then. If we have already passed nextbcast, ! 175: * just poll. ! 176: */ ! 177: if (needupdate) { ! 178: waittime = nextbcast; ! 179: timevalsub(&waittime, &now); ! 180: if (waittime.tv_sec < 0) { ! 181: waittime.tv_sec = 0; ! 182: waittime.tv_usec = 0; ! 183: } ! 184: if (traceactions) ! 185: fprintf(ftrace, ! 186: "select until dynamic update %d/%d sec/usec\n", ! 187: waittime.tv_sec, waittime.tv_usec); ! 188: tvp = &waittime; ! 189: } else ! 190: tvp = (struct timeval *)NULL; ! 191: n = select(nfd, &ibits, 0, 0, tvp); ! 192: if (n <= 0) { ! 193: /* ! 194: * Need delayed dynamic update if select returned ! 195: * nothing and we timed out. Otherwise, ignore ! 196: * errors (e.g. EINTR). ! 197: */ ! 198: if (n < 0) { ! 199: if (errno == EINTR) ! 200: continue; ! 201: syslog(LOG_ERR, "select: %m"); ! 202: } ! 203: omask = sigblock(sigmask(SIGALRM)); ! 204: if (n == 0 && needupdate) { ! 205: if (traceactions) ! 206: fprintf(ftrace, ! 207: "send delayed dynamic update\n"); ! 208: (void) gettimeofday(&now, ! 209: (struct timezone *)NULL); ! 210: toall(supply, RTS_CHANGED, ! 211: (struct interface *)NULL); ! 212: lastbcast = now; ! 213: needupdate = 0; ! 214: nextbcast.tv_sec = 0; ! 215: } ! 216: sigsetmask(omask); ! 217: continue; ! 218: } ! 219: (void) gettimeofday(&now, (struct timezone *)NULL); ! 220: omask = sigblock(sigmask(SIGALRM)); ! 221: #ifdef doesntwork ! 222: /* ! 223: printf("s %d, ibits %x index %d, mod %d, sh %x, or %x &ibits %x\n", ! 224: s, ! 225: ibits.fds_bits[0], ! 226: (s)/(sizeof(fd_mask) * 8), ! 227: ((s) % (sizeof(fd_mask) * 8)), ! 228: (1 << ((s) % (sizeof(fd_mask) * 8))), ! 229: ibits.fds_bits[(s)/(sizeof(fd_mask) * 8)] & (1 << ((s) % (sizeof(fd_mask) * 8))), ! 230: &ibits ! 231: ); ! 232: */ ! 233: if (FD_ISSET(s, &ibits)) ! 234: #else ! 235: if (ibits.fds_bits[s/32] & (1 << s)) ! 236: #endif ! 237: process(s); ! 238: /* handle ICMP redirects */ ! 239: sigsetmask(omask); ! 240: } ! 241: } ! 242: ! 243: timevaladd(t1, t2) ! 244: struct timeval *t1, *t2; ! 245: { ! 246: ! 247: t1->tv_sec += t2->tv_sec; ! 248: if ((t1->tv_usec += t2->tv_usec) > 1000000) { ! 249: t1->tv_sec++; ! 250: t1->tv_usec -= 1000000; ! 251: } ! 252: } ! 253: ! 254: timevalsub(t1, t2) ! 255: struct timeval *t1, *t2; ! 256: { ! 257: ! 258: t1->tv_sec -= t2->tv_sec; ! 259: if ((t1->tv_usec -= t2->tv_usec) < 0) { ! 260: t1->tv_sec--; ! 261: t1->tv_usec += 1000000; ! 262: } ! 263: } ! 264: ! 265: process(fd) ! 266: int fd; ! 267: { ! 268: struct sockaddr from; ! 269: int fromlen, cc; ! 270: union { ! 271: char buf[MAXPACKETSIZE+1]; ! 272: struct rip rip; ! 273: } inbuf; ! 274: ! 275: for (;;) { ! 276: fromlen = sizeof (from); ! 277: cc = recvfrom(fd, &inbuf, sizeof (inbuf), 0, &from, &fromlen); ! 278: if (cc <= 0) { ! 279: if (cc < 0 && errno != EWOULDBLOCK) ! 280: perror("recvfrom"); ! 281: break; ! 282: } ! 283: if (fromlen != sizeof (struct sockaddr_in)) ! 284: break; ! 285: rip_input(&from, &inbuf.rip, cc); ! 286: } ! 287: } ! 288: ! 289: getsocket(domain, type, sin) ! 290: int domain, type; ! 291: struct sockaddr_in *sin; ! 292: { ! 293: int sock, on = 1; ! 294: ! 295: if ((sock = socket(domain, type, 0)) < 0) { ! 296: perror("socket"); ! 297: syslog(LOG_ERR, "socket: %m"); ! 298: return (-1); ! 299: } ! 300: #ifdef SO_BROADCAST ! 301: if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { ! 302: syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); ! 303: close(sock); ! 304: return (-1); ! 305: } ! 306: #endif ! 307: #ifdef SO_RCVBUF ! 308: for (on = bufspace; ; on -= 1024) { ! 309: if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, ! 310: &on, sizeof (on)) == 0) ! 311: break; ! 312: if (on <= 8*1024) { ! 313: syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m"); ! 314: break; ! 315: } ! 316: } ! 317: if (traceactions) ! 318: fprintf(ftrace, "recv buf %d\n", on); ! 319: #endif ! 320: if (bind(sock, sin, sizeof (*sin), 0) < 0) { ! 321: perror("bind"); ! 322: syslog(LOG_ERR, "bind: %m"); ! 323: close(sock); ! 324: return (-1); ! 325: } ! 326: if (fcntl(sock, F_SETFL, FNDELAY) == -1) ! 327: syslog(LOG_ERR, "fcntl FNDELAY: %m\n"); ! 328: return (sock); ! 329: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.