summaryrefslogtreecommitdiffstats
path: root/usr.sbin/XNSrouted/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/XNSrouted/input.c')
-rw-r--r--usr.sbin/XNSrouted/input.c189
1 files changed, 189 insertions, 0 deletions
diff --git a/usr.sbin/XNSrouted/input.c b/usr.sbin/XNSrouted/input.c
new file mode 100644
index 0000000..b64fca2
--- /dev/null
+++ b/usr.sbin/XNSrouted/input.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This file includes significant work done at Cornell University by
+ * Bill Nesheim. That work included by permission.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/5/93";
+#endif /* not lint */
+
+/*
+ * XNS Routing Table Management Daemon
+ */
+#include "defs.h"
+
+struct sockaddr *
+xns_nettosa(net)
+union ns_net net;
+{
+ static struct sockaddr_ns sxn;
+ extern char ether_broadcast_addr[6];
+
+ bzero(&sxn, sizeof (struct sockaddr_ns));
+ sxn.sns_family = AF_NS;
+ sxn.sns_len = sizeof (sxn);
+ sxn.sns_addr.x_net = net;
+ sxn.sns_addr.x_host = *(union ns_host *)ether_broadcast_addr;
+ return( (struct sockaddr *)&sxn);
+
+}
+
+/*
+ * 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];
+
+ size -= sizeof (u_short) /* command */;
+ n = msg->rip_nets;
+
+ switch (ntohs(msg->rip_cmd)) {
+
+ case RIPCMD_REQUEST:
+ newsize = 0;
+ while (size > 0) {
+ if (size < sizeof (struct netinfo))
+ break;
+ size -= sizeof (struct netinfo);
+
+ /*
+ * A single entry with rip_dst == DSTNETS_ALL and
+ * metric ``infinity'' means ``all routes''.
+ */
+ if (ns_neteqnn(n->rip_dst, ns_anynet) &&
+ ntohs(n->rip_metric) == HOPCNT_INFINITY &&
+ size == 0) {
+ ifp = if_ifwithnet(from);
+ supply(from, 0, ifp);
+ return;
+ }
+ /*
+ * request for specific nets
+ */
+ rt = rtlookup(xns_nettosa(n->rip_dst));
+ if (ftrace) {
+ fprintf(ftrace,
+ "specific request for %s",
+ xns_nettoa(n->rip_dst));
+ fprintf(ftrace,
+ " yields route %x\n",
+ rt);
+ }
+ n->rip_metric = htons( rt == 0 ? HOPCNT_INFINITY :
+ min(rt->rt_metric+1, HOPCNT_INFINITY));
+ n++;
+ newsize += sizeof (struct netinfo);
+ }
+ if (newsize > 0) {
+ msg->rip_cmd = htons(RIPCMD_RESPONSE);
+ newsize += sizeof (u_short);
+ /* should check for if with dstaddr(from) first */
+ (*afp->af_output)(0, from, newsize);
+ ifp = if_ifwithnet(from);
+ TRACE_OUTPUT(ifp, from, newsize);
+ if (ftrace) {
+ fprintf(ftrace,
+ "request arrived on interface %s\n",
+ ifp->int_name);
+ }
+ }
+ 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? */
+ if (ifp = if_ifwithaddr(from)) {
+ rt = rtfind(from);
+ if (rt == 0 || (rt->rt_state & RTS_INTERFACE) == 0)
+ addrouteforif(ifp);
+ else
+ rt->rt_timer = 0;
+ return;
+ }
+ /* Update timer for interface on which the packet arrived.
+ * If from other end of a point-to-point link that isn't
+ * in the routing tables, (re-)add the route.
+ */
+ if ((rt = rtfind(from)) && (rt->rt_state & RTS_INTERFACE)) {
+ if(ftrace) fprintf(ftrace, "Got route\n");
+ rt->rt_timer = 0;
+ } else if (ifp = if_ifwithdstaddr(from)) {
+ if(ftrace) fprintf(ftrace, "Got partner\n");
+ addrouteforif(ifp);
+ }
+ for (; size > 0; size -= sizeof (struct netinfo), n++) {
+ struct sockaddr *sa;
+ if (size < sizeof (struct netinfo))
+ break;
+ if ((unsigned) ntohs(n->rip_metric) >= HOPCNT_INFINITY)
+ continue;
+ rt = rtfind(sa = xns_nettosa(n->rip_dst));
+ if (rt == 0) {
+ rtadd(sa, from, ntohs(n->rip_metric), 0);
+ continue;
+ }
+
+ /*
+ * Update if from gateway and different,
+ * from anywhere and shorter, or getting stale and equivalent.
+ */
+ if ((equal(from, &rt->rt_router) &&
+ ntohs(n->rip_metric) != rt->rt_metric ) ||
+ (unsigned) ntohs(n->rip_metric) < rt->rt_metric ||
+ (rt->rt_timer > (EXPIRE_TIME/2) &&
+ rt->rt_metric == ntohs(n->rip_metric))) {
+ rtchange(rt, from, ntohs(n->rip_metric));
+ rt->rt_timer = 0;
+ }
+ }
+ return;
+ }
+}
OpenPOWER on IntegriCloud