date and time created 82/11/02 22:28:04 by sam
authorSam Leffler <sam@ucbvax.Berkeley.EDU>
Wed, 3 Nov 1982 14:28:04 +0000 (06:28 -0800)
committerSam Leffler <sam@ucbvax.Berkeley.EDU>
Wed, 3 Nov 1982 14:28:04 +0000 (06:28 -0800)
SCCS-vsn: sbin/routed/main.c 4.1

usr/src/sbin/routed/main.c [new file with mode: 0644]

diff --git a/usr/src/sbin/routed/main.c b/usr/src/sbin/routed/main.c
new file mode 100644 (file)
index 0000000..263e9e5
--- /dev/null
@@ -0,0 +1,149 @@
+#ifndef lint
+static char sccsid[] = "@(#)main.c     4.1 %G%";
+#endif
+
+/*
+ * Routing Table Management Daemon
+ */
+#include "router.h"
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <errno.h>
+#include <nlist.h>
+#include <signal.h>
+#include <time.h>
+
+int    supplier = -1;          /* process should supply updates */
+
+struct rip *msg = (struct rip *)packet;
+
+main(argc, argv)
+       int argc;
+       char *argv[];
+{
+       int cc;
+       struct sockaddr from;
+       
+       argv0 = argv;
+#ifndef DEBUG
+       if (fork())
+               exit(0);
+       for (cc = 0; cc < 10; cc++)
+               (void) close(cc);
+       (void) open("/", 0);
+       (void) dup2(0, 1);
+       (void) dup2(0, 2);
+       { int t = open("/dev/tty", 2);
+         if (t >= 0) {
+               ioctl(t, TIOCNOTTY, (char *)0);
+               (void) close(t);
+         }
+       }
+#endif
+       if (tracing)
+               traceon("/etc/routerlog");
+
+       /*
+        * We use two sockets.  One for which outgoing
+        * packets are routed and for which they're not.
+        * The latter allows us to delete routing table
+        * entries in the kernel for network interfaces
+        * attached to our host which we believe are down
+        * while still polling it to see when/if it comes
+        * back up.  With the new ipc interface we'll be
+        * able to specify ``don't route'' as an option
+        * to send, but until then we utilize a second port.
+        */
+       sp = getservbyname("router", "udp");
+       if (sp == 0) {
+               fprintf(stderr, "routed: udp/router: unknown service\n");
+               exit(1);
+       }
+       routingaddr.sin_family = AF_INET;
+       routingaddr.sin_port = htons(sp->s_port);
+       noroutingaddr.sin_family = AF_INET;
+       noroutingaddr.sin_port = htons(sp->s_port + 1);
+again:
+       s = socket(SOCK_DGRAM, 0, &routingaddr, 0);
+       if (s < 0) {
+               perror("socket");
+               sleep(30);
+               goto again;
+       }
+again2:
+       snoroute = socket(SOCK_DGRAM, 0, &noroutingaddr, SO_DONTROUTE);
+       if (snoroute < 0) {
+               perror("socket");
+               sleep(30);
+               goto again2;
+       }
+       argv++, argc--;
+       while (argc > 0 && **argv == '-') {
+               if (!strcmp(*argv, "-s") == 0) {
+                       supplier = 1;
+                       argv++, argc--;
+                       continue;
+               }
+               if (!strcmp(*argv, "-q") == 0) {
+                       supplier = 0;
+                       argv++, argc--;
+                       continue;
+               }
+               goto usage;
+       }
+       if (argc > 0) {
+usage:
+               fprintf(stderr, "usage: routed [ -s ] [ -q ]\n");
+               exit(1);
+       }
+       /*
+        * Collect an initial view of the world by
+        * snooping in the kernel and the gateway kludge
+        * file.  Then, send a request packet on all
+        * directly connected networks to find out what
+        * everyone else thinks.
+        */
+       rtinit();
+       gwkludge();
+       ifinit();
+       if (supplier < 0)
+               supplier = 0;
+       msg->rip_cmd = RIPCMD_REQUEST;
+       msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
+       msg->rip_nets[0].rip_metric = HOPCNT_INFINITY;
+       toall(sendmsg);
+       sigset(SIGALRM, timer);
+       timer();
+
+#define        INFINITY        1000000
+       for (;;) {
+               int ibits;
+               register int n;
+
+               ibits = (1 << s) | (1 << snoroute);
+               n = select(32, &ibits, 0, INFINITY);
+               if (n < 0)
+                       continue;
+               if (ibits & (1 << s))
+                       process(s);
+               if (ibits & (1 << snoroute))
+                       process(snoroute);
+       }
+}
+
+process(fd)
+       int fd;
+{
+       register int cc;
+       struct sockaddr from;
+
+       cc = receive(fd, &from, packet, sizeof (packet));
+       if (cc <= 0) {
+               if (cc < 0 && errno != EINTR)
+                       perror("receive");
+               return;
+       }
+       sighold(SIGALRM);
+       rip_input(&from, cc);
+       sigrelse(SIGALRM);
+}