121996Sdist /* 221996Sdist * Copyright (c) 1983 Regents of the University of California. 3*33489Sbostic * All rights reserved. 4*33489Sbostic * 5*33489Sbostic * Redistribution and use in source and binary forms are permitted 6*33489Sbostic * provided that this notice is preserved and that due credit is given 7*33489Sbostic * to the University of California at Berkeley. The name of the University 8*33489Sbostic * may not be used to endorse or promote products derived from this 9*33489Sbostic * software without specific prior written permission. This software 10*33489Sbostic * is provided ``as is'' without express or implied warranty. 1121996Sdist */ 1221996Sdist 139017Ssam #ifndef lint 1421996Sdist char copyright[] = 1521996Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 1621996Sdist All rights reserved.\n"; 17*33489Sbostic #endif /* not lint */ 189017Ssam 1921996Sdist #ifndef lint 20*33489Sbostic static char sccsid[] = "@(#)main.c 5.12 (Berkeley) 02/16/88"; 21*33489Sbostic #endif /* not lint */ 2221996Sdist 239017Ssam /* 249017Ssam * Routing Table Management Daemon 259017Ssam */ 2610245Ssam #include "defs.h" 279017Ssam #include <sys/ioctl.h> 2813602Ssam #include <sys/time.h> 2913602Ssam 309017Ssam #include <net/if.h> 3113602Ssam 329017Ssam #include <errno.h> 339017Ssam #include <signal.h> 3417570Skarels #include <syslog.h> 359017Ssam 369017Ssam int supplier = -1; /* process should supply updates */ 3721847Skarels int gateway = 0; /* 1 if we are a gateway to parts beyond */ 3831220Skarels int debug = 0; 399017Ssam 409017Ssam struct rip *msg = (struct rip *)packet; 4131220Skarels int hup(), rtdeleteall(); 429017Ssam 439017Ssam main(argc, argv) 449017Ssam int argc; 459017Ssam char *argv[]; 469017Ssam { 479017Ssam int cc; 489017Ssam struct sockaddr from; 4910245Ssam u_char retry; 509017Ssam 519017Ssam argv0 = argv; 5224848Seric openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON); 5330930Skarels setlogmask(LOG_UPTO(LOG_WARNING)); 549017Ssam sp = getservbyname("router", "udp"); 5510245Ssam if (sp == NULL) { 5610245Ssam fprintf(stderr, "routed: router/udp: unknown service\n"); 579017Ssam exit(1); 589017Ssam } 5910245Ssam addr.sin_family = AF_INET; 6010245Ssam addr.sin_port = sp->s_port; 6110245Ssam s = getsocket(AF_INET, SOCK_DGRAM, &addr); 6210245Ssam if (s < 0) 6310245Ssam exit(1); 649017Ssam argv++, argc--; 659017Ssam while (argc > 0 && **argv == '-') { 6610636Ssam if (strcmp(*argv, "-s") == 0) { 679017Ssam supplier = 1; 689017Ssam argv++, argc--; 699017Ssam continue; 709017Ssam } 7110636Ssam if (strcmp(*argv, "-q") == 0) { 729017Ssam supplier = 0; 739017Ssam argv++, argc--; 749017Ssam continue; 759017Ssam } 7610636Ssam if (strcmp(*argv, "-t") == 0) { 7710636Ssam tracepackets++; 7830930Skarels setlogmask(LOG_UPTO(LOG_DEBUG)); 7910636Ssam argv++, argc--; 8010636Ssam continue; 8110636Ssam } 8226341Skarels if (strcmp(*argv, "-d") == 0) { 8331220Skarels debug++; 8430930Skarels setlogmask(LOG_UPTO(LOG_DEBUG)); 8526341Skarels argv++, argc--; 8626341Skarels continue; 8726341Skarels } 8816326Skarels if (strcmp(*argv, "-g") == 0) { 8916326Skarels gateway = 1; 9016326Skarels argv++, argc--; 9116326Skarels continue; 9216326Skarels } 9316326Skarels fprintf(stderr, 9421847Skarels "usage: routed [ -s ] [ -q ] [ -t ] [ -g ]\n"); 959017Ssam exit(1); 969017Ssam } 9731220Skarels if (tracepackets == 0 && debug == 0) { 9810636Ssam int t; 9910636Ssam 10010636Ssam if (fork()) 10110636Ssam exit(0); 10210637Ssam for (t = 0; t < 20; t++) 10310637Ssam if (t != s) 10424761Ssklower (void) close(t); 10510636Ssam (void) open("/", 0); 10610636Ssam (void) dup2(0, 1); 10710636Ssam (void) dup2(0, 2); 10810636Ssam t = open("/dev/tty", 2); 10910636Ssam if (t >= 0) { 11010636Ssam ioctl(t, TIOCNOTTY, (char *)0); 11110636Ssam (void) close(t); 11210636Ssam } 11310636Ssam } 1149017Ssam /* 11510245Ssam * Any extra argument is considered 11610245Ssam * a tracing log file. 11710245Ssam */ 11810245Ssam if (argc > 0) 11910245Ssam traceon(*argv); 12010245Ssam /* 1219017Ssam * Collect an initial view of the world by 12221847Skarels * checking the interface configuration and the gateway kludge 1239017Ssam * file. Then, send a request packet on all 1249017Ssam * directly connected networks to find out what 1259017Ssam * everyone else thinks. 1269017Ssam */ 1279017Ssam rtinit(); 12830927Skarels ifinit(); 1299017Ssam gwkludge(); 13021847Skarels if (gateway > 0) 13121847Skarels rtdefault(); 1329017Ssam if (supplier < 0) 1339017Ssam supplier = 0; 1349017Ssam msg->rip_cmd = RIPCMD_REQUEST; 13512726Ssam msg->rip_vers = RIPVERSION; 1369017Ssam msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC; 1379017Ssam msg->rip_nets[0].rip_metric = HOPCNT_INFINITY; 13812726Ssam msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC); 13912726Ssam msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY); 1409017Ssam toall(sendmsg); 14113036Ssam signal(SIGALRM, timer); 14216314Skarels signal(SIGHUP, hup); 14317570Skarels signal(SIGTERM, hup); 14431220Skarels signal(SIGINT, rtdeleteall); 1459017Ssam timer(); 1469017Ssam 1479017Ssam for (;;) { 1489017Ssam int ibits; 1499017Ssam register int n; 1509017Ssam 15110245Ssam ibits = 1 << s; 15210245Ssam n = select(20, &ibits, 0, 0, 0); 1539017Ssam if (n < 0) 1549017Ssam continue; 1559017Ssam if (ibits & (1 << s)) 1569017Ssam process(s); 15710245Ssam /* handle ICMP redirects */ 1589017Ssam } 1599017Ssam } 1609017Ssam 1619017Ssam process(fd) 1629017Ssam int fd; 1639017Ssam { 1649017Ssam struct sockaddr from; 16513036Ssam int fromlen = sizeof (from), cc, omask; 1669017Ssam 16710245Ssam cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen); 1689017Ssam if (cc <= 0) { 1699017Ssam if (cc < 0 && errno != EINTR) 17010245Ssam perror("recvfrom"); 1719017Ssam return; 1729017Ssam } 17310245Ssam if (fromlen != sizeof (struct sockaddr_in)) 17410245Ssam return; 17524761Ssklower omask = sigblock(sigmask(SIGALRM)); 1769017Ssam rip_input(&from, cc); 17713036Ssam sigsetmask(omask); 1789017Ssam } 17910245Ssam 18010245Ssam getsocket(domain, type, sin) 18110245Ssam int domain, type; 18210245Ssam struct sockaddr_in *sin; 18310245Ssam { 18425516Skarels int s, on = 1; 18510245Ssam 18625702Smckusick if ((s = socket(domain, type, 0)) < 0) { 18710245Ssam perror("socket"); 18817570Skarels syslog(LOG_ERR, "socket: %m"); 18910245Ssam return (-1); 19017570Skarels } 19117570Skarels if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { 19217570Skarels syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); 19325516Skarels close(s); 19425516Skarels return (-1); 19517570Skarels } 19630927Skarels on = 48*1024; 19730927Skarels if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &on, sizeof (on)) < 0) 19830927Skarels syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m"); 19925516Skarels if (bind(s, sin, sizeof (*sin), 0) < 0) { 20010245Ssam perror("bind"); 20117570Skarels syslog(LOG_ERR, "bind: %m"); 20225516Skarels close(s); 20310245Ssam return (-1); 20417570Skarels } 20510245Ssam return (s); 20610245Ssam } 207