summaryrefslogtreecommitdiffstats
path: root/usr.sbin/routed/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/routed/input.c')
-rw-r--r--usr.sbin/routed/input.c193
1 files changed, 93 insertions, 100 deletions
diff --git a/usr.sbin/routed/input.c b/usr.sbin/routed/input.c
index 46ae9dc..2a369d0 100644
--- a/usr.sbin/routed/input.c
+++ b/usr.sbin/routed/input.c
@@ -31,17 +31,19 @@
* SUCH DAMAGE.
*/
-#ifndef lint
+#if !defined(lint) && !defined(sgi)
+/*
static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/5/93";
+*/
+static const char rcsid[] =
+ "$Id$";
#endif /* not lint */
-#ident "$Revision: 1.1.3.1 $"
-
#include "defs.h"
static void input(struct sockaddr_in *, struct interface*, struct rip *, int);
static void input_route(struct interface *, naddr,
- naddr, naddr, naddr, int, u_short);
+ naddr, naddr, naddr, struct netinfo *);
/* process RIP input
@@ -97,8 +99,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
if (ifp != 0)
ifp->int_state |= IS_ACTIVE;
- if (TRACEPACKETS)
- trace_rip("Recv", "from", from, ifp, rip, size);
+ trace_rip("Recv", "from", from, ifp, rip, size);
if (rip->rip_vers == 0) {
if (from->sin_addr.s_addr != bad_router)
@@ -138,8 +139,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
" from %s discarded",
naddr_ntoa(FROM_NADDR));
use_auth = from->sin_addr.s_addr;
- if (TRACEPACKETS)
- trace_msg("discard authenticated RIPv2 message\n");
+ trace_pkt("discard authenticated RIPv2 message\n");
return;
}
@@ -148,28 +148,29 @@ input(struct sockaddr_in *from, /* received from this IP address */
/* did the request come from a router?
*/
if (from->sin_port == htons(RIP_PORT)) {
- /* yes, ignore it if RIP is off
+ /* yes, ignore it if RIP is off so that it does not
+ * depend on us.
*/
if (rip_sock < 0) {
- trace_msg("ignore request while RIP off");
+ trace_pkt("ignore request while RIP off\n");
return;
}
/* Ignore the request if we talking to ourself
* (and not a remote gateway).
*/
- ifp1 = ifwithaddr(FROM_NADDR, 0, 0);
- if (ifp1 != 0
- && (!(ifp1->int_state & IS_REMOTE)
- || ifp->int_metric != 0)) {
- if (TRACEPACKETS)
- trace_msg("discard our own packet\n");
+ if (ifwithaddr(FROM_NADDR, 0, 0) != 0) {
+ trace_pkt("discard our own RIP request\n");
return;
}
}
/* According to RFC 1723, we should ignore unathenticated
- * queries. That is too silly to bother with.
+ * queries. That is too silly to bother with. Sheesh!
+ * Are forwarding tables supposed to be secret? When
+ * a bad guy can infer them with test traffic?
+ * Maybe on firewalls you'd care, but not enough to
+ * give up the diagnostic facilities of remote probing.
*/
if (n >= lim
@@ -234,13 +235,10 @@ input(struct sockaddr_in *from, /* received from this IP address */
return;
}
- if (rip->rip_vers == RIPv1) {
- mask = ripv1_mask_host(dst,ifp,0);
- } else {
- mask = ntohl(n->n_mask);
- if (mask == 0)
- mask = ripv1_mask_host(dst,ifp,0);
- }
+ if (rip->rip_vers == RIPv1
+ || 0 == (mask = ntohl(n->n_mask)))
+ mask = ripv1_mask_host(dst,ifp);
+
rt = rtget(dst, mask);
if (!rt)
rt = rtfind(n->n_dst);
@@ -250,8 +248,9 @@ input(struct sockaddr_in *from, /* received from this IP address */
if (!rt) {
n->n_metric = HOPCNT_INFINITY;
} else {
- n->n_metric = (rt->rt_metric
- + (ifp ? ifp->int_metric : 1));
+ n->n_metric = rt->rt_metric+1;
+ if (ifp != 0)
+ n->n_metric += ifp->int_metric;
if (n->n_metric > HOPCNT_INFINITY)
n->n_metric = HOPCNT_INFINITY;
if (rip->rip_vers == RIPv1) {
@@ -304,7 +303,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
rip->rip_tracefile[size-4] = '\0';
trace_on(rip->rip_tracefile, 0);
} else {
- trace_off("tracing turned off by ",
+ trace_off("tracing turned off by %s\n",
naddr_ntoa(FROM_NADDR));
}
return;
@@ -319,15 +318,12 @@ input(struct sockaddr_in *from, /* received from this IP address */
/* verify message came from a router */
if (from->sin_port != ntohs(RIP_PORT)) {
- if (TRACEPACKETS)
- trace_msg("discard response"
- " from unknown port\n");
+ trace_pkt("discard RIP response from unknown port\n");
return;
}
if (rip_sock < 0) {
- if (TRACEPACKETS)
- trace_msg("discard response while RIP off");
+ trace_pkt("discard response while RIP off\n");
return;
}
@@ -335,18 +331,19 @@ input(struct sockaddr_in *from, /* received from this IP address */
*/
ifp1 = ifwithaddr(FROM_NADDR, 0, 1);
if (ifp1) {
- if (ifp1->int_state & IS_PASSIVE) {
- msglog("bogus input from %s on supposedly"
- " passive interface %s",
- naddr_ntoa(FROM_NADDR),
- ifp1->int_name);
-
- } else if (ifp1->int_state & IS_REMOTE) {
- ifp1->int_act_time = now.tv_sec;
- if (ifok(ifp1, "remote "))
- addrouteforif(ifp1);
- } else if (TRACEPACKETS) {
- trace_msg("discard our own packet\n");
+ if (ifp1->int_state & IS_REMOTE) {
+ if (ifp1->int_state & IS_PASSIVE) {
+ msglog("bogus input from %s on"
+ " supposedly passive %s",
+ naddr_ntoa(FROM_NADDR),
+ ifp1->int_name);
+ } else {
+ ifp1->int_act_time = now.tv_sec;
+ if (if_ok(ifp1, "remote "))
+ addrouteforif(ifp1);
+ }
+ } else {
+ trace_pkt("discard our own RIP response\n");
}
return;
}
@@ -356,13 +353,20 @@ input(struct sockaddr_in *from, /* received from this IP address */
* broadcast or point-to-point networks, and from
* those listed in /etc/gateways.
*/
- if (!ifp || (ifp->int_state & IS_PASSIVE)) {
+ if (!ifp) {
if (from->sin_addr.s_addr != unk_router)
- msglog("packet from unknown router %s",
+ msglog("packet from unknown router %s"
+ " or via unidentified interface",
naddr_ntoa(FROM_NADDR));
unk_router = from->sin_addr.s_addr;
return;
}
+ if (ifp->int_state & IS_PASSIVE) {
+ trace_act("packet from %s via passive interface %s\n",
+ naddr_ntoa(FROM_NADDR),
+ ifp->int_name);
+ return;
+ }
/* Check required version
*/
@@ -370,19 +374,16 @@ input(struct sockaddr_in *from, /* received from this IP address */
&& rip->rip_vers == RIPv1)
|| ((ifp->int_state & IS_NO_RIPV2_IN)
&& rip->rip_vers != RIPv1)) {
- if (TRACEPACKETS)
- trace_msg("discard RIPv%d response\n",
- rip->rip_vers);
+ trace_pkt("discard RIPv%d response\n",
+ rip->rip_vers);
return;
}
/* Ignore routes via dead interface.
*/
if (ifp->int_state & IS_BROKE) {
- if (TRACEPACKETS)
- trace_msg("discard response via"
- " broken interface %s\n",
- ifp->int_name);
+ trace_pkt("discard response via broken interface %s\n",
+ ifp->int_name);
return;
}
@@ -466,9 +467,9 @@ input(struct sockaddr_in *from, /* received from this IP address */
}
}
- mask = ntohl(n->n_mask);
- if (rip->rip_vers == RIPv1 || mask == 0) {
- mask = ripv1_mask_host(dst,ifp,0);
+ if (rip->rip_vers == RIPv1
+ || 0 == (mask = ntohl(n->n_mask))) {
+ mask = ripv1_mask_host(dst,ifp);
} else if ((ntohl(dst) & ~mask) != 0) {
if (bad_mask != from->sin_addr.s_addr) {
msglog("router %s sent bad netmask"
@@ -480,14 +481,10 @@ input(struct sockaddr_in *from, /* received from this IP address */
}
continue;
}
- v1_mask = (have_ripv1
- ? ripv1_mask_host(dst,0,0)
- : mask);
-
if (rip->rip_vers == RIPv1)
n->n_tag = 0;
- /* Adjust metric according to incoming interface.
+ /* Adjust metric according to incoming interface..
*/
n->n_metric += ifp->int_metric;
if (n->n_metric > HOPCNT_INFINITY)
@@ -496,18 +493,19 @@ input(struct sockaddr_in *from, /* received from this IP address */
/* Recognize and ignore a default route we faked
* which is being sent back to us by a machine with
* broken split-horizon.
+ * Be a little more paranoid than that, and reject
+ * default routes with the same metric we advertised.
*/
if (ifp->int_d_metric != 0
&& dst == RIP_DEFAULT
- && n->n_family == RIP_AF_UNSPEC
- && n->n_metric > ifp->int_d_metric)
+ && n->n_metric >= ifp->int_d_metric)
continue;
- /* We can receive aggregated RIPv2 routes via one
- * interface that must be broken down before
- * they are transmitted by RIPv1 via an interface
- * on a subnet. We might receive the same routes
- * aggregated otherwise via other RIPv2 interfaces.
+ /* We can receive aggregated RIPv2 routes that must
+ * be broken down before they are transmitted by
+ * RIPv1 via an interface on a subnet.
+ * We might also receive the same routes aggregated
+ * via other RIPv2 interfaces.
* This could cause duplicate routes to be sent on
* the RIPv1 interfaces. "Longest matching variable
* length netmasks" lets RIPv2 listeners understand,
@@ -521,9 +519,12 @@ input(struct sockaddr_in *from, /* received from this IP address */
*
* Notice that this does not break down network
* routes corresponding to subnets. This is part
- * of the defense against RS_NET_SUB.
+ * of the defense against RS_NET_SYN.
*/
- if (0 != (ntohl(dst) & (v1_mask & ~mask))) {
+ if (have_ripv1_out
+ && (v1_mask = ripv1_mask_net(dst,0)) > mask
+ && (((rt = rtget(dst,mask)) == 0
+ || !(rt->rt_state & RS_NET_SYN)))) {
ddst_h = v1_mask & -v1_mask;
i = (v1_mask & ~mask)/ddst_h;
if (i >= 1024) {
@@ -546,8 +547,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
for (;;) {
input_route(ifp, FROM_NADDR,
- dst, mask, gate,
- n->n_metric, n->n_tag);
+ dst, mask, gate, n);
if (i-- == 0)
break;
dst = htonl(ntohl(dst) + ddst_h);
@@ -566,8 +566,7 @@ input_route(struct interface *ifp,
naddr dst,
naddr mask,
naddr gate,
- int metric,
- u_short tag)
+ struct netinfo *n)
{
int i;
struct rt_entry *rt;
@@ -594,19 +593,18 @@ input_route(struct interface *ifp,
/* Consider adding the route if we do not already have it.
*/
if (rt == 0) {
- /* Usually ignore routes being poisoned.
+ /* Ignore unknown routes being poisoned.
*/
- if (metric == HOPCNT_INFINITY)
+ if (n->n_metric == HOPCNT_INFINITY)
return;
- rtadd(dst, mask, gate, from, metric, tag, 0, ifp);
+ rtadd(dst, mask, gate, from, n->n_metric, n->n_tag, 0, ifp);
return;
}
- /* We already know about the route. Consider
- * this update.
+ /* We already know about the route. Consider this update.
*
- * If (rt->rt_state & RS_NET_SUB), then this route
+ * If (rt->rt_state & RS_NET_SYN), then this route
* is the same as a network route we have inferred
* for subnets we know, in order to tell RIPv1 routers
* about the subnets.
@@ -633,7 +631,7 @@ input_route(struct interface *ifp,
* other than the current slot.
*/
if (rts0 == rt->rt_spares
- || BETTER_LINK(rts0, rts))
+ || BETTER_LINK(rt, rts0, rts))
rts0 = rts;
}
if (i != 0) {
@@ -641,26 +639,21 @@ input_route(struct interface *ifp,
*/
int old_metric = rts->rts_metric;
- if (old_metric < HOPCNT_INFINITY) {
+ /* Keep poisoned routes around only long
+ * enough to pass the poison on.
+ */
+ if (old_metric < HOPCNT_INFINITY)
new_time = now.tv_sec;
- } else {
- /* Keep poisoned routes around only long
- * enough to pass the poison on.
- */
- new_time = rts->rts_time;
- if (new_time > now.tv_sec-POISON_SECS)
- new_time = now.tv_sec-POISON_SECS;
- }
/* If this is an update for the router we currently prefer,
* then note it.
*/
if (i == NUM_SPARES) {
rtchange(rt,rt->rt_state, gate,rt->rt_router,
- metric, tag, ifp, new_time, 0);
+ n->n_metric, n->n_tag, ifp, new_time, 0);
/* If the route got worse, check for something better.
*/
- if (metric > old_metric)
+ if (n->n_metric > old_metric)
rtswitch(rt, 0);
return;
}
@@ -669,8 +662,8 @@ input_route(struct interface *ifp,
* Finished if the route is unchanged.
*/
if (rts->rts_gate == gate
- && old_metric == metric
- && rts->rts_tag == tag) {
+ && old_metric == n->n_metric
+ && rts->rts_tag == n->n_tag) {
rts->rts_time = new_time;
return;
}
@@ -684,20 +677,20 @@ input_route(struct interface *ifp,
/* Save the route as a spare only if it has
* a better metric than our worst spare.
* This also ignores poisoned routes (those
- * with metric HOPCNT_INFINITY).
+ * received with metric HOPCNT_INFINITY).
*/
- if (metric >= rts->rts_metric)
+ if (n->n_metric >= rts->rts_metric)
return;
new_time = now.tv_sec;
}
- if (TRACEACTIONS)
- trace_upslot(rt, rts, gate, from, ifp, metric, tag, new_time);
+ trace_upslot(rt, rts, gate, from, ifp, n->n_metric,n->n_tag, new_time);
+
rts->rts_gate = gate;
rts->rts_router = from;
- rts->rts_metric = metric;
- rts->rts_tag = tag;
+ rts->rts_metric = n->n_metric;
+ rts->rts_tag = n->n_tag;
rts->rts_time = new_time;
rts->rts_ifp = ifp;
OpenPOWER on IntegriCloud