Virgin import of new BSD/SGI routed. This update contains a number

of important bug fixes.

Obtained from:	Vernon J. Schryver <vjs@mica.denver.sgi.com>
This commit is contained in:
Garrett Wollman 1996-09-16 16:51:32 +00:00
parent 38cfd0b437
commit 7b6ab19dde
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/SGI/dist2/; revision=18316
svn path=/vendor/SGI/vjs_960912/; revision=18318; tag=vendor/SGI/vjs_960912
21 changed files with 377 additions and 330 deletions

View File

@ -36,7 +36,7 @@
*/ */
#ifndef __NetBSD__ #ifndef __NetBSD__
#ident "$Revision: 1.13 $" #ident "$Revision: 1.16 $"
#endif #endif
/* Definitions for RIPv2 routing process. /* Definitions for RIPv2 routing process.
@ -178,7 +178,6 @@ struct rt_entry {
# define RS_MHOME 0x020 /* from -m */ # define RS_MHOME 0x020 /* from -m */
# define RS_STATIC 0x040 /* from the kernel */ # define RS_STATIC 0x040 /* from the kernel */
# define RS_RDISC 0x080 /* from router discovery */ # 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; struct sockaddr_in rt_dst_sock;
naddr rt_mask; naddr rt_mask;
struct rt_spare { struct rt_spare {
@ -212,11 +211,12 @@ struct rt_entry {
* nor non-passive, remote interfaces that are not aliases * nor non-passive, remote interfaces that are not aliases
* (i.e. remote & metric=0) * (i.e. remote & metric=0)
*/ */
#define AGE_RT(rt,ifp) (0 == ((rt)->rt_state & RS_PERMANENT) \ #define AGE_RT(rt_state,ifp) (0 == ((rt_state) & (RS_MHOME | RS_STATIC \
&& (!((rt)->rt_state & RS_IF) \ | RS_NET_SYN | RS_RDISC)) \
|| (ifp) == 0 \ && (!((rt_state) & RS_IF) \
|| (((ifp)->int_state & IS_REMOTE) \ || (ifp) == 0 \
&& !((ifp)->int_state & IS_PASSIVE)))) || (((ifp)->int_state & IS_REMOTE) \
&& !((ifp)->int_state & IS_PASSIVE))))
/* true if A is better than B /* true if A is better than B
* Better if * Better if
@ -256,7 +256,7 @@ struct interface {
naddr int_std_net; /* class A/B/C network (h) */ naddr int_std_net; /* class A/B/C network (h) */
naddr int_std_mask; /* class A/B/C netmask (h) */ naddr int_std_mask; /* class A/B/C netmask (h) */
int int_rip_sock; /* for queries */ 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; u_int int_state;
time_t int_act_time; /* last thought healthy */ time_t int_act_time; /* last thought healthy */
u_short int_transitions; /* times gone up-down */ u_short int_transitions; /* times gone up-down */
@ -279,6 +279,7 @@ struct interface {
struct timeval int_rdisc_timer; struct timeval int_rdisc_timer;
}; };
/* bits in int_state */
#define IS_ALIAS 0x0000001 /* interface alias */ #define IS_ALIAS 0x0000001 /* interface alias */
#define IS_SUBNET 0x0000002 /* interface on subnetted network */ #define IS_SUBNET 0x0000002 /* interface on subnetted network */
#define IS_REMOTE 0x0000004 /* interface is not on this machine */ #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 epoch; /* when started */
extern struct timeval now; /* current idea of time */ extern struct timeval now; /* current idea of time */
extern time_t now_stale; extern time_t now_stale;
extern time_t now_expire;
extern time_t now_garbage; extern time_t now_garbage;
extern struct timeval next_bcast; /* next general broadcast */ 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 int update_seqno; /* a route has changed */
extern u_int tracelevel, new_tracelevel; 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 TRACECONTENTS (tracelevel >= 3) /* display packet contents */
#define TRACEPACKETS (tracelevel >= 2) /* note packets */ #define TRACEPACKETS (tracelevel >= 2) /* note packets */
#define TRACEACTIONS (tracelevel != 0) #define TRACEACTIONS (tracelevel != 0)
@ -483,6 +486,7 @@ extern void trace_on(char *, int);
extern void trace_off(char*, ...); extern void trace_off(char*, ...);
extern void trace_flush(void); extern void trace_flush(void);
extern void set_tracelevel(void); extern void set_tracelevel(void);
extern void trace_kernel(char *, ...);
extern void trace_act(char *, ...); extern void trace_act(char *, ...);
extern void trace_pkt(char *, ...); extern void trace_pkt(char *, ...);
extern void trace_add_del(char *, struct rt_entry *); extern void trace_add_del(char *, struct rt_entry *);

View File

