1: /* 2: * Copyright (c) 1985 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: * Includes material written at Cornell University by Bill Nesheim 7: * with permission of the author. 8: */ 9: 10: #ifndef lint 11: char copyright[] = 12: "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 13: All rights reserved.\n"; 14: #endif not lint 15: 16: #ifndef lint 17: static char sccsid[] = "@(#)main.c 5.5 (Berkeley) 2/14/86"; 18: #endif not lint 19: 20: /* 21: * XNS Routing Information Protocol Daemon 22: */ 23: #include "defs.h" 24: #include <sys/ioctl.h> 25: #include <sys/time.h> 26: 27: #include <net/if.h> 28: 29: #include <errno.h> 30: #include <nlist.h> 31: #include <signal.h> 32: 33: int supplier = -1; /* process should supply updates */ 34: extern int gateway; 35: 36: struct rip *msg = (struct rip *) &packet[sizeof (struct idp)]; 37: int hup(), fkexit(); 38: 39: main(argc, argv) 40: int argc; 41: char *argv[]; 42: { 43: int cc; 44: struct sockaddr from; 45: u_char retry; 46: 47: argv0 = argv; 48: argv++, argc--; 49: while (argc > 0 && **argv == '-') { 50: if (strcmp(*argv, "-s") == 0) { 51: supplier = 1; 52: argv++, argc--; 53: continue; 54: } 55: if (strcmp(*argv, "-q") == 0) { 56: supplier = 0; 57: argv++, argc--; 58: continue; 59: } 60: if (strcmp(*argv, "-R") == 0) { 61: noteremoterequests++; 62: argv++, argc--; 63: continue; 64: } 65: if (strcmp(*argv, "-t") == 0) { 66: tracepackets++; 67: argv++, argc--; 68: ftrace = stderr; 69: tracing = 1; 70: continue; 71: } 72: if (strcmp(*argv, "-g") == 0) { 73: gateway = 1; 74: argv++, argc--; 75: continue; 76: } 77: if (strcmp(*argv, "-l") == 0) { 78: gateway = -1; 79: argv++, argc--; 80: continue; 81: } 82: fprintf(stderr, 83: "usage: xnsrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ]\n"); 84: exit(1); 85: } 86: 87: 88: #ifndef DEBUG 89: if (!tracepackets) { 90: int t; 91: 92: if (fork()) 93: exit(0); 94: for (t = 0; t < 20; t++) 95: (void) close(t); 96: (void) open("/", 0); 97: (void) dup2(0, 1); 98: (void) dup2(0, 2); 99: t = open("/dev/tty", 2); 100: if (t >= 0) { 101: ioctl(t, TIOCNOTTY, (char *)0); 102: (void) close(t); 103: } 104: } 105: #endif 106: openlog("XNSrouted", LOG_PID, LOG_DAEMON); 107: 108: ns_anynet.s_net[0] = -1; ns_anynet.s_net[1] = -1; 109: addr.sns_family = AF_NS; 110: addr.sns_port = htons(IDPPORT_RIF); 111: s = getsocket(SOCK_DGRAM, 0, &addr); 112: if (s < 0) 113: exit(1); 114: /* 115: * Any extra argument is considered 116: * a tracing log file. 117: */ 118: if (argc > 0) 119: traceon(*argv); 120: /* 121: * Collect an initial view of the world by 122: * snooping in the kernel. Then, send a request packet on all 123: * directly connected networks to find out what 124: * everyone else thinks. 125: */ 126: rtinit(); 127: ifinit(); 128: if (supplier < 0) 129: supplier = 0; 130: /* request the state of the world */ 131: msg->rip_cmd = htons(RIPCMD_REQUEST); 132: msg->rip_nets[0].rip_dst = ns_anynet; 133: msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); 134: toall(sendmsg); 135: signal(SIGALRM, timer); 136: signal(SIGHUP, hup); 137: signal(SIGINT, hup); 138: signal(SIGEMT, fkexit); 139: timer(); 140: 141: 142: for (;;) 143: process(s); 144: 145: } 146: 147: process(fd) 148: int fd; 149: { 150: struct sockaddr from; 151: int fromlen = sizeof (from), cc, omask; 152: struct idp *idp = (struct idp *)packet; 153: 154: cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen); 155: if (cc <= 0) { 156: if (cc < 0 && errno != EINTR) 157: syslog("recvfrom: %m"); 158: return; 159: } 160: if (tracepackets > 1 && ftrace) { 161: fprintf(ftrace,"rcv %d bytes on %s ", cc, xns_ntoa(&idp->idp_dna)); 162: fprintf(ftrace," from %s\n", xns_ntoa(&idp->idp_sna)); 163: } 164: 165: if (noteremoterequests && !ns_neteqnn(idp->idp_sna.x_net, ns_zeronet) 166: && !ns_neteq(idp->idp_sna, idp->idp_dna)) 167: { 168: syslog(LOG_ERR, 169: "net of interface (%s) != net on ether (%s)!\n", 170: xns_nettoa(idp->idp_dna.x_net), 171: xns_nettoa(idp->idp_sna.x_net)); 172: } 173: 174: /* We get the IDP header in front of the RIF packet*/ 175: cc -= sizeof (struct idp); 176: #define mask(s) (1<<((s)-1)) 177: omask = sigblock(mask(SIGALRM)); 178: rip_input(&from, cc); 179: sigsetmask(omask); 180: } 181: 182: getsocket(type, proto, sns) 183: int type, proto; 184: struct sockaddr_ns *sns; 185: { 186: int domain = sns->sns_family; 187: int retry, s, on = 1; 188: 189: retry = 1; 190: while ((s = socket(domain, type, proto)) < 0 && retry) { 191: syslog("socket: %m"); 192: sleep(5 * retry); 193: retry <<= 1; 194: } 195: if (retry == 0) 196: return (-1); 197: while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) { 198: syslog("bind: %m"); 199: sleep(5 * retry); 200: retry <<= 1; 201: } 202: if (retry == 0) 203: return (-1); 204: if (domain==AF_NS) { 205: struct idp idp; 206: if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) { 207: syslog("setsockopt SEE HEADERS: %m"); 208: exit(1); 209: } 210: idp.idp_pt = NSPROTO_RI; 211: if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) { 212: syslog("setsockopt SET HEADER: %m"); 213: exit(1); 214: } 215: } 216: if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { 217: syslog("setsockopt SO_BROADCAST: %m"); 218: exit(1); 219: } 220: return (s); 221: } 222: 223: /* 224: * Fork and exit on EMT-- for profiling. 225: */ 226: fkexit() 227: { 228: if (fork() == 0) 229: exit(0); 230: }