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:
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
@ -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 *);
|
@ -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) {
|
@ -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
|
@ -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 */
|
@ -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,
|
@ -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;
|
@ -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"
|
@ -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
|
@ -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 ,
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
@ -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,
|
@ -1 +0,0 @@
|
|||||||
.include "../../Makefile.inc"
|
|
@ -1,6 +0,0 @@
|
|||||||
# @(#)Makefile 8.1 (Berkeley) 6/5/93
|
|
||||||
|
|
||||||
PROG= rttrace
|
|
||||||
NOMAN= noman
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
@ -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;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user