diff options
author | Garrett Wollman <wollman@FreeBSD.org> | 1996-08-27 16:13:00 +0000 |
---|---|---|
committer | Garrett Wollman <wollman@FreeBSD.org> | 1996-08-27 16:13:00 +0000 |
commit | 38cfd0b437d4376607181b9329b6e39940d8a553 (patch) | |
tree | 532c9e8ae13ddb3e682aeaf586e35ac1243a2f34 | |
parent | 1823680765faa251d4ecd9229988ba71fce9c175 (diff) |
Notes
-rw-r--r-- | usr.sbin/routed/Makefile | 16 | ||||
-rw-r--r-- | usr.sbin/routed/defs.h | 36 | ||||
-rw-r--r-- | usr.sbin/routed/if.c | 72 | ||||
-rw-r--r-- | usr.sbin/routed/input.c | 99 | ||||
-rw-r--r-- | usr.sbin/routed/main.c | 31 | ||||
-rw-r--r-- | usr.sbin/routed/output.c | 27 | ||||
-rw-r--r-- | usr.sbin/routed/parms.c | 17 | ||||
-rw-r--r-- | usr.sbin/routed/pathnames.h | 2 | ||||
-rw-r--r-- | usr.sbin/routed/radix.c | 171 | ||||
-rw-r--r-- | usr.sbin/routed/radix.h | 161 | ||||
-rw-r--r-- | usr.sbin/routed/rdisc.c | 83 | ||||
-rw-r--r-- | usr.sbin/routed/routed.h | 37 | ||||
-rw-r--r-- | usr.sbin/routed/rtquery/Makefile | 3 | ||||
-rw-r--r-- | usr.sbin/routed/rtquery/rtquery.c | 25 | ||||
-rw-r--r-- | usr.sbin/routed/table.c | 140 | ||||
-rw-r--r-- | usr.sbin/routed/trace.c | 78 |
16 files changed, 662 insertions, 336 deletions
diff --git a/usr.sbin/routed/Makefile b/usr.sbin/routed/Makefile index 594a05059d75..c567e68e87ad 100644 --- a/usr.sbin/routed/Makefile +++ b/usr.sbin/routed/Makefile @@ -2,7 +2,21 @@ PROG= routed SRCS= if.c input.c main.c output.c parms.c radix.c rdisc.c table.c trace.c -MAN8= routed.8 +MAN8= routed.0 SUBDIR= rtquery +DPADD= ${LIBCOMPAT} +LDADD= -lcompat +#COPTS= -g -DDEBUG -Wall .include <bsd.prog.mk> + +.if (${MACHINE} == "vax") +# The following can be deleted where not appropriate to use the kernel's +# inline code expansions. +INLINE= /sys/vax/inline/obj/inline +C2= /usr/libexec/c2 +.c.o: + ${CC} -S ${CFLAGS} ${.CURDIR}/${.PREFIX}.c + @${C2} ${.PREFIX}.s | ${INLINE} | ${AS} -o ${.PREFIX}.o + @rm -f ${.PREFIX}.s +.endif diff --git a/usr.sbin/routed/defs.h b/usr.sbin/routed/defs.h index 85eb3dad5176..f64991222191 100644 --- a/usr.sbin/routed/defs.h +++ b/usr.sbin/routed/defs.h @@ -31,9 +31,13 @@ * SUCH DAMAGE. * * @(#)defs.h 8.1 (Berkeley) 6/5/93 + * + * $NetBSD$ */ -#ident "$Revision: 1.11 $" +#ifndef __NetBSD__ +#ident "$Revision: 1.13 $" +#endif /* Definitions for RIPv2 routing process. * @@ -78,18 +82,20 @@ #include <sys/ioctl.h> #include <sys/sysctl.h> #include <sys/socket.h> -#include <net/if.h> -#include <net/route.h> +#ifdef sgi #include <net/radix.h> -#ifndef sgi -struct walkarg; +#else +#include "radix.h" #endif +#include <net/if.h> +#include <net/route.h> #include <net/if_dl.h> #include <netinet/in.h> #include <arpa/inet.h> #define RIPVERSION RIPv2 #include <protocols/routed.h> + /* Type of an IP address. * Some systems do not like to pass structures, so do not use in_addr. * Some systems think a long has 64 bits, which would be a gross waste. @@ -99,7 +105,11 @@ struct walkarg; #ifdef sgi #define naddr __uint32_t #else +#ifdef __NetBSD__ +#define naddr u_int32_t +#else #define naddr u_long +#endif #define _HAVE_SA_LEN #define _HAVE_SIN_LEN #endif @@ -148,6 +158,12 @@ union pkt_buf { }; +/* no more routes than this, to protect ourself in case something goes + * whacko and starts broadcast zillions of bogus routes. + */ +#define MAX_ROUTES (128*1024) +extern int total_routes; + /* Main, daemon routing table structure */ struct rt_entry { @@ -449,15 +465,10 @@ extern void logbad(int, char *, ...); #else #define DBGERR(dump,msg) LOGERR(msg) #endif -#ifdef MCAST_PPP_BUG -extern void mcasterr(struct interface *, int, char *); -#define MCASTERR(ifp,dump,msg) mcasterr(ifp, dump, "setsockopt(IP_"msg")") -#else -#define MCASTERR(ifp, dump,msg) DBGERR(dump,"setsockopt(IP_" msg ")") -#endif extern char *naddr_ntoa(naddr); extern char *saddr_ntoa(struct sockaddr *); +extern void *rtmalloc(size_t, char *); extern void timevaladd(struct timeval *, struct timeval *); extern void intvl_random(struct timeval *, u_long, u_long); extern int getnet(char *, naddr *, naddr *); @@ -539,9 +550,6 @@ extern naddr ripv1_mask_net(naddr, struct interface *); extern naddr ripv1_mask_host(naddr,struct interface *); #define on_net(a,net,mask) (((ntohl(a) ^ (net)) & (mask)) == 0) extern int check_dst(naddr); -#ifdef sgi -extern int sysctl(int *, u_int, void *, size_t *, void *, size_t); -#endif extern void addrouteforif(register struct interface *); extern void ifinit(void); extern int walk_bad(struct radix_node *, struct walkarg *); diff --git a/usr.sbin/routed/if.c b/usr.sbin/routed/if.c index 38d344ca0494..7143b319c54c 100644 --- a/usr.sbin/routed/if.c +++ b/usr.sbin/routed/if.c @@ -31,11 +31,12 @@ * SUCH DAMAGE. */ -#if !defined(lint) && !defined(sgi) +#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93"; -#endif /* not lint */ - -#ident "$Revision: 1.15 $" +#elif defined(__NetBSD__) +static char rcsid[] = "$NetBSD$"; +#endif +#ident "$Revision: 1.16 $" #include "defs.h" #include "pathnames.h" @@ -62,10 +63,7 @@ ifwithaddr(naddr addr, struct interface *ifp, *possible = 0; for (ifp = ifnet; ifp; ifp = ifp->int_next) { - if ((ifp->int_addr == addr - && !(ifp->int_if_flags & IFF_POINTOPOINT)) - || (ifp->int_dstaddr == addr - && (ifp->int_if_flags & IFF_POINTOPOINT)) + if (ifp->int_addr == addr || ((ifp->int_if_flags & IFF_BROADCAST) && ifp->int_brdaddr == addr && bcast)) { @@ -171,7 +169,7 @@ std_mask(naddr addr) /* in network order */ } -/* Find The netmask that would be inferred by RIPv1 listeners +/* Find the netmask that would be inferred by RIPv1 listeners * on the given interface for a given network. * If no interface is specified, look for the best fitting interface. */ @@ -453,14 +451,15 @@ ifinit(void) static size_t sysctl_buf_size = 0; uint complaints = 0; static u_int prev_complaints = 0; -# define COMP_NOT_INET 0x01 -# define COMP_WIERD 0x02 -# define COMP_NOADDR 0x04 -# define COMP_NODST 0x08 -# define COMP_NOBADR 0x10 -# define COMP_NOMASK 0x20 -# define COMP_DUP 0x40 -# define COMP_BAD_METRIC 0x80 +# define COMP_NOT_INET 0x001 +# define COMP_WIERD 0x002 +# define COMP_NOADDR 0x004 +# define COMP_NODST 0x008 +# define COMP_NOBADR 0x010 +# define COMP_NOMASK 0x020 +# define COMP_DUP 0x040 +# define COMP_BAD_METRIC 0x080 +# define COMP_NETMASK 0x100 struct interface ifs, ifs0, *ifp, *ifp1; struct rt_entry *rt; @@ -498,7 +497,6 @@ ifinit(void) if ((needed = sysctl_buf_size) != 0) { if (sysctl(mib, 6, sysctl_buf,&needed, 0, 0) >= 0) break; - if (errno != ENOMEM && errno != EFAULT) BADERR(1, "ifinit: get interface table"); free(sysctl_buf); @@ -506,8 +504,7 @@ ifinit(void) } if (sysctl(mib, 6, 0, &needed, 0, 0) < 0) BADERR(1,"ifinit: route-sysctl-estimate"); - if ((sysctl_buf = malloc(sysctl_buf_size = needed)) == 0) - BADERR(1,"ifinit: malloc"); + sysctl_buf = rtmalloc(sysctl_buf_size = needed, "ifinit"); } ifam_lim = (struct ifa_msghdr *)(sysctl_buf + needed); @@ -540,7 +537,7 @@ ifinit(void) continue; } if (ifam->ifam_type != RTM_NEWADDR) { - DBGERR(1,"ifinit: out of sync"); + logbad(1,"ifinit: out of sync"); continue; } @@ -705,6 +702,9 @@ ifinit(void) } if (ifp != 0) { + /* The primary representative of an alias worries + * about how things are working. + */ if (ifp->int_state & IS_ALIAS) continue; @@ -850,9 +850,7 @@ ifinit(void) /* Add it to the list of interfaces */ - ifp = (struct interface *)malloc(sizeof(*ifp)); - if (ifp == 0) - BADERR(1,"ifinit: out of memory"); + ifp = (struct interface *)rtmalloc(sizeof(*ifp), "ifinit"); bcopy(&ifs, ifp, sizeof(*ifp)); if (ifnet != 0) { ifp->int_next = ifnet; @@ -861,6 +859,32 @@ ifinit(void) ifnet = ifp; trace_if("Add", ifp); + /* Notice likely bad netmask. + */ + if (!(prev_complaints & COMP_NETMASK) + && !(ifp->int_if_flags & IFF_POINTOPOINT)) { + for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { + if (ifp1->int_mask == ifp->int_mask) + continue; + if (ifp1->int_if_flags & IFF_POINTOPOINT) + continue; + if (on_net(ifp->int_addr, + ifp1->int_net, ifp1->int_mask) + || on_net(ifp1->int_addr, + ifp->int_net, ifp->int_mask)) { + msglog("possible netmask problem" + " betwen %s:%s and %s:%s", + ifp->int_name, + addrname(htonl(ifp->int_net), + ifp->int_mask, 1), + ifp1->int_name, + addrname(htonl(ifp1->int_net), + ifp1->int_mask, 1)); + complaints |= COMP_NETMASK; + } + } + } + /* Count the # of directly connected networks. */ if (!(ifp->int_state & IS_ALIAS)) { diff --git a/usr.sbin/routed/input.c b/usr.sbin/routed/input.c index aab1b0adc84c..6bbc572af577 100644 --- a/usr.sbin/routed/input.c +++ b/usr.sbin/routed/input.c @@ -31,11 +31,12 @@ * SUCH DAMAGE. */ -#if !defined(lint) && !defined(sgi) +#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/5/93"; -#endif /* not lint */ - -#ident "$Revision: 1.10 $" +#elif defined(__NetBSD__) +static char rcsid[] = "$NetBSD$"; +#endif +#ident "$Revision: 1.13 $" #include "defs.h" @@ -201,10 +202,14 @@ input(struct sockaddr_in *from, /* received from this IP address */ && n == rip->rip_nets && n+1 == lim) { if (from->sin_port != htons(RIP_PORT)) { - /* query */ + /* query from `rtquery` or similar + */ supply(from, ifp, OUT_QUERY, 0, rip->rip_vers); } else if (supplier) { + /* a router trying to prime its + * tables. + */ supply(from, ifp, OUT_UNICAST, 0, rip->rip_vers); } @@ -234,34 +239,35 @@ input(struct sockaddr_in *from, /* received from this IP address */ } if (rip->rip_vers == RIPv1 - || 0 == (mask = ntohl(n->n_mask))) + || 0 == (mask = ntohl(n->n_mask)) + || 0 != (ntohl(dst) & ~mask)) mask = ripv1_mask_host(dst,ifp); rt = rtget(dst, mask); - if (!rt) + if (!rt && dst != RIP_DEFAULT) rt = rtfind(n->n_dst); n->n_tag = 0; n->n_nhop = 0; - if (!rt) { + if (rip->rip_vers == RIPv1) { + n->n_mask = 0; + } else { + n->n_mask = mask; + } + if (rt == 0) { n->n_metric = HOPCNT_INFINITY; } else { n->n_metric = rt->rt_metric+1; - if (ifp != 0) - n->n_metric += ifp->int_metric; + n->n_metric += (ifp!=0) ? ifp->int_metric : 1; if (n->n_metric > HOPCNT_INFINITY) n->n_metric = HOPCNT_INFINITY; - if (rip->rip_vers == RIPv1) { - n->n_mask = 0; - } else { + if (rip->rip_vers != RIPv1) { n->n_tag = rt->rt_tag; - if (!ifp - || !on_net(rt->rt_gate, + if (ifp != 0 + && on_net(rt->rt_gate, ifp->int_net, ifp->int_mask) - || rt->rt_gate != ifp->int_addr) - n->n_nhop = 0; - else + && rt->rt_gate != ifp->int_addr) n->n_nhop = rt->rt_gate; } } @@ -299,7 +305,7 @@ input(struct sockaddr_in *from, /* received from this IP address */ } if (rip->rip_cmd == RIPCMD_TRACEON) { rip->rip_tracefile[size-4] = '\0'; - trace_on(rip->rip_tracefile, 0); + trace_on((char*)rip->rip_tracefile, 0); } else { trace_off("tracing turned off by %s\n", naddr_ntoa(FROM_NADDR)); @@ -385,20 +391,27 @@ input(struct sockaddr_in *from, /* received from this IP address */ return; } - /* Authenticate the packet. + /* Authenticate the packet if we have a secret. */ - if (ifp->int_passwd[0] != '\0' - && (n >= lim - || n->n_family != RIP_AF_AUTH - || ((struct netauth*)n)->a_type != RIP_AUTH_PW - || 0 != bcmp(((struct netauth*)n)->au.au_pw, - ifp->int_passwd, - sizeof(ifp->int_passwd)))) { - if (from->sin_addr.s_addr != use_auth) - msglog("missing authentication from %s", - naddr_ntoa(FROM_NADDR)); - use_auth = from->sin_addr.s_addr; - return; + if (ifp->int_passwd[0] != '\0') { + if (n >= lim + || n->n_family != RIP_AF_AUTH + || ((struct netauth*)n)->a_type != RIP_AUTH_PW) { + if (from->sin_addr.s_addr != use_auth) + msglog("missing password from %s", + naddr_ntoa(FROM_NADDR)); + use_auth = from->sin_addr.s_addr; + return; + + } else if (0 != bcmp(((struct netauth*)n)->au.au_pw, + ifp->int_passwd, + sizeof(ifp->int_passwd))) { + if (from->sin_addr.s_addr != use_auth) + msglog("bad password from %s", + naddr_ntoa(FROM_NADDR)); + use_auth = from->sin_addr.s_addr; + return; + } } for (; n < lim; n++) { @@ -525,15 +538,16 @@ input(struct sockaddr_in *from, /* received from this IP address */ || !(rt->rt_state & RS_NET_SYN)))) { ddst_h = v1_mask & -v1_mask; i = (v1_mask & ~mask)/ddst_h; - if (i >= 1024) { + if (i >= 511) { /* Punt if we would have to generate * an unreasonable number of routes. */ #ifdef DEBUG - msglog("accept %s from %s as-is" - " instead of as %d routes", + msglog("accept %s from %s as 1" + " instead of %d routes", addrname(dst,mask,0), - naddr_ntoa(FROM_NADDR), i); + naddr_ntoa(FROM_NADDR), + i+1); #endif i = 0; } else { @@ -596,7 +610,9 @@ input_route(struct interface *ifp, if (n->n_metric == HOPCNT_INFINITY) return; - rtadd(dst, mask, gate, from, n->n_metric, n->n_tag, 0, ifp); + if (total_routes < MAX_ROUTES) + rtadd(dst, mask, gate, from, n->n_metric, + n->n_tag, 0, ifp); return; } @@ -637,11 +653,12 @@ input_route(struct interface *ifp, */ int old_metric = rts->rts_metric; - /* Keep poisoned routes around only long - * enough to pass the poison on. + /* Keep poisoned routes around only long enough to pass + * the poison on. Get a new timestamp for good routes. */ - if (old_metric < HOPCNT_INFINITY) - new_time = now.tv_sec; + new_time =((old_metric == HOPCNT_INFINITY) + ? rts->rts_time + : now.tv_sec); /* If this is an update for the router we currently prefer, * then note it. diff --git a/usr.sbin/routed/main.c b/usr.sbin/routed/main.c index 96afecc25e07..700762ed5dcb 100644 --- a/usr.sbin/routed/main.c +++ b/usr.sbin/routed/main.c @@ -34,11 +34,12 @@ char copyright[] = "@(#) Copyright (c) 1983, 1988, 1993\n\ The Regents of the University of California. All rights reserved.\n"; -#if !defined(lint) && !defined(sgi) +#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/5/93"; -#endif /* not lint */ - -#ident "$Revision: 1.13 $" +#elif defined(__NetBSD__) +static char rcsid[] = "$NetBSD$"; +#endif +#ident "$Revision: 1.14 $" #include "defs.h" #include "pathnames.h" @@ -274,14 +275,7 @@ usage: if (setsockopt(rt_sock, SOL_SOCKET,SO_USELOOPBACK, &off,sizeof(off)) < 0) LOGERR("setsockopt(SO_USELOOPBACK,0)"); - - /* prepare Router Discovery socket. - */ - rdisc_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); - if (rdisc_sock < 0) - BADERR(1,"rdisc_sock = socket()"); - fix_sock(rdisc_sock,"rdisc_sock"); - + fix_select(); @@ -735,6 +729,19 @@ rip_on(struct interface *ifp) } +/* die if malloc(3) fails + */ +void * +rtmalloc(size_t size, + char *msg) +{ + void *p = malloc(size); + if (p == 0) + logbad(1,"malloc() failed in %s", msg); + return p; +} + + /* get a random instant in an interval */ void diff --git a/usr.sbin/routed/output.c b/usr.sbin/routed/output.c index 8750c412dfd3..be30609743a7 100644 --- a/usr.sbin/routed/output.c +++ b/usr.sbin/routed/output.c @@ -31,11 +31,12 @@ * SUCH DAMAGE. */ -#if !defined(lint) && !defined(sgi) +#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 6/5/93"; -#endif /* not lint */ - -#ident "$Revision: 1.14 $" +#elif defined(__NetBSD__) +static char rcsid[] = "$NetBSD$"; +#endif +#ident "$Revision: 1.16 $" #include "defs.h" @@ -61,6 +62,7 @@ struct { } v12, v2; char metric; /* adjust metrics by interface */ int npackets; + int gen_limit; u_int state; #define WS_ST_FLASH 0x001 /* send only changed routes */ #define WS_ST_RIP2_SAFE 0x002 /* send RIPv2 safe for RIPv1 */ @@ -170,6 +172,10 @@ output(enum output_type type, } sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP); } + + case NO_OUT_MULTICAST: + case NO_OUT_RIPV2: + break; } trace_rip(msg, "to", &sin, ifp, buf, size); @@ -297,20 +303,22 @@ supply_out(struct ag_info *ag) ddst_h = v1_mask & -v1_mask; i = (v1_mask & ~mask)/ddst_h; - if (i >= 1024) { + if (i > ws.gen_limit) { /* Punt if we would have to generate an * unreasonable number of routes. */ #ifdef DEBUG - msglog("sending %s to %s as-is instead" - " of as %d routes", - addrname(htonl(dst_h),mask,0), - naddr_ntoa(ws.to.sin_addr.s_addr), i); + msglog("sending %s to %s as 1 instead" + " of %d routes", + addrname(htonl(dst_h),mask,1), + naddr_ntoa(ws.to.sin_addr.s_addr), + i+1); #endif i = 0; } else { mask = v1_mask; + ws.gen_limit -= i; } } } @@ -539,6 +547,7 @@ supply(struct sockaddr_in *dst, ws.state = 0; + ws.gen_limit = 1024; ws.to = *dst; ws.to_std_mask = std_mask(ws.to.sin_addr.s_addr); diff --git a/usr.sbin/routed/parms.c b/usr.sbin/routed/parms.c index e5c9ac6f3f10..fcd37a6b6c3a 100644 --- a/usr.sbin/routed/parms.c +++ b/usr.sbin/routed/parms.c @@ -31,11 +31,12 @@ * SUCH DAMAGE. */ -#if !defined(lint) && !defined(sgi) +#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93"; -#endif /* not lint */ - -#ident "$Revision: 1.7 $" +#elif defined(__NetBSD__) +static char rcsid[] = "$NetBSD$"; +#endif +#ident "$Revision: 1.8 $" #include "defs.h" #include "pathnames.h" @@ -110,7 +111,8 @@ get_parms(struct interface *ifp) ifp->int_state |= IS_NO_RDISC; if (ifp->int_state & IS_PASSIVE) ifp->int_state |= (IS_NO_RIP | IS_NO_RDISC); - if (ifp->int_state&(IS_NO_RIP|IS_NO_RDISC) == (IS_NO_RIP|IS_NO_RDISC)) + if ((ifp->int_state & (IS_NO_RIP | IS_NO_RDISC)) + == (IS_NO_RIP|IS_NO_RDISC)) ifp->int_state |= IS_PASSIVE; } @@ -270,7 +272,8 @@ gwkludge(void) state |= IS_NO_RDISC; if (state & IS_PASSIVE) state |= (IS_NO_RIP | IS_NO_RDISC); - if (state & (IS_NO_RIP|IS_NO_RDISC) == (IS_NO_RIP|IS_NO_RDISC)) + if ((state & (IS_NO_RIP | IS_NO_RDISC)) + == (IS_NO_RIP|IS_NO_RDISC)) state |= IS_PASSIVE; parmp = (struct parm*)malloc(sizeof(*parmp)); @@ -353,7 +356,7 @@ parse_parms(char *line) if (!strncasecmp("subnet=",line,7)) { intnetp = (struct intnet*)malloc(sizeof(*intnetp)); intnetp->intnet_metric = 1; - if (p = strrchr(line,',')) { + if ((p = strrchr(line,','))) { *p++ = '\0'; intnetp->intnet_metric = (int)strtol(p,&p,0); if (*p != '\0' diff --git a/usr.sbin/routed/pathnames.h b/usr.sbin/routed/pathnames.h index d539eb51dab7..e9e6c48c6392 100644 --- a/usr.sbin/routed/pathnames.h +++ b/usr.sbin/routed/pathnames.h @@ -31,6 +31,8 @@ * SUCH DAMAGE. * * @(#)pathnames.h 8.1 (Berkeley) 6/5/93 + * + * $NetBSD$ */ #include <paths.h> diff --git a/usr.sbin/routed/radix.c b/usr.sbin/routed/radix.c index 7552e0832a50..7f7e1e47b79e 100644 --- a/usr.sbin/routed/radix.c +++ b/usr.sbin/routed/radix.c @@ -36,16 +36,18 @@ /* * Routines to build and maintain radix trees for routing lookups. */ -#include <sys/param.h> -#include <sys/malloc.h> -#include <sys/domain.h> -#include <sys/syslog.h> -#include <net/radix.h> -#include <stdlib.h> -#define min(a,b) (((a)<(b))?(a):(b)) +#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) +static char sccsid[] = "@(#)rdisc.c 8.1 (Berkeley) x/y/95"; +#elif defined(__NetBSD__) +static char rcsid[] = "$NetBSD$"; +#endif +#ident "$Revision: 1.10 $" + +#include "defs.h" + #define log(x, msg) syslog(x, msg) #define panic(s) {log(LOG_ERR,s); exit(1);} - +#define min(a,b) (((a)<(b))?(a):(b)) int max_keylen; struct radix_mask *rn_mkfreelist; @@ -75,18 +77,18 @@ static int rn_satsifies_leaf(char *, struct radix_node *, int); * We define the index of a route to associated with the mask to be * the first bit number in the mask where 0 occurs (with bit number 0 * representing the highest order bit). - * + * * We say a mask is normal if every bit is 0, past the index of the mask. * If a node n has a descendant (k, m) with index(m) == index(n) == rn_b, * and m is a normal mask, then the route applies to every descendant of n. * If the index(m) < rn_b, this implies the trailing last few bits of k * before bit b are all 0, (and hence consequently true of every descendant * of n), so the route applies to all descendants of the node as well. - * + * * Similar logic shows that a non-normal mask m such that * index(m) <= index(n) could potentially apply to many children of n. * Thus, for each non-host route, we attach its mask to a list at an internal - * node as high in the tree as we can go. + * node as high in the tree as we can go. * * The present version of the code makes use of normal routes in short- * circuiting an explict mask and compare operation when testing whether @@ -95,9 +97,8 @@ static int rn_satsifies_leaf(char *, struct radix_node *, int); */ struct radix_node * -rn_search(v_arg, head) - void *v_arg; - struct radix_node *head; +rn_search(void *v_arg, + struct radix_node *head) { register struct radix_node *x; register caddr_t v; @@ -112,9 +113,9 @@ rn_search(v_arg, head) } struct radix_node * -rn_search_m(v_arg, head, m_arg) - struct radix_node *head; - void *v_arg, *m_arg; +rn_search_m(void *v_arg, + struct radix_node *head, + void *m_arg) { register struct radix_node *x; register caddr_t v = v_arg, m = m_arg; @@ -130,8 +131,7 @@ rn_search_m(v_arg, head, m_arg) } int -rn_refines(m_arg, n_arg) - void *m_arg, *n_arg; +rn_refines(void* m_arg, void *n_arg) { register caddr_t m = m_arg, n = n_arg; register caddr_t lim, lim2 = lim = n + *(u_char *)n; @@ -198,9 +198,8 @@ rn_satsifies_leaf(char *trial, } struct radix_node * -rn_match(v_arg, head) - void *v_arg; - struct radix_node_head *head; +rn_match(void *v_arg, + struct radix_node_head *head) { caddr_t v = v_arg; register struct radix_node *t = head->rnh_treetop, *x; @@ -240,14 +239,30 @@ rn_match(v_arg, head) /* * This extra grot is in case we are explicitly asked * to look up the default. Ugh! + * Or 255.255.255.255 + * + * In this case, we have a complete match of the key. Unless + * the node is one of the roots, we are finished. + * If it is the zeros root, then take what we have, prefering + * any real data. + * If it is the ones root, then pretend the target key was followed + * by a byte of zeros. */ - if ((t->rn_flags & RNF_ROOT) && t->rn_dupedkey) + if (!(t->rn_flags & RNF_ROOT)) + return t; /* not a root */ + if (t->rn_dupedkey) { t = t->rn_dupedkey; - return t; + return t; /* have some real data */ + } + if (*(cp-1) == 0) + return t; /* not the ones root */ + b = 0; /* fake a zero after 255.255.255.255 */ + goto on2; on1: test = (*cp ^ *cp2) & 0xff; /* find first bit that differs */ for (b = 7; (test >>= 1) > 0;) b--; +on2: matched_off = cp - v; b += matched_off << 3; rn_b = -1 - b; @@ -272,7 +287,7 @@ on1: do { register struct radix_mask *m; t = t->rn_p; - if (m = t->rn_mklist) { + if ((m = t->rn_mklist)) { /* * If non-contiguous masks ever become important * we can restore the masking and open coding of @@ -291,12 +306,12 @@ on1: if (x && rn_satsifies_leaf(v, x, off)) return x; } - } while (m = m->rm_mklist); + } while ((m = m->rm_mklist)); } } while (t != top); return 0; } - + #ifdef RN_DEBUG int rn_nodenum; struct radix_node *rn_clist; @@ -305,10 +320,7 @@ int rn_debug = 1; #endif struct radix_node * -rn_newpair(v, b, nodes) - void *v; - int b; - struct radix_node nodes[2]; +rn_newpair(void *v, int b, struct radix_node nodes[2]) { register struct radix_node *tt = nodes, *t = tt + 1; t->rn_b = b; t->rn_bmask = 0x80 >> (b & 7); @@ -323,11 +335,10 @@ rn_newpair(v, b, nodes) } struct radix_node * -rn_insert(v_arg, head, dupentry, nodes) - void *v_arg; - struct radix_node_head *head; - int *dupentry; - struct radix_node nodes[2]; +rn_insert(void* v_arg, + struct radix_node_head *head, + int *dupentry, + struct radix_node nodes[2]) { caddr_t v = v_arg; struct radix_node *top = head->rnh_treetop; @@ -336,7 +347,8 @@ rn_insert(v_arg, head, dupentry, nodes) register caddr_t cp = v + head_off; register int b; struct radix_node *tt; - /* + + /* * Find first bit at which v and t->rn_key differ */ { @@ -347,8 +359,11 @@ rn_insert(v_arg, head, dupentry, nodes) while (cp < cplim) if (*cp2++ != *cp++) goto on1; - *dupentry = 1; - return t; + /* handle adding 255.255.255.255 */ + if (!(t->rn_flags & RNF_ROOT) || *(cp2-1) == 0) { + *dupentry = 1; + return t; + } on1: *dupentry = 0; cmp_res = (cp[-1] ^ cp2[-1]) & 0xff; @@ -360,7 +375,7 @@ on1: cp = v; do { p = x; - if (cp[x->rn_off] & x->rn_bmask) + if (cp[x->rn_off] & x->rn_bmask) x = x->rn_r; else x = x->rn_l; } while (b > (unsigned) x->rn_b); /* x->rn_b < b && x->rn_b >= 0 */ @@ -388,9 +403,7 @@ on1: } struct radix_node * -rn_addmask(n_arg, search, skip) - int search, skip; - void *n_arg; +rn_addmask(void *n_arg, int search, int skip) { caddr_t netmask = (caddr_t)n_arg; register struct radix_node *x; @@ -448,7 +461,7 @@ rn_addmask(n_arg, search, skip) for (cp = netmask + skip; (cp < cplim) && *(u_char *)cp == 0xff;) cp++; if (cp != cplim) { - for (j = 0x80; (j & *cp) != 0; j >>= 1) + for (j = 0x80; (j & *cp) != 0; j >>= 1) b++; if (*cp != normal_chars[b] || cp != (cplim - 1)) isnormal = 0; @@ -467,7 +480,7 @@ rn_lexobetter(void *m_arg, void *n_arg) if (*mp > *np) return 1; /* not really, but need to check longer one first */ - if (*mp == *np) + if (*mp == *np) for (lim = mp + *mp; mp < lim;) if (*mp++ > *np++) return 1; @@ -498,15 +511,15 @@ rn_new_radix_mask(register struct radix_node *tt, } struct radix_node * -rn_addroute(v_arg, n_arg, head, treenodes) - void *v_arg, *n_arg; - struct radix_node_head *head; - struct radix_node treenodes[2]; +rn_addroute(void *v_arg, + void *n_arg, + struct radix_node_head *head, + struct radix_node treenodes[2]) { caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg; - register struct radix_node *t, *x, *tt; + register struct radix_node *t, *x = 0, *tt; struct radix_node *saved_tt, *top = head->rnh_treetop; - short b = 0, b_leaf; + short b = 0, b_leaf = 0; int keyduplicated; caddr_t mmask; struct radix_mask *m, **mp; @@ -584,17 +597,17 @@ rn_addroute(v_arg, n_arg, head, treenodes) b_leaf = -1 - t->rn_b; if (t->rn_r == saved_tt) x = t->rn_l; else x = t->rn_r; /* Promote general routes from below */ - if (x->rn_b < 0) { + if (x->rn_b < 0) { for (mp = &t->rn_mklist; x; x = x->rn_dupedkey) if (x->rn_mask && (x->rn_b >= b_leaf) && x->rn_mklist == 0) { - if (*mp = m = rn_new_radix_mask(x, 0)) + if ((*mp = m = rn_new_radix_mask(x, 0))) mp = &m->rm_mklist; } } else if (x->rn_mklist) { /* * Skip over masks whose index is > that of new node */ - for (mp = &x->rn_mklist; m = *mp; mp = &m->rm_mklist) + for (mp = &x->rn_mklist; (m = *mp); mp = &m->rm_mklist) if (m->rm_b >= b_leaf) break; t->rn_mklist = m; *mp = 0; @@ -614,7 +627,7 @@ on2: * Need same criteria as when sorting dupedkeys to avoid * double loop on deletion. */ - for (mp = &x->rn_mklist; m = *mp; mp = &m->rm_mklist) { + for (mp = &x->rn_mklist; (m = *mp); mp = &m->rm_mklist) { if (m->rm_b < b_leaf) continue; if (m->rm_b > b_leaf) @@ -641,9 +654,9 @@ on2: } struct radix_node * -rn_delete(v_arg, netmask_arg, head) - void *v_arg, *netmask_arg; - struct radix_node_head *head; +rn_delete(void *v_arg, + void *netmask_arg, + struct radix_node_head *head) { register struct radix_node *t, *p, *x, *tt; struct radix_mask *m, *saved_m, **mp; @@ -680,7 +693,7 @@ rn_delete(v_arg, netmask_arg, head) log(LOG_ERR, "rn_delete: inconsistent annotation\n"); return 0; /* dangling ref could cause disaster */ } - } else { + } else { if (m->rm_mask != tt->rn_mask) { log(LOG_ERR, "rn_delete: inconsistent annotation\n"); goto on1; @@ -696,7 +709,7 @@ rn_delete(v_arg, netmask_arg, head) x = t; t = t->rn_p; } while (b <= t->rn_b && x != top); - for (mp = &x->rn_mklist; m = *mp; mp = &m->rm_mklist) + for (mp = &x->rn_mklist; (m = *mp); mp = &m->rm_mklist) if (m == saved_m) { *mp = m->rm_mklist; MKFree(m); @@ -719,7 +732,7 @@ on1: if (t) t->rn_ybro = tt->rn_ybro; #endif t = tt->rn_p; - if (dupedkey = saved_tt->rn_dupedkey) { + if ((dupedkey = saved_tt->rn_dupedkey)) { if (tt == saved_tt) { x = dupedkey; x->rn_p = t; if (t->rn_l == tt) t->rn_l = x; else t->rn_r = x; @@ -750,7 +763,7 @@ on1: */ if (t->rn_mklist) { if (x->rn_b >= 0) { - for (mp = &x->rn_mklist; m = *mp;) + for (mp = &x->rn_mklist; (m = *mp);) mp = &m->rm_mklist; *mp = t->rn_mklist; } else { @@ -766,13 +779,10 @@ on1: m = mm; } if (m) -#ifdef _KERNEL - printf("%s %x at %x\n", - "rn_delete: Orphaned Mask", m, x); -#else - syslog(LOG_ERR, "%s %x at %x\n", - "rn_delete: Orphaned Mask", m, x); -#endif + syslog(LOG_ERR, "%s %lx at %lx\n", + "rn_delete: Orphaned Mask", + (unsigned long)m, + (unsigned long)x); } } /* @@ -796,10 +806,9 @@ out: } int -rn_walktree(h, f, w) - struct radix_node_head *h; - register int (*f)(); - void *w; +rn_walktree(struct radix_node_head *h, + register int (*f)(struct radix_node *, struct walkarg*), + struct walkarg *w) { int error; struct radix_node *base, *next; @@ -822,7 +831,7 @@ rn_walktree(h, f, w) rn = rn->rn_l; next = rn; /* Process leaves */ - while (rn = base) { + while ((rn = base)) { base = rn->rn_dupedkey; if (!(rn->rn_flags & RNF_ROOT) && (error = (*f)(rn, w))) return (error); @@ -835,9 +844,7 @@ rn_walktree(h, f, w) } int -rn_inithead(head, off) - void **head; - int off; +rn_inithead(void **head, int off) { register struct radix_node_head *rnh; register struct radix_node *t, *tt, *ttt; @@ -867,16 +874,9 @@ rn_inithead(head, off) } void -rn_init() +rn_init(void) { char *cp, *cplim; -#ifdef KERNEL - struct domain *dom; - - for (dom = domains; dom; dom = dom->dom_next) - if (dom->dom_maxrtkey > max_keylen) - max_keylen = dom->dom_maxrtkey; -#endif if (max_keylen == 0) { printf("rn_init: radix functions require max_keylen be set\n"); return; @@ -892,3 +892,4 @@ rn_init() if (rn_inithead((void **)&mask_rnhead, 0) == 0) panic("rn_init 2"); } + diff --git a/usr.sbin/routed/radix.h b/usr.sbin/routed/radix.h new file mode 100644 index 000000000000..fddf02ead7a6 --- /dev/null +++ b/usr.sbin/routed/radix.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 1988, 1989, 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. + * + * @(#)radix.h 8.2 (Berkeley) 10/31/94 + */ + +#ifndef __RADIX_H_ +#define __RADIX_H_ + +#include <sys/cdefs.h> +struct walkarg; + +/* + * Radix search tree node layout. + */ + +struct radix_node { + struct radix_mask *rn_mklist; /* list of masks contained in subtree */ + struct radix_node *rn_p; /* parent */ + short rn_b; /* bit offset; -1-index(netmask) */ + char rn_bmask; /* node: mask for bit test*/ + u_char rn_flags; /* enumerated next */ +#define RNF_NORMAL 1 /* leaf contains normal route */ +#define RNF_ROOT 2 /* leaf is root leaf for tree */ +#define RNF_ACTIVE 4 /* This node is alive (for rtfree) */ + union { + struct { /* leaf only data: */ + caddr_t rn_Key; /* object of search */ + caddr_t rn_Mask; /* netmask, if present */ + struct radix_node *rn_Dupedkey; + } rn_leaf; + struct { /* node only data: */ + int rn_Off; /* where to start compare */ + struct radix_node *rn_L;/* progeny */ + struct radix_node *rn_R;/* progeny */ + }rn_node; + } rn_u; +#ifdef RN_DEBUG + int rn_info; + struct radix_node *rn_twin; + struct radix_node *rn_ybro; +#endif +}; + +#define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey +#define rn_key rn_u.rn_leaf.rn_Key +#define rn_mask rn_u.rn_leaf.rn_Mask +#define rn_off rn_u.rn_node.rn_Off +#define rn_l rn_u.rn_node.rn_L +#define rn_r rn_u.rn_node.rn_R + +/* + * Annotations to tree concerning potential routes applying to subtrees. + */ + +extern struct radix_mask { + short rm_b; /* bit offset; -1-index(netmask) */ + char rm_unused; /* cf. rn_bmask */ + u_char rm_flags; /* cf. rn_flags */ + struct radix_mask *rm_mklist; /* more masks to try */ + union { + caddr_t rmu_mask; /* the mask */ + struct radix_node *rmu_leaf; /* for normal routes */ + } rm_rmu; + int rm_refs; /* # of references to this struct */ +} *rn_mkfreelist; + +#define rm_mask rm_rmu.rmu_mask +#define rm_leaf rm_rmu.rmu_leaf /* extra field would make 32 bytes */ + +#define MKGet(m) {\ + if (rn_mkfreelist) {\ + m = rn_mkfreelist; \ + rn_mkfreelist = (m)->rm_mklist; \ + } else \ + R_Malloc(m, struct radix_mask *, sizeof (*(m))); }\ + +#define MKFree(m) { (m)->rm_mklist = rn_mkfreelist; rn_mkfreelist = (m);} + +struct radix_node_head { + struct radix_node *rnh_treetop; + int rnh_addrsize; /* permit, but not require fixed keys */ + int rnh_pktsize; /* permit, but not require fixed keys */ + struct radix_node *(*rnh_addaddr) /* add based on sockaddr */ + __P((void *v, void *mask, + struct radix_node_head *head, struct radix_node nodes[])); + struct radix_node *(*rnh_addpkt) /* add based on packet hdr */ + __P((void *v, void *mask, + struct radix_node_head *head, struct radix_node nodes[])); + struct radix_node *(*rnh_deladdr) /* remove based on sockaddr */ + __P((void *v, void *mask, struct radix_node_head *head)); + struct radix_node *(*rnh_delpkt) /* remove based on packet hdr */ + __P((void *v, void *mask, struct radix_node_head *head)); + struct radix_node *(*rnh_matchaddr) /* locate based on sockaddr */ + __P((void *v, struct radix_node_head *head)); + struct radix_node *(*rnh_lookup) /* locate based on sockaddr */ + __P((void *v, void *mask, struct radix_node_head *head)); + struct radix_node *(*rnh_matchpkt) /* locate based on packet hdr */ + __P((void *v, struct radix_node_head *head)); + int (*rnh_walktree) /* traverse tree */ + (struct radix_node_head *head, + int (*f)(struct radix_node *, struct walkarg *), + struct walkarg *w); + struct radix_node rnh_nodes[3]; /* empty tree for common case */ +}; + + +#define Bcmp(a, b, n) bcmp(((char *)(a)), ((char *)(b)), (n)) +#define Bcopy(a, b, n) bcopy(((char *)(a)), ((char *)(b)), (unsigned)(n)) +#define Bzero(p, n) bzero((char *)(p), (int)(n)); +#define R_Malloc(p, t, n) (p = (t) malloc((unsigned int)(n))) +#define Free(p) free((char *)p); + +void rn_init __P((void)); +int rn_inithead __P((void **, int)); +int rn_refines __P((void *, void *)); +int rn_walktree __P((struct radix_node_head *, + int (*)__P((struct radix_node *, struct walkarg*)), + struct walkarg*)); +struct radix_node + *rn_addmask __P((void *, int, int)), + *rn_addroute __P((void *, void *, struct radix_node_head *, + struct radix_node [2])), + *rn_delete __P((void *, void *, struct radix_node_head *)), + *rn_insert __P((void *, struct radix_node_head *, int *, + struct radix_node [2])), + *rn_match __P((void *, struct radix_node_head *)), + *rn_newpair __P((void *, int, struct radix_node[2])), + *rn_search __P((void *, struct radix_node *)), + *rn_search_m __P((void *, struct radix_node *, void *)); + +#endif /* __RADIX_H_ */ diff --git a/usr.sbin/routed/rdisc.c b/usr.sbin/routed/rdisc.c index 5a4809475bcd..da1784c793e4 100644 --- a/usr.sbin/routed/rdisc.c +++ b/usr.sbin/routed/rdisc.c @@ -31,11 +31,12 @@ * SUCH DAMAGE. */ -#if !defined(lint) && !defined(sgi) +#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) static char sccsid[] = "@(#)rdisc.c 8.1 (Berkeley) x/y/95"; -#endif /* not lint */ - -#ident "$Revision: 1.14 $" +#elif defined(__NetBSD__) +static char rcsid[] = "$NetBSD$"; +#endif +#ident "$Revision: 1.16 $" #include "defs.h" #include <netinet/in_systm.h> @@ -44,12 +45,12 @@ static char sccsid[] = "@(#)rdisc.c 8.1 (Berkeley) x/y/95"; /* router advertisement ICMP packet */ struct icmp_ad { - u_char icmp_type; /* type of message */ - u_char icmp_code; /* type sub code */ - u_short icmp_cksum; /* ones complement cksum of struct */ - u_char icmp_ad_num; /* # of following router addresses */ - u_char icmp_ad_asize; /* 2--words in each advertisement */ - u_short icmp_ad_life; /* seconds of validity */ + u_int8_t icmp_type; /* type of message */ + u_int8_t icmp_code; /* type sub code */ + u_int16_t icmp_cksum; /* ones complement cksum of struct */ + u_int8_t icmp_ad_num; /* # of following router addresses */ + u_int8_t icmp_ad_asize; /* 2--words in each advertisement */ + u_int16_t icmp_ad_life; /* seconds of validity */ struct icmp_ad_info { n_long icmp_ad_addr; n_long icmp_ad_pref; @@ -58,10 +59,10 @@ struct icmp_ad { /* router solicitation ICMP packet */ struct icmp_so { - u_char icmp_type; /* type of message */ - u_char icmp_code; /* type sub code */ - u_short icmp_cksum; /* ones complement cksum of struct */ - n_long icmp_so_rsvd; + u_int8_t icmp_type; /* type of message */ + u_int8_t icmp_code; /* type sub code */ + u_int16_t icmp_cksum; /* ones complement cksum of struct */ + n_long icmp_so_rsvd; }; union ad_u { @@ -127,7 +128,7 @@ trace_rdisc(char *act, lim = &wp[(len - sizeof(p->ad)) / sizeof(*wp)]; for (i = 0; i < p->ad.icmp_ad_num && wp <= lim; i++) { (void)fprintf(ftrace, "\t%s preference=%#x", - naddr_ntoa(wp[0]), ntohl(wp[1])); + naddr_ntoa(wp[0]), (int)ntohl(wp[1])); wp += p->ad.icmp_ad_asize; } (void)fputc('\n',ftrace); @@ -141,6 +142,20 @@ trace_rdisc(char *act, } } +/* prepare Router Discovery socket. + */ +static void +get_rdisc_sock(void) +{ + if (rdisc_sock < 0) { + rdisc_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + if (rdisc_sock < 0) + BADERR(1,"rdisc_sock = socket()"); + fix_sock(rdisc_sock,"rdisc_sock"); + fix_select(); + } +} + /* Pick multicast group for router-discovery socket */ @@ -149,8 +164,17 @@ set_rdisc_mg(struct interface *ifp, int on) { /* 0=turn it off */ struct ip_mreq m; - if (rdisc_sock == -1 - || !(ifp->int_if_flags & IFF_MULTICAST) + if (rdisc_sock < 0) { + /* Create the raw socket so that we can hear at least + * broadcast router discovery packets. + */ + if ((ifp->int_state & IS_NO_RDISC) == IS_NO_RDISC + || !on) + return; + get_rdisc_sock(); + } + + if (!(ifp->int_if_flags & IFF_MULTICAST) || (ifp->int_state & IS_ALIAS)) { ifp->int_state &= ~(IS_ALL_HOSTS | IS_ALL_ROUTERS); return; @@ -167,7 +191,8 @@ set_rdisc_mg(struct interface *ifp, if (supplier || (ifp->int_state & IS_NO_ADV_IN) || !on) { - /* stop listening to advertisements */ + /* stop listening to advertisements + */ if (ifp->int_state & IS_ALL_HOSTS) { m.imr_multiaddr.s_addr = htonl(INADDR_ALLHOSTS_GROUP); if (setsockopt(rdisc_sock, IPPROTO_IP, @@ -178,7 +203,8 @@ set_rdisc_mg(struct interface *ifp, } } else if (!(ifp->int_state & IS_ALL_HOSTS)) { - /* start listening to advertisements */ + /* start listening to advertisements + */ m.imr_multiaddr.s_addr = htonl(INADDR_ALLHOSTS_GROUP); if (setsockopt(rdisc_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &m, sizeof(m)) < 0) { @@ -191,7 +217,8 @@ set_rdisc_mg(struct interface *ifp, if (!supplier || (ifp->int_state & IS_NO_ADV_OUT) || !on) { - /* stop listening to solicitations */ + /* stop listening to solicitations + */ if (ifp->int_state & IS_ALL_ROUTERS) { m.imr_multiaddr.s_addr=htonl(INADDR_ALLROUTERS_GROUP); if (setsockopt(rdisc_sock, IPPROTO_IP, @@ -202,7 +229,8 @@ set_rdisc_mg(struct interface *ifp, } } else if (!(ifp->int_state & IS_ALL_ROUTERS)) { - /* start hearing solicitations */ + /* start hearing solicitations + */ m.imr_multiaddr.s_addr=htonl(INADDR_ALLROUTERS_GROUP); if (setsockopt(rdisc_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &m, sizeof(m)) < 0) { @@ -541,12 +569,12 @@ parse_ad(naddr from, /* ignore pointers to ourself and routes via unreachable networks */ if (ifwithaddr(gate, 1, 0) != 0) { - trace_pkt("\tdiscard our own Router Discovery Ad\n"); + trace_pkt("\tdiscard Router Discovery Ad pointing at us\n"); return; } if (!on_net(gate, ifp->int_net, ifp->int_mask)) { trace_pkt("\tdiscard Router Discovery Ad" - " from unreachable net\n"); + " toward unreachable net\n"); return; } @@ -554,7 +582,7 @@ parse_ad(naddr from, * and later bias it by the metric of the interface. */ pref = ntohl(pref) ^ MIN_PreferenceLevel; - + if (pref == 0 || life == 0) { pref = 0; life = 0; @@ -657,6 +685,10 @@ send_rdisc(union ad_u *p, bzero(&sin, sizeof(sin)); sin.sin_addr.s_addr = dst; + sin.sin_family = AF_INET; +#ifdef _HAVE_SIN_LEN + sin.sin_len = sizeof(sin); +#endif flags = MSG_DONTROUTE; switch (type) { @@ -711,6 +743,9 @@ send_rdisc(union ad_u *p, break; } + if (rdisc_sock < 0) + get_rdisc_sock(); + trace_rdisc(msg, ifp->int_addr, sin.sin_addr.s_addr, ifp, p, p_size); diff --git a/usr.sbin/routed/routed.h b/usr.sbin/routed/routed.h index 2ab50f64f12c..8bfc0a191257 100644 --- a/usr.sbin/routed/routed.h +++ b/usr.sbin/routed/routed.h @@ -31,6 +31,8 @@ * SUCH DAMAGE. * * @(#)routed.h 8.1 (Berkeley) 6/2/93 + * + * $NetBSD$ */ #ifndef _ROUTED_H_ @@ -38,7 +40,7 @@ #ifdef __cplusplus extern "C" { #endif -#ident "$Revision: 1.8 $" +#ident "$Revision: 1.9 $" /* * Routing Information Protocol @@ -55,48 +57,49 @@ extern "C" { #endif #define RIP_PORT 520 - + #if RIPVERSION == 1 /* Note that this so called sockaddr has a 2-byte sa_family and no sa_len. * It is not a UNIX sockaddr, but the shape of an address as defined - * in RIPv1. + * in RIPv1. It is still defined to allow old versions of programs + * such as `gated` to use this file to define RIPv1. */ struct netinfo { struct sockaddr rip_dst; /* destination net/host */ - int rip_metric; /* cost of route */ + u_int32_t rip_metric; /* cost of route */ }; #else struct netinfo { - u_short n_family; + u_int16_t n_family; #define RIP_AF_INET htons(AF_INET) #define RIP_AF_UNSPEC 0 #define RIP_AF_AUTH 0xffff - u_short n_tag; /* optional in RIPv2 */ - u_int n_dst; /* destination net or host */ + u_int16_t n_tag; /* optional in RIPv2 */ + u_int32_t n_dst; /* destination net or host */ #define RIP_DEFAULT 0 - u_int n_mask; /* netmask in RIPv2 */ - u_int n_nhop; /* optional next hop in RIPv2 */ - u_int n_metric; /* cost of route */ + u_int32_t n_mask; /* netmask in RIPv2 */ + u_int32_t n_nhop; /* optional next hop in RIPv2 */ + u_int32_t n_metric; /* cost of route */ }; #endif /* RIPv2 authentication */ struct netauth { - u_short a_type; + u_int16_t a_type; #define RIP_AUTH_PW htons(2) /* password type */ union { #define RIP_AUTH_PW_LEN 16 - char au_pw[RIP_AUTH_PW_LEN]; + int8_t au_pw[RIP_AUTH_PW_LEN]; } au; }; struct rip { - u_char rip_cmd; /* request/response */ - u_char rip_vers; /* protocol version # */ - u_short rip_res1; /* pad to 32-bit boundary */ + u_int8_t rip_cmd; /* request/response */ + u_int8_t rip_vers; /* protocol version # */ + u_int16_t rip_res1; /* pad to 32-bit boundary */ union { /* variable length... */ struct netinfo ru_nets[1]; - char ru_tracefile[1]; + int8_t ru_tracefile[1]; struct netauth ru_auth[1]; } ripun; #define rip_nets ripun.ru_nets @@ -129,7 +132,7 @@ char *ripcmds[RIPCMD_MAX] = { #define NETS_LEN ((MAXPACKETSIZE-sizeof(struct rip)) \ / sizeof(struct netinfo) +1) -#define INADDR_RIP_GROUP (u_long)0xe0000009 /* 224.0.0.9 */ +#define INADDR_RIP_GROUP (u_int32_t)0xe0000009 /* 224.0.0.9 */ /* Timer values used in managing the routing table. diff --git a/usr.sbin/routed/rtquery/Makefile b/usr.sbin/routed/rtquery/Makefile index a8d2110a8d30..f9aee5c55d06 100644 --- a/usr.sbin/routed/rtquery/Makefile +++ b/usr.sbin/routed/rtquery/Makefile @@ -1,7 +1,8 @@ # @(#)Makefile 8.1 (Berkeley) 6/5/93 PROG= rtquery -MAN8= rtquery.8 +MAN8= rtquery.0 +#COPTS= -g -DDEBUG -Wall .include "../../Makefile.inc" .include <bsd.prog.mk> diff --git a/usr.sbin/routed/rtquery/rtquery.c b/usr.sbin/routed/rtquery/rtquery.c index a75d8f478f2d..cc1be10ab228 100644 --- a/usr.sbin/routed/rtquery/rtquery.c +++ b/usr.sbin/routed/rtquery/rtquery.c @@ -35,9 +35,12 @@ char copyright[] = "@(#) Copyright (c) 1982, 1986, 1993\n\ The Regents of the University of California. All rights reserved.\n"; -#if !defined(lint) && !defined(sgi) +#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) static char sccsid[] = "@(#)query.c 8.1 (Berkeley) 6/5/93"; -#endif /* not lint */ +#elif defined(__NetBSD__) +static char rcsid[] = "$NetBSD$"; +#endif +#ident "$Revision: 1.8 $" #include <sys/param.h> #include <sys/protosw.h> @@ -151,7 +154,7 @@ main(int argc, } bcopy(hp->h_addr, &OMSG.rip_nets[0].n_dst, sizeof(OMSG.rip_nets[0].n_dst)); - OMSG.rip_nets[0].n_family = AF_INET; + OMSG.rip_nets[0].n_family = RIP_AF_INET; OMSG.rip_nets[0].n_mask = -1; rflag = 1; } @@ -176,7 +179,7 @@ main(int argc, if (!value || strlen(value) > MAXPATHLEN) goto usage; - strcpy(OMSG.rip_tracefile, value); + strcpy((char*)OMSG.rip_tracefile,value); omsg_len += (strlen(value) - sizeof(OMSG.ripun)); break; @@ -544,7 +547,7 @@ rip_input(struct sockaddr_in *from, } else { (void)sprintf(net_buf, "(af %#x) %d.%d.%d.%d", - n->n_family, + ntohs(n->n_family), (char)(n->n_dst >> 24), (char)(n->n_dst >> 16), (char)(n->n_dst >> 8), @@ -576,11 +579,11 @@ rip_input(struct sockaddr_in *from, /* Return the classical netmask for an IP address. */ static u_int -std_mask(u_int addr) +std_mask(u_int addr) /* in network order */ { - NTOHL(addr); + NTOHL(addr); /* was a host, not a network */ - if (addr == 0) + if (addr == 0) /* default route has mask 0 */ return 0; if (IN_CLASSA(addr)) return IN_CLASSA_NET; @@ -628,6 +631,8 @@ getnet(char *name, if (mname == 0) { mask = std_mask(in.s_addr); + if ((~mask & in.s_addr) != 0) + mask = 0xffffffff; } else { mask = (u_int)strtoul(mname, &p, 0); if (*p != '\0' || mask > 32) @@ -635,8 +640,8 @@ getnet(char *name, mask = 0xffffffff << (32-mask); } - rt->n_dst = in.s_addr; - rt->n_family = AF_INET; + rt->n_dst = htonl(in.s_addr); + rt->n_family = RIP_AF_INET; rt->n_mask = htonl(mask); return 1; } diff --git a/usr.sbin/routed/table.c b/usr.sbin/routed/table.c index 9b354e79dbf6..b1566a3792a8 100644 --- a/usr.sbin/routed/table.c +++ b/usr.sbin/routed/table.c @@ -31,11 +31,12 @@ * SUCH DAMAGE. */ -#if !defined(lint) && !defined(sgi) +#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) static char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 6/5/93"; -#endif /* not lint */ - -#ident "$Revision: 1.16 $" +#elif defined(__NetBSD__) +static char rcsid[] = "$NetBSD$"; +#endif +#ident "$Revision: 1.23 $" #include "defs.h" @@ -54,6 +55,8 @@ struct timeval need_kern = { /* need to update kernel table */ int stopint; +int total_routes; + naddr age_bad_gate; @@ -726,12 +729,12 @@ static struct khash { u_short k_state; #define KS_NEW 0x001 #define KS_DELETE 0x002 -#define KS_ADD 0x004 -#define KS_CHANGE 0x008 -#define KS_DEL_ADD 0x010 -#define KS_STATIC 0x020 -#define KS_GATEWAY 0x040 -#define KS_DYNAMIC 0x080 +#define KS_ADD 0x004 /* add to the kernel */ +#define KS_CHANGE 0x008 /* tell kernel to change the route */ +#define KS_DEL_ADD 0x010 /* delete & add to change the kernel */ +#define KS_STATIC 0x020 /* Static flag in kernel */ +#define KS_GATEWAY 0x040 /* G flag in kernel */ +#define KS_DYNAMIC 0x080 /* result of redirect */ #define KS_DELETED 0x100 /* already deleted */ time_t k_keep; #define K_KEEP_LIM 30 @@ -769,7 +772,6 @@ kern_add(naddr dst, naddr mask) k->k_dst = dst; k->k_mask = mask; k->k_state = KS_NEW; - k->k_redirect_time = now.tv_sec; k->k_keep = now.tv_sec; *pk = k; @@ -777,8 +779,8 @@ kern_add(naddr dst, naddr mask) } -/* If it has a non-zero metric, check that it is still in the table, not - * having been deleted by interfaces coming and going. +/* If a kernel route has a non-zero metric, check that it is still in the + * daemon table, and not deleted by interfaces coming and going. */ static void kern_check_static(struct khash *k, @@ -848,22 +850,25 @@ rtm_add(struct rt_msghdr *rtm, k->k_state |= KS_GATEWAY; if (rtm->rtm_flags & RTF_STATIC) k->k_state |= KS_STATIC; - if (rtm->rtm_flags & RTF_DYNAMIC) { - k->k_state |= KS_DYNAMIC; - k->k_redirect_time = now.tv_sec; - /* Routers are not supposed to listen to redirects, - * so delete it. - */ + if (0 != (rtm->rtm_flags & (RTF_DYNAMIC | RTF_MODIFIED))) { if (supplier) { - k->k_keep = now.tv_sec; + /* Routers are not supposed to listen to redirects, + * so delete it. + */ + k->k_state &= ~KS_DYNAMIC; + k->k_state |= KS_DELETE; 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), naddr_ntoa(k->k_gate)); + } else { + k->k_state |= KS_DYNAMIC; + k->k_redirect_time = now.tv_sec; } } - /* If it is not a static route, quite until it is time to delete it. + /* If it is not a static route, quit until the next comparison + * between the kernel and daemon tables, when it will be deleted. */ if (!(k->k_state & KS_STATIC)) { k->k_state |= KS_DELETE; @@ -878,7 +883,8 @@ rtm_add(struct rt_msghdr *rtm, */ ifp = iflookup(k->k_gate); if (ifp == 0) { - /* if there is no interface, maybe it is new + /* if there is no known interface, + * maybe there is a new interface */ ifinit(); ifp = iflookup(k->k_gate); @@ -1098,11 +1104,11 @@ read_rt(void) ? HOST_MASK : std_mask(S_ADDR(INFO_DST(&info)))); - strp += sprintf(strp, " %s", + strp += sprintf(strp, ": %s", addrname(S_ADDR(INFO_DST(&info)), mask, 0)); if (IN_MULTICAST(ntohl(S_ADDR(INFO_DST(&info))))) { - trace_act("ignore %s for multicast %s\n", str); + trace_act("ignore multicast %s\n", str); continue; } @@ -1163,11 +1169,13 @@ kern_out(struct ag_info *ag) * This includes routes that had RS_NET_SYN for interfaces that * recently died. */ - if (ag->ag_metric == HOPCNT_INFINITY - && 0 == kern_find(htonl(ag->ag_dst_h), ag->ag_mask, 0)) - return; - - k = kern_add(htonl(ag->ag_dst_h), ag->ag_mask); + if (ag->ag_metric == HOPCNT_INFINITY) { + k = kern_find(htonl(ag->ag_dst_h), ag->ag_mask, 0); + if (k == 0) + return; + } else { + k = kern_add(htonl(ag->ag_dst_h), ag->ag_mask); + } if (k->k_state & KS_NEW) { /* will need to add new entry to the kernel table */ @@ -1183,7 +1191,6 @@ kern_out(struct ag_info *ag) return; /* modify existing kernel entry if necessary */ - k->k_state &= ~KS_DELETE; if (k->k_gate != ag->ag_gate || k->k_metric != ag->ag_metric) { k->k_gate = ag->ag_gate; @@ -1205,6 +1212,16 @@ kern_out(struct ag_info *ag) k->k_state |= KS_GATEWAY; k->k_state |= (KS_ADD | KS_DEL_ADD); } + + /* Deleting-and-adding is necessary to change aspects of a route. + * Just delete instead of deleting and then adding a bad route. + * Otherwise, we want to keep the route in the kernel. + */ + if (k->k_metric == HOPCNT_INFINITY + && (k->k_state & KS_DEL_ADD)) + k->k_state |= KS_DELETE; + else + k->k_state &= ~KS_DELETE; #undef RT } @@ -1298,31 +1315,40 @@ fix_kern(void) continue; } - if (k->k_state & KS_DELETE) { + if ((k->k_state & (KS_DELETE | KS_DYNAMIC)) + == KS_DELETE) { if (!(k->k_state & KS_DELETED)) rtioctl(RTM_DELETE, - k->k_dst,k->k_gate, - k->k_mask, 0, 0); + k->k_dst, k->k_gate, k->k_mask, + 0, 0); *pk = k->k_next; free(k); continue; } - if (k->k_state & KS_DEL_ADD) - rtioctl(RTM_DELETE, - k->k_dst,k->k_gate,k->k_mask, 0, 0); - - flags = (k->k_state & KS_GATEWAY) ? RTF_GATEWAY : 0; - if (k->k_state & KS_ADD) { - rtioctl(RTM_ADD, - k->k_dst, k->k_gate, k->k_mask, - k->k_metric, flags); - } else if (k->k_state & KS_CHANGE) { - rtioctl(RTM_CHANGE, - k->k_dst,k->k_gate,k->k_mask, - k->k_metric, flags); + if (0 != (k->k_state&(KS_ADD|KS_CHANGE|KS_DEL_ADD))) { + if (k->k_state & KS_DEL_ADD) { + rtioctl(RTM_DELETE, + k->k_dst,k->k_gate,k->k_mask, + 0, 0); + k->k_state &= ~KS_DYNAMIC; + } + + flags = 0; + if (0 != (k->k_state&(KS_GATEWAY|KS_DYNAMIC))) + flags |= RTF_GATEWAY; + + if (k->k_state & KS_ADD) { + rtioctl(RTM_ADD, + k->k_dst, k->k_gate, k->k_mask, + k->k_metric, flags); + } else if (k->k_state & KS_CHANGE) { + rtioctl(RTM_CHANGE, + k->k_dst,k->k_gate,k->k_mask, + k->k_metric, flags); + } + k->k_state &= ~(KS_ADD|KS_CHANGE|KS_DEL_ADD); } - k->k_state &= ~(KS_ADD | KS_CHANGE | KS_DEL_ADD); /* Mark this route to be deleted in the next cycle. * This deletes routes that disappear from the @@ -1356,7 +1382,7 @@ del_static(naddr dst, */ k = kern_find(dst, mask, 0); if (k != 0) { - k->k_state &= ~KS_STATIC; + k->k_state &= ~(KS_STATIC | KS_DYNAMIC); k->k_state |= KS_DELETE; if (gone) { k->k_state |= KS_DELETED; @@ -1370,8 +1396,8 @@ del_static(naddr dst, } -/* Delete all routes generated from ICMP Redirects that use a given - * gateway, as well as all old redirected routes. +/* Delete all routes generated from ICMP Redirects that use a given gateway, + * as well as old redirected routes. */ void del_redirects(naddr bad_gate, @@ -1393,6 +1419,7 @@ del_redirects(naddr bad_gate, continue; k->k_state |= KS_DELETE; + k->k_state &= ~KS_DYNAMIC; need_kern.tv_sec = now.tv_sec; trace_act("mark redirected %s --> %s for deletion\n", addrname(k->k_dst, k->k_mask, 0), @@ -1494,11 +1521,7 @@ rtadd(naddr dst, int i; struct rt_spare *rts; - rt = (struct rt_entry *)malloc(sizeof (*rt)); - if (rt == 0) { - BADERR(1,"rtadd malloc"); - return; - } + rt = (struct rt_entry *)rtmalloc(sizeof (*rt), "rtadd"); bzero(rt, sizeof(*rt)); for (rts = rt->rt_spares, i = NUM_SPARES; i != 0; i--, rts++) rts->rts_metric = HOPCNT_INFINITY; @@ -1527,6 +1550,8 @@ rtadd(naddr dst, rt->rt_ifp = ifp; rt->rt_seqno = update_seqno; + if (++total_routes == MAX_ROUTES) + msglog("have maximum (%d) routes", total_routes); if (TRACEACTIONS) trace_add_del("Add", rt); @@ -1667,6 +1692,7 @@ rtdelete(struct rt_entry *rt) msglog("rnh_deladdr() failed"); } else { free(rt); + total_routes--; } } @@ -1747,7 +1773,7 @@ rtbad_sub(struct rt_entry *rt) if (ifp1 != 0 || (state & RS_NET_SYN)) { rtchange(rt, ((rt->rt_state & ~(RS_NET_SYN | RS_LOCAL)) | state), - rt->rt_gate, rt->rt_router, 1, + rt->rt_gate, rt->rt_router, rt->rt_metric, rt->rt_tag, ifp1, rt->rt_time, 0); } else { rtbad(rt); diff --git a/usr.sbin/routed/trace.c b/usr.sbin/routed/trace.c index 01220c7dbaad..e9c1e03f05aa 100644 --- a/usr.sbin/routed/trace.c +++ b/usr.sbin/routed/trace.c @@ -31,11 +31,12 @@ * SUCH DAMAGE. */ -#if !defined(lint) && !defined(sgi) +#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) static char sccsid[] = "@(#)trace.c 8.1 (Berkeley) 6/5/93"; -#endif /* not lint */ - -#ident "$Revision: 1.8 $" +#elif defined(__NetBSD__) +static char rcsid[] = "$NetBSD$"; +#endif +#ident "$Revision: 1.11 $" #define RIPCMDS #include "defs.h" @@ -65,17 +66,18 @@ char * naddr_ntoa(naddr a) { #define NUM_BUFS 4 - static int i; + static int bufno; static struct { char str[16]; /* xxx.xxx.xxx.xxx\0 */ } bufs[NUM_BUFS]; - struct in_addr addr; char *s; + struct in_addr addr; addr.s_addr = a; - s = strcpy(bufs[i].str, inet_ntoa(addr)); - i = (i+1) % NUM_BUFS; + s = strcpy(bufs[bufno].str, inet_ntoa(addr)); + bufno = (bufno+1) % NUM_BUFS; return s; +#undef NUM_BUFS } @@ -320,12 +322,17 @@ addrname(naddr addr, /* in network byte order */ naddr mask, int force) /* 0=show mask if nonstandard, */ { /* 1=always show mask, 2=never */ - static char s[15+20]; - char *sp; +#define NUM_BUFS 4 + static int bufno; + static struct { + char str[15+20]; + } bufs[NUM_BUFS]; + char *s, *sp; naddr dmask; int i; - (void)strcpy(s, naddr_ntoa(addr)); + s = strcpy(bufs[bufno].str, naddr_ntoa(addr)); + bufno = (bufno+1) % NUM_BUFS; if (force == 1 || (force == 0 && mask != std_mask(addr))) { sp = &s[strlen(s)]; @@ -337,11 +344,12 @@ addrname(naddr addr, /* in network byte order */ (void)sprintf(sp, "/%d", 32-i); } else { - (void)sprintf(sp, " (mask %#x)", mask); + (void)sprintf(sp, " (mask %#x)", (u_int)mask); } } return s; +#undef NUM_BUFS } @@ -450,7 +458,7 @@ trace_bits(struct bits *tbl, c = '|'; } - if (c || force) + if (c != '<' || force) (void)fputs("> ", ftrace); } @@ -479,12 +487,14 @@ trace_if(char *act, lastlog(); (void)fprintf(ftrace, "%s interface %-4s ", act, ifp->int_name); - (void)fprintf(ftrace, "%-15s --> %s ", + (void)fprintf(ftrace, "%-15s-->%-15s ", naddr_ntoa(ifp->int_addr), - ((ifp->int_if_flags & IFF_POINTOPOINT) - ? naddr_ntoa(ifp->int_dstaddr) - : addrname(htonl(ifp->int_net), ifp->int_mask, 0))); - (void)fprintf(ftrace, "metric=%d ", ifp->int_metric); + addrname(htonl((ifp->int_if_flags & IFF_POINTOPOINT) + ? ifp->int_dstaddr + : ifp->int_net), + ifp->int_mask, 1)); + if (ifp->int_metric != 0) + (void)fprintf(ftrace, "metric=%d ", ifp->int_metric); trace_bits(if_bits, ifp->int_if_flags, 0); trace_bits(is_bits, ifp->int_state, 0); (void)fputc('\n',ftrace); @@ -519,7 +529,7 @@ trace_upslot(struct rt_entry *rt, (void)fprintf(ftrace, "router=%s ", naddr_ntoa(rts->rts_gate)); if (rts->rts_tag != 0) - (void)fprintf(ftrace, "tag=%#x ", rts->rts_tag); + (void)fprintf(ftrace, "tag=%#x ", ntohs(rts->rts_tag)); (void)fprintf(ftrace, "metric=%-2d ", rts->rts_metric); if (rts->rts_ifp != 0) (void)fprintf(ftrace, "%s ", @@ -532,7 +542,7 @@ trace_upslot(struct rt_entry *rt, if (gate != router) (void)fprintf(ftrace,"router=%s ",naddr_ntoa(router)); if (tag != rts->rts_tag) - (void)fprintf(ftrace, "tag=%#x ", tag); + (void)fprintf(ftrace, "tag=%#x ", ntohs(tag)); if (metric != rts->rts_metric) (void)fprintf(ftrace, "metric=%-2d ", metric); if (ifp != rts->rts_ifp && ifp != 0 ) @@ -548,7 +558,7 @@ trace_upslot(struct rt_entry *rt, if (gate != router) (void)fprintf(ftrace, "router=%s ", naddr_ntoa(gate)); if (tag != 0) - (void)fprintf(ftrace, "tag=%#x ", tag); + (void)fprintf(ftrace, "tag=%#x ", ntohs(tag)); (void)fprintf(ftrace, "metric=%-2d ", metric); if (ifp != 0) (void)fprintf(ftrace, "%s ", ifp->int_name); @@ -620,7 +630,7 @@ trace_change(struct rt_entry *rt, (void)fprintf(ftrace, "router=%s ", naddr_ntoa(rt->rt_router)); if (rt->rt_tag != 0) - (void)fprintf(ftrace, "tag=%#x ", rt->rt_tag); + (void)fprintf(ftrace, "tag=%#x ", ntohs(rt->rt_tag)); trace_bits(rs_bits, rt->rt_state, rt->rt_state != state); (void)fprintf(ftrace, "%s ", rt->rt_ifp == 0 ? "?" : rt->rt_ifp->int_name); @@ -635,7 +645,7 @@ trace_change(struct rt_entry *rt, if (router != gate) (void)fprintf(ftrace, "router=%s ", naddr_ntoa(router)); if (rt->rt_tag != tag) - (void)fprintf(ftrace, "tag=%#x ", tag); + (void)fprintf(ftrace, "tag=%#x ", ntohs(tag)); if (rt->rt_state != state) trace_bits(rs_bits, state, 1); if (rt->rt_ifp != ifp) @@ -665,10 +675,10 @@ trace_add_del(char * action, struct rt_entry *rt) (void)fprintf(ftrace, "router=%s ", naddr_ntoa(rt->rt_router)); if (rt->rt_tag != 0) - (void)fprintf(ftrace, "tag=%#x ", rt->rt_tag); + (void)fprintf(ftrace, "tag=%#x ", ntohs(rt->rt_tag)); trace_bits(rs_bits, state, 0); - if (rt->rt_ifp != 0) - (void)fprintf(ftrace, "%s ", rt->rt_ifp->int_name); + (void)fprintf(ftrace, "%s ", + rt->rt_ifp != 0 ? rt->rt_ifp->int_name : "?"); (void)fprintf(ftrace, "%s\n", ts(rt->rt_time)); } @@ -690,12 +700,12 @@ trace_rip(char *dir1, char *dir2, lastlog(); if (msg->rip_cmd >= RIPCMD_MAX || msg->rip_vers == 0) { - (void)fprintf(ftrace, "%s bad RIPv%d cmd=%d %s %s.%d%s%s" - " size=%d msg=%#x\n", + (void)fprintf(ftrace, "%s bad RIPv%d cmd=%d %s" + " %s.%d size=%d\n", dir1, msg->rip_vers, msg->rip_cmd, dir2, naddr_ntoa(who->sin_addr.s_addr), ntohs(who->sin_port), - size, msg); + size); return; } @@ -723,13 +733,13 @@ trace_rip(char *dir1, char *dir2, naddr_ntoa(n->n_dst)); if (n->n_mask != 0) (void)fprintf(ftrace, "mask=%#x ", - ntohl(n->n_mask)); + (u_int)ntohl(n->n_mask)); if (n->n_nhop != 0) (void)fprintf(ftrace, " nhop=%s ", naddr_ntoa(n->n_nhop)); if (n->n_tag != 0) (void)fprintf(ftrace, "tag=%#x", - n->n_tag); + ntohs(n->n_tag)); (void)fputc('\n',ftrace); continue; } @@ -753,7 +763,7 @@ trace_rip(char *dir1, char *dir2, "\t(af %d) %-18s mask=%#x", ntohs(n->n_family), naddr_ntoa(n->n_dst), - ntohl(n->n_mask)); + (u_int)ntohl(n->n_mask)); } else if (msg->rip_vers == RIPv1) { (void)fprintf(ftrace, "\t%-18s ", addrname(n->n_dst, @@ -766,13 +776,13 @@ trace_rip(char *dir1, char *dir2, n->n_mask==0 ? 2 : 0)); } (void)fprintf(ftrace, "metric=%-2d ", - ntohl(n->n_metric)); + (u_int)ntohl(n->n_metric)); if (n->n_nhop != 0) (void)fprintf(ftrace, " nhop=%s ", naddr_ntoa(n->n_nhop)); if (n->n_tag != 0) (void)fprintf(ftrace, "tag=%#x", - n->n_tag); + ntohs(n->n_tag)); (void)fputc('\n',ftrace); } if (size != (char *)n - (char *)msg) |