summaryrefslogtreecommitdiff
path: root/sbin/routed
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1996-10-02 06:51:50 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1996-10-02 06:51:50 +0000
commit5858b0f0fdcc8c3e53139bf50214ba36dd81620f (patch)
tree670b117c58fb0de32035646045de69b8b6f7c369 /sbin/routed
parent2d0181727eae9dd33e29514e34e5985fd08af1e5 (diff)
update to the latest version from Sep 12.
Diffstat (limited to 'sbin/routed')
-rw-r--r--sbin/routed/defs.h15
-rw-r--r--sbin/routed/if.c51
-rw-r--r--sbin/routed/input.c131
-rw-r--r--sbin/routed/main.c21
-rw-r--r--sbin/routed/parms.c24
-rw-r--r--sbin/routed/routed.85
-rw-r--r--sbin/routed/rtquery/rtquery.88
-rw-r--r--sbin/routed/rtquery/rtquery.c19
-rw-r--r--sbin/routed/table.c10
-rw-r--r--sbin/routed/trace.c92
10 files changed, 246 insertions, 130 deletions
diff --git a/sbin/routed/defs.h b/sbin/routed/defs.h
index 6e61b27674a..6a8b25cc2f9 100644
--- a/sbin/routed/defs.h
+++ b/sbin/routed/defs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: defs.h,v 1.3 1996/09/05 14:31:18 mickey Exp $ */
+/* $OpenBSD: defs.h,v 1.4 1996/10/02 06:51:41 mickey Exp $ */
/*
* Copyright (c) 1983, 1988, 1993
@@ -159,7 +159,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 {
@@ -193,10 +192,11 @@ struct rt_entry {
* nor non-passive, remote interfaces that are not aliases
* (i.e. remote & metric=0)
*/
-#define AGE_RT(rt_state,ifp) (0 == ((rt_state) & RS_PERMANENT) \
- && (!((rt_state) & RS_IF) \
- || (ifp) == 0 \
- || (((ifp)->int_state & IS_REMOTE) \
+#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
@@ -237,7 +237,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 */
@@ -260,6 +260,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 */
diff --git a/sbin/routed/if.c b/sbin/routed/if.c
index 946c797ee93..02246359644 100644
--- a/sbin/routed/if.c
+++ b/sbin/routed/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.3 1996/09/05 14:31:21 mickey Exp $ */
+/* $OpenBSD: if.c,v 1.4 1996/10/02 06:51:43 mickey Exp $ */
/*
* Copyright (c) 1983, 1993
@@ -36,7 +36,7 @@
#if !defined(lint)
static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93";
#else
-static char rcsid[] = "$OpenBSD: if.c,v 1.3 1996/09/05 14:31:21 mickey Exp $";
+static char rcsid[] = "$OpenBSD: if.c,v 1.4 1996/10/02 06:51:43 mickey Exp $";
#endif
#include "defs.h"
@@ -455,12 +455,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;
@@ -549,7 +550,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;
}
@@ -570,6 +571,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)) {
@@ -613,6 +625,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);
@@ -950,12 +973,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/sbin/routed/input.c b/sbin/routed/input.c
index 85010a9f1f4..db66da6398b 100644
--- a/sbin/routed/input.c
+++ b/sbin/routed/input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: input.c,v 1.6 1996/09/06 13:22:07 deraadt Exp $ */
+/* $OpenBSD: input.c,v 1.7 1996/10/02 06:51:44 mickey Exp $ */
/*
* Copyright (c) 1983, 1988, 1993
@@ -36,7 +36,7 @@
#if !defined(lint)
static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/5/93";
#else
-static char rcsid[] = "$OpenBSD: input.c,v 1.6 1996/09/06 13:22:07 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: input.c,v 1.7 1996/10/02 06:51:44 mickey Exp $";
#endif
#include "defs.h"
@@ -70,9 +70,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);
}
}
@@ -81,7 +79,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)
{
@@ -89,17 +87,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)
@@ -108,6 +110,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)
@@ -132,7 +136,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"
@@ -188,32 +192,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 as 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
- */
- supply(from, ifp,
- OUT_QUERY, 0, rip->rip_vers);
- } else if (supplier) {
- /* a router trying to prime its
- * tables.
+ /* Answer a query from a utility
+ * program with all we know.
*/
- 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;
}
@@ -242,7 +256,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)
@@ -259,16 +273,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;
}
}
@@ -285,9 +299,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;
@@ -299,12 +313,11 @@ 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;
}
-#if PERMIT_TRACE
if (rip->rip_cmd == RIPCMD_TRACEON) {
rip->rip_tracefile[size-4] = '\0';
trace_on((char*)rip->rip_tracefile, 0);
@@ -312,10 +325,6 @@ input(struct sockaddr_in *from, /* received from this IP address */
trace_off("tracing turned off by %s\n",
naddr_ntoa(FROM_NADDR));
}
-#else
- msglog("trace command from %s ignored: %s\n",
- rip->rip_tracefile);
-#endif
return;
case RIPCMD_RESPONSE:
@@ -363,7 +372,7 @@ 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("discard packet from unknown router %s"
" or via unidentified interface",
@@ -371,19 +380,19 @@ input(struct sockaddr_in *from, /* received from this IP address */
unk_router = from->sin_addr.s_addr;
return;
}
- if (ifp->int_state & IS_PASSIVE) {
+ 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);
@@ -392,15 +401,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) {
@@ -411,8 +420,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));
@@ -469,7 +478,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
} else {
/* Use it only if it is valid. */
if (on_net(n->n_nhop,
- ifp->int_net, ifp->int_mask)
+ aifp->int_net, aifp->int_mask)
&& check_dst(n->n_nhop)) {
gate = n->n_nhop;
} else {
@@ -487,7 +496,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
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"
@@ -504,7 +513,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;
@@ -514,9 +523,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
@@ -565,7 +574,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;
@@ -645,10 +654,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.
*/
diff --git a/sbin/routed/main.c b/sbin/routed/main.c
index 55faf5d70dc..e1f06adf418 100644
--- a/sbin/routed/main.c
+++ b/sbin/routed/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.3 1996/09/05 14:31:32 mickey Exp $ */
+/* $OpenBSD: main.c,v 1.4 1996/10/02 06:51:45 mickey Exp $ */
/*
* Copyright (c) 1983, 1988, 1993
@@ -39,7 +39,7 @@ char copyright[] =
#if !defined(lint)
static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/5/93";
#else
-static char rcsid[] = "$OpenBSD: main.c,v 1.3 1996/09/05 14:31:32 mickey Exp $";
+static char rcsid[] = "$OpenBSD: main.c,v 1.4 1996/10/02 06:51:45 mickey Exp $";
#endif
#include "defs.h"
@@ -250,6 +250,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
@@ -307,13 +317,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.
*/
diff --git a/sbin/routed/parms.c b/sbin/routed/parms.c
index 22fbd9a34c0..2620c9b3ff5 100644
--- a/sbin/routed/parms.c
+++ b/sbin/routed/parms.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parms.c,v 1.2 1996/09/22 20:48:13 millert Exp $ */
+/* $OpenBSD: parms.c,v 1.3 1996/10/02 06:51:45 mickey Exp $ */
/*
* Copyright (c) 1983, 1993
@@ -473,13 +473,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
@@ -494,6 +487,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/sbin/routed/routed.8 b/sbin/routed/routed.8
index 460d955e56e..1a2913d2ae2 100644
--- a/sbin/routed/routed.8
+++ b/sbin/routed/routed.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: routed.8,v 1.5 1996/09/05 14:31:41 mickey Exp $
+.\" $OpenBSD: routed.8,v 1.6 1996/10/02 06:51:46 mickey Exp $
.\"
.\" Copyright (c) 1983, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -300,6 +300,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/sbin/routed/rtquery/rtquery.8 b/sbin/routed/rtquery/rtquery.8
index 1afb8b9478b..d77ca30b9c8 100644
--- a/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/sbin/routed/rtquery/rtquery.c b/sbin/routed/rtquery/rtquery.c
index 33053b41992..64fddb212b7 100644
--- a/sbin/routed/rtquery/rtquery.c
+++ b/sbin/routed/rtquery/rtquery.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtquery.c,v 1.2 1996/09/22 20:48:10 millert Exp $ */
+/* $OpenBSD: rtquery.c,v 1.3 1996/10/02 06:51:49 mickey Exp $ */
/*-
* Copyright (c) 1982, 1986, 1993
@@ -170,6 +170,8 @@ main(int argc,
"more",
# define TRACE_OFF 2
"off",
+# define TRACE_DUMP 3
+ "dump",
0
};
switch (getsubopt(&options,traceopts,&value)) {
@@ -178,25 +180,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/sbin/routed/table.c b/sbin/routed/table.c
index 7a7f11660c0..0d3be6f61fe 100644
--- a/sbin/routed/table.c
+++ b/sbin/routed/table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: table.c,v 1.2 1996/09/22 20:48:12 millert Exp $ */
+/* $OpenBSD: table.c,v 1.3 1996/10/02 06:51:47 mickey Exp $ */
/*
* Copyright (c) 1983, 1988, 1993
@@ -1660,12 +1660,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 */
diff --git a/sbin/routed/trace.c b/sbin/routed/trace.c
index 55add251038..3bce42f7917 100644
--- a/sbin/routed/trace.c
+++ b/sbin/routed/trace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trace.c,v 1.4 1996/09/06 13:05:02 deraadt Exp $ */
+/* $OpenBSD: trace.c,v 1.5 1996/10/02 06:51:47 mickey Exp $ */
/* $NetBSD: trace.c,v 1.13 1995/06/20 22:28:03 christos Exp $ */
/*
@@ -37,7 +37,7 @@
#if !defined(lint)
static char sccsid[] = "@(#)trace.c 8.1 (Berkeley) 6/5/93";
#else
-static char rcsid[] = "$OpenBSD: trace.c,v 1.4 1996/09/06 13:05:02 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: trace.c,v 1.5 1996/10/02 06:51:47 mickey Exp $";
#endif
#define RIPCMDS
@@ -61,6 +61,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
*/
@@ -207,27 +209,31 @@ trace_on(char *filename,
}
filename = savetracename;
- } else if (lstat(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;
}
}
- /* XXX lstat -> fopen race */
n_ftrace = fopen(filename, "a");
if (n_ftrace == 0) {
msglog("failed to open trace file \"%s\" %s",
@@ -704,6 +710,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,