diff options
-rw-r--r-- | usr.sbin/IPXrouted/af.c | 30 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/defs.h | 10 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/if.c | 4 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/input.c | 49 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/main.c | 44 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/output.c | 31 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/sap.h | 15 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/sap_input.c | 53 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/sap_output.c | 18 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/sap_tables.c | 42 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/table.h | 5 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/tables.c | 79 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/timer.c | 61 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/trace.c | 83 | ||||
-rw-r--r-- | usr.sbin/IPXrouted/trace.h | 8 |
15 files changed, 355 insertions, 177 deletions
diff --git a/usr.sbin/IPXrouted/af.c b/usr.sbin/IPXrouted/af.c index 0936b43..05034ab 100644 --- a/usr.sbin/IPXrouted/af.c +++ b/usr.sbin/IPXrouted/af.c @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: af.c,v 1.4 1997/02/22 16:00:54 peter Exp $ */ #ifndef lint @@ -93,14 +93,32 @@ ipxnet_hash(sipx, hp) register struct sockaddr_ipx *sipx; struct afhash *hp; { - register long hash = 0; - register u_short *s = sipx->sipx_addr.x_host.s_host; - union ipx_net_u net; + long hash; +#if 0 + u_short *s = sipx->sipx_addr.x_host.s_host; +#endif + u_char *c; + + c = sipx->sipx_addr.x_net.c_net; - net.net_e = sipx->sipx_addr.x_net; - hp->afh_nethash = net.long_e; +#define IMVAL 33 + hash = 0; + hash = hash * IMVAL + *c++; + hash = hash * IMVAL + *c++; + hash = hash * IMVAL + *c++; + hash = hash * IMVAL + *c++; +#undef IMVAL + + hp->afh_nethash = hash; + hp->afh_nethash ^= (hash >> 8); + hp->afh_nethash ^= (hash >> 16); + hp->afh_nethash ^= (hash >> 24); + +#if 0 + hash = 0; hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s; hp->afh_hosthash = hash; +#endif } int diff --git a/usr.sbin/IPXrouted/defs.h b/usr.sbin/IPXrouted/defs.h index a295028..55e08b3 100644 --- a/usr.sbin/IPXrouted/defs.h +++ b/usr.sbin/IPXrouted/defs.h @@ -34,7 +34,7 @@ * * @(#)defs.h 8.1 (Berkeley) 6/5/93 * - * $Id$ + * $Id: defs.h,v 1.5 1997/02/22 16:00:55 peter Exp $ */ #include <sys/types.h> @@ -96,11 +96,11 @@ extern char **argv0; #define DELETE 2 #define CHANGE 3 -void sndmsg(struct sockaddr *, int, struct interface *); -void supply(struct sockaddr *, int, struct interface *); +void sndmsg(struct sockaddr *, int, struct interface *, int); +void supply(struct sockaddr *, int, struct interface *, int); void addrouteforif(struct interface *); void ifinit(void); -void toall(void (*f)(struct sockaddr *, int, struct interface *), - struct rt_entry *); +void toall(void (*f)(struct sockaddr *, int, struct interface *, int), + struct rt_entry *, int); void rip_input(struct sockaddr *, int); diff --git a/usr.sbin/IPXrouted/if.c b/usr.sbin/IPXrouted/if.c index e8aeaa6..c2522a9 100644 --- a/usr.sbin/IPXrouted/if.c +++ b/usr.sbin/IPXrouted/if.c @@ -34,7 +34,7 @@ * * static char sccsid[] = "@(#)if.c 5.1 (Berkeley) 6/4/85"; (routed/if.c) * - * $Id$ + * $Id: if.c,v 1.3 1997/02/22 16:00:55 peter Exp $ */ #ifndef lint @@ -58,7 +58,7 @@ if_ifwithaddr(addr) register struct interface *ifp; #define same(a1, a2) \ - (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0) + (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 10) == 0) for (ifp = ifnet; ifp; ifp = ifp->int_next) { if (ifp->int_flags & IFF_REMOTE) continue; diff --git a/usr.sbin/IPXrouted/input.c b/usr.sbin/IPXrouted/input.c index cf54e89..a9e2f39 100644 --- a/usr.sbin/IPXrouted/input.c +++ b/usr.sbin/IPXrouted/input.c @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: input.c,v 1.5 1997/02/22 16:00:56 peter Exp $ */ #ifndef lint @@ -69,10 +69,11 @@ rip_input(from, size) struct sockaddr *from; int size; { + int newsize; + int rtchanged = 0; struct rt_entry *rt; struct netinfo *n; struct interface *ifp = 0; - int newsize; struct afswitch *afp; struct sockaddr_ipx *ipxp; @@ -116,7 +117,7 @@ rip_input(from, size) if (ipx_neteqnn(n->rip_dst, ipx_anynet) && ntohs(n->rip_metric) == HOPCNT_INFINITY && size == 0) { - supply(from, 0, ifp); + supply(from, 0, ifp, 0); return; } /* @@ -195,9 +196,10 @@ rip_input(from, size) /* are we talking to ourselves? */ if ((ifp = if_ifwithaddr(from)) != 0) { rt = rtfind(from); - if (rt == 0 || (rt->rt_state & RTS_INTERFACE) == 0) + if (rt == 0 || (rt->rt_state & RTS_INTERFACE) == 0) { addrouteforif(ifp); - else + rtchanged = 1; + } else rt->rt_timer = 0; return; } @@ -211,17 +213,21 @@ rip_input(from, size) } else if ((ifp = if_ifwithdstaddr(from)) != 0) { if(ftrace) fprintf(ftrace, "Got partner\n"); addrouteforif(ifp); + rtchanged = 1; } for (; size > 0; size -= sizeof (struct netinfo), n++) { struct sockaddr *sa; if (size < sizeof (struct netinfo)) break; - if ((unsigned) ntohs(n->rip_metric) >= HOPCNT_INFINITY) + if ((unsigned) ntohs(n->rip_metric) > HOPCNT_INFINITY) continue; rt = rtfind(sa = ipx_nettosa(n->rip_dst)); if (rt == 0) { + if (ntohs(n->rip_metric) == HOPCNT_INFINITY) + continue; rtadd(sa, from, ntohs(n->rip_metric), ntohs(n->rip_ticks), 0); + rtchanged = 1; continue; } @@ -237,12 +243,11 @@ rip_input(from, size) * from anywhere and less ticks or * if same ticks and shorter, * or getting stale and equivalent. - * - * XXX I don't think this is quite right. */ if (!equal(from, &rt->rt_router) && - ntohs(n->rip_ticks == rt->rt_ticks) && - ntohs(n->rip_metric == rt->rt_metric)) { + ntohs(n->rip_ticks) == rt->rt_ticks && + ntohs(n->rip_metric) == rt->rt_metric && + ntohs(n->rip_metric) != HOPCNT_INFINITY) { register struct rt_entry *trt = rt->rt_clone; while (trt) { @@ -266,16 +271,34 @@ rip_input(from, size) ((ntohs(n->rip_ticks) == rt->rt_ticks) && (ntohs(n->rip_metric) < rt->rt_metric)) || (rt->rt_timer > (EXPIRE_TIME*2/3) && - rt->rt_metric == ntohs(n->rip_metric))) { + rt->rt_metric == ntohs(n->rip_metric) && + ntohs(n->rip_metric) != HOPCNT_INFINITY)) { rtchange(rt, from, ntohs(n->rip_metric), ntohs(n->rip_ticks)); - rt->rt_timer = 0; + if (ntohs(n->rip_metric) == HOPCNT_INFINITY) + rt->rt_timer = EXPIRE_TIME; + else + rt->rt_timer = 0; + rtchanged = 1; } else if (equal(from, &rt->rt_router) && (ntohs(n->rip_ticks) == rt->rt_ticks) && - (ntohs(n->rip_metric) == rt->rt_metric)) { + (ntohs(n->rip_metric) == rt->rt_metric) && + (ntohs(n->rip_metric) != HOPCNT_INFINITY)) { rt->rt_timer = 0; } } + if (rtchanged) { + register struct rthash *rh; + register struct rt_entry *rt; + + toall(supply, NULL, 1); + for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) + for (rt = rh->rt_forw; + rt != (struct rt_entry *)rh; + rt = rt->rt_forw) + rt->rt_state &= ~RTS_CHANGED; + } + return; } } diff --git a/usr.sbin/IPXrouted/main.c b/usr.sbin/IPXrouted/main.c index a441371..9af5b2e 100644 --- a/usr.sbin/IPXrouted/main.c +++ b/usr.sbin/IPXrouted/main.c @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: main.c,v 1.6 1997/02/22 16:00:57 peter Exp $ */ #ifndef lint @@ -85,6 +85,8 @@ char **argv0; int supplier = -1; /* process should supply updates */ int dosap = 1; /* By default do SAP services. */ +int dobcast = 1; /* A RIP/SAP broadcast is needed. */ +time_t lastbcast; /* Time of last RIP/SAP broadcast */ struct rip *msg = (struct rip *) &packet[sizeof (struct ipx)]; struct sap_packet *sap_msg = @@ -93,6 +95,7 @@ void hup(), fkexit(), timer(); void process(int fd, int pkt_type); int getsocket(int type, int proto, struct sockaddr_ipx *sipx); void getinfo(); +void catchtimer(); int main(argc, argv) @@ -101,6 +104,8 @@ main(argc, argv) { int nfds; fd_set fdvar; + time_t ttime; + struct itimerval tval; argv0 = argv; argv++, argc--; @@ -203,24 +208,35 @@ main(argc, argv) msg->rip_nets[0].rip_dst = ipx_anynet; msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); msg->rip_nets[0].rip_ticks = htons(-1); - toall(sndmsg, NULL); + toall(sndmsg, NULL, 0); if (dosap) { sap_msg->sap_cmd = htons(SAP_REQ); sap_msg->sap[0].ServType = htons(SAP_WILDCARD); - toall(sapsndmsg, NULL); + toall(sapsndmsg, NULL, 0); } - signal(SIGALRM, timer); + signal(SIGALRM, catchtimer); signal(SIGHUP, hup); signal(SIGINT, hup); signal(SIGEMT, fkexit); signal(SIGINFO, getinfo); - timer(); - + + tval.it_interval.tv_sec = TIMER_RATE; + tval.it_interval.tv_usec = 0; + tval.it_value.tv_sec = TIMER_RATE; + tval.it_value.tv_usec = 0; + setitimer(ITIMER_REAL, &tval, NULL); + nfds = 1 + max(sapsock, ripsock); for (;;) { + if (dobcast) { + dobcast = 0; + lastbcast = time(NULL); + timer(); + } + FD_ZERO(&fdvar); if (dosap) { FD_SET(sapsock, &fdvar); @@ -240,6 +256,12 @@ main(argc, argv) if(dosap && FD_ISSET(sapsock, &fdvar)) process(sapsock, SAP_PKT); + + ttime = time(NULL); + if (ttime > (lastbcast + TIMER_RATE + (TIMER_RATE * 2 / 3))) { + dobcast = 1; + syslog(LOG_ERR, "Missed alarm"); + } } } @@ -319,7 +341,11 @@ getsocket(type, proto, sipx) if (ntohs(sipx->sipx_addr.x_port) == IPXPORT_RIP) ipxdp.ipx_pt = IPXPROTO_RI; else if (ntohs(sipx->sipx_addr.x_port) == IPXPORT_SAP) +#ifdef IPXPROTO_SAP ipxdp.ipx_pt = IPXPROTO_SAP; +#else + ipxdp.ipx_pt = IPXPROTO_PXP; +#endif else { syslog(LOG_ERR, "port should be either RIP or SAP"); exit(1); @@ -347,6 +373,12 @@ fkexit() } void +catchtimer() +{ + dobcast = 1; +} + +void getinfo() { FILE *fh; diff --git a/usr.sbin/IPXrouted/output.c b/usr.sbin/IPXrouted/output.c index 06b9a16..f824ecd 100644 --- a/usr.sbin/IPXrouted/output.c +++ b/usr.sbin/IPXrouted/output.c @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: output.c,v 1.6 1997/02/22 16:00:58 peter Exp $ */ #ifndef lint @@ -55,9 +55,10 @@ static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 6/5/93"; * the output to the known router. */ void -toall(f, except) - void (*f)(struct sockaddr *, int, struct interface *); +toall(f, except, changesonly) + void (*f)(struct sockaddr *, int, struct interface *, int); struct rt_entry *except; + int changesonly; { register struct interface *ifp; register struct sockaddr *dst; @@ -89,7 +90,7 @@ toall(f, except) ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr : &ifp->int_addr; flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0; - (*f)(dst, flags, ifp); + (*f)(dst, flags, ifp, changesonly); } } @@ -97,10 +98,11 @@ toall(f, except) * Output a preformed packet. */ void -sndmsg(dst, flags, ifp) +sndmsg(dst, flags, ifp, changesonly) struct sockaddr *dst; int flags; struct interface *ifp; + int changesonly; { (*afswitch[dst->sa_family].af_output) @@ -120,20 +122,20 @@ sndmsg(dst, flags, ifp) * clones. */ void -supply(dst, flags, ifp) +supply(dst, flags, ifp, changesonly) struct sockaddr *dst; int flags; struct interface *ifp; + int changesonly; { register struct rt_entry *rt; register struct rt_entry *crt; /* Clone route */ register struct rthash *rh; register struct netinfo *nn; register struct netinfo *n = msg->rip_nets; - struct rthash *base = hosthash; struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) dst; af_output_t *output = afswitch[dst->sa_family].af_output; - int doinghost = 1, size, metric, ticks; + int size, metric, ticks; union ipx_net net; int delay = 0; @@ -141,8 +143,7 @@ supply(dst, flags, ifp) sipx->sipx_port = htons(IPXPORT_RIP); msg->rip_cmd = ntohs(RIPCMD_RESPONSE); -again: - for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) + for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { size = (char *)n - (char *)msg; if (size >= ((MAXRIPNETS * sizeof (struct netinfo)) + @@ -152,11 +153,14 @@ again: n = msg->rip_nets; delay++; if(delay == 2) { - usleep(20000); + usleep(50000); delay = 0; } } + if (changesonly && !(rt->rt_state & RTS_CHANGED)) + continue; + /* * This should do rule one and two of the split horizon * algorithm. @@ -219,11 +223,6 @@ again: n++; next:; } - if (doinghost) { - doinghost = 0; - base = nethash; - goto again; - } if (n != msg->rip_nets) { size = (char *)n - (char *)msg; (*output)(ripsock, flags, dst, size); diff --git a/usr.sbin/IPXrouted/sap.h b/usr.sbin/IPXrouted/sap.h index f5780d6..5473851 100644 --- a/usr.sbin/IPXrouted/sap.h +++ b/usr.sbin/IPXrouted/sap.h @@ -28,13 +28,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: sap.h,v 1.5 1997/02/22 16:00:59 peter Exp $ */ #ifndef _SAP_H_ #define _SAP_H_ -#define IPXPROTO_SAP IPXPROTO_PXP - #define SAP_REQ 1 #define SAP_RESP 2 #define SAP_REQ_NEAR 3 @@ -71,10 +69,9 @@ typedef struct sap_entry { int hash; int state; int timer; - int metric; }sap_entry; -#define SAPHASHSIZ 32 /* Should be a power of 2 */ +#define SAPHASHSIZ 256 /* Should be a power of 2 */ #define SAPHASHMASK (SAPHASHSIZ-1) typedef struct sap_hash { struct sap_entry *forw; @@ -87,12 +84,14 @@ extern struct sap_packet *sap_msg; void sapinit(void); void sap_input(struct sockaddr *from, int size); -void sapsndmsg(struct sockaddr *dst, int flags, struct interface *ifp); -void sap_supply_toall(void); +void sapsndmsg(struct sockaddr *dst, int flags, struct interface *ifp, + int changesonly); +void sap_supply_toall(int changesonly); void sap_supply(struct sockaddr *dst, int flags, struct interface *ifp, - int ServType); + int ServType, + int changesonly); struct sap_entry *sap_lookup(u_short ServType, char *ServName); struct sap_entry *sap_nearestserver(ushort ServType, struct interface *ifp); diff --git a/usr.sbin/IPXrouted/sap_input.c b/usr.sbin/IPXrouted/sap_input.c index c55d82f..26130fe 100644 --- a/usr.sbin/IPXrouted/sap_input.c +++ b/usr.sbin/IPXrouted/sap_input.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: sap_input.c,v 1.4 1997/02/22 16:00:59 peter Exp $ */ /* @@ -45,10 +45,11 @@ sap_input(from, size) struct sockaddr *from; int size; { + int newsize; + int sapchanged = 0; struct sap_entry *sap; struct sap_info *n; struct interface *ifp = 0; - int newsize; struct afswitch *afp; struct sockaddr_ipx *ipxp; @@ -106,7 +107,7 @@ sap_input(from, size) if (ftrace) fprintf(ftrace, "Received a sap REQ packet.\n"); - sap_supply(from, 0, ifp, n->ServType); + sap_supply(from, 0, ifp, n->ServType, 0); return; case SAP_RESP_NEAR: @@ -128,9 +129,24 @@ sap_input(from, size) for (; size > 0; size -= sizeof (struct sap_info), n++) { if (size < sizeof (struct netinfo)) break; + /* + * The idea here is that if the hop count is more + * than INFINITY it is bogus and should be discarded. + * If it is equal to INFINITY it is a message to say + * that a service went down. If we don't allready + * have it in our tables discard it. Otherwise + * update our table and set the timer to EXPIRE_TIME + * so that it is removed next time we go through the + * tables. + */ + if (ntohs(n->hops) > HOPCNT_INFINITY) + continue; sap = sap_lookup(n->ServType, n->ServName); if (sap == 0) { + if (ntohs(n->hops) == HOPCNT_INFINITY) + continue; sap_add(n, from); + sapchanged = 1; continue; } @@ -145,8 +161,6 @@ sap_input(from, size) * Update if from gateway and different, * from anywhere and less hops or * getting stale and equivalent. - * - * XXX I don't think this is quite right yet. */ if (((ifp != sap->ifp) || !equal(&sap->source, from)) && @@ -167,15 +181,32 @@ sap_input(from, size) } continue; } - if (((ifp == sap->ifp) && - equal(&sap->source, from) && - (n->hops != sap->sap.hops)) || - (ntohs(n->hops) < ntohs(sap->sap.hops)) || - (sap->timer > (EXPIRE_TIME*2/3) && - ntohs(sap->sap.hops) == ntohs(n->hops))) { + if ((ifp == sap->ifp) && + equal(&sap->source, from) && + (ntohs(n->hops) == ntohs(sap->sap.hops))) + sap->timer = 0; + else if (((ifp == sap->ifp) && + equal(&sap->source, from) && + (n->hops != sap->sap.hops)) || + (ntohs(n->hops) < ntohs(sap->sap.hops)) || + (sap->timer > (EXPIRE_TIME*2/3) && + ntohs(sap->sap.hops) == ntohs(n->hops) && + ntohs(n->hops) != HOPCNT_INFINITY)) { sap_change(sap, n, from); + sapchanged = 1; } } + if (sapchanged) { + register struct sap_entry *sap; + register struct sap_hash *sh; + sap_supply_toall(1); + + for (sh = sap_head; sh < &sap_head[SAPHASHSIZ]; sh++) + for (sap = sh->forw; + sap != (struct sap_entry *)sh; + sap = sap->forw) + sap->state &= ~RTS_CHANGED; + } return; } } diff --git a/usr.sbin/IPXrouted/sap_output.c b/usr.sbin/IPXrouted/sap_output.c index 11c9cc0..7f7dbcd 100644 --- a/usr.sbin/IPXrouted/sap_output.c +++ b/usr.sbin/IPXrouted/sap_output.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: sap_output.c,v 1.7 1997/02/22 16:01:00 peter Exp $ */ /* @@ -44,7 +44,8 @@ * the output to the known router. */ void -sap_supply_toall(void) +sap_supply_toall(changesonly) + int changesonly; { register struct interface *ifp; struct sockaddr dst; @@ -65,15 +66,16 @@ sap_supply_toall(void) ipx_dst->sipx_addr.x_port = htons(IPXPORT_SAP); flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0; - sap_supply(&dst, flags, ifp, SAP_WILDCARD); + sap_supply(&dst, flags, ifp, SAP_WILDCARD, changesonly); } } void -sapsndmsg(dst, flags, ifp) +sapsndmsg(dst, flags, ifp, changesonly) struct sockaddr *dst; int flags; struct interface *ifp; + int changesonly; { struct sockaddr t_dst; struct sockaddr_ipx *ipx_dst; @@ -104,11 +106,12 @@ sapsndmsg(dst, flags, ifp) * clones. */ void -sap_supply(dst, flags, ifp, ServType) +sap_supply(dst, flags, ifp, ServType, changesonly) struct sockaddr *dst; int flags; struct interface *ifp; int ServType; + int changesonly; { register struct sap_entry *sap; register struct sap_entry *csap; /* Clone route */ @@ -135,11 +138,14 @@ sap_supply(dst, flags, ifp, ServType) n = sap_msg->sap; delay++; if(delay == 2) { - usleep(20000); + usleep(50000); delay = 0; } } + if (changesonly && !(sap->state & RTS_CHANGED)) + continue; + /* * Check for the servicetype except if the ServType is * a wildcard (0xFFFF). diff --git a/usr.sbin/IPXrouted/sap_tables.c b/usr.sbin/IPXrouted/sap_tables.c index 1e33dd4..863943b 100644 --- a/usr.sbin/IPXrouted/sap_tables.c +++ b/usr.sbin/IPXrouted/sap_tables.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: sap_tables.c,v 1.3 1997/02/22 16:01:01 peter Exp $ + * $Id: sap_tables.c,v 1.4 1997/07/01 00:33:41 bde Exp $ */ #include "defs.h" @@ -50,16 +50,9 @@ sapinit(void) } /* - * XXX Make sure that this hash is good enough. - * - * This hash use the first 8 letters of the ServName and the ServType + * This hash use the first 14 letters of the ServName and the ServType * to create a 32 bit hash value. - * - * NOTE: The first two letters of ServName will be used to generate - * the lower bits of the hash. This is used to index into the hash table. */ -#define rol(x) (((x * 2) & 0xFFFF) + ((x & 0x8000) != 0)) - int saphash(u_short ServType, char *ServName) { @@ -72,14 +65,18 @@ saphash(u_short ServType, char *ServName) hsh = 0; - for (i=0;i<8;i++) { - hsh = rol(hsh) + *ServName; +#define SMVAL 33 + + hsh = hsh * SMVAL + (ServType & 0xff); + hsh = hsh * SMVAL + (ServType >> 8); + + for (i=0;i<14;i++) { + hsh = hsh * SMVAL + *ServName++; ServName++; } - hsh = rol(hsh) + (ServType >> 8); - hsh = rol(hsh) + (ServType & 0xff); - hsh = (hsh >> 7) ^ hsh; +#undef SMVAL + return hsh; } @@ -171,6 +168,9 @@ sap_add(struct sap_info *si, struct sockaddr *from) register struct sap_entry *nsap; register struct sap_hash *sh; + if (ntohs(si->hops) == HOPCNT_INFINITY) + return; + FIXLEN(from); nsap = malloc(sizeof(struct sap_entry)); if (nsap == NULL) @@ -187,6 +187,7 @@ sap_add(struct sap_info *si, struct sockaddr *from) sh = &sap_head[nsap->hash & SAPHASHMASK]; insque(nsap, sh); + TRACE_SAP_ACTION("ADD", nsap); } /* @@ -202,6 +203,7 @@ sap_change(struct sap_entry *sap, struct sap_entry *osap = NULL; FIXLEN(from); + TRACE_SAP_ACTION("CHANGE FROM", sap); /* * If the hopcount (metric) is HOPCNT_INFINITY (16) it means that * a service has gone down. We should keep it like that for 30 @@ -228,6 +230,7 @@ sap_change(struct sap_entry *sap, while (osap) { nsap = osap->clone; + TRACE_SAP_ACTION("DELETE", osap); free(osap); osap = nsap; } @@ -239,6 +242,7 @@ sap_change(struct sap_entry *sap, while (osap) { if (equal(&osap->source, from)) { psap->clone = osap->clone; + TRACE_SAP_ACTION("DELETE", osap); free(osap); osap = psap->clone; } else { @@ -261,8 +265,11 @@ sap_change(struct sap_entry *sap, else sap->timer = 0; - if (osap) + if (osap) { + TRACE_SAP_ACTION("DELETE", osap); free(osap); + } + TRACE_SAP_ACTION("CHANGE TO", sap); } /* @@ -280,6 +287,9 @@ sap_add_clone(struct sap_entry *sap, register struct sap_entry *nsap; register struct sap_entry *csap; + if (ntohs(clone->hops) == HOPCNT_INFINITY) + return; + FIXLEN(from); nsap = malloc(sizeof(struct sap_entry)); if (nsap == NULL) @@ -302,6 +312,7 @@ sap_add_clone(struct sap_entry *sap, while (csap->clone) csap = csap->clone; csap->clone = nsap; + TRACE_SAP_ACTION("ADD CLONE", nsap); } /* @@ -319,5 +330,6 @@ sap_delete(struct sap_entry *sap) return; } remque(sap); + TRACE_SAP_ACTION("DELETE", sap); free(sap); } diff --git a/usr.sbin/IPXrouted/table.h b/usr.sbin/IPXrouted/table.h index 8debdcd..dbfdfe5 100644 --- a/usr.sbin/IPXrouted/table.h +++ b/usr.sbin/IPXrouted/table.h @@ -36,7 +36,7 @@ * * @(#)table.h 8.1 (Berkeley) 6/5/93 * - * $Id$ + * $Id: table.h,v 1.4 1997/02/22 16:01:02 peter Exp $ */ /* @@ -91,7 +91,7 @@ struct rt_entry { #define rt_ticks rt_rtu.rtu_entry.rtu_ticks /* time of route */ #define rt_ifp rt_rtu.rtu_entry.rtu_ifp /* interface to take */ -#define ROUTEHASHSIZ 32 /* must be a power of 2 */ +#define ROUTEHASHSIZ 128 /* must be a power of 2 */ #define ROUTEHASHMASK (ROUTEHASHSIZ - 1) /* @@ -103,7 +103,6 @@ struct rt_entry { #define RTS_REMOTE IFF_REMOTE /* route is for ``remote'' entity */ extern struct rthash nethash[ROUTEHASHSIZ]; -extern struct rthash hosthash[ROUTEHASHSIZ]; struct rt_entry *rtlookup(struct sockaddr *); struct rt_entry *rtfind(struct sockaddr *); void rtadd(struct sockaddr *, struct sockaddr *, short, short, int); diff --git a/usr.sbin/IPXrouted/tables.c b/usr.sbin/IPXrouted/tables.c index 17b2660..9fe7f45 100644 --- a/usr.sbin/IPXrouted/tables.c +++ b/usr.sbin/IPXrouted/tables.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: tables.c,v 1.4 1997/02/22 16:01:03 peter Exp $ + * $Id: tables.c,v 1.5 1997/07/01 00:33:42 bde Exp $ */ #ifndef lint @@ -58,7 +58,6 @@ int install = !DEBUG; /* if 1 call kernel */ int delete = 1; struct rthash nethash[ROUTEHASHSIZ]; -struct rthash hosthash[ROUTEHASHSIZ]; /* * Lookup dst in the tables for an exact match. @@ -71,26 +70,18 @@ rtlookup(dst) register struct rthash *rh; register u_int hash; struct afhash h; - int doinghost = 1; if (dst->sa_family >= AF_MAX) return (0); (*afswitch[dst->sa_family].af_hash)(dst, &h); - hash = h.afh_hosthash; - rh = &hosthash[hash & ROUTEHASHMASK]; -again: + hash = h.afh_nethash; + rh = &nethash[hash & ROUTEHASHMASK]; for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { if (rt->rt_hash != hash) continue; if (equal(&rt->rt_dst, dst)) return (rt); } - if (doinghost) { - doinghost = 0; - hash = h.afh_nethash; - rh = &nethash[hash & ROUTEHASHMASK]; - goto again; - } return (0); } @@ -106,34 +97,21 @@ rtfind(dst) register u_int hash; struct afhash h; int af = dst->sa_family; - int doinghost = 1, (*match)() = 0; + int (*match)() = 0; if (af >= AF_MAX) return (0); (*afswitch[af].af_hash)(dst, &h); - hash = h.afh_hosthash; - rh = &hosthash[hash & ROUTEHASHMASK]; -again: + hash = h.afh_nethash; + rh = &nethash[hash & ROUTEHASHMASK]; + match = afswitch[af].af_netmatch; for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { if (rt->rt_hash != hash) continue; - if (doinghost) { - if (equal(&rt->rt_dst, dst)) - return (rt); - } else { - if (rt->rt_dst.sa_family == af && - (match != 0) && - (*match)(&rt->rt_dst, dst)) - return (rt); - } - } - if (doinghost) { - doinghost = 0; - hash = h.afh_nethash; - rh = &nethash[hash & ROUTEHASHMASK]; - match = afswitch[af].af_netmatch; - goto again; + if (rt->rt_dst.sa_family == af && + (*match)(&rt->rt_dst, dst)) + return (rt); } return (0); } @@ -156,13 +134,8 @@ rtadd(dst, gate, metric, ticks, state) return; (*afswitch[af].af_hash)(dst, &h); flags = (*afswitch[af].af_ishost)(dst) ? RTF_HOST : 0; - if (flags & RTF_HOST) { - hash = h.afh_hosthash; - rh = &hosthash[hash & ROUTEHASHMASK]; - } else { - hash = h.afh_nethash; - rh = &nethash[hash & ROUTEHASHMASK]; - } + hash = h.afh_nethash; + rh = &nethash[hash & ROUTEHASHMASK]; rt = (struct rt_entry *)malloc(sizeof (*rt)); if (rt == 0) return; @@ -179,7 +152,7 @@ rtadd(dst, gate, metric, ticks, state) if (metric) rt->rt_flags |= RTF_GATEWAY; insque(rt, rh); - TRACE_ACTION(ADD, rt); + TRACE_ACTION("ADD", rt); /* * If the ioctl fails because the gateway is unreachable * from this host, discard the entry. This should only @@ -189,7 +162,7 @@ rtadd(dst, gate, metric, ticks, state) if (errno != EEXIST) perror("SIOCADDRT"); if (errno == ENETUNREACH) { - TRACE_ACTION(DELETE, rt); + TRACE_ACTION("DELETE", rt); remque(rt); free((char *)rt); } @@ -215,13 +188,8 @@ rtadd_clone(ort, dst, gate, metric, ticks, state) return; (*afswitch[af].af_hash)(dst, &h); flags = (*afswitch[af].af_ishost)(dst) ? RTF_HOST : 0; - if (flags & RTF_HOST) { - hash = h.afh_hosthash; - rh = &hosthash[hash & ROUTEHASHMASK]; - } else { - hash = h.afh_nethash; - rh = &nethash[hash & ROUTEHASHMASK]; - } + hash = h.afh_nethash; + rh = &nethash[hash & ROUTEHASHMASK]; rt = (struct rt_entry *)malloc(sizeof (*rt)); if (rt == 0) return; @@ -243,7 +211,7 @@ rtadd_clone(ort, dst, gate, metric, ticks, state) while(ort->rt_clone != NULL) ort = ort->rt_clone; ort->rt_clone = rt; - TRACE_ACTION(ADD_CLONE, rt); + TRACE_ACTION("ADD_CLONE", rt); } void @@ -319,7 +287,7 @@ rtchange(rt, gate, metric, ticks) if ((metric != rt->rt_metric) || (ticks != rt->rt_ticks)) metricchanged++; if (doioctl || metricchanged) { - TRACE_ACTION(CHANGE FROM, rt); + TRACE_ACTION("CHANGE FROM", rt); if (doioctl) { oldroute = rt->rt_rt; rt->rt_router = *gate; @@ -340,15 +308,16 @@ rtchange(rt, gate, metric, ticks) rt->rt_flags |= RTF_GATEWAY; else rt->rt_flags &= ~RTF_GATEWAY; + rt->rt_ifp = if_ifwithnet(&rt->rt_router); rt->rt_state |= RTS_CHANGED; - TRACE_ACTION(CHANGE TO, rt); + TRACE_ACTION("CHANGE TO", rt); } if (doioctl && install) { #ifndef RTM_ADD if (rtioctl(ADD, &rt->rt_rt) < 0) syslog(LOG_ERR, "rtioctl ADD dst %s, gw %s: %m", - xns_ntoa(&((struct sockaddr_ns *)&rt->rt_dst)->sns_addr), - xns_ntoa(&((struct sockaddr_ns *)&rt->rt_router)->sns_addr)); + ipx_ntoa(&((struct sockaddr_ipx *)&rt->rt_dst)->sipx_addr), + ipx_ntoa(&((struct sockaddr_ipx *)&rt->rt_router)->sipx_addr)); if (delete && rtioctl(DELETE, &oldroute) < 0) perror("rtioctl DELETE"); #else @@ -392,7 +361,7 @@ rtdelete(rt) syslog(LOG_ERR, "deleting route to interface ??? (timed out)"); } - TRACE_ACTION(DELETE, rt); + TRACE_ACTION("DELETE", rt); if (install && rtioctl(DELETE, &rt->rt_rt) < 0) perror("rtioctl DELETE"); remque(rt); @@ -406,8 +375,6 @@ rtinit(void) for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) rh->rt_forw = rh->rt_back = (struct rt_entry *)rh; - for (rh = hosthash; rh < &hosthash[ROUTEHASHSIZ]; rh++) - rh->rt_forw = rh->rt_back = (struct rt_entry *)rh; } int seqno; diff --git a/usr.sbin/IPXrouted/timer.c b/usr.sbin/IPXrouted/timer.c index d6b064e..ea75a98 100644 --- a/usr.sbin/IPXrouted/timer.c +++ b/usr.sbin/IPXrouted/timer.c @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: timer.c,v 1.3 1997/02/22 16:01:03 peter Exp $ */ #ifndef lint @@ -60,11 +60,10 @@ timer() { register struct rthash *rh; register struct rt_entry *rt; - struct rthash *base = hosthash; register struct sap_hash *sh; register struct sap_entry *sap; struct sap_hash *sap_base = sap_head; - int doinghost = 1, timetobroadcast, ripbroadcast, sapbroadcast; + int timetobroadcast, ripbroadcast, sapbroadcast; timeval += TIMER_RATE; if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0) @@ -74,8 +73,7 @@ timer() (timeval % RIP_INTERVAL) == 0; sapbroadcast = timetobroadcast && dosap && !ripbroadcast; -again: - for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { + for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) { rt = rh->rt_forw; for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { if (rt->rt_clone) { @@ -112,8 +110,10 @@ again: if (!(rt->rt_state & RTS_PASSIVE) && !(rt->rt_state & RTS_INTERFACE)) rt->rt_timer += TIMER_RATE; - if (rt->rt_timer >= EXPIRE_TIME) + if (rt->rt_timer >= EXPIRE_TIME) { rt->rt_metric = HOPCNT_INFINITY; + rt->rt_state |= RTS_CHANGED; + } if (rt->rt_timer >= GARBAGE_TIME) { rt = rt->rt_back; /* Perhaps we should send a REQUEST for this route? */ @@ -125,6 +125,8 @@ again: /* don't send extraneous packets */ if (!supplier || ripbroadcast) continue; + if ((rt->rt_metric + 1) == HOPCNT_INFINITY) + continue; msg->rip_cmd = htons(RIPCMD_RESPONSE); msg->rip_nets[0].rip_dst = (satoipx_addr(rt->rt_dst)).x_net; @@ -132,17 +134,12 @@ again: htons(min(rt->rt_metric+1, HOPCNT_INFINITY)); msg->rip_nets[0].rip_ticks = htons(rt->rt_ticks + 1); - toall(sndmsg, rt); + toall(sndmsg, rt, 0); } } } - if (doinghost) { - doinghost = 0; - base = nethash; - goto again; - } if (ripbroadcast) - toall(supply, NULL); + toall(supply, NULL, 0); /* * Now do the SAP stuff. @@ -172,8 +169,10 @@ again: } } sap->timer += TIMER_RATE; - if (sap->timer >= EXPIRE_TIME) - sap->metric = HOPCNT_INFINITY; + if (sap->timer >= EXPIRE_TIME) { + sap->sap.hops = htons(HOPCNT_INFINITY); + sap->state |= RTS_CHANGED; + } if (sap->timer >= GARBAGE_TIME) { sap = sap->back; /* Perhaps we should send a REQUEST for this route? */ @@ -183,13 +182,27 @@ again: /* * XXX sap_sndmsg on RTS_CHANGED */ + if (sap->state & RTS_CHANGED) { + sap->state &= ~RTS_CHANGED; +#ifdef notyet + /* don't send extraneous packets */ + if (!supplier || sapbroadcast) + continue; + if ((ntohs(sap->sap.hops) + 1) == HOPCNT_INFINITY) + continue; + sap_msg->sap_cmd = htons(SAP_RESP); + sap_msg->sap[0] = sap->sap; + sap_msg->sap[0].hops = + htons(min(sap->sap.hops+1, HOPCNT_INFINITY)); + toall(sapsndmsg, rt, 0); +#endif + } } } if (sapbroadcast) - sap_supply_toall(); + sap_supply_toall(0); if (ftrace && sapbroadcast) dumpsaptable(ftrace, sap_head); - alarm(TIMER_RATE); } /* @@ -200,24 +213,16 @@ hup() { register struct rthash *rh; register struct rt_entry *rt; - struct rthash *base = hosthash; register struct sap_hash *sh; register struct sap_entry *sap; - int doinghost = 1; if (supplier) { -again: - for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { + for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) { rt = rh->rt_forw; for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) rt->rt_metric = HOPCNT_INFINITY; } - if (doinghost) { - doinghost = 0; - base = nethash; - goto again; - } - toall(supply, NULL); + toall(supply, NULL, 0); /* * Now for SAP. @@ -228,7 +233,7 @@ again: sap->sap.hops = htons(HOPCNT_INFINITY); } if (dosap) - sap_supply_toall(); + sap_supply_toall(0); } exit(1); } diff --git a/usr.sbin/IPXrouted/trace.c b/usr.sbin/IPXrouted/trace.c index 3b76d2c..a4c5df9 100644 --- a/usr.sbin/IPXrouted/trace.c +++ b/usr.sbin/IPXrouted/trace.c @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: trace.c,v 1.4 1997/02/22 16:01:04 peter Exp $ */ #ifndef lint @@ -219,6 +219,87 @@ traceaction(fd, action, rt) } void +traceactionlog(action, rt) + char *action; + struct rt_entry *rt; +{ + struct sockaddr_ipx *dst, *gate; + static struct bits { + int t_bits; + char *t_name; + } flagbits[] = { + { RTF_UP, "UP" }, + { RTF_GATEWAY, "GATEWAY" }, + { RTF_HOST, "HOST" }, + { 0 } + }, statebits[] = { + { RTS_PASSIVE, "PASSIVE" }, + { RTS_REMOTE, "REMOTE" }, + { RTS_INTERFACE,"INTERFACE" }, + { RTS_CHANGED, "CHANGED" }, + { 0 } + }; + register struct bits *p; + register int first; + char *cp; + char *lstr, *olstr; + + dst = (struct sockaddr_ipx *)&rt->rt_dst; + gate = (struct sockaddr_ipx *)&rt->rt_router; + asprintf(&lstr, "%s dst %s,", action, ipxdp_ntoa(&dst->sipx_addr)); + olstr = lstr; + asprintf(&lstr, "%s router %s, metric %d, ticks %d, flags", + olstr, ipxdp_ntoa(&gate->sipx_addr), rt->rt_metric, rt->rt_ticks); + free(olstr); + olstr = lstr; + cp = "%s %s"; + for (first = 1, p = flagbits; p->t_bits > 0; p++) { + if ((rt->rt_flags & p->t_bits) == 0) + continue; + asprintf(&lstr, cp, olstr, p->t_name); + free(olstr); + olstr = lstr; + if (first) { + cp = "%s|%s"; + first = 0; + } + } + asprintf(&lstr, "%s state", olstr); + free(olstr); + olstr = lstr; + cp = "%s %s"; + for (first = 1, p = statebits; p->t_bits > 0; p++) { + if ((rt->rt_state & p->t_bits) == 0) + continue; + asprintf(&lstr, cp, olstr, p->t_name); + free(olstr); + olstr = lstr; + if (first) { + cp = "%s|%s"; + first = 0; + } + } + syslog(LOG_DEBUG, lstr); + free(lstr); +} + +void +tracesapactionlog(action, sap) + char *action; + struct sap_entry *sap; +{ + syslog(LOG_DEBUG, "%-12.12s service %04X %-20.20s " + "addr %s.%04X %c metric %d\n", + action, + ntohs(sap->sap.ServType), + sap->sap.ServName, + ipxdp_ntoa(&sap->sap.ipx), + ntohs(sap->sap.ipx.x_port), + (sap->clone ? 'C' : ' '), + ntohs(sap->sap.hops)); +} + +void dumpif(fd, ifp) register struct interface *ifp; FILE *fd; diff --git a/usr.sbin/IPXrouted/trace.h b/usr.sbin/IPXrouted/trace.h index cbe52d5..17fef0f 100644 --- a/usr.sbin/IPXrouted/trace.h +++ b/usr.sbin/IPXrouted/trace.h @@ -37,7 +37,7 @@ * * @(#)trace.h 8.1 (Berkeley) 6/5/93 * - * $Id$ + * $Id: trace.h,v 1.5 1997/02/22 16:01:04 peter Exp $ */ /* @@ -78,6 +78,10 @@ FILE *ftrace; /* output trace file */ #define TRACE_ACTION(action, route) { \ if (tracing) \ traceaction(ftrace, "action", route); \ + traceactionlog(action, route); \ + } +#define TRACE_SAP_ACTION(action, service) { \ + tracesapactionlog(action, service); \ } #define TRACE_INPUT(ifp, src, size) { \ if (tracing) { \ @@ -121,6 +125,8 @@ void traceinit(struct interface *); void traceon(char *file); void traceoff(void); void traceaction(FILE *, char *, struct rt_entry *); +void traceactionlog(char *, struct rt_entry *); +void tracesapactionlog(char *action, struct sap_entry *sap); void trace(struct ifdebug *, struct sockaddr *, char *, int, int); void dumppacket(FILE *, char *, struct sockaddr *, char *, int); void dumpsappacket(FILE *, char *, struct sockaddr *, char *, int); |