+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
#ifndef lint
-static char sccsid[] = "@(#)input.c 4.11 (Berkeley) %G%";
-#endif
+static char sccsid[] = "@(#)input.c 5.2 (Berkeley) %G%";
+#endif not lint
/*
* Routing Table Management Daemon
*/
#include "defs.h"
+#include <sys/syslog.h>
/*
* Process a newly received packet.
struct sockaddr *from;
int size;
{
- struct rt_entry *rt;
- struct netinfo *n;
- struct interface *ifp, *if_ifwithdstaddr();
+ register struct rt_entry *rt;
+ register struct netinfo *n;
+ register struct interface *ifp;
+ struct interface *if_ifwithdstaddr();
int newsize;
- struct afswitch *afp;
+ register struct afswitch *afp;
ifp = 0;
TRACE_INPUT(ifp, from, size);
- if (from->sa_family >= AF_MAX)
+ if (from->sa_family >= af_max ||
+ (afp = &afswitch[from->sa_family])->af_hash == (int (*)())0) {
+ syslog(LOG_INFO,
+ "\"from\" address in unsupported address family (%d), cmd %d\n",
+ from->sa_family, msg->rip_cmd);
return;
- afp = &afswitch[from->sa_family];
+ }
switch (msg->rip_cmd) {
case RIPCMD_REQUEST:
/*
* A single entry with sa_family == AF_UNSPEC and
* metric ``infinity'' means ``all routes''.
+ * We respond to routers only if we are acting
+ * as a supplier, or to anyone other than a router
+ * (eg, query).
*/
if (n->rip_dst.sa_family == AF_UNSPEC &&
- n->rip_metric == HOPCNT_INFINITY && size == 0) {
+ n->rip_metric == HOPCNT_INFINITY && size == 0 &&
+ (supplier || (*afp->af_portcheck)(from) == 0)) {
supply(from, 0, ifp);
return;
}
ntohs(n->rip_dst.sa_family);
n->rip_metric = ntohl(n->rip_metric);
}
- if ((unsigned) n->rip_metric >= HOPCNT_INFINITY)
+ if ((unsigned) n->rip_metric > HOPCNT_INFINITY)
continue;
- if (n->rip_dst.sa_family >= AF_MAX)
+ if (n->rip_dst.sa_family >= af_max ||
+ (afp = &afswitch[n->rip_dst.sa_family])->af_hash ==
+ (int (*)())0) {
+ syslog(LOG_INFO,
+ "route in unsupported address family (%d), from %s (af %d)\n",
+ n->rip_dst.sa_family,
+ (*afswitch[from->sa_family].af_format)(from),
+ from->sa_family);
continue;
- afp = &afswitch[n->rip_dst.sa_family];
- if (((*afp->af_checkhost)(&n->rip_dst)) == 0)
+ }
+ if (((*afp->af_checkhost)(&n->rip_dst)) == 0) {
+ syslog(LOG_DEBUG,
+ "bad host in route from %s (af %d)\n",
+ (*afswitch[from->sa_family].af_format)(from),
+ from->sa_family);
continue;
+ }
rt = rtlookup(&n->rip_dst);
if (rt == 0) {
- rtadd(&n->rip_dst, from, n->rip_metric, 0);
+ if (n->rip_metric < HOPCNT_INFINITY)
+ rtadd(&n->rip_dst, from, n->rip_metric, 0);
continue;
}
* shorter, or getting stale and equivalent.
*/
if (equal(from, &rt->rt_router)) {
+ if (n->rip_metric == HOPCNT_INFINITY) {
+ rtdelete(rt);
+ continue;
+ }
if (n->rip_metric != rt->rt_metric)
rtchange(rt, from, n->rip_metric);
rt->rt_timer = 0;