@ -36,7 +36,7 @@ static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$"; static char rcsid[] = "$NetBSD$";
#endif #endif
#ident "$Revision: 1.16 $" #ident "$Revision: 1.17 $"
#include "defs.h" #include "defs.h"
#include "pathnames.h" #include "pathnames.h"
@ -454,12 +454,13 @@ ifinit(void)
# define COMP_NOT_INET 0x001 # define COMP_NOT_INET 0x001
# define COMP_WIERD 0x002 # define COMP_WIERD 0x002
# define COMP_NOADDR 0x004 # define COMP_NOADDR 0x004
# define COMP_NODST 0x008 # define COMP_BADADDR 0x008
# define COMP_NOBADR 0x010 # define COMP_NODST 0x010
# define COMP_NOMASK 0x020 # define COMP_NOBADR 0x020
# define COMP_DUP 0x040 # define COMP_NOMASK 0x040
# define COMP_BAD_METRIC 0x080 # define COMP_DUP 0x080
# define COMP_NETMASK 0x100 # define COMP_BAD_METRIC 0x100
# define COMP_NETMASK 0x200
struct interface ifs, ifs0, *ifp, *ifp1; struct interface ifs, ifs0, *ifp, *ifp1;
struct rt_entry *rt; struct rt_entry *rt;
@ -548,7 +549,7 @@ ifinit(void)
if (INFO_IFA(&info) == 0) { if (INFO_IFA(&info) == 0) {
if (iff_alive(ifs.int_if_flags)) { if (iff_alive(ifs.int_if_flags)) {
if (!(prev_complaints & COMP_NOADDR)) if (!(prev_complaints & COMP_NOADDR))
msglog("%s has a bad address", msglog("%s has no address",
sdl->sdl_data); sdl->sdl_data);
complaints |= COMP_NOADDR; complaints |= COMP_NOADDR;
} }
@ -569,6 +570,17 @@ ifinit(void)
ifs.int_addr = S_ADDR(INFO_IFA(&info)); 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 (ifs.int_if_flags & IFF_BROADCAST) {
if (INFO_MASK(&info) == 0) { if (INFO_MASK(&info) == 0) {
if (iff_alive(ifs.int_if_flags)) { if (iff_alive(ifs.int_if_flags)) {
@ -612,6 +624,17 @@ ifinit(void)
continue; continue;
} }
ifs.int_dstaddr = S_ADDR(INFO_BRD(&info)); 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_mask = HOST_MASK;
ifs.int_ripv1_mask = ntohl(S_ADDR(INFO_MASK(&info))); ifs.int_ripv1_mask = ntohl(S_ADDR(INFO_MASK(&info)));
ifs.int_net = ntohl(ifs.int_dstaddr); ifs.int_net = ntohl(ifs.int_dstaddr);
@ -949,12 +972,10 @@ ifinit(void)
/* If we ever have a RIPv1 interface, assume we always will. /* If we ever have a RIPv1 interface, assume we always will.
* It might come back if it ever goes away. * It might come back if it ever goes away.
*/ */
if (!(ifp->int_if_flags & IFF_LOOPBACK)) { if (!(ifp->int_state & IS_NO_RIPV1_OUT) && supplier)
if (!(ifp->int_state & IS_NO_RIPV1_OUT)) have_ripv1_out = 1;
have_ripv1_out = 1; if (!(ifp->int_state & IS_NO_RIPV1_IN))
if (!(ifp->int_state & IS_NO_RIPV1_IN)) have_ripv1_in = 1;
have_ripv1_in = 1;
}
} }
for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) { for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) {

View File

@ -36,7 +36,7 @@ static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$"; static char rcsid[] = "$NetBSD$";
#endif #endif
#ident "$Revision: 1.13 $" #ident "$Revision: 1.16 $"
#include "defs.h" #include "defs.h"
@ -69,9 +69,7 @@ read_rip(int sock,
logbad(1,"impossible recvfrom(rip) fromlen=%d", logbad(1,"impossible recvfrom(rip) fromlen=%d",
fromlen); fromlen);
input(&from, input(&from, ifp, &inbuf.rip, cc);
(ifp != 0) ? ifp : iflookup(from.sin_addr.s_addr),
&inbuf.rip, cc);
} }
} }
@ -80,7 +78,7 @@ read_rip(int sock,
*/ */
static void static void
input(struct sockaddr_in *from, /* received from this IP address */ input(struct sockaddr_in *from, /* received from this IP address */
struct interface *ifp, struct interface *sifp, /* interface by which it arrived */
struct rip *rip, struct rip *rip,
int size) 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 use_auth, bad_len, bad_mask;
static naddr unk_router, bad_router, bad_nhop; static naddr unk_router, bad_router, bad_nhop;
struct interface *aifp; /* interface if via 1 hop */
struct rt_entry *rt; struct rt_entry *rt;
struct netinfo *n, *lim; struct netinfo *n, *lim;
struct interface *ifp1; struct interface *ifp1;
naddr gate, mask, v1_mask, dst, ddst_h; naddr gate, mask, v1_mask, dst, ddst_h;
int i; int i;
aifp = iflookup(from->sin_addr.s_addr);
if (sifp == 0)
sifp = aifp;
if (ifp != 0) if (sifp != 0)
ifp->int_state |= IS_ACTIVE; 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 (rip->rip_vers == 0) {
if (from->sin_addr.s_addr != bad_router) 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)); rip->rip_cmd, naddr_ntoa(FROM_NADDR));
bad_router = from->sin_addr.s_addr; bad_router = from->sin_addr.s_addr;
return; return;
} else if (rip->rip_vers > RIPv2) {
rip->rip_vers = RIPv2;
} }
if (size > MAXPACKETSIZE) { if (size > MAXPACKETSIZE) {
if (from->sin_addr.s_addr != bad_router) 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! * RIPv1 systems will listen? Crazy!
*/ */
if (!auth_ok if (!auth_ok
&& rip->rip_vers >= RIPv2 && rip->rip_vers == RIPv2
&& n < lim && n->n_family == RIP_AF_AUTH) { && n < lim && n->n_family == RIP_AF_AUTH) {
if (from->sin_addr.s_addr != use_auth) if (from->sin_addr.s_addr != use_auth)
msglog("RIPv2 message with authentication" 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 * We respond to routers only if we are acting
* as a supplier, or to anyone other than a router * as a supplier, or to anyone other than a router
* (i.e. a query). * (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 if (n->n_family == RIP_AF_UNSPEC
&& n->n_metric == HOPCNT_INFINITY && n->n_metric == HOPCNT_INFINITY
&& n == rip->rip_nets && n == rip->rip_nets
&& n+1 == lim) { && n+1 == lim) {
if (from->sin_port != htons(RIP_PORT)) { 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, supply(from, sifp, OUT_QUERY, 0,
OUT_QUERY, 0, rip->rip_vers); rip->rip_vers);
} else if (supplier) { return;
/* a router trying to prime its
* tables.
*/
supply(from, ifp,
OUT_UNICAST, 0, rip->rip_vers);
} }
/* 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; return;
} }
@ -241,7 +255,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
if (rip->rip_vers == RIPv1 if (rip->rip_vers == RIPv1
|| 0 == (mask = ntohl(n->n_mask)) || 0 == (mask = ntohl(n->n_mask))
|| 0 != (ntohl(dst) & ~mask)) || 0 != (ntohl(dst) & ~mask))
mask = ripv1_mask_host(dst,ifp); mask = ripv1_mask_host(dst,sifp);
rt = rtget(dst, mask); rt = rtget(dst, mask);
if (!rt && dst != RIP_DEFAULT) if (!rt && dst != RIP_DEFAULT)
@ -258,16 +272,16 @@ input(struct sockaddr_in *from, /* received from this IP address */
n->n_metric = HOPCNT_INFINITY; n->n_metric = HOPCNT_INFINITY;
} else { } else {
n->n_metric = rt->rt_metric+1; 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) if (n->n_metric > HOPCNT_INFINITY)
n->n_metric = HOPCNT_INFINITY; n->n_metric = HOPCNT_INFINITY;
if (rip->rip_vers != RIPv1) { if (rip->rip_vers != RIPv1) {
n->n_tag = rt->rt_tag; n->n_tag = rt->rt_tag;
if (ifp != 0 if (sifp != 0
&& on_net(rt->rt_gate, && on_net(rt->rt_gate,
ifp->int_net, sifp->int_net,
ifp->int_mask) sifp->int_mask)
&& rt->rt_gate != ifp->int_addr) && rt->rt_gate != sifp->int_addr)
n->n_nhop = rt->rt_gate; n->n_nhop = rt->rt_gate;
} }
} }
@ -284,9 +298,9 @@ input(struct sockaddr_in *from, /* received from this IP address */
rip->rip_vers = RIPv2; rip->rip_vers = RIPv2;
if (from->sin_port != htons(RIP_PORT)) { if (from->sin_port != htons(RIP_PORT)) {
/* query */ /* query */
(void)output(OUT_QUERY, from, ifp, rip, size); (void)output(OUT_QUERY, from, sifp, rip, size);
} else if (supplier) { } else if (supplier) {
(void)output(OUT_UNICAST, from, ifp, rip, size); (void)output(OUT_UNICAST, from, sifp, rip, size);
} }
return; return;
@ -298,7 +312,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
naddr_ntoa(FROM_NADDR)); naddr_ntoa(FROM_NADDR));
return; return;
} }
if (ifp == 0) { if (aifp == 0) {
msglog("trace command from unknown router %s", msglog("trace command from unknown router %s",
naddr_ntoa(FROM_NADDR)); naddr_ntoa(FROM_NADDR));
return; return;
@ -357,26 +371,27 @@ input(struct sockaddr_in *from, /* received from this IP address */
* broadcast or point-to-point networks, and from * broadcast or point-to-point networks, and from
* those listed in /etc/gateways. * those listed in /etc/gateways.
*/ */
if (!ifp) { if (!aifp) {
if (from->sin_addr.s_addr != unk_router) 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", " or via unidentified interface",
naddr_ntoa(FROM_NADDR)); naddr_ntoa(FROM_NADDR));
unk_router = from->sin_addr.s_addr; unk_router = from->sin_addr.s_addr;
return; return;
} }
if (ifp->int_state & IS_PASSIVE) { if (aifp->int_state & IS_PASSIVE) {
trace_act("packet from %s via passive interface %s\n", trace_act("discard packet from %s"
" via passive interface %s\n",
naddr_ntoa(FROM_NADDR), naddr_ntoa(FROM_NADDR),
ifp->int_name); aifp->int_name);
return; return;
} }
/* Check required version /* Check required version
*/ */
if (((ifp->int_state & IS_NO_RIPV1_IN) if (((aifp->int_state & IS_NO_RIPV1_IN)
&& rip->rip_vers == RIPv1) && rip->rip_vers == RIPv1)
|| ((ifp->int_state & IS_NO_RIPV2_IN) || ((aifp->int_state & IS_NO_RIPV2_IN)
&& rip->rip_vers != RIPv1)) { && rip->rip_vers != RIPv1)) {
trace_pkt("discard RIPv%d response\n", trace_pkt("discard RIPv%d response\n",
rip->rip_vers); rip->rip_vers);
@ -385,15 +400,15 @@ input(struct sockaddr_in *from, /* received from this IP address */
/* Ignore routes via dead interface. /* 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", trace_pkt("discard response via broken interface %s\n",
ifp->int_name); aifp->int_name);
return; return;
} }
/* Authenticate the packet if we have a secret. /* Authenticate the packet if we have a secret.
*/ */
if (ifp->int_passwd[0] != '\0') { if (aifp->int_passwd[0] != '\0') {
if (n >= lim if (n >= lim
|| n->n_family != RIP_AF_AUTH || n->n_family != RIP_AF_AUTH
|| ((struct netauth*)n)->a_type != RIP_AUTH_PW) { || ((struct netauth*)n)->a_type != RIP_AUTH_PW) {
@ -404,8 +419,8 @@ input(struct sockaddr_in *from, /* received from this IP address */
return; return;
} else if (0 != bcmp(((struct netauth*)n)->au.au_pw, } else if (0 != bcmp(((struct netauth*)n)->au.au_pw,
ifp->int_passwd, aifp->int_passwd,
sizeof(ifp->int_passwd))) { sizeof(aifp->int_passwd))) {
if (from->sin_addr.s_addr != use_auth) if (from->sin_addr.s_addr != use_auth)
msglog("bad password from %s", msglog("bad password from %s",
naddr_ntoa(FROM_NADDR)); naddr_ntoa(FROM_NADDR));
@ -456,31 +471,31 @@ input(struct sockaddr_in *from, /* received from this IP address */
/* Notice the next-hop. /* Notice the next-hop.
*/ */
gate = from->sin_addr.s_addr; gate = from->sin_addr.s_addr;
if (n->n_nhop != 0 if (n->n_nhop != 0) {
&& rip->rip_vers == RIPv2) { if (rip->rip_vers == RIPv2) {
/* Ignore the route if it points to us */ n->n_nhop = 0;
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;
} else { } 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) if (bad_nhop != from->sin_addr.s_addr)
msglog("router %s to %s has" msglog("router %s to %s has"
" bad next hop %s", " bad next hop %s",
naddr_ntoa(FROM_NADDR), naddr_ntoa(FROM_NADDR),
naddr_ntoa(dst), naddr_ntoa(dst),
naddr_ntoa(n->n_nhop)); naddr_ntoa(n->n_nhop));
bad_nhop = from->sin_addr.s_addr; bad_nhop = from->sin_addr.s_addr;
n->n_nhop = 0;
}
} }
} }
if (rip->rip_vers == RIPv1 if (rip->rip_vers == RIPv1
|| 0 == (mask = ntohl(n->n_mask))) { || 0 == (mask = ntohl(n->n_mask))) {
mask = ripv1_mask_host(dst,ifp); mask = ripv1_mask_host(dst,aifp);
} else if ((ntohl(dst) & ~mask) != 0) { } else if ((ntohl(dst) & ~mask) != 0) {
if (bad_mask != from->sin_addr.s_addr) { if (bad_mask != from->sin_addr.s_addr) {
msglog("router %s sent bad netmask" 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.. /* Adjust metric according to incoming interface..
*/ */
n->n_metric += ifp->int_metric; n->n_metric += aifp->int_metric;
if (n->n_metric > HOPCNT_INFINITY) if (n->n_metric > HOPCNT_INFINITY)
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 * Be a little more paranoid than that, and reject
* default routes with the same metric we advertised. * default routes with the same metric we advertised.
*/ */
if (ifp->int_d_metric != 0 if (aifp->int_d_metric != 0
&& dst == RIP_DEFAULT && dst == RIP_DEFAULT
&& n->n_metric >= ifp->int_d_metric) && n->n_metric >= aifp->int_d_metric)
continue; continue;
/* We can receive aggregated RIPv2 routes that must /* We can receive aggregated RIPv2 routes that must
@ -558,7 +573,7 @@ input(struct sockaddr_in *from, /* received from this IP address */
} }
for (;;) { for (;;) {
input_route(ifp, FROM_NADDR, input_route(aifp, FROM_NADDR,
dst, mask, gate, n); dst, mask, gate, n);
if (i-- == 0) if (i-- == 0)
break; break;
@ -610,6 +625,14 @@ input_route(struct interface *ifp,
if (n->n_metric == HOPCNT_INFINITY) if (n->n_metric == HOPCNT_INFINITY)
return; 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) if (total_routes < MAX_ROUTES)
rtadd(dst, mask, gate, from, n->n_metric, rtadd(dst, mask, gate, from, n->n_metric,
n->n_tag, 0, ifp); n->n_tag, 0, ifp);
@ -630,10 +653,8 @@ input_route(struct interface *ifp,
* synthetic, RIPv1 network route of our own. * synthetic, RIPv1 network route of our own.
* The worst is that both kinds of routes might be * The worst is that both kinds of routes might be
* received, and the bad one might have the smaller * received, and the bad one might have the smaller
* metric. Partly solve this problem by faking the * metric. Partly solve this problem by never
* RIPv1 route with a metric that reflects the most * aggregating into such a route. Also keep it
* distant part of the subnet. Also never
* aggregate into such a route. Also keep it
* around as long as the interface exists. * around as long as the interface exists.
*/ */
@ -686,7 +707,13 @@ input_route(struct interface *ifp,
} else { } else {
/* The update is for a route we know about, /* The update is for a route we know about,
* but not from a familiar router. * 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; rts = rts0;
/* Save the route as a spare only if it has /* Save the route as a spare only if it has

View File

@ -39,7 +39,7 @@ static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$"; static char rcsid[] = "$NetBSD$";
#endif #endif
#ident "$Revision: 1.14 $" #ident "$Revision: 1.17 $"
#include "defs.h" #include "defs.h"
#include "pathnames.h" #include "pathnames.h"
@ -70,6 +70,7 @@ struct timeval epoch; /* when started */
struct timeval clk, prev_clk; struct timeval clk, prev_clk;
struct timeval now; /* current idea of time */ struct timeval now; /* current idea of time */
time_t now_stale; time_t now_stale;
time_t now_expire;
time_t now_garbage; time_t now_garbage;
struct timeval next_bcast; /* next general broadcast */ struct timeval next_bcast; /* next general broadcast */
@ -111,6 +112,7 @@ main(int argc,
epoch.tv_sec -= EPOCH; epoch.tv_sec -= EPOCH;
now.tv_sec = EPOCH; now.tv_sec = EPOCH;
now_stale = EPOCH - STALE_TIME; now_stale = EPOCH - STALE_TIME;
now_expire = EPOCH - EXPIRE_TIME;
now_garbage = EPOCH - GARBAGE_TIME; now_garbage = EPOCH - GARBAGE_TIME;
wtime.tv_sec = 0; wtime.tv_sec = 0;
@ -247,6 +249,16 @@ main(int argc,
} }
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 */ /* get into the background */
if (background) { if (background) {
#ifdef sgi #ifdef sgi
@ -275,7 +287,7 @@ main(int argc,
if (setsockopt(rt_sock, SOL_SOCKET,SO_USELOOPBACK, if (setsockopt(rt_sock, SOL_SOCKET,SO_USELOOPBACK,
&off,sizeof(off)) < 0) &off,sizeof(off)) < 0)
LOGERR("setsockopt(SO_USELOOPBACK,0)"); LOGERR("setsockopt(SO_USELOOPBACK,0)");
fix_select(); fix_select();
@ -304,13 +316,6 @@ main(int argc,
rdisc_timer = next_bcast; rdisc_timer = next_bcast;
ifinit_timer.tv_usec = next_bcast.tv_usec; 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 /* Collect an initial view of the world by checking the interface
* configuration and the kludge file. * configuration and the kludge file.
*/ */
@ -342,6 +347,7 @@ main(int argc,
} }
timevalsub(&now, &clk, &epoch); timevalsub(&now, &clk, &epoch);
now_stale = now.tv_sec - STALE_TIME; now_stale = now.tv_sec - STALE_TIME;
now_expire = now.tv_sec - EXPIRE_TIME;
now_garbage = now.tv_sec - GARBAGE_TIME; now_garbage = now.tv_sec - GARBAGE_TIME;
/* deal with interrupts that should affect tracing */ /* deal with interrupts that should affect tracing */

View File

@ -36,7 +36,7 @@ static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$"; static char rcsid[] = "$NetBSD$";
#endif #endif
#ident "$Revision: 1.16 $" #ident "$Revision: 1.17 $"
#include "defs.h" #include "defs.h"
@ -263,7 +263,7 @@ supply_out(struct ag_info *ag)
&& (ws.state & WS_ST_FLASH)) && (ws.state & WS_ST_FLASH))
return; return;
/* Skip this route if required by split-horizon /* Skip this route if required by split-horizon.
*/ */
if (ag->ag_state & AGS_SPLIT_HZ) if (ag->ag_state & AGS_SPLIT_HZ)
return; return;
@ -363,7 +363,7 @@ walk_supply(struct radix_node *rn,
struct walkarg *w) struct walkarg *w)
{ {
#define RT ((struct rt_entry *)rn) #define RT ((struct rt_entry *)rn)
u_short ags = 0; u_short ags;
char metric, pref; char metric, pref;
naddr dst, nhop; naddr dst, nhop;
@ -371,7 +371,8 @@ walk_supply(struct radix_node *rn,
/* Do not advertise the loopback interface /* Do not advertise the loopback interface
* or external remote interfaces * 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_if_flags & IFF_LOOPBACK)
|| (RT->rt_ifp->int_state & IS_EXTERNAL)) || (RT->rt_ifp->int_state & IS_EXTERNAL))
&& !(RT->rt_state & RS_MHOME)) && !(RT->rt_state & RS_MHOME))
@ -429,32 +430,8 @@ walk_supply(struct radix_node *rn,
nhop = 0; nhop = 0;
} }
/* Adjust the outgoing metric by the cost of the link. metric = RT->rt_metric;
*/ ags = 0;
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;
}
if (RT->rt_state & RS_MHOME) { if (RT->rt_state & RS_MHOME) {
/* retain host route of multi-homed servers */ /* retain host route of multi-homed servers */
@ -521,8 +498,47 @@ walk_supply(struct radix_node *rn,
&& (ws.state & WS_ST_TO_ON_NET) && (ws.state & WS_ST_TO_ON_NET)
&& (!(RT->rt_state & RS_IF) && (!(RT->rt_state & RS_IF)
|| ws.ifp->int_if_flags & IFF_POINTOPOINT)) { || ws.ifp->int_if_flags & IFF_POINTOPOINT)) {
ags |= AGS_SPLIT_HZ; /* Poison-reverse the route instead of only not advertising it
ags &= ~(AGS_PROMOTE | AGS_SUPPRESS); * 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, ag_check(dst, RT->rt_mask, 0, nhop, metric, pref,

View File

@ -36,7 +36,7 @@ static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$"; static char rcsid[] = "$NetBSD$";
#endif #endif
#ident "$Revision: 1.8 $" #ident "$Revision: 1.9 $"
#include "defs.h" #include "defs.h"
#include "pathnames.h" #include "pathnames.h"
@ -474,13 +474,6 @@ parse_parms(char *line)
if (tgt != 0) if (tgt != 0)
return tgt; 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); return check_parms(&parm);
#undef DELIMS #undef DELIMS
#undef PARS #undef PARS
@ -495,6 +488,21 @@ check_parms(struct parm *new)
struct parm *parmp; 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) { for (parmp = parms; parmp != 0; parmp = parmp->parm_next) {
if (strcmp(new->parm_name, parmp->parm_name)) if (strcmp(new->parm_name, parmp->parm_name))
continue; continue;

View File

@ -43,5 +43,8 @@
* or be the same as the tracefile specified when the daemon was started. * 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 * If this is a directory, routed will create log files in it. That
* might be a security problem. * 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"

View File

@ -298,6 +298,9 @@ does not care about authentication.
.It Fl T Ar tracefile .It Fl T Ar tracefile
increases the debugging level to at least 1 and increases the debugging level to at least 1 and
causes debugging information to be appended to the trace file. 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 .It Fl t
increases the debugging level, which causes more information to be logged increases the debugging level, which causes more information to be logged
on the tracefile specified with on the tracefile specified with

View File

@ -79,18 +79,20 @@ change tracing, where
.Em op .Em op
is one of the following. is one of the following.
Requests from processes not running with UID 0 or on distant networks 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 .El
.Bl -tag -width Ds -offset indent-two .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 turn tracing on into the specified file. That file must usually
have been specified when the daemon was started or be the same have been specified when the daemon was started or be the same
as a fixed name, often as a fixed name, often
.Pa /tmp/routed.log . .Pa /etc/routed.trace .
.It Em more .It Em more
increases the debugging level. increases the debugging level.
.It Em off .It Em off
turns off tracing. turns off tracing.
.It Em dump
dumps the daemon's routing table to the current tracefile.
.El .El
.Sh SEE ALSO .Sh SEE ALSO
.Xr routed 8 , .Xr routed 8 ,

View File

@ -40,7 +40,7 @@ static char sccsid[] = "@(#)query.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$"; static char rcsid[] = "$NetBSD$";
#endif #endif
#ident "$Revision: 1.8 $" #ident "$Revision: 1.9 $"
#include <sys/param.h> #include <sys/param.h>
#include <sys/protosw.h> #include <sys/protosw.h>
@ -171,6 +171,8 @@ main(int argc,
"more", "more",
# define TRACE_OFF 2 # define TRACE_OFF 2
"off", "off",
# define TRACE_DUMP 3
"dump",
0 0
}; };
switch (getsubopt(&options,traceopts,&value)) { switch (getsubopt(&options,traceopts,&value)) {
@ -179,25 +181,30 @@ main(int argc,
if (!value if (!value
|| strlen(value) > MAXPATHLEN) || strlen(value) > MAXPATHLEN)
goto usage; goto usage;
strcpy((char*)OMSG.rip_tracefile,value);
omsg_len += (strlen(value)
- sizeof(OMSG.ripun));
break; break;
case TRACE_MORE: case TRACE_MORE:
if (value) if (value)
goto usage; goto usage;
OMSG.rip_cmd = RIPCMD_TRACEON; OMSG.rip_cmd = RIPCMD_TRACEON;
OMSG.rip_tracefile[0] = '\0'; value = "";
break; break;
case TRACE_OFF: case TRACE_OFF:
if (value) if (value)
goto usage; goto usage;
OMSG.rip_cmd = RIPCMD_TRACEOFF; 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; break;
default: default:
goto usage; goto usage;
} }
strcpy((char*)OMSG.rip_tracefile, value);
omsg_len += strlen(value) - sizeof(OMSG.ripun);
} }
break; break;

View File

@ -36,7 +36,7 @@ static char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$"; static char rcsid[] = "$NetBSD$";
#endif #endif
#ident "$Revision: 1.23 $" #ident "$Revision: 1.25 $"
#include "defs.h" #include "defs.h"
@ -690,6 +690,13 @@ rtioctl(int action, /* RTM_DELETE, etc */
w.w_rtm.rtm_msglen -= (sizeof(w.w_mask) - w.w_mask.sin_len); w.w_rtm.rtm_msglen -= (sizeof(w.w_mask) - w.w_mask.sin_len);
#endif #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 #ifndef NO_INSTALL
cc = write(rt_sock, &w, w.w_rtm.rtm_msglen); cc = write(rt_sock, &w, w.w_rtm.rtm_msglen);
if (cc == 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; k->k_state |= KS_GATEWAY;
if (rtm->rtm_flags & RTF_STATIC) if (rtm->rtm_flags & RTF_STATIC)
k->k_state |= KS_STATIC; k->k_state |= KS_STATIC;
if (0 != (rtm->rtm_flags & (RTF_DYNAMIC | RTF_MODIFIED))) { if (0 != (rtm->rtm_flags & (RTF_DYNAMIC | RTF_MODIFIED))) {
if (supplier) { if (supplier) {
/* Routers are not supposed to listen to redirects, /* 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_DYNAMIC;
k->k_state |= KS_DELETE; k->k_state |= KS_DELETE;
LIM_SEC(need_kern, 0);
trace_act("mark redirected %s --> %s for deletion" trace_act("mark redirected %s --> %s for deletion"
" since this is a router\n", " since this is a router\n",
addrname(k->k_dst, k->k_mask, 0), 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_state |= KS_DYNAMIC;
k->k_redirect_time = now.tv_sec; k->k_redirect_time = now.tv_sec;
} }
return;
} }
/* If it is not a static route, quit until the next comparison /* 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 * has gone bad, since there may be a working route that
* aggregates this route. * aggregates this route.
*/ */
if (metric == HOPCNT_INFINITY) if (metric == HOPCNT_INFINITY) {
need_kern.tv_sec = now.tv_sec; 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; rt->rt_seqno = update_seqno;
set_need_flash(); set_need_flash();
} }
@ -1598,6 +1611,11 @@ rtchange(struct rt_entry *rt,
state |= (rt->rt_state & RS_SUBNET); 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) if (TRACEACTIONS)
trace_change(rt, state, gate, router, metric, tag, ifp, trace_change(rt, state, gate, router, metric, tag, ifp,
new_time, new_time,
@ -1643,12 +1661,8 @@ rtswitch(struct rt_entry *rt,
/* Do not change permanent routes */ /* Do not change permanent routes */
if (0 != (rt->rt_state & RS_PERMANENT)) if (0 != (rt->rt_state & (RS_MHOME | RS_STATIC | RS_RDISC
return; | RS_NET_SYN | RS_IF)))
/* Do not discard synthetic routes until they go bad */
if ((rt->rt_state & RS_NET_SYN)
&& rt->rt_metric < HOPCNT_INFINITY)
return; return;
/* find the best alternative among the spares */ /* find the best alternative among the spares */
@ -1803,6 +1817,7 @@ walk_bad(struct radix_node *rn,
if (rts->rts_ifp != 0 if (rts->rts_ifp != 0
&& (rts->rts_ifp->int_state & IS_BROKE)) { && (rts->rts_ifp->int_state & IS_BROKE)) {
/* mark the spare route to be deleted immediately */
new_time = rts->rts_time; new_time = rts->rts_time;
if (new_time >= now_garbage) if (new_time >= now_garbage)
new_time = now_garbage-1; new_time = now_garbage-1;
@ -1857,9 +1872,10 @@ walk_age(struct radix_node *rn,
ifp = rts->rts_ifp; ifp = rts->rts_ifp;
if (i == NUM_SPARES) { if (i == NUM_SPARES) {
if (!AGE_RT(RT, ifp)) { if (!AGE_RT(RT->rt_state, ifp)) {
/* Keep various things from deciding ageless /* Keep various things from deciding ageless
* routes are stale */ * routes are stale
*/
rts->rts_time = now.tv_sec; rts->rts_time = now.tv_sec;
continue; continue;
} }

View File

@ -36,7 +36,7 @@ static char sccsid[] = "@(#)trace.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$"; static char rcsid[] = "$NetBSD$";
#endif #endif
#ident "$Revision: 1.11 $" #ident "$Revision: 1.13 $"
#define RIPCMDS #define RIPCMDS
#include "defs.h" #include "defs.h"
@ -59,6 +59,8 @@ static char *tracelevel_pat = "%s\n";
char savetracename[MAXPATHLEN+1]; char savetracename[MAXPATHLEN+1];
static void trace_dump(void);
/* convert IP address to a string, but not into a single buffer /* convert IP address to a string, but not into a single buffer
*/ */
@ -205,21 +207,26 @@ trace_on(char *filename,
} }
filename = savetracename; filename = savetracename;
} else if (stat(filename, &stbuf) >= 0) { } else if (!strcmp(filename,"dump/../table")) {
if (!trusted) { trace_dump();
msglog("trace file \"%s\" already exists"); return;
return;
} } else {
if ((stbuf.st_mode & S_IFMT) != S_IFREG) { if (stat(filename, &stbuf) >= 0
&& (stbuf.st_mode & S_IFMT) != S_IFREG) {
msglog("wrong type (%#x) of trace file \"%s\"", msglog("wrong type (%#x) of trace file \"%s\"",
stbuf.st_mode, filename); stbuf.st_mode, filename);
return; return;
} }
if (!trusted if (!trusted
&& strcmp(filename, savetracename) #ifdef _PATH_TRACE
&& strncmp(filename, _PATH_TRACE, sizeof(_PATH_TRACE)-1)) { && (strncmp(filename, _PATH_TRACE, sizeof(_PATH_TRACE)-1)
msglog("wrong directory for trace file: \"%s\"", || strstr(filename,"../")
|| 0 > stat(_PATH_TRACE, &stbuf))
#endif
&& strcmp(filename, savetracename)) {
msglog("wrong directory for trace file \"%s\"",
filename); filename);
return; return;
} }
@ -280,11 +287,13 @@ set_tracelevel(void)
"Tracing actions stopped", "Tracing actions stopped",
"Tracing packets stopped", "Tracing packets stopped",
"Tracing packet contents stopped", "Tracing packet contents stopped",
"Tracing kernel changes stopped",
}; };
static char *on_msgs[MAX_TRACELEVEL] = { static char *on_msgs[MAX_TRACELEVEL] = {
"Tracing actions started", "Tracing actions started",
"Tracing packets started", "Tracing packets started",
"Tracing packet contents 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 /* display a message if tracing actions
*/ */
void void
@ -635,7 +660,7 @@ trace_change(struct rt_entry *rt,
(void)fprintf(ftrace, "%s ", (void)fprintf(ftrace, "%s ",
rt->rt_ifp == 0 ? "?" : rt->rt_ifp->int_name); rt->rt_ifp == 0 ? "?" : rt->rt_ifp->int_name);
(void)fprintf(ftrace, "%s\n", (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 ", (void)fprintf(ftrace, "%*s %19s%-16s ",
strlen(label), "", "", strlen(label), "", "",
@ -652,7 +677,7 @@ trace_change(struct rt_entry *rt,
(void)fprintf(ftrace, "%s ", (void)fprintf(ftrace, "%s ",
ifp != 0 ? ifp->int_name : "?"); ifp != 0 ? ifp->int_name : "?");
(void)fprintf(ftrace, "%s\n", (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))); ? "" : 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 void
trace_rip(char *dir1, char *dir2, trace_rip(char *dir1, char *dir2,
struct sockaddr_in *who, struct sockaddr_in *who,

View File

@ -1 +0,0 @@
.include "../../Makefile.inc"

View File

@ -1,6 +0,0 @@
# @(#)Makefile 8.1 (Berkeley) 6/5/93
PROG= rttrace
NOMAN= noman
.include <bsd.prog.mk>

View File

@ -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;
}