aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGarrett Wollman <wollman@FreeBSD.org>1996-09-16 16:51:32 +0000
committerGarrett Wollman <wollman@FreeBSD.org>1996-09-16 16:51:32 +0000
commit7b6ab19dde850fe54facf1dbc5b00466a0a12b53 (patch)
treed0cf0716582d71e52642d52be087985ce5d2c7d8
parent38cfd0b437d4376607181b9329b6e39940d8a553 (diff)
downloadsrc-7b6ab19dde850fe54facf1dbc5b00466a0a12b53.tar.gz
src-7b6ab19dde850fe54facf1dbc5b00466a0a12b53.zip
Virgin import of new BSD/SGI routed. This update contains a numbervendor/SGI/vjs_960912
of important bug fixes. Obtained from: Vernon J. Schryver <vjs@mica.denver.sgi.com>
Notes
Notes: svn path=/vendor/SGI/dist2/; revision=18316 svn path=/vendor/SGI/vjs_960912/; revision=18318; tag=vendor/SGI/vjs_960912
-rw-r--r--sbin/routed/Makefile (renamed from usr.sbin/routed/Makefile)0
-rw-r--r--sbin/routed/defs.h (renamed from usr.sbin/routed/defs.h)22
-rw-r--r--sbin/routed/if.c (renamed from usr.sbin/routed/if.c)49
-rw-r--r--sbin/routed/input.c (renamed from usr.sbin/routed/input.c)173
-rw-r--r--sbin/routed/main.c (renamed from usr.sbin/routed/main.c)24
-rw-r--r--sbin/routed/output.c (renamed from usr.sbin/routed/output.c)80
-rw-r--r--sbin/routed/parms.c (renamed from usr.sbin/routed/parms.c)24
-rw-r--r--sbin/routed/pathnames.h (renamed from usr.sbin/routed/pathnames.h)5
-rw-r--r--sbin/routed/radix.c (renamed from usr.sbin/routed/radix.c)0
-rw-r--r--sbin/routed/radix.h (renamed from usr.sbin/routed/radix.h)0
-rw-r--r--sbin/routed/rdisc.c (renamed from usr.sbin/routed/rdisc.c)0
-rw-r--r--sbin/routed/routed.8 (renamed from usr.sbin/routed/routed.8)3
-rw-r--r--sbin/routed/routed.h (renamed from usr.sbin/routed/routed.h)0
-rw-r--r--sbin/routed/rtquery/Makefile (renamed from usr.sbin/routed/rtquery/Makefile)0
-rw-r--r--sbin/routed/rtquery/rtquery.8 (renamed from usr.sbin/routed/rtquery/rtquery.8)8
-rw-r--r--sbin/routed/rtquery/rtquery.c (renamed from usr.sbin/routed/rtquery/rtquery.c)19
-rw-r--r--sbin/routed/table.c (renamed from usr.sbin/routed/table.c)36
-rw-r--r--sbin/routed/trace.c (renamed from usr.sbin/routed/trace.c)111
-rw-r--r--usr.sbin/routed/Makefile.inc1
-rw-r--r--usr.sbin/routed/rttrace/Makefile6
-rw-r--r--usr.sbin/routed/rttrace/rttrace.c146
21 files changed, 377 insertions, 330 deletions
diff --git a/usr.sbin/routed/Makefile b/sbin/routed/Makefile
index c567e68e87ad..c567e68e87ad 100644
--- a/usr.sbin/routed/Makefile
+++ b/sbin/routed/Makefile
diff --git a/usr.sbin/routed/defs.h b/sbin/routed/defs.h
index f64991222191..452b71aa067e 100644
--- a/usr.sbin/routed/defs.h
+++ b/sbin/routed/defs.h
@@ -36,7 +36,7 @@
*/
#ifndef __NetBSD__
-#ident "$Revision: 1.13 $"
+#ident "$Revision: 1.16 $"
#endif
/* Definitions for RIPv2 routing process.
@@ -178,7 +178,6 @@ struct rt_entry {
# define RS_MHOME 0x020 /* from -m */
# define RS_STATIC 0x040 /* from the kernel */
# define RS_RDISC 0x080 /* from router discovery */
-# define RS_PERMANENT (RS_MHOME | RS_STATIC | RS_NET_SYN | RS_RDISC)
struct sockaddr_in rt_dst_sock;
naddr rt_mask;
struct rt_spare {
@@ -212,11 +211,12 @@ struct rt_entry {
* nor non-passive, remote interfaces that are not aliases
* (i.e. remote & metric=0)
*/
-#define AGE_RT(rt,ifp) (0 == ((rt)->rt_state & RS_PERMANENT) \
- && (!((rt)->rt_state & RS_IF) \
- || (ifp) == 0 \
- || (((ifp)->int_state & IS_REMOTE) \
- && !((ifp)->int_state & IS_PASSIVE))))
+#define AGE_RT(rt_state,ifp) (0 == ((rt_state) & (RS_MHOME | RS_STATIC \
+ | RS_NET_SYN | RS_RDISC)) \
+ && (!((rt_state) & RS_IF) \
+ || (ifp) == 0 \
+ || (((ifp)->int_state & IS_REMOTE) \
+ && !((ifp)->int_state & IS_PASSIVE))))
/* true if A is better than B
* Better if
@@ -256,7 +256,7 @@ struct interface {
naddr int_std_net; /* class A/B/C network (h) */
naddr int_std_mask; /* class A/B/C netmask (h) */
int int_rip_sock; /* for queries */
- int int_if_flags; /* copied from kernel */
+ int int_if_flags; /* some bits copied from kernel */
u_int int_state;
time_t int_act_time; /* last thought healthy */
u_short int_transitions; /* times gone up-down */
@@ -279,6 +279,7 @@ struct interface {
struct timeval int_rdisc_timer;
};
+/* bits in int_state */
#define IS_ALIAS 0x0000001 /* interface alias */
#define IS_SUBNET 0x0000002 /* interface on subnetted network */
#define IS_REMOTE 0x0000004 /* interface is not on this machine */
@@ -407,6 +408,7 @@ extern int auth_ok; /* 1=ignore auth if we do not care */
extern struct timeval epoch; /* when started */
extern struct timeval now; /* current idea of time */
extern time_t now_stale;
+extern time_t now_expire;
extern time_t now_garbage;
extern struct timeval next_bcast; /* next general broadcast */
@@ -428,7 +430,8 @@ extern struct timeval need_kern; /* need to update kernel table */
extern int update_seqno; /* a route has changed */
extern u_int tracelevel, new_tracelevel;
-#define MAX_TRACELEVEL 3
+#define MAX_TRACELEVEL 4
+#define TRACEKERNEL (tracelevel >= 4) /* log kernel changes */
#define TRACECONTENTS (tracelevel >= 3) /* display packet contents */
#define TRACEPACKETS (tracelevel >= 2) /* note packets */
#define TRACEACTIONS (tracelevel != 0)
@@ -483,6 +486,7 @@ extern void trace_on(char *, int);
extern void trace_off(char*, ...);
extern void trace_flush(void);
extern void set_tracelevel(void);
+extern void trace_kernel(char *, ...);
extern void trace_act(char *, ...);
extern void trace_pkt(char *, ...);
extern void trace_add_del(char *, struct rt_entry *);
diff --git a/usr.sbin/routed/if.c b/sbin/routed/if.c
index 7143b319c54c..539b07323e3a 100644
--- a/usr.sbin/routed/if.c
+++ b/sbin/routed/if.c
@@ -36,7 +36,7 @@ static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$";
#endif
-#ident "$Revision: 1.16 $"
+#ident "$Revision: 1.17 $"
#include "defs.h"
#include "pathnames.h"
@@ -454,12 +454,13 @@ ifinit(void)
# define COMP_NOT_INET 0x001
# define COMP_WIERD 0x002
# define COMP_NOADDR 0x004
-# define COMP_NODST 0x008
-# define COMP_NOBADR 0x010
-# define COMP_NOMASK 0x020
-# define COMP_DUP 0x040
-# define COMP_BAD_METRIC 0x080
-# define COMP_NETMASK 0x100
+# define COMP_BADADDR 0x008
+# define COMP_NODST 0x010
+# define COMP_NOBADR 0x020
+# define COMP_NOMASK 0x040
+# define COMP_DUP 0x080
+# define COMP_BAD_METRIC 0x100
+# define COMP_NETMASK 0x200
struct interface ifs, ifs0, *ifp, *ifp1;
struct rt_entry *rt;
@@ -548,7 +549,7 @@ ifinit(void)
if (INFO_IFA(&info) == 0) {
if (iff_alive(ifs.int_if_flags)) {
if (!(prev_complaints & COMP_NOADDR))
- msglog("%s has a bad address",
+ msglog("%s has no address",
sdl->sdl_data);
complaints |= COMP_NOADDR;
}
@@ -569,6 +570,17 @@ ifinit(void)
ifs.int_addr = S_ADDR(INFO_IFA(&info));
+ if (ntohl(ifs.int_addr)>>24 == 0
+ || ntohl(ifs.int_addr)>>24 == 0xff) {
+ if (iff_alive(ifs.int_if_flags)) {
+ if (!(prev_complaints & COMP_BADADDR))
+ msglog("%s has a bad address",
+ sdl->sdl_data);
+ complaints |= COMP_BADADDR;
+ }
+ continue;
+ }
+
if (ifs.int_if_flags & IFF_BROADCAST) {
if (INFO_MASK(&info) == 0) {
if (iff_alive(ifs.int_if_flags)) {
@@ -612,6 +624,17 @@ ifinit(void)
continue;
}
ifs.int_dstaddr = S_ADDR(INFO_BRD(&info));
+ if (ntohl(ifs.int_dstaddr)>>24 == 0
+ || ntohl(ifs.int_dstaddr)>>24 == 0xff) {
+ if (iff_alive(ifs.int_if_flags)) {
+ if (!(prev_complaints & COMP_NODST))
+ msglog("%s has a bad"
+ " destination address",
+ sdl->sdl_data);
+ complaints |= COMP_NODST;
+ }
+ continue;
+ }
ifs.int_mask = HOST_MASK;
ifs.int_ripv1_mask = ntohl(S_ADDR(INFO_MASK(&info)));
ifs.int_net = ntohl(ifs.int_dstaddr);
@@ -949,12 +972,10 @@ ifinit(void)
/* If we ever have a RIPv1 interface, assume we always will.
* It might come back if it ever goes away.
*/
- if (!(ifp->int_if_flags & IFF_LOOPBACK)) {
- if (!(ifp->int_state & IS_NO_RIPV1_OUT))
- have_ripv1_out = 1;
- if (!(ifp->int_state & IS_NO_RIPV1_IN))
- have_ripv1_in = 1;
- }
+ if (!(ifp->int_state & IS_NO_RIPV1_OUT) && supplier)
+ have_ripv1_out = 1;
+ if (!(ifp->int_state & IS_NO_RIPV1_IN))
+ have_ripv1_in = 1;
}
for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) {
diff --git a/usr.sbin/routed/input.c b/sbin/routed/input.c
index 6bbc572af577..a854c41914e4 100644
--- a/usr.sbin/routed/input.c
+++ b/sbin/routed/input.c
@@ -36,7 +36,7 @@ static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$";
#endif
-#ident "$Revision: 1.13 $"
+#ident "$Revision: 1.16 $"
#include "defs.h"
@@ -69,9 +69,7 @@ read_rip(int sock,
logbad(1,"impossible recvfrom(rip) fromlen=%d",
fromlen);
- input(&from,
- (ifp != 0) ? ifp : iflookup(from.sin_addr.s_addr),
- &inbuf.rip, cc);
+ input(&from, ifp, &inbuf.rip, cc);
}
}
@@ -80,7 +78,7 @@ read_rip(int sock,
*/
static void
input(struct sockaddr_in *from, /* received from this IP address */
- struct interface *ifp,
+ struct interface *sifp, /* interface by which it arrived */
struct rip *rip,
int size)
{
@@ -88,17 +86,21 @@ input(struct sockaddr_in *from, /* received from this IP address */
static naddr use_auth, bad_len, bad_mask;
static naddr unk_router, bad_router, bad_nhop;
+ struct interface *aifp; /* interface if via 1 hop */
struct rt_entry *rt;
struct netinfo *n, *lim;
struct interface *ifp1;
naddr gate, mask, v1_mask, dst, ddst_h;
int i;
+ aifp = iflookup(from->sin_addr.s_addr);
+ if (sifp == 0)
+ sifp = aifp;
- if (ifp != 0)
- ifp->int_state |= IS_ACTIVE;
+ if (sifp != 0)
+ sifp->int_state |= IS_ACTIVE;
- trace_rip("Recv", "from", from, ifp, rip, size);
+ trace_rip("Recv", "from", from, sifp, rip, size);
if (rip->rip_vers == 0) {
if (from->sin_addr.s_addr != bad_router)
@@ -107,6 +109,8 @@ input(struct sockaddr_in *from, /* received from this IP address */
rip->rip_cmd, naddr_ntoa(FROM_NADDR));
bad_router = from->sin_addr.s_addr;
return;
+ } else if (rip->rip_vers > RIPv2) {
+ rip->rip_vers = RIPv2;
}
if (size > MAXPACKETSIZE) {
if (from->sin_addr.s_addr != bad_router)
@@ -131,7 +135,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
* RIPv1 systems will listen? Crazy!
*/
if (!auth_ok
- && rip->rip_vers >= RIPv2
+ && rip->rip_vers == RIPv2
&& n < lim && n->n_family == RIP_AF_AUTH) {
if (from->sin_addr.s_addr != use_auth)
msglog("RIPv2 message with authentication"
@@ -187,32 +191,42 @@ input(struct sockaddr_in *from, /* received from this IP address */
* We respond to routers only if we are acting
* as a supplier, or to anyone other than a router
* (i.e. a query).
- *
- * Answer a query from a stray program with all
- * we know. Filter the answer to a query from a
- * router in the about same way broadcasts are
- * filtered.
- *
- * Only answer a router if we are a supplier
- * to keep an unwary host that is just starting
- * from picking us an a router.
*/
if (n->n_family == RIP_AF_UNSPEC
&& n->n_metric == HOPCNT_INFINITY
&& n == rip->rip_nets
&& n+1 == lim) {
if (from->sin_port != htons(RIP_PORT)) {
- /* query from `rtquery` or similar
+ /* Answer a query from a utility
+ * program with all we know.
*/
- supply(from, ifp,
- OUT_QUERY, 0, rip->rip_vers);
- } else if (supplier) {
- /* a router trying to prime its
- * tables.
- */
- supply(from, ifp,
- OUT_UNICAST, 0, rip->rip_vers);
+ supply(from, sifp, OUT_QUERY, 0,
+ rip->rip_vers);
+ return;
}
+ /* A router trying to prime its tables.
+ * Filter the answer in the about same way
+ * broadcasts are filtered.
+ *
+ * Only answer a router if we are a supplier
+ * to keep an unwary host that is just starting
+ * from picking us as a router. Respond with
+ * RIPv1 instead of RIPv2 if that is what we
+ * are broadcasting on the interface to keep
+ * the remote router from getting the wrong
+ * initial idea of the routes we send.
+ */
+ if (!supplier
+ || aifp == 0
+ || (aifp->int_state & IS_PASSIVE)
+ || (aifp->int_state & IS_ALIAS)
+ || ((aifp->int_state & IS_NO_RIPV1_OUT)
+ && (aifp->int_state&IS_NO_RIPV2_OUT)))
+ return;
+
+ supply(from, aifp, OUT_UNICAST, 0,
+ (aifp->int_state&IS_NO_RIPV1_OUT)
+ ? RIPv2 : RIPv1);
return;
}
@@ -241,7 +255,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
if (rip->rip_vers == RIPv1
|| 0 == (mask = ntohl(n->n_mask))
|| 0 != (ntohl(dst) & ~mask))
- mask = ripv1_mask_host(dst,ifp);
+ mask = ripv1_mask_host(dst,sifp);
rt = rtget(dst, mask);
if (!rt && dst != RIP_DEFAULT)
@@ -258,16 +272,16 @@ input(struct sockaddr_in *from, /* received from this IP address */
n->n_metric = HOPCNT_INFINITY;
} else {
n->n_metric = rt->rt_metric+1;
- n->n_metric += (ifp!=0) ? ifp->int_metric : 1;
+ n->n_metric += (sifp!=0)?sifp->int_metric : 1;
if (n->n_metric > HOPCNT_INFINITY)
n->n_metric = HOPCNT_INFINITY;
if (rip->rip_vers != RIPv1) {
n->n_tag = rt->rt_tag;
- if (ifp != 0
+ if (sifp != 0
&& on_net(rt->rt_gate,
- ifp->int_net,
- ifp->int_mask)
- && rt->rt_gate != ifp->int_addr)
+ sifp->int_net,
+ sifp->int_mask)
+ && rt->rt_gate != sifp->int_addr)
n->n_nhop = rt->rt_gate;
}
}
@@ -284,9 +298,9 @@ input(struct sockaddr_in *from, /* received from this IP address */
rip->rip_vers = RIPv2;
if (from->sin_port != htons(RIP_PORT)) {
/* query */
- (void)output(OUT_QUERY, from, ifp, rip, size);
+ (void)output(OUT_QUERY, from, sifp, rip, size);
} else if (supplier) {
- (void)output(OUT_UNICAST, from, ifp, rip, size);
+ (void)output(OUT_UNICAST, from, sifp, rip, size);
}
return;
@@ -298,7 +312,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
naddr_ntoa(FROM_NADDR));
return;
}
- if (ifp == 0) {
+ if (aifp == 0) {
msglog("trace command from unknown router %s",
naddr_ntoa(FROM_NADDR));
return;
@@ -357,26 +371,27 @@ 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) {
+ if (!aifp) {
if (from->sin_addr.s_addr != unk_router)
- msglog("packet from unknown router %s"
+ msglog("discard 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",
+ if (aifp->int_state & IS_PASSIVE) {
+ trace_act("discard packet from %s"
+ " via passive interface %s\n",
naddr_ntoa(FROM_NADDR),
- ifp->int_name);
+ aifp->int_name);
return;
}
/* Check required version
*/
- if (((ifp->int_state & IS_NO_RIPV1_IN)
+ if (((aifp->int_state & IS_NO_RIPV1_IN)
&& rip->rip_vers == RIPv1)
- || ((ifp->int_state & IS_NO_RIPV2_IN)
+ || ((aifp->int_state & IS_NO_RIPV2_IN)
&& rip->rip_vers != RIPv1)) {
trace_pkt("discard RIPv%d response\n",
rip->rip_vers);
@@ -385,15 +400,15 @@ input(struct sockaddr_in *from, /* received from this IP address */
/* Ignore routes via dead interface.
*/
- if (ifp->int_state & IS_BROKE) {
+ if (aifp->int_state & IS_BROKE) {
trace_pkt("discard response via broken interface %s\n",
- ifp->int_name);
+ aifp->int_name);
return;
}
/* Authenticate the packet if we have a secret.
*/
- if (ifp->int_passwd[0] != '\0') {
+ if (aifp->int_passwd[0] != '\0') {
if (n >= lim
|| n->n_family != RIP_AF_AUTH
|| ((struct netauth*)n)->a_type != RIP_AUTH_PW) {
@@ -404,8 +419,8 @@ input(struct sockaddr_in *from, /* received from this IP address */
return;
} else if (0 != bcmp(((struct netauth*)n)->au.au_pw,
- ifp->int_passwd,
- sizeof(ifp->int_passwd))) {
+ aifp->int_passwd,
+ sizeof(aifp->int_passwd))) {
if (from->sin_addr.s_addr != use_auth)
msglog("bad password from %s",
naddr_ntoa(FROM_NADDR));
@@ -456,31 +471,31 @@ input(struct sockaddr_in *from, /* received from this IP address */
/* Notice the next-hop.
*/
gate = from->sin_addr.s_addr;
- if (n->n_nhop != 0
- && rip->rip_vers == RIPv2) {
- /* Ignore the route if it points to us */
- if (0 != ifwithaddr(n->n_nhop, 1, 0))
- continue;
-
- /* Use it only if it is valid. */
- if (on_net(n->n_nhop,
- ifp->int_net, ifp->int_mask)
- && check_dst(n->n_nhop)) {
- gate = n->n_nhop;
+ if (n->n_nhop != 0) {
+ if (rip->rip_vers == RIPv2) {
+ n->n_nhop = 0;
} else {
+ /* Use it only if it is valid. */
+ if (on_net(n->n_nhop,
+ aifp->int_net, aifp->int_mask)
+ && check_dst(n->n_nhop)) {
+ gate = n->n_nhop;
+ } else {
if (bad_nhop != from->sin_addr.s_addr)
- msglog("router %s to %s has"
- " bad next hop %s",
- naddr_ntoa(FROM_NADDR),
- naddr_ntoa(dst),
- naddr_ntoa(n->n_nhop));
+ msglog("router %s to %s has"
+ " bad next hop %s",
+ naddr_ntoa(FROM_NADDR),
+ naddr_ntoa(dst),
+ naddr_ntoa(n->n_nhop));
bad_nhop = from->sin_addr.s_addr;
+ n->n_nhop = 0;
+ }
}
}
if (rip->rip_vers == RIPv1
|| 0 == (mask = ntohl(n->n_mask))) {
- mask = ripv1_mask_host(dst,ifp);
+ mask = ripv1_mask_host(dst,aifp);
} else if ((ntohl(dst) & ~mask) != 0) {
if (bad_mask != from->sin_addr.s_addr) {
msglog("router %s sent bad netmask"
@@ -497,7 +512,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
/* Adjust metric according to incoming interface..
*/
- n->n_metric += ifp->int_metric;
+ n->n_metric += aifp->int_metric;
if (n->n_metric > HOPCNT_INFINITY)
n->n_metric = HOPCNT_INFINITY;
@@ -507,9 +522,9 @@ input(struct sockaddr_in *from, /* received from this IP address */
* Be a little more paranoid than that, and reject
* default routes with the same metric we advertised.
*/
- if (ifp->int_d_metric != 0
+ if (aifp->int_d_metric != 0
&& dst == RIP_DEFAULT
- && n->n_metric >= ifp->int_d_metric)
+ && n->n_metric >= aifp->int_d_metric)
continue;
/* We can receive aggregated RIPv2 routes that must
@@ -558,7 +573,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
}
for (;;) {
- input_route(ifp, FROM_NADDR,
+ input_route(aifp, FROM_NADDR,
dst, mask, gate, n);
if (i-- == 0)
break;
@@ -610,6 +625,14 @@ input_route(struct interface *ifp,
if (n->n_metric == HOPCNT_INFINITY)
return;
+ /* Ignore the route if it points to us */
+ if (n->n_nhop != 0
+ && 0 != ifwithaddr(n->n_nhop, 1, 0))
+ return;
+
+ /* If something has not gone crazy and tried to fill
+ * our memory, accept the new route.
+ */
if (total_routes < MAX_ROUTES)
rtadd(dst, mask, gate, from, n->n_metric,
n->n_tag, 0, ifp);
@@ -630,10 +653,8 @@ input_route(struct interface *ifp,
* synthetic, RIPv1 network route of our own.
* The worst is that both kinds of routes might be
* received, and the bad one might have the smaller
- * metric. Partly solve this problem by faking the
- * RIPv1 route with a metric that reflects the most
- * distant part of the subnet. Also never
- * aggregate into such a route. Also keep it
+ * metric. Partly solve this problem by never
+ * aggregating into such a route. Also keep it
* around as long as the interface exists.
*/
@@ -686,7 +707,13 @@ input_route(struct interface *ifp,
} else {
/* The update is for a route we know about,
* but not from a familiar router.
+ *
+ * Ignore the route if it points to us.
*/
+ if (n->n_nhop != 0
+ && 0 != ifwithaddr(n->n_nhop, 1, 0))
+ return;
+
rts = rts0;
/* Save the route as a spare only if it has
diff --git a/usr.sbin/routed/main.c b/sbin/routed/main.c
index 700762ed5dcb..84a7fac3dbe7 100644
--- a/usr.sbin/routed/main.c
+++ b/sbin/routed/main.c
@@ -39,7 +39,7 @@ static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$";
#endif
-#ident "$Revision: 1.14 $"
+#ident "$Revision: 1.17 $"
#include "defs.h"
#include "pathnames.h"
@@ -70,6 +70,7 @@ struct timeval epoch; /* when started */
struct timeval clk, prev_clk;
struct timeval now; /* current idea of time */
time_t now_stale;
+time_t now_expire;
time_t now_garbage;
struct timeval next_bcast; /* next general broadcast */
@@ -111,6 +112,7 @@ main(int argc,
epoch.tv_sec -= EPOCH;
now.tv_sec = EPOCH;
now_stale = EPOCH - STALE_TIME;
+ now_expire = EPOCH - EXPIRE_TIME;
now_garbage = EPOCH - GARBAGE_TIME;
wtime.tv_sec = 0;
@@ -247,6 +249,16 @@ usage:
}
+ signal(SIGALRM, sigalrm);
+ if (!background)
+ signal(SIGHUP, sigterm); /* SIGHUP fatal during debugging */
+ else
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGTERM, sigterm);
+ signal(SIGINT, sigterm);
+ signal(SIGUSR1, sigtrace_on);
+ signal(SIGUSR2, sigtrace_off);
+
/* get into the background */
if (background) {
#ifdef sgi
@@ -275,7 +287,7 @@ usage:
if (setsockopt(rt_sock, SOL_SOCKET,SO_USELOOPBACK,
&off,sizeof(off)) < 0)
LOGERR("setsockopt(SO_USELOOPBACK,0)");
-
+
fix_select();
@@ -304,13 +316,6 @@ usage:
rdisc_timer = next_bcast;
ifinit_timer.tv_usec = next_bcast.tv_usec;
- signal(SIGALRM, sigalrm);
- signal(SIGHUP, sigterm);
- signal(SIGTERM, sigterm);
- signal(SIGINT, sigterm);
- signal(SIGUSR1, sigtrace_on);
- signal(SIGUSR2, sigtrace_off);
-
/* Collect an initial view of the world by checking the interface
* configuration and the kludge file.
*/
@@ -342,6 +347,7 @@ usage:
}
timevalsub(&now, &clk, &epoch);
now_stale = now.tv_sec - STALE_TIME;
+ now_expire = now.tv_sec - EXPIRE_TIME;
now_garbage = now.tv_sec - GARBAGE_TIME;
/* deal with interrupts that should affect tracing */
diff --git a/usr.sbin/routed/output.c b/sbin/routed/output.c
index be30609743a7..eafcf31e7864 100644
--- a/usr.sbin/routed/output.c
+++ b/sbin/routed/output.c
@@ -36,7 +36,7 @@ static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$";
#endif
-#ident "$Revision: 1.16 $"
+#ident "$Revision: 1.17 $"
#include "defs.h"
@@ -263,7 +263,7 @@ supply_out(struct ag_info *ag)
&& (ws.state & WS_ST_FLASH))
return;
- /* Skip this route if required by split-horizon
+ /* Skip this route if required by split-horizon.
*/
if (ag->ag_state & AGS_SPLIT_HZ)
return;
@@ -363,7 +363,7 @@ walk_supply(struct radix_node *rn,
struct walkarg *w)
{
#define RT ((struct rt_entry *)rn)
- u_short ags = 0;
+ u_short ags;
char metric, pref;
naddr dst, nhop;
@@ -371,7 +371,8 @@ walk_supply(struct radix_node *rn,
/* Do not advertise the loopback interface
* or external remote interfaces
*/
- if (RT->rt_ifp != 0
+ if ((RT->rt_state & RS_IF)
+ && RT->rt_ifp != 0
&& ((RT->rt_ifp->int_if_flags & IFF_LOOPBACK)
|| (RT->rt_ifp->int_state & IS_EXTERNAL))
&& !(RT->rt_state & RS_MHOME))
@@ -429,32 +430,8 @@ walk_supply(struct radix_node *rn,
nhop = 0;
}
- /* Adjust the outgoing metric by the cost of the link.
- */
- pref = metric = RT->rt_metric + ws.metric;
- if (pref < HOPCNT_INFINITY) {
- /* Keep track of the best metric with which the
- * route has been advertised recently.
- */
- if (RT->rt_poison_metric >= metric
- || RT->rt_poison_time <= now_garbage) {
- RT->rt_poison_time = now.tv_sec;
- RT->rt_poison_metric = RT->rt_metric;
- }
-
- } else {
- /* Do not advertise stable routes that will be ignored,
- * unless they are being held down and poisoned. If the
- * route recently was advertised with a metric that would
- * have been less than infinity through this interface, we
- * need to continue to advertise it in order to poison it.
- */
- pref = RT->rt_poison_metric + ws.metric;
- if (pref >= HOPCNT_INFINITY)
- return 0;
-
- metric = HOPCNT_INFINITY;
- }
+ metric = RT->rt_metric;
+ ags = 0;
if (RT->rt_state & RS_MHOME) {
/* retain host route of multi-homed servers */
@@ -521,8 +498,47 @@ walk_supply(struct radix_node *rn,
&& (ws.state & WS_ST_TO_ON_NET)
&& (!(RT->rt_state & RS_IF)
|| ws.ifp->int_if_flags & IFF_POINTOPOINT)) {
- ags |= AGS_SPLIT_HZ;
- ags &= ~(AGS_PROMOTE | AGS_SUPPRESS);
+ /* Poison-reverse the route instead of only not advertising it
+ * it is recently changed from some other route.
+ * In almost all cases, if there is no spare for the route
+ * then it is either old or a brand new route, and if it
+ * is brand new, there is no need for poison-reverse.
+ */
+ metric = HOPCNT_INFINITY;
+ if (RT->rt_poison_time < now_expire
+ || RT->rt_spares[1].rts_gate ==0) {
+ ags |= AGS_SPLIT_HZ;
+ ags &= ~(AGS_PROMOTE | AGS_SUPPRESS);
+ }
+ }
+
+ /* Adjust the outgoing metric by the cost of the link.
+ */
+ pref = metric + ws.metric;
+ if (pref < HOPCNT_INFINITY) {
+ /* Keep track of the best metric with which the
+ * route has been advertised recently.
+ */
+ if (RT->rt_poison_metric >= metric
+ || RT->rt_poison_time < now_expire) {
+ RT->rt_poison_time = now.tv_sec;
+ RT->rt_poison_metric = metric;
+ }
+ metric = pref;
+
+ } else {
+ /* Do not advertise stable routes that will be ignored,
+ * unless they are being held down and poisoned. If the
+ * route recently was advertised with a metric that would
+ * have been less than infinity through this interface, we
+ * need to continue to advertise it in order to poison it.
+ */
+ pref = RT->rt_poison_metric + ws.metric;
+ if (pref >= HOPCNT_INFINITY
+ || RT->rt_poison_time < now_garbage )
+ return 0;
+
+ metric = HOPCNT_INFINITY;
}
ag_check(dst, RT->rt_mask, 0, nhop, metric, pref,
diff --git a/usr.sbin/routed/parms.c b/sbin/routed/parms.c
index fcd37a6b6c3a..0d178c3698bc 100644
--- a/usr.sbin/routed/parms.c
+++ b/sbin/routed/parms.c
@@ -36,7 +36,7 @@ static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$";
#endif
-#ident "$Revision: 1.8 $"
+#ident "$Revision: 1.9 $"
#include "defs.h"
#include "pathnames.h"
@@ -474,13 +474,6 @@ parse_parms(char *line)
if (tgt != 0)
return tgt;
- if (parm.parm_int_state & IS_NO_ADV_IN)
- parm.parm_int_state |= IS_NO_SOL_OUT;
-
- if ((parm.parm_int_state & (IS_NO_RIP | IS_NO_RDISC))
- == (IS_NO_RIP | IS_NO_RDISC))
- parm.parm_int_state |= IS_PASSIVE;
-
return check_parms(&parm);
#undef DELIMS
#undef PARS
@@ -495,6 +488,21 @@ check_parms(struct parm *new)
struct parm *parmp;
+ /* set implicit values
+ */
+ if (!supplier && supplier_set)
+ new->parm_int_state |= (IS_NO_RIPV1_OUT
+ | IS_NO_RIPV2_OUT
+ | IS_NO_ADV_OUT);
+ if (new->parm_int_state & IS_NO_ADV_IN)
+ new->parm_int_state |= IS_NO_SOL_OUT;
+
+ if ((new->parm_int_state & (IS_NO_RIP | IS_NO_RDISC))
+ == (IS_NO_RIP | IS_NO_RDISC))
+ new->parm_int_state |= IS_PASSIVE;
+
+ /* compare with existing sets of parameters
+ */
for (parmp = parms; parmp != 0; parmp = parmp->parm_next) {
if (strcmp(new->parm_name, parmp->parm_name))
continue;
diff --git a/usr.sbin/routed/pathnames.h b/sbin/routed/pathnames.h
index e9e6c48c6392..14b721c2d473 100644
--- a/usr.sbin/routed/pathnames.h
+++ b/sbin/routed/pathnames.h
@@ -43,5 +43,8 @@
* or be the same as the tracefile specified when the daemon was started.
* If this is a directory, routed will create log files in it. That
* might be a security problem.
+ *
+ * Leave this undefined, and only the trace file originally specified
+ * when routed was started, if any, will be appended to.
*/
-#define _PATH_TRACE "/tmp/routed.log"
+#define _PATH_TRACE "/etc/routed.trace"
diff --git a/usr.sbin/routed/radix.c b/sbin/routed/radix.c
index 7f7e1e47b79e..7f7e1e47b79e 100644
--- a/usr.sbin/routed/radix.c
+++ b/sbin/routed/radix.c
diff --git a/usr.sbin/routed/radix.h b/sbin/routed/radix.h
index fddf02ead7a6..fddf02ead7a6 100644
--- a/usr.sbin/routed/radix.h
+++ b/sbin/routed/radix.h
diff --git a/usr.sbin/routed/rdisc.c b/sbin/routed/rdisc.c
index da1784c793e4..da1784c793e4 100644
--- a/usr.sbin/routed/rdisc.c
+++ b/sbin/routed/rdisc.c
diff --git a/usr.sbin/routed/routed.8 b/sbin/routed/routed.8
index 828bdd89fb1c..de3abf34e84e 100644
--- a/usr.sbin/routed/routed.8
+++ b/sbin/routed/routed.8
@@ -298,6 +298,9 @@ does not care about authentication.
.It Fl T Ar tracefile
increases the debugging level to at least 1 and
causes debugging information to be appended to the trace file.
+Note that because of security concerns, it is wisest to not run
+.Nm routed
+routinely with tracing directed to a file.
.It Fl t
increases the debugging level, which causes more information to be logged
on the tracefile specified with
diff --git a/usr.sbin/routed/routed.h b/sbin/routed/routed.h
index 8bfc0a191257..8bfc0a191257 100644
--- a/usr.sbin/routed/routed.h
+++ b/sbin/routed/routed.h
diff --git a/usr.sbin/routed/rtquery/Makefile b/sbin/routed/rtquery/Makefile
index f9aee5c55d06..f9aee5c55d06 100644
--- a/usr.sbin/routed/rtquery/Makefile
+++ b/sbin/routed/rtquery/Makefile
diff --git a/usr.sbin/routed/rtquery/rtquery.8 b/sbin/routed/rtquery/rtquery.8
index 1afb8b9478be..d77ca30b9c8f 100644
--- a/usr.sbin/routed/rtquery/rtquery.8
+++ b/sbin/routed/rtquery/rtquery.8
@@ -79,18 +79,20 @@ change tracing, where
.Em op
is one of the following.
Requests from processes not running with UID 0 or on distant networks
-are generally ignored.
+are generally ignored by the daemon except for a message in the system log.
.El
.Bl -tag -width Ds -offset indent-two
-.It Em on=filename
+.It Em on=tracefile
turn tracing on into the specified file. That file must usually
have been specified when the daemon was started or be the same
as a fixed name, often
-.Pa /tmp/routed.log .
+.Pa /etc/routed.trace .
.It Em more
increases the debugging level.
.It Em off
turns off tracing.
+.It Em dump
+dumps the daemon's routing table to the current tracefile.
.El
.Sh SEE ALSO
.Xr routed 8 ,
diff --git a/usr.sbin/routed/rtquery/rtquery.c b/sbin/routed/rtquery/rtquery.c
index cc1be10ab228..7d6913a048d7 100644
--- a/usr.sbin/routed/rtquery/rtquery.c
+++ b/sbin/routed/rtquery/rtquery.c
@@ -40,7 +40,7 @@ static char sccsid[] = "@(#)query.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$";
#endif
-#ident "$Revision: 1.8 $"
+#ident "$Revision: 1.9 $"
#include <sys/param.h>
#include <sys/protosw.h>
@@ -171,6 +171,8 @@ main(int argc,
"more",
# define TRACE_OFF 2
"off",
+# define TRACE_DUMP 3
+ "dump",
0
};
switch (getsubopt(&options,traceopts,&value)) {
@@ -179,25 +181,30 @@ main(int argc,
if (!value
|| strlen(value) > MAXPATHLEN)
goto usage;
- strcpy((char*)OMSG.rip_tracefile,value);
- omsg_len += (strlen(value)
- - sizeof(OMSG.ripun));
break;
case TRACE_MORE:
if (value)
goto usage;
OMSG.rip_cmd = RIPCMD_TRACEON;
- OMSG.rip_tracefile[0] = '\0';
+ value = "";
break;
case TRACE_OFF:
if (value)
goto usage;
OMSG.rip_cmd = RIPCMD_TRACEOFF;
- OMSG.rip_tracefile[0] = '\0';
+ value = "";
+ break;
+ case TRACE_DUMP:
+ if (value)
+ goto usage;
+ OMSG.rip_cmd = RIPCMD_TRACEON;
+ value = "dump/../table";
break;
default:
goto usage;
}
+ strcpy((char*)OMSG.rip_tracefile, value);
+ omsg_len += strlen(value) - sizeof(OMSG.ripun);
}
break;
diff --git a/usr.sbin/routed/table.c b/sbin/routed/table.c
index b1566a3792a8..6ad97f0ada15 100644
--- a/usr.sbin/routed/table.c
+++ b/sbin/routed/table.c
@@ -36,7 +36,7 @@ static char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$";
#endif
-#ident "$Revision: 1.23 $"
+#ident "$Revision: 1.25 $"
#include "defs.h"
@@ -690,6 +690,13 @@ again:
w.w_rtm.rtm_msglen -= (sizeof(w.w_mask) - w.w_mask.sin_len);
#endif
}
+
+ if (TRACEKERNEL)
+ trace_kernel("write kernel %s %s->%s metric=%d flags=%#x\n",
+ rtm_type_name(action),
+ addrname(dst, mask, 0), naddr_ntoa(gate),
+ metric, flags);
+
#ifndef NO_INSTALL
cc = write(rt_sock, &w, w.w_rtm.rtm_msglen);
if (cc == w.w_rtm.rtm_msglen)
@@ -850,6 +857,7 @@ rtm_add(struct rt_msghdr *rtm,
k->k_state |= KS_GATEWAY;
if (rtm->rtm_flags & RTF_STATIC)
k->k_state |= KS_STATIC;
+
if (0 != (rtm->rtm_flags & (RTF_DYNAMIC | RTF_MODIFIED))) {
if (supplier) {
/* Routers are not supposed to listen to redirects,
@@ -857,6 +865,7 @@ rtm_add(struct rt_msghdr *rtm,
*/
k->k_state &= ~KS_DYNAMIC;
k->k_state |= KS_DELETE;
+ LIM_SEC(need_kern, 0);
trace_act("mark redirected %s --> %s for deletion"
" since this is a router\n",
addrname(k->k_dst, k->k_mask, 0),
@@ -865,6 +874,7 @@ rtm_add(struct rt_msghdr *rtm,
k->k_state |= KS_DYNAMIC;
k->k_redirect_time = now.tv_sec;
}
+ return;
}
/* If it is not a static route, quit until the next comparison
@@ -1584,8 +1594,11 @@ rtchange(struct rt_entry *rt,
* has gone bad, since there may be a working route that
* aggregates this route.
*/
- if (metric == HOPCNT_INFINITY)
+ if (metric == HOPCNT_INFINITY) {
need_kern.tv_sec = now.tv_sec;
+ if (new_time >= now.tv_sec - EXPIRE_TIME)
+ new_time = now.tv_sec - EXPIRE_TIME;
+ }
rt->rt_seqno = update_seqno;
set_need_flash();
}
@@ -1598,6 +1611,11 @@ rtchange(struct rt_entry *rt,
state |= (rt->rt_state & RS_SUBNET);
+ /* Keep various things from deciding ageless routes are stale.
+ */
+ if (!AGE_RT(state, ifp))
+ new_time = now.tv_sec;
+
if (TRACEACTIONS)
trace_change(rt, state, gate, router, metric, tag, ifp,
new_time,
@@ -1643,12 +1661,8 @@ rtswitch(struct rt_entry *rt,
/* Do not change permanent routes */
- if (0 != (rt->rt_state & RS_PERMANENT))
- return;
-
- /* Do not discard synthetic routes until they go bad */
- if ((rt->rt_state & RS_NET_SYN)
- && rt->rt_metric < HOPCNT_INFINITY)
+ if (0 != (rt->rt_state & (RS_MHOME | RS_STATIC | RS_RDISC
+ | RS_NET_SYN | RS_IF)))
return;
/* find the best alternative among the spares */
@@ -1803,6 +1817,7 @@ walk_bad(struct radix_node *rn,
if (rts->rts_ifp != 0
&& (rts->rts_ifp->int_state & IS_BROKE)) {
+ /* mark the spare route to be deleted immediately */
new_time = rts->rts_time;
if (new_time >= now_garbage)
new_time = now_garbage-1;
@@ -1857,9 +1872,10 @@ walk_age(struct radix_node *rn,
ifp = rts->rts_ifp;
if (i == NUM_SPARES) {
- if (!AGE_RT(RT, ifp)) {
+ if (!AGE_RT(RT->rt_state, ifp)) {
/* Keep various things from deciding ageless
- * routes are stale */
+ * routes are stale
+ */
rts->rts_time = now.tv_sec;
continue;
}
diff --git a/usr.sbin/routed/trace.c b/sbin/routed/trace.c
index e9c1e03f05aa..8a0b59ccb023 100644
--- a/usr.sbin/routed/trace.c
+++ b/sbin/routed/trace.c
@@ -36,7 +36,7 @@ static char sccsid[] = "@(#)trace.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$";
#endif
-#ident "$Revision: 1.11 $"
+#ident "$Revision: 1.13 $"
#define RIPCMDS
#include "defs.h"
@@ -59,6 +59,8 @@ static char *tracelevel_pat = "%s\n";
char savetracename[MAXPATHLEN+1];
+static void trace_dump(void);
+
/* convert IP address to a string, but not into a single buffer
*/
@@ -205,21 +207,26 @@ trace_on(char *filename,
}
filename = savetracename;
- } else if (stat(filename, &stbuf) >= 0) {
- if (!trusted) {
- msglog("trace file \"%s\" already exists");
- return;
- }
- if ((stbuf.st_mode & S_IFMT) != S_IFREG) {
+ } else if (!strcmp(filename,"dump/../table")) {
+ trace_dump();
+ return;
+
+ } else {
+ if (stat(filename, &stbuf) >= 0
+ && (stbuf.st_mode & S_IFMT) != S_IFREG) {
msglog("wrong type (%#x) of trace file \"%s\"",
stbuf.st_mode, filename);
return;
}
if (!trusted
- && strcmp(filename, savetracename)
- && strncmp(filename, _PATH_TRACE, sizeof(_PATH_TRACE)-1)) {
- msglog("wrong directory for trace file: \"%s\"",
+#ifdef _PATH_TRACE
+ && (strncmp(filename, _PATH_TRACE, sizeof(_PATH_TRACE)-1)
+ || strstr(filename,"../")
+ || 0 > stat(_PATH_TRACE, &stbuf))
+#endif
+ && strcmp(filename, savetracename)) {
+ msglog("wrong directory for trace file \"%s\"",
filename);
return;
}
@@ -280,11 +287,13 @@ set_tracelevel(void)
"Tracing actions stopped",
"Tracing packets stopped",
"Tracing packet contents stopped",
+ "Tracing kernel changes stopped",
};
static char *on_msgs[MAX_TRACELEVEL] = {
"Tracing actions started",
"Tracing packets started",
"Tracing packet contents started",
+ "Tracing kernel changes started",
};
@@ -567,6 +576,22 @@ trace_upslot(struct rt_entry *rt,
}
+/* talk about a change made to the kernel table
+ */
+void
+trace_kernel(char *p, ...)
+{
+ va_list args;
+
+ if (!TRACEKERNEL || ftrace == 0)
+ return;
+
+ lastlog();
+ va_start(args, p);
+ vfprintf(ftrace, p, args);
+}
+
+
/* display a message if tracing actions
*/
void
@@ -635,7 +660,7 @@ trace_change(struct rt_entry *rt,
(void)fprintf(ftrace, "%s ",
rt->rt_ifp == 0 ? "?" : rt->rt_ifp->int_name);
(void)fprintf(ftrace, "%s\n",
- AGE_RT(rt, rt->rt_ifp) ? ts(rt->rt_time) : "");
+ AGE_RT(rt->rt_state, rt->rt_ifp) ? ts(rt->rt_time) : "");
(void)fprintf(ftrace, "%*s %19s%-16s ",
strlen(label), "", "",
@@ -652,7 +677,7 @@ trace_change(struct rt_entry *rt,
(void)fprintf(ftrace, "%s ",
ifp != 0 ? ifp->int_name : "?");
(void)fprintf(ftrace, "%s\n",
- ((rt->rt_time == new_time || !AGE_RT(rt, ifp))
+ ((rt->rt_time == new_time || !AGE_RT(rt->rt_state, ifp))
? "" : ts(new_time)));
}
@@ -683,6 +708,68 @@ trace_add_del(char * action, struct rt_entry *rt)
}
+/* ARGSUSED */
+static int
+walk_trace(struct radix_node *rn,
+ struct walkarg *w)
+{
+#define RT ((struct rt_entry *)rn)
+ struct rt_spare *rts;
+ int i, age;
+
+ (void)fprintf(ftrace, " %-35s metric=%-2d ",
+ trace_pair(RT->rt_dst, RT->rt_mask,
+ naddr_ntoa(RT->rt_gate)),
+ RT->rt_metric);
+ if (RT->rt_router != RT->rt_gate)
+ (void)fprintf(ftrace, "router=%s ",
+ naddr_ntoa(RT->rt_router));
+ if (RT->rt_tag != 0)
+ (void)fprintf(ftrace, "tag=%#x ",
+ ntohs(RT->rt_tag));
+ trace_bits(rs_bits, RT->rt_state, 0);
+ (void)fprintf(ftrace, "%s ",
+ RT->rt_ifp == 0 ? "?" : RT->rt_ifp->int_name);
+ age = AGE_RT(RT->rt_state, RT->rt_ifp);
+ if (age)
+ (void)fprintf(ftrace, "%s", ts(RT->rt_time));
+
+ rts = &RT->rt_spares[1];
+ for (i = 1; i < NUM_SPARES; i++, rts++) {
+ if (rts->rts_metric != HOPCNT_INFINITY) {
+ (void)fprintf(ftrace,"\n #%d%15s%-16s metric=%-2d ",
+ i, "", naddr_ntoa(rts->rts_gate),
+ rts->rts_metric);
+ if (rts->rts_router != rts->rts_gate)
+ (void)fprintf(ftrace, "router=%s ",
+ naddr_ntoa(rts->rts_router));
+ if (rts->rts_tag != 0)
+ (void)fprintf(ftrace, "tag=%#x ",
+ ntohs(rts->rts_tag));
+ (void)fprintf(ftrace, "%s ",
+ (rts->rts_ifp == 0
+ ? "?" : rts->rts_ifp->int_name));
+ if (age)
+ (void)fprintf(ftrace, "%s", ts(rts->rts_time));
+ }
+ }
+ (void)fputc('\n',ftrace);
+
+ return 0;
+}
+
+
+static void
+trace_dump(void)
+{
+ if (ftrace == 0)
+ return;
+ lastlog();
+
+ (void)rn_walktree(rhead, walk_trace, 0);
+}
+
+
void
trace_rip(char *dir1, char *dir2,
struct sockaddr_in *who,
diff --git a/usr.sbin/routed/Makefile.inc b/usr.sbin/routed/Makefile.inc
deleted file mode 100644
index 10fa13f1ed80..000000000000
--- a/usr.sbin/routed/Makefile.inc
+++ /dev/null
@@ -1 +0,0 @@
-.include "../../Makefile.inc"
diff --git a/usr.sbin/routed/rttrace/Makefile b/usr.sbin/routed/rttrace/Makefile
deleted file mode 100644
index df19d5c61b44..000000000000
--- a/usr.sbin/routed/rttrace/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# @(#)Makefile 8.1 (Berkeley) 6/5/93
-
-PROG= rttrace
-NOMAN= noman
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/routed/rttrace/rttrace.c b/usr.sbin/routed/rttrace/rttrace.c
deleted file mode 100644
index 0d8ac6224ce7..000000000000
--- a/usr.sbin/routed/rttrace/rttrace.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*-
- * Copyright (c) 1983, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * 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 copyright[] =
-"@(#) Copyright (c) 1983, 1988, 1993\n\
- The Regents of the University of California. All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-static char sccsid[] = "@(#)trace.c 8.1 (Berkeley) 6/5/93";
-#endif /* not lint */
-
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#ifdef sgi
-#include <bstring.h>
-#endif
-#include <sys/param.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <protocols/routed.h>
-#include <arpa/inet.h>
-
-#ifndef sgi
-#define _HAVE_SIN_LEN
-#endif
-
-struct sockaddr_in myaddr;
-char packet[MAXPACKETSIZE];
-
-int
-main(int argc,
- char **argv)
-{
- int size, s;
- struct sockaddr_in router;
- char *tgt;
- register struct rip *msg = (struct rip *)packet;
- struct hostent *hp;
-
- if (argc < 2) {
-usage:
- printf("usage: on filename host1 host2 ...\n"
- " or: off host1 host2 ...\n");
- exit(1);
- }
- s = socket(AF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- perror("socket");
- exit(2);
- }
- myaddr.sin_family = AF_INET;
-#ifdef _HAVE_SIN_LEN
- myaddr.sin_len = sizeof(myaddr);
-#endif
- myaddr.sin_port = htons(IPPORT_RESERVED-1);
- while (bind(s, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
- if (errno != EADDRINUSE
- || myaddr.sin_port == 0) {
- perror("bind");
- exit(2);
- }
- myaddr.sin_port = htons(ntohs(myaddr.sin_port)-1);
- }
-
- msg->rip_vers = RIPVERSION;
- size = sizeof(int);
-
- argv++, argc--;
- if (!strcmp(*argv, "on")) {
- msg->rip_cmd = RIPCMD_TRACEON;
- if (--argc <= 1)
- goto usage;
- strcpy(msg->rip_tracefile, *++argv);
- size += strlen(msg->rip_tracefile);
-
- } else if (!strcmp(*argv, "off")) {
- msg->rip_cmd = RIPCMD_TRACEOFF;
-
- } else {
- goto usage;
- }
- argv++, argc--;
-
- bzero(&router, sizeof(router));
- router.sin_family = AF_INET;
-#ifdef _HAVE_SIN_LEN
- router.sin_len = sizeof(router);
-#endif
- router.sin_port = htons(RIP_PORT);
-
- do {
- tgt = argc > 0 ? *argv++ : "localhost";
- router.sin_family = AF_INET;
- router.sin_addr.s_addr = inet_addr(tgt);
- if (router.sin_addr.s_addr == -1) {
- hp = gethostbyname(tgt);
- if (hp == 0) {
- herror(tgt);
- continue;
- }
- bcopy(hp->h_addr, &router.sin_addr, hp->h_length);
- }
- if (sendto(s, packet, size, 0,
- (struct sockaddr *)&router, sizeof(router)) < 0)
- perror(*argv);
- } while (--argc > 0);
-
- return 0;
-}