From 4841cf292751a6ea60883362b9ff4f506607ae6f Mon Sep 17 00:00:00 2001 From: christos Date: Tue, 20 Jun 1995 22:25:51 +0000 Subject: [PATCH] - Support rip version 2. - Add ansi prototypes. - Be less internet centric. - Convert queues to use so we don't need -lcompat --- sbin/routed/Makefile | 4 +- sbin/routed/af.c | 135 ++++++++++++++++++++-------- sbin/routed/af.h | 51 +++++++---- sbin/routed/defs.h | 71 ++++++++------- sbin/routed/if.c | 8 +- sbin/routed/inet.c | 14 +-- sbin/routed/input.c | 184 +++++++++++++++++++------------------- sbin/routed/interface.h | 10 +-- sbin/routed/main.c | 26 +++--- sbin/routed/output.c | 31 +++---- sbin/routed/query/query.c | 6 +- sbin/routed/startup.c | 30 ++++--- sbin/routed/table.h | 30 ++++--- sbin/routed/tables.c | 116 +++++++++++++++++------- sbin/routed/timer.c | 31 ++++--- sbin/routed/trace.c | 51 ++++++----- sbin/routed/trace.h | 16 +++- sbin/routed/trace/trace.c | 6 +- 18 files changed, 489 insertions(+), 331 deletions(-) diff --git a/sbin/routed/Makefile b/sbin/routed/Makefile index c93762c9a538..4420b69f4342 100644 --- a/sbin/routed/Makefile +++ b/sbin/routed/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.13 1995/05/31 20:44:35 ragge Exp $ +# $NetBSD: Makefile,v 1.14 1995/06/20 22:25:51 christos Exp $ # @(#)Makefile 8.1 (Berkeley) 6/19/93 PROG= routed @@ -6,7 +6,5 @@ SRCS= af.c if.c input.c main.c output.c startup.c tables.c timer.c \ trace.c inet.c MAN= routed.8 #SUBDIR= query trace -DPADD= ${LIBCOMPAT} -LDADD= -lcompat .include diff --git a/sbin/routed/af.c b/sbin/routed/af.c index d8699f6c0a47..c1da36ff4670 100644 --- a/sbin/routed/af.c +++ b/sbin/routed/af.c @@ -1,4 +1,4 @@ -/* $NetBSD: af.c,v 1.9 1995/05/24 15:54:00 mycroft Exp $ */ +/* $NetBSD: af.c,v 1.10 1995/06/20 22:26:27 christos Exp $ */ /* * Copyright (c) 1983, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)af.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$NetBSD: af.c,v 1.9 1995/05/24 15:54:00 mycroft Exp $"; +static char rcsid[] = "$NetBSD: af.c,v 1.10 1995/06/20 22:26:27 christos Exp $"; #endif #endif /* not lint */ @@ -46,21 +46,23 @@ static char rcsid[] = "$NetBSD: af.c,v 1.9 1995/05/24 15:54:00 mycroft Exp $"; /* * Address family support routines */ -int inet_canon __P((struct sockaddr_in *)); -int inet_checkhost __P((struct sockaddr_in *)); -char *inet_format __P((struct sockaddr_in *, char *, size_t)); -int inet_hash __P((struct sockaddr_in *, struct afhash *)); -int inet_netmatch __P((struct sockaddr_in *, struct sockaddr_in *)); -int inet_portcheck __P((struct sockaddr_in *)); -int inet_portmatch __P((struct sockaddr_in *)); -int inet_output __P((int, int, struct sockaddr_in *, int)); +static void inet_canon __P((struct sockaddr *)); +static int inet_checkhost __P((struct sockaddr *)); +static char *inet_format __P((struct sockaddr *, char *buf, size_t sz)); +static void inet_hash __P((struct sockaddr *, struct afhash *)); +static int inet_netmatch __P((struct sockaddr *, struct sockaddr *)); +static int inet_portcheck __P((struct sockaddr *)); +static int inet_portmatch __P((struct sockaddr *)); +static void inet_output __P((int, int, struct sockaddr *, int)); +static int inet_get __P((int, void *, struct sockaddr *)); +static void inet_put __P((void *, struct sockaddr *)); #define NIL { 0 } #define INET \ { inet_hash, inet_netmatch, inet_output, \ inet_portmatch, inet_portcheck, inet_checkhost, \ inet_rtflags, inet_sendroute, inet_canon, \ - inet_format \ + inet_format, inet_get, inet_put \ } struct afswitch afswitch[AF_MAX] = { @@ -77,11 +79,12 @@ struct sockaddr_in inet_default = { #endif AF_INET, INADDR_ANY }; -int -inet_hash(sin, hp) - register struct sockaddr_in *sin; +static void +inet_hash(sa, hp) + struct sockaddr *sa; struct afhash *hp; { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; register u_long n; n = inet_netof_subnet(sin->sin_addr); @@ -93,22 +96,25 @@ inet_hash(sin, hp) hp->afh_hosthash &= 0x7fffffff; } -int -inet_netmatch(sin1, sin2) - struct sockaddr_in *sin1, *sin2; +static int +inet_netmatch(sa1, sa2) + struct sockaddr *sa1, *sa2; { + struct sockaddr_in *sin1 = (struct sockaddr_in *) sa1; + struct sockaddr_in *sin2 = (struct sockaddr_in *) sa2; return (inet_netof_subnet(sin1->sin_addr) == - inet_netof_subnet(sin2->sin_addr)); + inet_netof_subnet(sin2->sin_addr)); } /* * Verify the message is from the right port. */ -int -inet_portmatch(sin) - register struct sockaddr_in *sin; +static int +inet_portmatch(sa) + struct sockaddr *sa; { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; return (sin->sin_port == sp->s_port); } @@ -116,10 +122,11 @@ inet_portmatch(sin) /* * Verify the message is from a "trusted" port. */ -int -inet_portcheck(sin) - struct sockaddr_in *sin; +static int +inet_portcheck(sa) + struct sockaddr *sa; { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; return (ntohs(sin->sin_port) <= IPPORT_RESERVED); } @@ -127,12 +134,13 @@ inet_portcheck(sin) /* * Internet output routine. */ -int -inet_output(s, flags, sin, size) +static void +inet_output(s, flags, sa, size) int s, flags; - struct sockaddr_in *sin; + struct sockaddr *sa; int size; { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; struct sockaddr_in dst; dst = *sin; @@ -150,10 +158,11 @@ inet_output(s, flags, sin, size) * Return 1 if the address is believed * for an Internet host -- THIS IS A KLUDGE. */ -int -inet_checkhost(sin) - struct sockaddr_in *sin; +static int +inet_checkhost(sa) + struct sockaddr *sa; { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; u_long i = ntohl(sin->sin_addr.s_addr); #ifndef IN_EXPERIMENTAL @@ -170,23 +179,71 @@ inet_checkhost(sin) return (1); } -int -inet_canon(sin) - struct sockaddr_in *sin; +static void +inet_canon(sa) + struct sockaddr *sa; { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; sin->sin_port = 0; sin->sin_len = sizeof(*sin); } -char * -inet_format(sin, buf, sz) - struct sockaddr_in *sin; - char *buf; - size_t sz; +static char * +inet_format(sa, buf, sz) + struct sockaddr *sa; + char *buf; size_t sz; { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; strncpy(buf, inet_ntoa(sin->sin_addr), sz); buf[sz - 1] = '\0'; - return (buf); + return buf; +} + +static int +inet_get(what, pck, sa) + int what; + void *pck; + struct sockaddr *sa; +{ + struct sockaddr_in *sin = (struct sockaddr_in *) sa; + struct netinfo *n = pck; + /* XXX: Internet only */ + memset(sin, 0, sizeof(*sin)); + switch (what) { + case DESTINATION: + sin->sin_addr.s_addr = n->rip_dst; + break; + case NETMASK: + if (n->rip_netmask == 0) + return 0; + sin->sin_addr.s_addr = n->rip_netmask; + break; + case GATEWAY: + if (n->rip_router == 0) + return 0; + sin->sin_addr.s_addr = n->rip_router; + break; + default: + abort(); + break; + } + + sin->sin_family = n->rip_family; +#if BSD >= 198810 + sin->sin_len = sizeof(sin); +#endif + return 1; +} + +static void +inet_put(pck, sa) + void *pck; + struct sockaddr *sa; +{ + struct netinfo *n = pck; + struct sockaddr_in *sin = (struct sockaddr_in *) sa; + n->rip_family = sin->sin_family; + n->rip_dst = sin->sin_addr.s_addr; } diff --git a/sbin/routed/af.h b/sbin/routed/af.h index 24a2f2fc33e1..d001c528ac17 100644 --- a/sbin/routed/af.h +++ b/sbin/routed/af.h @@ -1,4 +1,4 @@ -/* $NetBSD: af.h,v 1.7 1995/03/18 15:00:24 cgd Exp $ */ +/* $NetBSD: af.h,v 1.8 1995/06/20 22:26:45 christos Exp $ */ /* * Copyright (c) 1983, 1993 @@ -39,22 +39,6 @@ * Routing table management daemon. */ -/* - * Per address family routines. - */ -struct afswitch { - int (*af_hash)(); /* returns keys based on address */ - int (*af_netmatch)(); /* verifies net # matching */ - int (*af_output)(); /* interprets address for sending */ - int (*af_portmatch)(); /* packet from some other router? */ - int (*af_portcheck)(); /* packet from privileged peer? */ - int (*af_checkhost)(); /* tells if address is valid */ - int (*af_rtflags)(); /* get flags for route (host or net) */ - int (*af_sendroute)(); /* check bounds of subnet broadcast */ - int (*af_canon)(); /* canonicalize address for compares */ - char *(*af_format)(); /* convert address to string */ -}; - /* * Structure returned by af_hash routines. */ @@ -63,5 +47,38 @@ struct afhash { u_int afh_nethash; /* network based hash */ }; +/* + * Per address family routines. + */ +struct afswitch { + /* returns keys based on address */ + void (*af_hash) __P((struct sockaddr *, struct afhash *)); + /* verifies net # matching */ + int (*af_netmatch) __P((struct sockaddr *, struct sockaddr *)); + /* interprets address for sending */ + void (*af_output) __P((int, int, struct sockaddr *, int)); + /* packet from some other router? */ + int (*af_portmatch) __P((struct sockaddr *)); + /* packet from privileged peer? */ + int (*af_portcheck) __P((struct sockaddr *)); + /* tells if address is valid */ + int (*af_checkhost) __P((struct sockaddr *)); + /* get flags for route (host or net) */ + int (*af_rtflags) __P((struct sockaddr *)); + /* check bounds of subnet broadcast */ + int (*af_sendroute) __P((struct rt_entry *, struct sockaddr *)); + /* canonicalize address for compares */ + void (*af_canon) __P((struct sockaddr *)); + /* convert address to string */ + char *(*af_format) __P((struct sockaddr *, char *, size_t)); + /* get address from packet */ +#define DESTINATION 0 +#define GATEWAY 1 +#define NETMASK 2 + int (*af_get) __P((int, void *, struct sockaddr *)); + /* put address to packet */ + void (*af_put) __P((void *, struct sockaddr *)); +}; + extern struct afswitch afswitch[]; /* table proper */ extern int af_max; /* number of entries in table */ diff --git a/sbin/routed/defs.h b/sbin/routed/defs.h index d76f1e566b02..a0313e754ccd 100644 --- a/sbin/routed/defs.h +++ b/sbin/routed/defs.h @@ -1,4 +1,4 @@ -/* $NetBSD: defs.h,v 1.10 1995/03/21 14:05:01 mycroft Exp $ */ +/* $NetBSD: defs.h,v 1.11 1995/06/20 22:26:57 christos Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -57,9 +57,9 @@ #include #include +#include "table.h" #include "trace.h" #include "interface.h" -#include "table.h" #include "af.h" /* @@ -97,42 +97,41 @@ struct rip *msg; char **argv0; struct servent *sp; -struct in_addr inet_makeaddr(); -int sndmsg(); -int supply(); - -void addrouteforif __P((struct interface *)); -void bumploglevel(); -void dumppacket __P((FILE *, char *, struct sockaddr_in *, char *, - int, struct timeval *)); -void gwkludge(); -void hup(); -void ifinit(); -#ifdef notdef /* XXX FUNCTION UNUSED */ -u_long inet_lnaof_subnet __P((struct in_addr)); -#endif -int inet_maskof __P((u_long)); +/* inet.c */ +struct in_addr inet_makeaddr __P((u_long, u_long )); u_long inet_netof_subnet __P((struct in_addr)); -int inet_rtflags __P((struct sockaddr_in *)); -int inet_sendroute __P((struct rt_entry *, struct sockaddr_in *)); +u_long inet_lnaof_subnet __P((struct in_addr)); +int inet_maskof __P((u_long)); +int inet_rtflags __P((struct sockaddr *)); +int inet_sendroute __P((struct rt_entry *, struct sockaddr *)); + +/* input.c */ void rip_input __P((struct sockaddr *, struct rip *, int)); -void rtadd __P((struct sockaddr *, struct sockaddr *, int, int)); -void rtchange __P((struct rt_entry *, struct sockaddr *, short)); -void rtdefault(); -void rtdelete __P((struct rt_entry *)); -void rtdeleteall __P((int)); -void rtinit(); -int rtioctl __P((int, struct rtuentry *)); -void sigtrace __P((int)); -int sndmsg __P((struct sockaddr *, int, struct interface *, int)); -void timer(); -void toall __P((int (*)(), int, struct interface *)); -void traceoff(); -void traceon __P((char *)); -void trace __P((struct ifdebug *, struct sockaddr *, char *, int, int)); -void traceaction __P((FILE *, char *, struct rt_entry *)); -void traceinit __P((struct interface *)); -void tracenewmetric __P((FILE *, struct rt_entry *, int)); + +/* main.c */ +int main __P((int, char *[])); +void process __P((int)); +int getsocket __P((int, int , struct sockaddr_in *)); + +/* output.c */ +void toall __P((void (*)(struct sockaddr *, int, struct interface *, int), + int, struct interface *)); +void sndmsg __P((struct sockaddr *, int, struct interface *, int)); +void supply __P((struct sockaddr *, int, struct interface *, int)); + +/* startup.c */ +void quit __P((char *)); +void rt_xaddrs __P((caddr_t, caddr_t , struct rt_addrinfo *)); +void ifinit __P((void)); +void addrouteforif __P((struct interface *)); +void add_ptopt_localrt __P((struct interface *)); +void gwkludge __P((void)); +int getnetorhostname __P((char *, char *, struct sockaddr_in *)); +int gethostnameornumber __P((char *, struct sockaddr_in *)); + +/* timer.c */ +void timer __P((int)); +void hup __P((int)); #define ADD 1 #define DELETE 2 diff --git a/sbin/routed/if.c b/sbin/routed/if.c index 642b20fe668c..0a61f02b36d6 100644 --- a/sbin/routed/if.c +++ b/sbin/routed/if.c @@ -1,4 +1,4 @@ -/* $NetBSD: if.c,v 1.7 1995/03/18 15:00:28 cgd Exp $ */ +/* $NetBSD: if.c,v 1.8 1995/06/20 22:27:21 christos Exp $ */ /* * Copyright (c) 1983, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$NetBSD: if.c,v 1.7 1995/03/18 15:00:28 cgd Exp $"; +static char rcsid[] = "$NetBSD: if.c,v 1.8 1995/06/20 22:27:21 christos Exp $"; #endif #endif /* not lint */ @@ -101,7 +101,7 @@ if_ifwithnet(addr) { register struct interface *ifp; register int af = addr->sa_family; - register int (*netmatch)(); + register int (*netmatch) __P((struct sockaddr *, struct sockaddr *)); if (af >= af_max) return (0); @@ -128,7 +128,7 @@ if_iflookup(addr) { register struct interface *ifp, *maybe; register int af = addr->sa_family; - register int (*netmatch)(); + register int (*netmatch) __P((struct sockaddr *, struct sockaddr *)); if (af >= af_max) return (0); diff --git a/sbin/routed/inet.c b/sbin/routed/inet.c index acebb316a2ea..1f6ddcd51235 100644 --- a/sbin/routed/inet.c +++ b/sbin/routed/inet.c @@ -1,4 +1,4 @@ -/* $NetBSD: inet.c,v 1.8 1995/03/18 15:00:29 cgd Exp $ */ +/* $NetBSD: inet.c,v 1.9 1995/06/20 22:27:40 christos Exp $ */ /* * Copyright (c) 1983, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)inet.c 8.2 (Berkeley) 8/14/93"; #else -static char rcsid[] = "$NetBSD: inet.c,v 1.8 1995/03/18 15:00:29 cgd Exp $"; +static char rcsid[] = "$NetBSD: inet.c,v 1.9 1995/06/20 22:27:40 christos Exp $"; #endif #endif /* not lint */ @@ -175,9 +175,10 @@ inet_maskof(inaddr) * 0 for a network. */ int -inet_rtflags(sin) - struct sockaddr_in *sin; +inet_rtflags(sa) + struct sockaddr *sa; { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; register u_long i = ntohl(sin->sin_addr.s_addr); register u_long net, host; register struct interface *ifp; @@ -218,10 +219,11 @@ inet_rtflags(sin) * otherwise only if the route is the "internal" route for the logical net. */ int -inet_sendroute(rt, dst) +inet_sendroute(rt, sa) struct rt_entry *rt; - struct sockaddr_in *dst; + struct sockaddr *sa; { + struct sockaddr_in *dst = (struct sockaddr_in *) sa; register u_long r = ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr); register u_long d = ntohl(dst->sin_addr.s_addr); diff --git a/sbin/routed/input.c b/sbin/routed/input.c index 913397b3d946..79273ce57c84 100644 --- a/sbin/routed/input.c +++ b/sbin/routed/input.c @@ -1,4 +1,4 @@ -/* $NetBSD: input.c,v 1.14 1995/05/28 05:37:32 jtc Exp $ */ +/* $NetBSD: input.c,v 1.15 1995/06/20 22:27:50 christos Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$NetBSD: input.c,v 1.14 1995/05/28 05:37:32 jtc Exp $"; +static char rcsid[] = "$NetBSD: input.c,v 1.15 1995/06/20 22:27:50 christos Exp $"; #endif #endif /* not lint */ @@ -47,6 +47,49 @@ static char rcsid[] = "$NetBSD: input.c,v 1.14 1995/05/28 05:37:32 jtc Exp $"; #include "defs.h" #include + +/* + * "Authenticate" router from which message originated. + * We accept routing packets from routers directly connected + * via broadcast or point-to-point networks, + * and from those listed in /etc/gateways. + */ +static struct interface * +rip_verify(from) + struct sockaddr *from; +{ + struct interface *ifp; + char buf[256]; + + if ((ifp = if_iflookup(from)) == 0) { + syslog(LOG_ERR, "trace command from unknown router, %s", + (*afswitch[from->sa_family].af_format)(from, buf, + sizeof(buf))); + return NULL; + } + + if ((ifp->int_flags & + (IFF_BROADCAST|IFF_POINTOPOINT|IFF_REMOTE)) == 0) { + syslog(LOG_ERR, + "trace command from router %s, with bad flags %x", + (*afswitch[from->sa_family].af_format)(from, buf, + sizeof(buf)), + ifp->int_flags); + return NULL; + } + + if ((ifp->int_flags & IFF_PASSIVE) != 0) { + syslog(LOG_ERR, + "trace command from %s on an active interface", + (*afswitch[from->sa_family].af_format)(from, buf, + sizeof(buf))); + return NULL; + } + + return ifp; +} + + /* * Process a newly received packet. */ @@ -59,16 +102,16 @@ rip_input(from, rip, size) register struct rt_entry *rt; register struct netinfo *n; register struct interface *ifp; - struct interface *if_ifwithdstaddr(); + struct sockaddr dst, gateway, netmask; int count, changes = 0; register struct afswitch *afp; - static struct sockaddr badfrom, badfrom2; + static struct sockaddr badfrom; char buf1[256], buf2[256]; ifp = 0; TRACE_INPUT(ifp, from, (char *)rip, size); if (from->sa_family >= af_max || - (afp = &afswitch[from->sa_family])->af_hash == (int (*)())0) { + (afp = &afswitch[from->sa_family])->af_hash == NULL) { syslog(LOG_INFO, "\"from\" address in unsupported address family (%d), cmd %d\n", from->sa_family, rip->rip_cmd); @@ -82,6 +125,7 @@ rip_input(from, rip, size) rip->rip_cmd); return; } + switch (rip->rip_cmd) { case RIPCMD_REQUEST: @@ -94,16 +138,8 @@ rip_input(from, rip, size) break; count -= sizeof (struct netinfo); -#if BSD < 198810 - if (sizeof(n->rip_dst.sa_family) > 1) /* XXX */ - n->rip_dst.sa_family = ntohs(n->rip_dst.sa_family); -#else -#define osa(x) ((struct osockaddr *)(&(x))) - n->rip_dst.sa_family = - ntohs(osa(n->rip_dst)->sa_family); - n->rip_dst.sa_len = sizeof(n->rip_dst); -#endif n->rip_metric = ntohl(n->rip_metric); + n->rip_family = ntohs(n->rip_family); /* * A single entry with sa_family == AF_UNSPEC and * metric ``infinity'' means ``all routes''. @@ -111,27 +147,23 @@ rip_input(from, rip, size) * as a supplier, or to anyone other than a router * (eg, query). */ - if (n->rip_dst.sa_family == AF_UNSPEC && + if (n->rip_family == AF_UNSPEC && n->rip_metric == HOPCNT_INFINITY && count == 0) { if (supplier || (*afp->af_portmatch)(from) == 0) supply(from, 0, 0, 0); return; } - if (n->rip_dst.sa_family < af_max && - afswitch[n->rip_dst.sa_family].af_hash) - rt = rtlookup(&n->rip_dst); + if (dst.sa_family < af_max && + afswitch[dst.sa_family].af_hash) { + (*afswitch[n->rip_family].af_get)(DESTINATION, + n, &dst); + rt = rtlookup(&dst); + } else rt = 0; #define min(a, b) (a < b ? a : b) n->rip_metric = rt == 0 ? HOPCNT_INFINITY : min(rt->rt_metric + 1, HOPCNT_INFINITY); -#if BSD < 198810 - if (sizeof(n->rip_dst.sa_family) > 1) /* XXX */ - n->rip_dst.sa_family = htons(n->rip_dst.sa_family); -#else - osa(n->rip_dst)->sa_family = - htons(n->rip_dst.sa_family); -#endif n->rip_metric = htonl(n->rip_metric); } rip->rip_cmd = RIPCMD_RESPONSE; @@ -144,30 +176,9 @@ rip_input(from, rip, size) /* verify message came from a privileged port */ if ((*afp->af_portcheck)(from) == 0) return; - if ((ifp = if_iflookup(from)) == 0) { - syslog(LOG_ERR, "trace command from unknown router, %s", - (*afswitch[from->sa_family].af_format)(from, buf1, - sizeof(buf1))); - return; - } - if ((ifp->int_flags & - (IFF_BROADCAST|IFF_POINTOPOINT|IFF_REMOTE)) == 0) { - syslog(LOG_ERR, - "trace command from router %s, with bad flags %x", - (*afswitch[from->sa_family].af_format)(from, buf1, - sizeof(buf1)), - ifp->int_flags); + if ((ifp = rip_verify(from)) == NULL) return; - } - - if ((ifp->int_flags & IFF_PASSIVE) != 0) { - syslog(LOG_ERR, - "trace command from %s on a passive interface", - (*afswitch[from->sa_family].af_format)(from, buf1, - sizeof(buf1))); - return; - } ((char *)rip)[size] = '\0'; if (rip->rip_cmd == RIPCMD_TRACEON) @@ -192,8 +203,8 @@ rip_input(from, rip, size) return; } rt = rtfind(from); - if (rt == 0 || ((rt->rt_state & RTS_INTERFACE) == 0) && - rt->rt_metric >= ifp->int_metric) + if (rt == 0 || (((rt->rt_state & RTS_INTERFACE) == 0) && + rt->rt_metric >= ifp->int_metric)) addrouteforif(ifp); else rt->rt_timer = 0; @@ -210,55 +221,41 @@ rip_input(from, rip, size) else if ((ifp = if_ifwithdstaddr(from)) && (rt == 0 || rt->rt_metric >= ifp->int_metric)) addrouteforif(ifp); - /* - * "Authenticate" router from which message originated. - * We accept routing packets from routers directly connected - * via broadcast or point-to-point networks, - * and from those listed in /etc/gateways. - */ - if ((ifp = if_iflookup(from)) == 0 || (ifp->int_flags & - (IFF_BROADCAST | IFF_POINTOPOINT | IFF_REMOTE)) == 0 || - ifp->int_flags & IFF_PASSIVE) { - if (memcmp(from, &badfrom, sizeof(badfrom)) != 0) { - syslog(LOG_ERR, - "packet from unknown router, %s", - (*afswitch[from->sa_family].af_format)(from, - buf1, sizeof(buf1))); - badfrom = *from; - } + + if ((ifp = rip_verify(from)) == NULL) return; - } + size -= 4 * sizeof (char); n = rip->rip_nets; for (; size > 0; size -= sizeof (struct netinfo), n++) { if (size < sizeof (struct netinfo)) break; -#if BSD < 198810 - if (sizeof(n->rip_dst.sa_family) > 1) /* XXX */ - n->rip_dst.sa_family = - ntohs(n->rip_dst.sa_family); -#else - n->rip_dst.sa_family = - ntohs(osa(n->rip_dst)->sa_family); - n->rip_dst.sa_len = sizeof(n->rip_dst); -#endif n->rip_metric = ntohl(n->rip_metric); - if (n->rip_dst.sa_family >= af_max || - (afp = &afswitch[n->rip_dst.sa_family])->af_hash == - (int (*)())0) { + n->rip_family = ntohs(n->rip_family); + if (!(*afswitch[n->rip_family].af_get)(DESTINATION, n, + &dst)) + continue; + if (!(*afswitch[n->rip_family].af_get)(NETMASK, + n, &netmask)) + memset(&netmask, 0, sizeof(netmask)); + if (!(*afswitch[n->rip_family].af_get)(GATEWAY, + n, &gateway)) + memcpy(&gateway, from, sizeof(gateway)); + if (dst.sa_family >= af_max || + (afp = &afswitch[dst.sa_family])->af_hash == NULL) { syslog(LOG_INFO, "route in unsupported address family (%d), from %s (af %d)\n", - n->rip_dst.sa_family, + dst.sa_family, (*afswitch[from->sa_family].af_format)(from, buf1, sizeof(buf1)), from->sa_family); continue; } - if (((*afp->af_checkhost)(&n->rip_dst)) == 0) { + if (((*afp->af_checkhost)(&dst)) == 0) { syslog(LOG_DEBUG, "bad host %s in route from %s (af %d)\n", - (*afswitch[n->rip_dst.sa_family].af_format)( - &n->rip_dst, buf1, sizeof(buf1)), + (*afswitch[dst.sa_family].af_format)( + &dst, buf1, sizeof(buf1)), (*afswitch[from->sa_family].af_format)(from, buf2, sizeof(buf2)), from->sa_family); @@ -266,14 +263,14 @@ rip_input(from, rip, size) } if (n->rip_metric == 0 || (unsigned) n->rip_metric > HOPCNT_INFINITY) { - if (memcmp(from, &badfrom2, - sizeof(badfrom2)) != 0) { + if (memcmp(from, &badfrom, + sizeof(badfrom)) != 0) { syslog(LOG_ERR, "bad metric (%d) from %s\n", n->rip_metric, (*afswitch[from->sa_family].af_format)(from, buf1, sizeof(buf1))); - badfrom2 = *from; + badfrom = *from; } continue; } @@ -284,7 +281,7 @@ rip_input(from, rip, size) n->rip_metric += ifp->int_metric; if ((unsigned) n->rip_metric > HOPCNT_INFINITY) n->rip_metric = HOPCNT_INFINITY; - rt = rtlookup(&n->rip_dst); + rt = rtlookup(&dst); if (rt == 0 || (rt->rt_state & (RTS_INTERNAL|RTS_INTERFACE)) == (RTS_INTERNAL|RTS_INTERFACE)) { @@ -302,10 +299,11 @@ rip_input(from, rip, size) * includes this one before adding * this route. */ - rt = rtfind(&n->rip_dst); - if (rt && equal(from, &rt->rt_router)) + rt = rtfind(&dst); + if (rt && equal(&gateway, &rt->rt_router)) continue; - rtadd(&n->rip_dst, from, n->rip_metric, 0); + rtadd(&dst, &gateway, &netmask, + n->rip_metric, 0); changes++; } continue; @@ -316,9 +314,10 @@ rip_input(from, rip, size) * shorter, or equivalent but old route * is getting stale. */ - if (equal(from, &rt->rt_router)) { + if (equal(&gateway, &rt->rt_router)) { if (n->rip_metric != rt->rt_metric) { - rtchange(rt, from, n->rip_metric); + rtchange(rt, &gateway, + &netmask, n->rip_metric); changes++; rt->rt_timer = 0; if (rt->rt_metric >= HOPCNT_INFINITY) @@ -330,7 +329,7 @@ rip_input(from, rip, size) (rt->rt_metric == n->rip_metric && rt->rt_timer > (EXPIRE_TIME/2) && (unsigned) n->rip_metric < HOPCNT_INFINITY)) { - rtchange(rt, from, n->rip_metric); + rtchange(rt, &gateway, &netmask, n->rip_metric); changes++; rt->rt_timer = 0; } @@ -353,7 +352,6 @@ rip_input(from, rip, size) if (changes && supplier && now.tv_sec - lastfullupdate.tv_sec < SUPPLY_INTERVAL-MAX_WAITTIME) { u_long delay; - extern long random(); if (now.tv_sec - lastbcast.tv_sec >= MIN_WAITTIME && timercmp(&nextbcast, &now, <)) { diff --git a/sbin/routed/interface.h b/sbin/routed/interface.h index 3ca065432fca..a30a1bd9b7bd 100644 --- a/sbin/routed/interface.h +++ b/sbin/routed/interface.h @@ -1,4 +1,4 @@ -/* $NetBSD: interface.h,v 1.7 1995/03/18 15:00:32 cgd Exp $ */ +/* $NetBSD: interface.h,v 1.8 1995/06/20 22:27:52 christos Exp $ */ /* * Copyright (c) 1983, 1993 @@ -86,7 +86,7 @@ struct interface { #define IFF_INTERFACE 0x400000 /* hardware interface */ #define IFF_REMOTE 0x800000 /* interface isn't on this machine */ -struct interface *if_ifwithaddr(); -struct interface *if_ifwithdstaddr(); -struct interface *if_ifwithnet(); -struct interface *if_iflookup(); +struct interface *if_ifwithaddr __P((struct sockaddr *)); +struct interface *if_ifwithdstaddr __P((struct sockaddr *)); +struct interface *if_ifwithnet __P((struct sockaddr *)); +struct interface *if_iflookup __P((struct sockaddr *)); diff --git a/sbin/routed/main.c b/sbin/routed/main.c index 0b1820905411..ae0286775893 100644 --- a/sbin/routed/main.c +++ b/sbin/routed/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.12 1995/05/28 05:37:34 jtc Exp $ */ +/* $NetBSD: main.c,v 1.13 1995/06/20 22:27:53 christos Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -43,7 +43,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$NetBSD: main.c,v 1.12 1995/05/28 05:37:34 jtc Exp $"; +static char rcsid[] = "$NetBSD: main.c,v 1.13 1995/06/20 22:27:53 christos Exp $"; #endif #endif /* not lint */ @@ -154,7 +154,7 @@ main(argc, argv) while (tflags-- > 0) bumploglevel(); - (void) gettimeofday(&now, (struct timezone *)NULL); + (void) gettimeofday(&now, NULL); /* * Collect an initial view of the world by * checking the interface configuration and the gateway kludge @@ -170,11 +170,11 @@ main(argc, argv) if (supplier < 0) supplier = 0; query->rip_cmd = RIPCMD_REQUEST; - query->rip_vers = RIPVERSION; - if (sizeof(query->rip_nets[0].rip_dst.sa_family) > 1) /* XXX */ - query->rip_nets[0].rip_dst.sa_family = htons((u_short)AF_UNSPEC); + query->rip_vers = RIP_VERSION_1; + if (sizeof(query->rip_nets[0].rip_family) > 1) /* XXX */ + query->rip_nets[0].rip_family = htons((u_short)AF_UNSPEC); else - query->rip_nets[0].rip_dst.sa_family = AF_UNSPEC; + query->rip_nets[0].rip_family = AF_UNSPEC; query->rip_nets[0].rip_metric = htonl((u_long)HOPCNT_INFINITY); toall(sndmsg, 0, NULL); signal(SIGALRM, timer); @@ -188,7 +188,7 @@ main(argc, argv) itval.it_interval.tv_usec = 0; itval.it_value.tv_usec = 0; srandom(getpid()); - if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0) + if (setitimer(ITIMER_REAL, &itval, NULL) < 0) syslog(LOG_ERR, "setitimer: %m\n"); FD_ZERO(&ibits); @@ -215,7 +215,7 @@ main(argc, argv) waittime.tv_sec, waittime.tv_usec); tvp = &waittime; } else - tvp = (struct timeval *)NULL; + tvp = NULL; n = select(nfd, &ibits, 0, 0, tvp); if (n <= 0) { /* @@ -235,10 +235,8 @@ main(argc, argv) if (traceactions) fprintf(ftrace, "send delayed dynamic update\n"); - (void) gettimeofday(&now, - (struct timezone *)NULL); - toall(supply, RTS_CHANGED, - (struct interface *)NULL); + (void) gettimeofday(&now, NULL); + toall(supply, RTS_CHANGED, NULL); lastbcast = now; needupdate = 0; nextbcast.tv_sec = 0; @@ -246,7 +244,7 @@ main(argc, argv) sigprocmask(SIG_SETMASK, &osigset, NULL); continue; } - (void) gettimeofday(&now, (struct timezone *)NULL); + (void) gettimeofday(&now, NULL); sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); sigprocmask(SIG_BLOCK, &sigset, &osigset); diff --git a/sbin/routed/output.c b/sbin/routed/output.c index 576b7cfa6c41..5020d022084e 100644 --- a/sbin/routed/output.c +++ b/sbin/routed/output.c @@ -1,4 +1,4 @@ -/* $NetBSD: output.c,v 1.8 1995/03/18 15:00:35 cgd Exp $ */ +/* $NetBSD: output.c,v 1.9 1995/06/20 22:27:54 christos Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$NetBSD: output.c,v 1.8 1995/03/18 15:00:35 cgd Exp $"; +static char rcsid[] = "$NetBSD: output.c,v 1.9 1995/06/20 22:27:54 christos Exp $"; #endif #endif /* not lint */ @@ -54,7 +54,7 @@ static char rcsid[] = "$NetBSD: output.c,v 1.8 1995/03/18 15:00:35 cgd Exp $"; */ void toall(f, rtstate, skipif) - int (*f)(); + void (*f) __P((struct sockaddr *, int, struct interface *, int)); int rtstate; struct interface *skipif; { @@ -78,7 +78,7 @@ toall(f, rtstate, skipif) * Output a preformed packet. */ /*ARGSUSED*/ -int +void sndmsg(dst, flags, ifp, rtstate) struct sockaddr *dst; int flags; @@ -95,11 +95,11 @@ sndmsg(dst, flags, ifp, rtstate) * Supply dst with the contents of the routing tables. * If this won't fit in one packet, chop it up into several. */ -int +void supply(dst, flags, ifp, rtstate) struct sockaddr *dst; int flags; - register struct interface *ifp; + struct interface *ifp; int rtstate; { register struct rt_entry *rt; @@ -107,16 +107,18 @@ supply(dst, flags, ifp, rtstate) register struct rthash *rh; struct rthash *base = hosthash; int doinghost = 1, size; - int (*output)() = afswitch[dst->sa_family].af_output; - int (*sendroute)() = afswitch[dst->sa_family].af_sendroute; + void (*output) __P((int, int, struct sockaddr *, int)) = + afswitch[dst->sa_family].af_output; + int (*sendroute) __P((struct rt_entry *, struct sockaddr *)) = + afswitch[dst->sa_family].af_sendroute; int npackets = 0; msg->rip_cmd = RIPCMD_RESPONSE; - msg->rip_vers = RIPVERSION; + msg->rip_vers = RIP_VERSION_1; memset(msg->rip_res1, 0, sizeof(msg->rip_res1)); again: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) - for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { + for (rt = rh->cqh_first; rt != (void *) rh; rt = rt->rt_entry.cqe_next) { /* * Don't resend the information on the network * from which it was received (unless sending @@ -157,14 +159,7 @@ again: n = msg->rip_nets; npackets++; } - n->rip_dst = rt->rt_dst; -#if BSD < 198810 - if (sizeof(n->rip_dst.sa_family) > 1) /* XXX */ - n->rip_dst.sa_family = htons(n->rip_dst.sa_family); -#else -#define osa(x) ((struct osockaddr *)(&(x))) - osa(n->rip_dst)->sa_family = htons(n->rip_dst.sa_family); -#endif + (*afswitch[rt->rt_dst.sa_family].af_put)(n, &rt->rt_dst); n->rip_metric = htonl(rt->rt_metric); n++; } diff --git a/sbin/routed/query/query.c b/sbin/routed/query/query.c index af7399b39029..319e87abf55a 100644 --- a/sbin/routed/query/query.c +++ b/sbin/routed/query/query.c @@ -1,4 +1,4 @@ -/* $NetBSD: query.c,v 1.9 1995/05/21 14:22:25 mycroft Exp $ */ +/* $NetBSD: query.c,v 1.10 1995/06/20 22:28:08 christos Exp $ */ /*- * Copyright (c) 1982, 1986, 1993 @@ -43,7 +43,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)query.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$NetBSD: query.c,v 1.9 1995/05/21 14:22:25 mycroft Exp $"; +static char rcsid[] = "$NetBSD: query.c,v 1.10 1995/06/20 22:28:08 christos Exp $"; #endif #endif /* not lint */ @@ -171,7 +171,7 @@ query(host) } router.sin_port = sp->s_port; msg->rip_cmd = RIPCMD_REQUEST; - msg->rip_vers = RIPVERSION; + msg->rip_vers = RIP_VERSION_1; msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC); msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY); if (sendto(s, packet, sizeof (struct rip), 0, diff --git a/sbin/routed/startup.c b/sbin/routed/startup.c index 68c882e08f4d..6807a105f056 100644 --- a/sbin/routed/startup.c +++ b/sbin/routed/startup.c @@ -1,4 +1,4 @@ -/* $NetBSD: startup.c,v 1.13 1995/05/21 14:22:23 mycroft Exp $ */ +/* $NetBSD: startup.c,v 1.14 1995/06/20 22:27:56 christos Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -37,7 +37,8 @@ #if 0 static char sccsid[] = "@(#)startup.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$NetBSD: startup.c,v 1.13 1995/05/21 14:22:23 mycroft Exp $"; +/*###40 [cc] warning: `rcsid' defined but not used%%%*/ +static char rcsid[] = "$NetBSD: startup.c,v 1.14 1995/06/20 22:27:56 christos Exp $"; #endif #endif /* not lint */ @@ -120,7 +121,7 @@ ifinit() char *buf, *cplim, *cp; register struct if_msghdr *ifm; register struct ifa_msghdr *ifam; - struct sockaddr_dl *sdl; + struct sockaddr_dl *sdl = NULL; struct sockaddr_in *sin; u_long i; @@ -152,8 +153,10 @@ ifinit() } if (ifm->ifm_type != RTM_NEWADDR) quit("ifinit: out of sync"); - if ((flags & IFF_UP) == 0) + if ((flags & IFF_UP) == 0) { + lookforinterfaces = 1; continue; + } ifam = (struct ifa_msghdr *)ifm; info.rti_addrs = ifam->ifam_addrs; rt_xaddrs((char *)(ifam + 1), cp + ifam->ifam_msglen, &info); @@ -282,7 +285,9 @@ addrouteforif(ifp) struct sockaddr *dst; int state; register struct rt_entry *rt; + struct sockaddr mask; + memset(&mask, 0, sizeof(mask)); if (ifp->int_flags & IFF_POINTOPOINT) dst = &ifp->int_dstaddr; else { @@ -309,13 +314,13 @@ addrouteforif(ifp) net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY); rt = rtfind(dst); if (rt == 0) - rtadd(dst, &ifp->int_addr, ifp->int_metric, + rtadd(dst, &ifp->int_addr, &mask, ifp->int_metric, ((ifp->int_flags & (IFF_INTERFACE|IFF_REMOTE)) | RTS_PASSIVE | RTS_INTERNAL | RTS_SUBNET)); else if ((rt->rt_state & (RTS_INTERNAL|RTS_SUBNET)) == (RTS_INTERNAL|RTS_SUBNET) && ifp->int_metric < rt->rt_metric) - rtchange(rt, &rt->rt_router, ifp->int_metric); + rtchange(rt, &rt->rt_router, &mask, ifp->int_metric); net.sin_addr = subnet; } if (ifp->int_transitions++ > 0) @@ -328,7 +333,7 @@ addrouteforif(ifp) state &= ~RTS_SUBNET; if (ifp->int_flags & IFF_LOOPBACK) state |= RTS_EXTERNAL; - rtadd(dst, &ifp->int_addr, ifp->int_metric, state); + rtadd(dst, &ifp->int_addr, &mask, ifp->int_metric, state); if (ifp->int_flags & IFF_POINTOPOINT && foundloopback) add_ptopt_localrt(ifp); } @@ -346,7 +351,9 @@ add_ptopt_localrt(ifp) struct sockaddr *dst; struct sockaddr_in net; int state; + struct sockaddr mask; + memset(&mask, 0, sizeof(mask)); state = RTS_INTERFACE | RTS_PASSIVE; /* look for route to logical network */ @@ -359,12 +366,12 @@ add_ptopt_localrt(ifp) state |= RTS_SUBNET; dst = &ifp->int_addr; - if (rt = rtfind(dst)) { + if ((rt = rtfind(dst)) != NULL) { if (rt && rt->rt_state & RTS_INTERFACE) return; rtdelete(rt); } - rtadd(dst, &loopaddr, 1, state); + rtadd(dst, &loopaddr, &mask, 1, state); } /* @@ -391,6 +398,9 @@ gwkludge() struct interface *ifp; int metric, n; struct rt_entry route; + struct sockaddr mask; + memset(&mask, 0, sizeof(mask)); + fp = fopen(_PATH_GATEWAYS, "r"); if (fp == NULL) @@ -442,7 +452,7 @@ gwkludge() * with something else. */ rtadd((struct sockaddr *)&dst, - (struct sockaddr *)&gate, metric, + (struct sockaddr *)&gate, &mask, metric, RTS_EXTERNAL|RTS_PASSIVE); continue; } diff --git a/sbin/routed/table.h b/sbin/routed/table.h index 81b51c530eeb..2449ee73efb7 100644 --- a/sbin/routed/table.h +++ b/sbin/routed/table.h @@ -1,4 +1,4 @@ -/* $NetBSD: table.h,v 1.6 1995/03/18 15:00:42 cgd Exp $ */ +/* $NetBSD: table.h,v 1.7 1995/06/20 22:27:58 christos Exp $ */ /* * Copyright (c) 1983, 1993 @@ -38,30 +38,26 @@ /* * Routing table management daemon. */ - +#include /* * Routing table structure; differs a bit from kernel tables. * * Note: the union below must agree in the first 4 members * so the ioctl's will work. */ -struct rthash { - struct rt_entry *rt_forw; - struct rt_entry *rt_back; -}; #ifdef RTM_ADD #define rtentry ortentry #endif struct rt_entry { - struct rt_entry *rt_forw; - struct rt_entry *rt_back; + CIRCLEQ_ENTRY(rt_entry) rt_entry; union { struct rtentry rtu_rt; struct rtuentry { u_long rtu_hash; struct sockaddr rtu_dst; struct sockaddr rtu_router; + struct sockaddr rtu_netmask; short rtu_rtflags; /* used by rtioctl */ short rtu_wasted[5]; int rtu_flags; @@ -78,6 +74,7 @@ struct rt_entry { #define rt_hash rt_rtu.rtu_entry.rtu_hash /* for net or host */ #define rt_dst rt_rtu.rtu_entry.rtu_dst /* match value */ #define rt_router rt_rtu.rtu_entry.rtu_router /* who to forward to */ +#define rt_netmask rt_rtu.rtu_entry.rtu_netmask /* mask for the route */ #define rt_flags rt_rtu.rtu_entry.rtu_flags /* kernel flags */ #define rt_timer rt_rtu.rtu_entry.rtu_timer /* for invalidation */ #define rt_state rt_rtu.rtu_entry.rtu_state /* see below */ @@ -104,7 +101,20 @@ struct rt_entry { */ #define RTF_SUBNET 0x80000 /* pseudo: route to subnet */ +CIRCLEQ_HEAD(rthash, rt_entry); + struct rthash nethash[ROUTEHASHSIZ]; struct rthash hosthash[ROUTEHASHSIZ]; -struct rt_entry *rtlookup(); -struct rt_entry *rtfind(); + +struct rt_entry *rtlookup __P((struct sockaddr *)); +struct rt_entry *rtfind __P((struct sockaddr *)); +struct rthash *rthead __P((struct sockaddr *, u_int *, int *)); +void rtadd __P((struct sockaddr *, struct sockaddr *, struct sockaddr *, + int, int )); +void rtchange __P((struct rt_entry *, struct sockaddr *, struct sockaddr *, + int)); +void rtdelete __P((struct rt_entry *)); +void rtdeleteall __P((int)); +void rtdefault __P((void)); +void rtinit __P((void)); +int rtioctl __P((int, struct rtuentry *)); diff --git a/sbin/routed/tables.c b/sbin/routed/tables.c index a7f64682558c..902b76b06987 100644 --- a/sbin/routed/tables.c +++ b/sbin/routed/tables.c @@ -1,4 +1,4 @@ -/* $NetBSD: tables.c,v 1.14 1995/05/28 05:37:36 jtc Exp $ */ +/* $NetBSD: tables.c,v 1.15 1995/06/20 22:27:59 christos Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$NetBSD: tables.c,v 1.14 1995/05/28 05:37:36 jtc Exp $"; +static char rcsid[] = "$NetBSD: tables.c,v 1.15 1995/06/20 22:27:59 christos Exp $"; #endif #endif /* not lint */ @@ -81,7 +81,7 @@ rtlookup(dst) hash = h.afh_hosthash; rh = &hosthash[hash & ROUTEHASHMASK]; again: - for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { + for (rt = rh->cqh_first; rt != (void *)rh; rt = rt->rt_entry.cqe_next) { if (rt->rt_hash != hash) continue; if (equal(&rt->rt_dst, dst)) @@ -110,7 +110,8 @@ rtfind(dst) register u_int hash; struct afhash h; int af = dst->sa_family; - int doinghost = 1, (*match)(); + int doinghost = 1, + (*match) __P((struct sockaddr *, struct sockaddr *)) = NULL; if (af >= af_max) return (0); @@ -119,14 +120,14 @@ rtfind(dst) rh = &hosthash[hash & ROUTEHASHMASK]; again: - for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { + for (rt = rh->cqh_first; rt != (void *)rh; rt = rt->rt_entry.cqe_next) { if (rt->rt_hash != hash) continue; if (doinghost) { if (equal(&rt->rt_dst, dst)) return (rt); } else { - if (rt->rt_dst.sa_family == af && + if (rt->rt_dst.sa_family == af && match && (*match)(&rt->rt_dst, dst)) return (rt); } @@ -150,44 +151,67 @@ again: return (0); } -void -rtadd(dst, gate, metric, state) - struct sockaddr *dst, *gate; - int metric, state; +struct rthash * +rthead(dst, hashp, flagsp) + struct sockaddr *dst; + u_int *hashp; + int *flagsp; { struct afhash h; + int af = dst->sa_family; + + if (af >= af_max) + return NULL; + + (*afswitch[af].af_hash)(dst, &h); + + *flagsp = (*afswitch[af].af_rtflags)(dst); + + if (*flagsp & RTF_HOST) { + *hashp = h.afh_hosthash; + return &hosthash[*hashp & ROUTEHASHMASK]; + } else { + *hashp = h.afh_nethash; + return &nethash[*hashp & ROUTEHASHMASK]; + } +} + +void +rtadd(dst, gate, netmask, metric, state) + struct sockaddr *dst, *gate, *netmask; + int metric, state; +{ register struct rt_entry *rt; struct rthash *rh; - int af = dst->sa_family, flags; + int flags; u_int hash; char buf1[256], buf2[256]; - if (af >= af_max) - return; - (*afswitch[af].af_hash)(dst, &h); - flags = (*afswitch[af].af_rtflags)(dst); /* * Subnet flag isn't visible to kernel, move to state. XXX */ FIXLEN(dst); FIXLEN(gate); + + rh = rthead(dst, &hash, &flags); + + if (rh == NULL) { + syslog(LOG_ERR, "rtadd: Internal error finding route\n"); + return; + } + if (flags & RTF_SUBNET) { state |= RTS_SUBNET; flags &= ~RTF_SUBNET; } - if (flags & RTF_HOST) { - hash = h.afh_hosthash; - rh = &hosthash[hash & ROUTEHASHMASK]; - } else { - hash = h.afh_nethash; - rh = &nethash[hash & ROUTEHASHMASK]; - } + rt = (struct rt_entry *)malloc(sizeof (*rt)); if (rt == 0) return; rt->rt_hash = hash; rt->rt_dst = *dst; rt->rt_router = *gate; + rt->rt_netmask = *netmask; rt->rt_timer = 0; rt->rt_flags = RTF_UP | flags; rt->rt_state = state | RTS_CHANGED; @@ -197,7 +221,7 @@ rtadd(dst, gate, metric, state) if ((state & RTS_INTERFACE) == 0) rt->rt_flags |= RTF_GATEWAY; rt->rt_metric = metric; - insque(rt, rh); + CIRCLEQ_INSERT_HEAD(rh, rt, rt_entry); TRACE_ACTION("ADD", rt); /* * If the ioctl fails because the gateway is unreachable @@ -216,22 +240,24 @@ rtadd(dst, gate, metric, state) perror("ADD ROUTE"); if (errno == ENETUNREACH) { TRACE_ACTION("DELETE", rt); - remque(rt); + CIRCLEQ_REMOVE(rh, rt, rt_entry); free((char *)rt); } } } void -rtchange(rt, gate, metric) +rtchange(rt, gate, netmask, metric) struct rt_entry *rt; struct sockaddr *gate; + struct sockaddr *netmask; short metric; { int add = 0, delete = 0, newgateway = 0; struct rtuentry oldroute; FIXLEN(gate); + FIXLEN(netmask); FIXLEN(&(rt->rt_router)); FIXLEN(&(rt->rt_dst)); if (!equal(&rt->rt_router, gate)) { @@ -272,6 +298,7 @@ rtchange(rt, gate, metric) if (rt->rt_ifp == 0) rt->rt_ifp = if_ifwithnet(&rt->rt_router); } + rt->rt_netmask = *netmask; rt->rt_metric = metric; rt->rt_state |= RTS_CHANGED; if (newgateway) @@ -299,6 +326,14 @@ void rtdelete(rt) struct rt_entry *rt; { + u_int hash; + int flags; + struct rthash *rh = rthead(&rt->rt_dst, &hash, &flags); + + if (rh == NULL) { + syslog(LOG_ERR, "rtdelete: Internal error finding route\n"); + return; + } TRACE_ACTION("DELETE", rt); FIXLEN(&(rt->rt_router)); @@ -312,7 +347,7 @@ rtdelete(rt) rtioctl(DELETE, &rt->rt_rt) < 0) perror("rtdelete"); } - remque(rt); + CIRCLEQ_REMOVE(rh, rt, rt_entry); free((char *)rt); } @@ -327,8 +362,8 @@ rtdeleteall(sig) again: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { - rt = rh->rt_forw; - for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { + rt = rh->cqh_first; + for (; rt != (void *)rh; rt = rt->rt_entry.cqe_next) { if (rt->rt_state & RTS_INTERFACE || rt->rt_metric >= HOPCNT_INFINITY) continue; @@ -358,7 +393,7 @@ rtdefault() { extern struct sockaddr inet_default; - rtadd(&inet_default, &inet_default, 1, + rtadd(&inet_default, &inet_default, &inet_default, 1, RTS_CHANGED | RTS_PASSIVE | RTS_INTERNAL); } @@ -368,9 +403,9 @@ rtinit() register struct rthash *rh; for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) - rh->rt_forw = rh->rt_back = (struct rt_entry *)rh; + CIRCLEQ_INIT(rh); for (rh = hosthash; rh < &hosthash[ROUTEHASHSIZ]; rh++) - rh->rt_forw = rh->rt_back = (struct rt_entry *)rh; + CIRCLEQ_INIT(rh); } int @@ -413,6 +448,7 @@ rtioctl(action, ort) rtm.rtm_addrs = RTA_DST|RTA_GATEWAY; memcpy(&w.w_dst, &ort->rtu_dst, sizeof(w.w_dst)); memcpy(&w.w_gate, &ort->rtu_router, sizeof(w.w_gate)); + memcpy(&w.w_netmask, &ort->rtu_netmask, sizeof(w.w_netmask)); w.w_dst.sin_family = AF_INET; w.w_dst.sin_len = sizeof(w.w_dst); w.w_gate.sa_family = AF_INET; @@ -424,8 +460,16 @@ rtioctl(action, ort) int len; rtm.rtm_addrs |= RTA_NETMASK; - w.w_netmask.sin_addr.s_addr = - inet_maskof(w.w_dst.sin_addr.s_addr); + /* + * Check if we had a version 2 rip packet that sets the + * netmask, and otherwise set it to the default for + * the destination of the interface. + */ + if (w.w_netmask.sin_family == AF_UNSPEC) { + w.w_netmask.sin_addr.s_addr = + inet_maskof(w.w_dst.sin_addr.s_addr); + } + for (cp = (char *)(1 + &w.w_netmask.sin_addr); --cp > (char *) &w.w_netmask; ) if (*cp) @@ -439,6 +483,12 @@ rtioctl(action, ort) len = sizeof(long); rtm.rtm_msglen -= (sizeof(w.w_netmask) - len); } +#if 0 + fprintf(stderr, "%s ", action == ADD ? "add" : (action == DELETE ? "delete" : "change")); + fprintf(stderr, "dst = %s, ", inet_ntoa(w.w_dst.sin_addr)); + fprintf(stderr, "gate = %s, ", inet_ntoa(((struct sockaddr_in *) &w.w_gate)->sin_addr)); + fprintf(stderr, "mask = %s\n", inet_ntoa(w.w_netmask.sin_addr)); +#endif errno = 0; return (install ? write(r, (char *)&w, rtm.rtm_msglen) : (errno = 0)); #endif /* RTM_ADD */ diff --git a/sbin/routed/timer.c b/sbin/routed/timer.c index 69a17dad6dd2..4bd6fa8955cf 100644 --- a/sbin/routed/timer.c +++ b/sbin/routed/timer.c @@ -1,4 +1,4 @@ -/* $NetBSD: timer.c,v 1.7 1995/03/18 15:00:45 cgd Exp $ */ +/* $NetBSD: timer.c,v 1.8 1995/06/20 22:28:02 christos Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)timer.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$NetBSD: timer.c,v 1.7 1995/03/18 15:00:45 cgd Exp $"; +static char rcsid[] = "$NetBSD: timer.c,v 1.8 1995/06/20 22:28:02 christos Exp $"; #endif #endif /* not lint */ @@ -55,22 +55,23 @@ int faketime; * each time called. */ void -timer() +timer(sig) + int sig; { register struct rthash *rh; register struct rt_entry *rt; struct rthash *base = hosthash; int doinghost = 1, timetobroadcast; - (void) gettimeofday(&now, (struct timezone *)NULL); + (void) gettimeofday(&now, NULL); faketime += TIMER_RATE; if (lookforinterfaces && (faketime % CHECK_INTERVAL) == 0) ifinit(); timetobroadcast = supplier && (faketime % SUPPLY_INTERVAL) == 0; again: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { - rt = rh->rt_forw; - for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { + rt = rh->cqh_first; + for (; rt != (void *)rh; rt = rt->rt_entry.cqe_next) { /* * We don't advance time on a routing entry for * a passive gateway, or any interface if we're @@ -80,13 +81,14 @@ again: (supplier || !(rt->rt_state & RTS_INTERFACE))) rt->rt_timer += TIMER_RATE; if (rt->rt_timer >= GARBAGE_TIME) { - rt = rt->rt_back; - rtdelete(rt->rt_forw); + rt = rt->rt_entry.cqe_prev; + rtdelete(rt->rt_entry.cqe_next); continue; } if (rt->rt_timer >= EXPIRE_TIME && rt->rt_metric < HOPCNT_INFINITY) - rtchange(rt, &rt->rt_router, HOPCNT_INFINITY); + rtchange(rt, &rt->rt_router, + &rt->rt_netmask, HOPCNT_INFINITY); rt->rt_state &= ~RTS_CHANGED; } } @@ -96,7 +98,7 @@ again: goto again; } if (timetobroadcast) { - toall(supply, 0, (struct interface *)NULL); + toall(supply, 0, NULL); lastbcast = now; lastfullupdate = now; needupdate = 0; /* cancel any pending dynamic update */ @@ -108,7 +110,8 @@ again: * On hangup, let everyone know we're going away. */ void -hup() +hup(sig) + int sig; { register struct rthash *rh; register struct rt_entry *rt; @@ -118,8 +121,8 @@ hup() if (supplier) { again: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { - rt = rh->rt_forw; - for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) + rt = rh->cqh_first; + for (; rt != (void *)rh; rt = rt->rt_entry.cqe_next) rt->rt_metric = HOPCNT_INFINITY; } if (doinghost) { @@ -127,7 +130,7 @@ again: base = nethash; goto again; } - toall(supply, 0, (struct interface *)NULL); + toall(supply, 0, NULL); } exit(1); } diff --git a/sbin/routed/trace.c b/sbin/routed/trace.c index 86a20ae5c2d6..a712a70f344a 100644 --- a/sbin/routed/trace.c +++ b/sbin/routed/trace.c @@ -1,4 +1,4 @@ -/* $NetBSD: trace.c,v 1.12 1995/05/28 05:37:38 jtc Exp $ */ +/* $NetBSD: trace.c,v 1.13 1995/06/20 22:28:03 christos Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)trace.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$NetBSD: trace.c,v 1.12 1995/05/28 05:37:38 jtc Exp $"; +static char rcsid[] = "$NetBSD: trace.c,v 1.13 1995/06/20 22:28:03 christos Exp $"; #endif #endif /* not lint */ @@ -67,8 +67,6 @@ void traceinit(ifp) register struct interface *ifp; { - static int iftraceinit(); - if (iftraceinit(ifp, &ifp->int_input) && iftraceinit(ifp, &ifp->int_output)) return; @@ -108,7 +106,7 @@ traceon(file) if (stat(file, &stbuf) >= 0 && !S_ISREG(stbuf.st_mode)) return; savetracename = file; - (void) gettimeofday(&now, (struct timezone *)NULL); + (void) gettimeofday(&now, NULL); ftrace = fopen(file, "a"); if (ftrace == NULL) return; @@ -166,7 +164,7 @@ void bumploglevel() { - (void) gettimeofday(&now, (struct timezone *)NULL); + (void) gettimeofday(&now, NULL); if (traceactions == 0) { traceactions++; if (ftrace) @@ -235,7 +233,7 @@ traceaction(fd, action, rt) char *action; struct rt_entry *rt; { - struct sockaddr_in *dst, *gate; + struct sockaddr_in *dst, *gate, *netmask; static struct bits { int t_bits; char *t_name; @@ -267,9 +265,11 @@ traceaction(fd, action, rt) fprintf(fd, "%s ", action); dst = (struct sockaddr_in *)&rt->rt_dst; gate = (struct sockaddr_in *)&rt->rt_router; + netmask = (struct sockaddr_in *)&rt->rt_netmask; fprintf(fd, "dst %s, ", inet_ntoa(dst->sin_addr)); - fprintf(fd, "router %s, metric %d, flags", - inet_ntoa(gate->sin_addr), rt->rt_metric); + fprintf(fd, "router %s, ", inet_ntoa(gate->sin_addr)); + fprintf(fd, " netmask %s, metric %d, flags", + inet_ntoa(netmask->sin_addr), rt->rt_metric); cp = " %s"; for (first = 1, p = flagbits; p->t_bits > 0; p++) { if ((rt->rt_flags & p->t_bits) == 0) @@ -387,10 +387,11 @@ dumppacket(fd, dir, who, cp, size, stamp) dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port), ctime((time_t *)&stamp->tv_sec)); else { - fprintf(fd, "Bad cmd 0x%x %s %x.%d %.19s\n", msg->rip_cmd, + fprintf(fd, "Bad cmd 0x%x %s %s.%d %.19s\n", msg->rip_cmd, dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port), ctime((time_t *)&stamp->tv_sec)); - fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet); + fprintf(fd, "size=%d cp=%lx packet=%lx\n", size, + (u_long) cp, (u_long) packet); fflush(fd); return; } @@ -410,24 +411,30 @@ dumppacket(fd, dir, who, cp, size, stamp) size); break; } - if (sizeof(n->rip_dst.sa_family) > 1) - n->rip_dst.sa_family = ntohs(n->rip_dst.sa_family); - - switch ((int)n->rip_dst.sa_family) { + switch (n->rip_family) { case AF_INET: - fprintf(fd, "\tdst %s metric %d\n", -#define satosin(sa) ((struct sockaddr_in *)&sa) - inet_ntoa(satosin(n->rip_dst)->sin_addr), - ntohl(n->rip_metric)); + { + struct sockaddr_in sa; + sa.sin_addr.s_addr = n->rip_dst; + fprintf(fd, "\tdst %s", + inet_ntoa(sa.sin_addr)); + if (msg->rip_vers > RIP_VERSION_1) { + fprintf(fd, ", mask 0x%.8x", + n->rip_netmask); + sa.sin_addr.s_addr = + n->rip_router; + fprintf(fd, ", router %s", + inet_ntoa(sa.sin_addr)); + } + } break; default: - fprintf(fd, "\taf %d? metric %d\n", - n->rip_dst.sa_family, - ntohl(n->rip_metric)); + fprintf(fd, "\taf %d?", n->rip_family); break; } + fprintf(fd, ", metric %d\n", ntohl(n->rip_metric)); } break; diff --git a/sbin/routed/trace.h b/sbin/routed/trace.h index 960862bc2d8e..2485a17e7f4a 100644 --- a/sbin/routed/trace.h +++ b/sbin/routed/trace.h @@ -1,4 +1,4 @@ -/* $NetBSD: trace.h,v 1.7 1995/04/24 13:24:35 cgd Exp $ */ +/* $NetBSD: trace.h,v 1.8 1995/06/20 22:28:04 christos Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -98,3 +98,17 @@ FILE *ftrace; /* output trace file */ dumppacket(ftrace, "to", (struct sockaddr_in *)dst, packet, \ size, &now); \ } + +/* trace.c */ +void traceinit __P((struct interface *)); +void traceon __P((char *)); +void traceoff __P((void)); +void sigtrace __P((int)); +void bumploglevel __P((void)); +void trace __P((struct ifdebug *, struct sockaddr *, char *, int, int )); +void traceaction __P((FILE *, char *, struct rt_entry *)); +void tracenewmetric __P((FILE *, struct rt_entry *, int)); +void dumpif __P((FILE *, struct interface *)); +void dumptrace __P((FILE *, char *, struct ifdebug *)); +void dumppacket __P((FILE *, char *, struct sockaddr_in *, char *, int, struct timeval *)); + diff --git a/sbin/routed/trace/trace.c b/sbin/routed/trace/trace.c index 651b65665b17..914b248121af 100644 --- a/sbin/routed/trace/trace.c +++ b/sbin/routed/trace/trace.c @@ -1,4 +1,4 @@ -/* $NetBSD: trace.c,v 1.8 1995/05/21 14:22:27 mycroft Exp $ */ +/* $NetBSD: trace.c,v 1.9 1995/06/20 22:28:11 christos Exp $ */ /*- * Copyright (c) 1983, 1988, 1993 @@ -43,7 +43,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)trace.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$NetBSD: trace.c,v 1.8 1995/05/21 14:22:27 mycroft Exp $"; +static char rcsid[] = "$NetBSD: trace.c,v 1.9 1995/06/20 22:28:11 christos Exp $"; #endif #endif /* not lint */ @@ -93,7 +93,7 @@ usage: argv++, argc--; msg->rip_cmd = strcmp(*argv, "on") == 0 ? RIPCMD_TRACEON : RIPCMD_TRACEOFF; - msg->rip_vers = RIPVERSION; + msg->rip_vers = RIP_VERSION_1; argv++, argc--; size = sizeof (int); if (msg->rip_cmd == RIPCMD_TRACEON) {