1*9017Ssam #ifndef lint 2*9017Ssam static char sccsid[] = "@(#)main.c 4.1 11/02/82"; 3*9017Ssam #endif 4*9017Ssam 5*9017Ssam /* 6*9017Ssam * Routing Table Management Daemon 7*9017Ssam */ 8*9017Ssam #include "router.h" 9*9017Ssam #include <sys/ioctl.h> 10*9017Ssam #include <net/if.h> 11*9017Ssam #include <errno.h> 12*9017Ssam #include <nlist.h> 13*9017Ssam #include <signal.h> 14*9017Ssam #include <time.h> 15*9017Ssam 16*9017Ssam int supplier = -1; /* process should supply updates */ 17*9017Ssam 18*9017Ssam struct rip *msg = (struct rip *)packet; 19*9017Ssam 20*9017Ssam main(argc, argv) 21*9017Ssam int argc; 22*9017Ssam char *argv[]; 23*9017Ssam { 24*9017Ssam int cc; 25*9017Ssam struct sockaddr from; 26*9017Ssam 27*9017Ssam argv0 = argv; 28*9017Ssam #ifndef DEBUG 29*9017Ssam if (fork()) 30*9017Ssam exit(0); 31*9017Ssam for (cc = 0; cc < 10; cc++) 32*9017Ssam (void) close(cc); 33*9017Ssam (void) open("/", 0); 34*9017Ssam (void) dup2(0, 1); 35*9017Ssam (void) dup2(0, 2); 36*9017Ssam { int t = open("/dev/tty", 2); 37*9017Ssam if (t >= 0) { 38*9017Ssam ioctl(t, TIOCNOTTY, (char *)0); 39*9017Ssam (void) close(t); 40*9017Ssam } 41*9017Ssam } 42*9017Ssam #endif 43*9017Ssam if (tracing) 44*9017Ssam traceon("/etc/routerlog"); 45*9017Ssam 46*9017Ssam /* 47*9017Ssam * We use two sockets. One for which outgoing 48*9017Ssam * packets are routed and for which they're not. 49*9017Ssam * The latter allows us to delete routing table 50*9017Ssam * entries in the kernel for network interfaces 51*9017Ssam * attached to our host which we believe are down 52*9017Ssam * while still polling it to see when/if it comes 53*9017Ssam * back up. With the new ipc interface we'll be 54*9017Ssam * able to specify ``don't route'' as an option 55*9017Ssam * to send, but until then we utilize a second port. 56*9017Ssam */ 57*9017Ssam sp = getservbyname("router", "udp"); 58*9017Ssam if (sp == 0) { 59*9017Ssam fprintf(stderr, "routed: udp/router: unknown service\n"); 60*9017Ssam exit(1); 61*9017Ssam } 62*9017Ssam routingaddr.sin_family = AF_INET; 63*9017Ssam routingaddr.sin_port = htons(sp->s_port); 64*9017Ssam noroutingaddr.sin_family = AF_INET; 65*9017Ssam noroutingaddr.sin_port = htons(sp->s_port + 1); 66*9017Ssam again: 67*9017Ssam s = socket(SOCK_DGRAM, 0, &routingaddr, 0); 68*9017Ssam if (s < 0) { 69*9017Ssam perror("socket"); 70*9017Ssam sleep(30); 71*9017Ssam goto again; 72*9017Ssam } 73*9017Ssam again2: 74*9017Ssam snoroute = socket(SOCK_DGRAM, 0, &noroutingaddr, SO_DONTROUTE); 75*9017Ssam if (snoroute < 0) { 76*9017Ssam perror("socket"); 77*9017Ssam sleep(30); 78*9017Ssam goto again2; 79*9017Ssam } 80*9017Ssam argv++, argc--; 81*9017Ssam while (argc > 0 && **argv == '-') { 82*9017Ssam if (!strcmp(*argv, "-s") == 0) { 83*9017Ssam supplier = 1; 84*9017Ssam argv++, argc--; 85*9017Ssam continue; 86*9017Ssam } 87*9017Ssam if (!strcmp(*argv, "-q") == 0) { 88*9017Ssam supplier = 0; 89*9017Ssam argv++, argc--; 90*9017Ssam continue; 91*9017Ssam } 92*9017Ssam goto usage; 93*9017Ssam } 94*9017Ssam if (argc > 0) { 95*9017Ssam usage: 96*9017Ssam fprintf(stderr, "usage: routed [ -s ] [ -q ]\n"); 97*9017Ssam exit(1); 98*9017Ssam } 99*9017Ssam /* 100*9017Ssam * Collect an initial view of the world by 101*9017Ssam * snooping in the kernel and the gateway kludge 102*9017Ssam * file. Then, send a request packet on all 103*9017Ssam * directly connected networks to find out what 104*9017Ssam * everyone else thinks. 105*9017Ssam */ 106*9017Ssam rtinit(); 107*9017Ssam gwkludge(); 108*9017Ssam ifinit(); 109*9017Ssam if (supplier < 0) 110*9017Ssam supplier = 0; 111*9017Ssam msg->rip_cmd = RIPCMD_REQUEST; 112*9017Ssam msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC; 113*9017Ssam msg->rip_nets[0].rip_metric = HOPCNT_INFINITY; 114*9017Ssam toall(sendmsg); 115*9017Ssam sigset(SIGALRM, timer); 116*9017Ssam timer(); 117*9017Ssam 118*9017Ssam #define INFINITY 1000000 119*9017Ssam for (;;) { 120*9017Ssam int ibits; 121*9017Ssam register int n; 122*9017Ssam 123*9017Ssam ibits = (1 << s) | (1 << snoroute); 124*9017Ssam n = select(32, &ibits, 0, INFINITY); 125*9017Ssam if (n < 0) 126*9017Ssam continue; 127*9017Ssam if (ibits & (1 << s)) 128*9017Ssam process(s); 129*9017Ssam if (ibits & (1 << snoroute)) 130*9017Ssam process(snoroute); 131*9017Ssam } 132*9017Ssam } 133*9017Ssam 134*9017Ssam process(fd) 135*9017Ssam int fd; 136*9017Ssam { 137*9017Ssam register int cc; 138*9017Ssam struct sockaddr from; 139*9017Ssam 140*9017Ssam cc = receive(fd, &from, packet, sizeof (packet)); 141*9017Ssam if (cc <= 0) { 142*9017Ssam if (cc < 0 && errno != EINTR) 143*9017Ssam perror("receive"); 144*9017Ssam return; 145*9017Ssam } 146*9017Ssam sighold(SIGALRM); 147*9017Ssam rip_input(&from, cc); 148*9017Ssam sigrelse(SIGALRM); 149*9017Ssam } 150