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

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

diff --git a/usr/src/sbin/routed/input.c b/usr/src/sbin/routed/input.c
new file mode 100644 (file)
index 0000000..8461d39
--- /dev/null
@@ -0,0 +1,114 @@
+#ifndef lint
+static char sccsid[] = "@(#)input.c    4.1 %G%";
+#endif
+
+/*
+ * Routing Table Management Daemon
+ */
+#include "router.h"
+
+/*
+ * Process a newly received packet.
+ */
+rip_input(from, size)
+       struct sockaddr *from;
+       int size;
+{
+       struct rt_entry *rt;
+       struct netinfo *n;
+       struct interface *ifp;
+       int newsize;
+       struct afswitch *afp;
+
+       ifp = 0;
+       TRACE_INPUT(ifp, from, size);
+       if (from->sa_family >= AF_MAX)
+               return;
+       afp = &afswitch[from->sa_family];
+       switch (msg->rip_cmd) {
+
+       case RIPCMD_REQUEST:
+               newsize = 0;
+               size -= 4 * sizeof (char);
+               n = msg->rip_nets;
+               while (size > 0) {
+                       if (size < sizeof (struct netinfo))
+                               break;
+                       size -= sizeof (struct netinfo);
+
+                       /* 
+                        * A single entry with sa_family == AF_UNSPEC and
+                        * metric ``infinity'' means ``all routes''.
+                        */
+                       if (n->rip_dst.sa_family == AF_UNSPEC &&
+                           n->rip_metric == HOPCNT_INFINITY && size == 0) {
+                               supply(from, 0, ifp);
+                               return;
+                       }
+                       rt = rtlookup(&n->rip_dst);
+                       n->rip_metric = rt == 0 ? HOPCNT_INFINITY :
+                               min(rt->rt_metric+1, HOPCNT_INFINITY);
+                       n++, newsize += sizeof (struct netinfo);
+               }
+               if (newsize > 0) {
+                       msg->rip_cmd = RIPCMD_RESPONSE;
+                       newsize += sizeof (int);
+                       (*afp->af_output)(s, from, newsize);
+               }
+               return;
+
+       case RIPCMD_TRACEON:
+       case RIPCMD_TRACEOFF:
+               /* verify message came from a priviledged port */
+               if ((*afp->af_portcheck)(from) == 0)
+                       return;
+               packet[size] = '\0';
+               if (msg->rip_cmd == RIPCMD_TRACEON)
+                       traceon(msg->rip_tracefile);
+               else
+                       traceoff();
+               return;
+
+       case RIPCMD_RESPONSE:
+               /* verify message came from a router */
+               if ((*afp->af_portmatch)(from) == 0)
+                       return;
+               (*afp->af_canon)(from);
+               /* are we talking to ourselves? */
+               ifp = if_ifwithaddr(from);
+               if (ifp) {
+                       rt = rtfind(from);
+                       if (rt == 0)
+                               addrouteforif(ifp);
+                       else
+                               rt->rt_timer = 0;
+                       return;
+               }
+               size -= 4 * sizeof (char);
+               n = msg->rip_nets;
+               for (; size > 0; size -= sizeof (struct netinfo), n++) {
+                       if (size < sizeof (struct netinfo))
+                               break;
+                       if (n->rip_metric >= HOPCNT_INFINITY)
+                               continue;
+                       rt = rtlookup(&n->rip_dst);
+                       if (rt == 0) {
+                               rtadd(&n->rip_dst, from, n->rip_metric, 0);
+                               continue;
+                       }
+
+                       /*
+                        * Update if from gateway, shorter, or getting
+                        * stale and equivalent.
+                        */
+                       if (equal(from, &rt->rt_router) ||
+                           n->rip_metric < rt->rt_metric ||
+                           (rt->rt_timer > (EXPIRE_TIME/2) &&
+                           rt->rt_metric == n->rip_metric)) {
+                               rtchange(rt, from, n->rip_metric);
+                               rt->rt_timer = 0;
+                       }
+               }
+               return;
+       }
+}