diff options
author | jkh <jkh@FreeBSD.org> | 1995-05-16 00:28:50 +0000 |
---|---|---|
committer | jkh <jkh@FreeBSD.org> | 1995-05-16 00:28:50 +0000 |
commit | 87a603cb4db64797ef2b3bfea6e637abf603a108 (patch) | |
tree | 568dda545a8895d56389de42401be9d79d1fb5ed /usr.sbin/mrouted | |
parent | e472db9bf5bf92db4b6e3d8bc71bbad2fe61eee3 (diff) | |
download | FreeBSD-src-87a603cb4db64797ef2b3bfea6e637abf603a108.zip FreeBSD-src-87a603cb4db64797ef2b3bfea6e637abf603a108.tar.gz |
A number of bug fixes to mrouted (no functionality enhancements from 3.5, just
the fixes!):
o Scoped addresses might let traffic in
o IGMP queries sent with wrong timeouts
o Possible core dump in mtrace if we get a request for which we have no route
o If a member on a transit network left a group, mrouted would stop forwarding
even if there was a downstream router
o Various code cleanups and logging changes
Reviewed by: wollman
Submitted by: Bill Fenner <fenner@parc.xerox.com>
Diffstat (limited to 'usr.sbin/mrouted')
-rw-r--r-- | usr.sbin/mrouted/callout.c | 14 | ||||
-rw-r--r-- | usr.sbin/mrouted/defs.h | 4 | ||||
-rw-r--r-- | usr.sbin/mrouted/igmp.c | 11 | ||||
-rw-r--r-- | usr.sbin/mrouted/mrinfo.c | 21 | ||||
-rw-r--r-- | usr.sbin/mrouted/mtrace.c | 56 | ||||
-rw-r--r-- | usr.sbin/mrouted/prune.c | 172 | ||||
-rw-r--r-- | usr.sbin/mrouted/vif.c | 110 |
7 files changed, 235 insertions, 153 deletions
diff --git a/usr.sbin/mrouted/callout.c b/usr.sbin/mrouted/callout.c index 0538a3f..51437e4 100644 --- a/usr.sbin/mrouted/callout.c +++ b/usr.sbin/mrouted/callout.c @@ -7,7 +7,7 @@ * Leland Stanford Junior University. * * - * $Id: callout.c,v 1.1 1994/08/24 23:52:49 thyagara Exp $ + * $Id: callout.c,v 1.2 1994/09/08 02:51:11 wollman Exp $ */ #include "defs.h" @@ -29,7 +29,9 @@ struct timeout_q { }; -callout_init() +static void print_Q(); + +void callout_init() { Q = (struct timeout_q *) 0; } @@ -38,7 +40,7 @@ callout_init() /* * signal handler for SIGALARM that is called once every second */ -age_callout_queue() +void age_callout_queue() { struct timeout_q *ptr; @@ -82,7 +84,7 @@ int timer_setTimer(delay, action, data) struct timeout_q *ptr, *node, *prev; if (in_callout) - return; + return -1; in_callout = 1; @@ -189,11 +191,11 @@ void timer_clearTimer( id) /* * debugging utility */ -print_Q() +static void print_Q() { +#ifdef IGMP_DEBUG struct timeout_q *ptr; -#ifdef IGMP_DEBUG for(ptr = Q; ptr; ptr = ptr->next) log(LOG_DEBUG,0,"(%d,%d) ", ptr->id, ptr->time); #endif IGMP_DEBUG diff --git a/usr.sbin/mrouted/defs.h b/usr.sbin/mrouted/defs.h index a0a9f4a..c75dd8e 100644 --- a/usr.sbin/mrouted/defs.h +++ b/usr.sbin/mrouted/defs.h @@ -7,7 +7,7 @@ * Leland Stanford Junior University. * * - * $Id: defs.h,v 1.8 1994/08/24 23:53:23 thyagara Exp $ + * $Id: defs.h,v 1.2 1994/09/08 02:51:13 wollman Exp $ */ @@ -45,7 +45,7 @@ #define PROTOCOL_VERSION 3 /* increment when packet format/content changes */ -#define MROUTED_VERSION 3 /* increment on local changes or bug fixes, */ +#define MROUTED_VERSION 4 /* increment on local changes or bug fixes, */ /* reset to 0 whever PROTOCOL_VERSION increments */ #define MROUTED_LEVEL ( (MROUTED_VERSION << 8) | PROTOCOL_VERSION ) diff --git a/usr.sbin/mrouted/igmp.c b/usr.sbin/mrouted/igmp.c index ce5c1ce..f7a04df 100644 --- a/usr.sbin/mrouted/igmp.c +++ b/usr.sbin/mrouted/igmp.c @@ -109,7 +109,6 @@ static char *packet_kind(type, code) void accept_igmp(recvlen) int recvlen; { - register vifi_t vifi; register u_long src, dst, group; struct ip *ip; struct igmp *igmp; @@ -131,7 +130,7 @@ void accept_igmp(recvlen) * necessary to install a route into the kernel for this. */ if (ip->ip_p == 0) { - if (src == NULL || dst == NULL) + if (src == 0 || dst == 0) log(LOG_WARNING, 0, "kernel request not accurate"); else add_table_entry(src, dst); @@ -280,8 +279,12 @@ void send_igmp(src, dst, type, code, group, datalen) sdst.sin_addr.s_addr = dst; if (sendto(igmp_socket, send_buf, ip->ip_len, 0, (struct sockaddr *)&sdst, sizeof(sdst)) < 0) { - if (errno == ENETDOWN) check_vif_state(); - else log(LOG_WARNING, errno, "sendto on %s", inet_fmt(src, s1)); + if (errno == ENETDOWN) + check_vif_state(); + else + log(LOG_WARNING, errno, + "sendto to %s on %s", + inet_fmt(dst, s1), inet_fmt(src, s2)); } if (dst == allhosts_group) k_set_loop(FALSE); diff --git a/usr.sbin/mrouted/mrinfo.c b/usr.sbin/mrouted/mrinfo.c index a24a2e3..f82b671 100644 --- a/usr.sbin/mrouted/mrinfo.c +++ b/usr.sbin/mrouted/mrinfo.c @@ -61,7 +61,7 @@ #ifndef lint static char rcsid[] = - "@(#) $Id: mrinfo.c,v 1.7 1994/08/24 23:54:04 thyagara Exp $"; + "@(#) $Id: mrinfo.c,v 1.2 1994/09/08 02:51:20 wollman Exp $"; /* original rcsid: "@(#) Header: mrinfo.c,v 1.6 93/04/08 15:14:16 van Exp (LBL)"; */ @@ -277,7 +277,7 @@ host_addr(name) } -main(argc, argv) +int main(argc, argv) int argc; char *argv[]; { @@ -389,6 +389,8 @@ usage: fprintf(stderr, continue; } ip = (struct ip *) recv_buf; + if (ip->ip_p == 0) + continue; /* Request to install cache entry */ src = ip->ip_src.s_addr; if (src != target_addr) { fprintf(stderr, "mrinfo: got reply from %s", @@ -419,6 +421,21 @@ usage: fprintf(stderr, continue; switch (igmp->igmp_code) { + case DVMRP_NEIGHBORS: + case DVMRP_NEIGHBORS2: + if (src != target_addr) { + fprintf(stderr, "mrinfo: got reply from %s", + inet_fmt(src, s1)); + fprintf(stderr, " instead of %s\n", + inet_fmt(target_addr, s1)); + continue; + } + break; + default: + continue; /* ignore all other DVMRP messages */ + } + + switch (igmp->igmp_code) { case DVMRP_NEIGHBORS: if (group) { diff --git a/usr.sbin/mrouted/mtrace.c b/usr.sbin/mrouted/mtrace.c index 5a8870e..590fe94 100644 --- a/usr.sbin/mrouted/mtrace.c +++ b/usr.sbin/mrouted/mtrace.c @@ -3,6 +3,7 @@ #include "defs.h" #define DEFAULT_TIMEOUT 10 /* How long to wait before retrying requests */ +#define JAN_1970 2208988800 /* 1970 - 1900 in seconds */ int timeout = DEFAULT_TIMEOUT; @@ -77,30 +78,12 @@ flag_type(type) } int -t_diff(a_sec, a_usec, b_sec, b_usec) - u_long a_sec, a_usec, b_sec, b_usec; +t_diff(a, b) + u_long a, b; { - int d = a_sec - b_sec; - int ms = a_usec - b_usec; + int d = a - b; - if ((d < 0) || - ((d == 0) && (ms < 0))) { - d = b_sec - a_sec; - ms = b_usec - a_usec; - } - - switch (d) { - case 0: - break; - case 2: - ms += 1000000; - case 1: - ms += 1000000; - break; - default: - ms += (1000000) * d; - } - return (ms/1000); + return ((d * 125) >> 13); } main(argc, argv) @@ -109,7 +92,7 @@ char *argv[]; { struct timeval tq; struct timezone tzp; - u_long resptime; + u_long querytime, resptime; int udp; struct sockaddr_in addr; @@ -136,8 +119,15 @@ char *argv[]; int i; int done = 0; + if (geteuid() != 0) { + fprintf(stderr, "must be root\n"); + exit(1); + } + argv++, argc--; + if (argc == 0) goto usage; + while (argc > 0 && *argv[0] == '-') { switch (argv[0][1]) { case 's': @@ -260,6 +250,7 @@ usage: printf("usage: mtrace -s <src> -g <grp> -d <dst> -n <# reports> \n"); * set timer to calculate delays & send query */ gettimeofday(&tq, &tzp); + querytime = ((tq.tv_sec + JAN_1970) << 16) + (tq.tv_usec << 10) / 15625; send_igmp(lcl_addr, dst, IGMP_MTRACE, qno, qgrp, datalen); @@ -278,7 +269,7 @@ usage: printf("usage: mtrace -s <src> -g <grp> -d <dst> -n <# reports> \n"); struct timezone tzp; int count, recvlen, dummy = 0; - register u_long src, dst, group, smask; + register u_long src, group, smask; struct ip *ip; struct igmp *igmp; struct tr_resp *resp; @@ -303,6 +294,9 @@ usage: printf("usage: mtrace -s <src> -g <grp> -d <dst> -n <# reports> \n"); exit(1); } + gettimeofday(&tq, &tzp); + resptime = ((tq.tv_sec + JAN_1970) << 16) + (tq.tv_usec << 10) / 15625; + recvlen = recvfrom(igmp_socket, recv_buf, sizeof(recv_buf), 0, NULL, &dummy); @@ -366,8 +360,9 @@ usage: printf("usage: mtrace -s <src> -g <grp> -d <dst> -n <# reports> \n"); /* * print the responses out in reverse order (from src to dst) */ - printf("src: <%s> grp: <%s> dst: <%s>\n\n", inet_fmt(qsrc, s1), - inet_fmt(qgrp, s2), inet_fmt(qdst, s3)); + printf("src: <%s> grp: <%s> dst: <%s> rtt: %d ms\n\n", + inet_fmt(qsrc, s1), inet_fmt(qgrp, s2), inet_fmt(qdst, s3), + t_diff(resptime, querytime)); VAL_TO_MASK(smask, (resp+rno-1)->tr_smask); @@ -376,19 +371,14 @@ usage: printf("usage: mtrace -s <src> -g <grp> -d <dst> -n <# reports> \n"); else printf(" * * *\n"); - resptime = 0; while (rno--) { struct tr_resp *r = resp + rno; printf(" | \n"); printf(" %-15s ", inet_fmt(r->tr_inaddr, s1)); printf("ttl %d ", r->tr_fttl); - printf("cum: %d ms ", - t_diff(r->tr_qarr >> 16, (r->tr_qarr & 0xffff) << 4, - tq.tv_sec & 0xffff, tq.tv_usec)); - printf("hop: %d ms ", - t_diff(resptime >> 16, (resptime & 0xffff) << 4, - r->tr_qarr >> 16, (r->tr_qarr & 0xffff) << 4)); + printf("cum: %d ms ", t_diff(r->tr_qarr, querytime)); + printf("hop: %d ms ", t_diff(resptime, r->tr_qarr)); printf("%s ", proto_type(r->tr_rproto)); printf("%s\n", flag_type(r->tr_rflags)); diff --git a/usr.sbin/mrouted/prune.c b/usr.sbin/mrouted/prune.c index dfab604..b18530a 100644 --- a/usr.sbin/mrouted/prune.c +++ b/usr.sbin/mrouted/prune.c @@ -7,12 +7,14 @@ * Leland Stanford Junior University. * * - * $Id: prune.c,v 1.2 1994/09/08 02:51:23 wollman Exp $ + * $Id: prune.c,v 1.3 1995/03/16 16:25:55 wollman Exp $ */ #include "defs.h" +#define JAN_1970 2208988800 /* 1970 - 1900 in seconds */ + extern int cache_lifetime; extern int max_prune_lifetime; @@ -81,7 +83,7 @@ void prun_add_ttls(kt) if (VIFM_ISSET(vifi, kt->kt_grpmems)) kt->kt_ttls[vifi] = v->uv_threshold; else - kt->kt_ttls[vifi] = NULL; + kt->kt_ttls[vifi] = 0; } } @@ -179,8 +181,10 @@ void add_table_entry(origin, mcastgrp) VIFM_SET(i, kt->kt_grpmems); } GET_SCOPE(kt); - if (VIFM_ISSET(kt->kt_parent, kt->kt_scope)) - kt->kt_grpmems = NULL; + if (VIFM_ISSET(kt->kt_parent, kt->kt_scope)) { + kt->kt_grpmems = 0; + kt->kt_scope = -1; /* make sure we don't forward */ + } else kt->kt_grpmems &= ~kt->kt_scope; } @@ -193,8 +197,10 @@ void add_table_entry(origin, mcastgrp) prun_add_ttls(kt); k_add_rg(kt); - log(LOG_DEBUG, 0, "add entry s:%x g:%x gm:%x", - kt->kt_origin, kt->kt_mcastgrp, kt->kt_grpmems); + log(LOG_DEBUG, 0, "add entry (%s %s) vif-list:%x", + inet_fmt(kt->kt_origin, s1), + inet_fmt(kt->kt_mcastgrp, s2), + kt->kt_grpmems); /* If there are no leaf vifs * which have this group, then @@ -285,7 +291,6 @@ void del_table_entry(r, mcastgrp, del_flag) u_long mcastgrp; u_int del_flag; { - struct mfcctl mc; struct ktable *kt, *prev_kt; struct prunlst *krl; @@ -294,8 +299,8 @@ void del_table_entry(r, mcastgrp, del_flag) kt = prev_kt->kt_next; prev_kt = kt) { if ((kt->kt_origin & r->rt_originmask) == r->rt_origin) { - log(LOG_DEBUG, 0, "delete all rtes %x grp %x", - kt->kt_origin, mcastgrp); + log(LOG_DEBUG, 0, "delete all rtes %s", + inet_fmt(kt->kt_origin, s1)); k_del_rg(kt); @@ -321,8 +326,8 @@ void del_table_entry(r, mcastgrp, del_flag) prev_kt = kt) { if ((kt->kt_origin & r->rt_originmask) == r->rt_origin && kt->kt_mcastgrp == mcastgrp) { - log(LOG_DEBUG, 0, "delete src %x grp %x", - kt->kt_origin, mcastgrp); + log(LOG_DEBUG, 0, "delete (%s, %s)", + inet_fmt(kt->kt_origin, s1), inet_fmt(mcastgrp, s2)); k_del_rg(kt); @@ -359,17 +364,18 @@ void update_table_entry(r) changed = 0; if (kt->kt_leaves != r->rt_leaves) - changed++; + changed |= 0x1; if (kt->kt_children != r->rt_children) - changed++; + changed |= 0x2; if (kt->kt_parent != r->rt_parent) - changed++; + changed |= 0x4; if (!changed) continue; - log(LOG_DEBUG, 0, "update entry: s %-15s g %-15s", - inet_fmt(kt->kt_origin, s1), inet_fmt(kt->kt_mcastgrp, s2)); + log(LOG_DEBUG, 0, "updating entry: (%s %s) code:%x", + inet_fmt(kt->kt_origin, s1), + inet_fmt(kt->kt_mcastgrp, s2), changed); /* free prun list entries */ while (kt->kt_rlist) { @@ -394,8 +400,10 @@ void update_table_entry(r) if (VIFM_ISSET(i, kt->kt_leaves) && grplst_mem(i, kt->kt_mcastgrp)) VIFM_SET(i, kt->kt_grpmems); } - if (VIFM_ISSET(kt->kt_parent, kt->kt_scope)) - kt->kt_grpmems = NULL; + if (VIFM_ISSET(kt->kt_parent, kt->kt_scope)) { + kt->kt_grpmems = 0; + kt->kt_scope = -1; + } else kt->kt_grpmems &= ~kt->kt_scope; @@ -427,13 +435,14 @@ void update_lclgrp(vifi, mcastgrp) { struct ktable *kt; - log(LOG_DEBUG, 0, "group %x joined at vif %d", mcastgrp, vifi); + log(LOG_DEBUG, 0, "group %s joined at vif %d", + inet_fmt(mcastgrp, s1), vifi); for (kt = kernel_rtable; kt; kt = kt->kt_next) if (kt->kt_mcastgrp == mcastgrp && VIFM_ISSET(vifi, kt->kt_children)) { VIFM_SET(vifi, kt->kt_grpmems); kt->kt_grpmems &= ~kt->kt_scope; - if (kt->kt_grpmems == NULL) + if (kt->kt_grpmems == 0) continue; prun_add_ttls(kt); k_add_rg(kt); @@ -447,23 +456,34 @@ void delete_lclgrp(vifi, mcastgrp) vifi_t vifi; u_long mcastgrp; { - struct ktable *kt; - log(LOG_DEBUG, 0, "group %x left at vif %d", mcastgrp, vifi); + log(LOG_DEBUG, 0, "group %s left at vif %d", + inet_fmt(mcastgrp, s1), vifi); for (kt = kernel_rtable; kt; kt = kt->kt_next) if (kt->kt_mcastgrp == mcastgrp) { - VIFM_CLR(vifi, kt->kt_grpmems); - prun_add_ttls(kt); - k_add_rg(kt); - - /* - * If there are no more members of this particular group, - * send prune upstream - */ - if (kt->kt_grpmems == NULL && kt->kt_gateway) - send_prune(kt); + struct listaddr *vr; + int stop_sending = 1; + + for (vr = uvifs[vifi].uv_neighbors; vr; vr = vr->al_next) + if (no_entry_exists(vr->al_addr, kt)) { + stop_sending = 0; + break; + } + + if (stop_sending) { + VIFM_CLR(vifi, kt->kt_grpmems); + prun_add_ttls(kt); + k_add_rg(kt); + + /* + * If there are no more members of this particular group, + * send prune upstream + */ + if (kt->kt_grpmems == NULL && kt->kt_gateway) + send_prune(kt); + } } } @@ -570,7 +590,6 @@ void accept_prune(src, dst, p, datalen) int stop_sending; struct ktable *kt; struct prunlst *pr_recv; - struct prunlst *krl; struct listaddr *vr; /* Don't process any prunes if router is not pruning */ @@ -579,16 +598,18 @@ void accept_prune(src, dst, p, datalen) if ((vifi = find_vif(src, dst)) == NO_VIF) { log(LOG_INFO, 0, - "ignoring prune report from non-neighbor %s", inet_fmt(src, s1)); + "ignoring prune report from non-neighbor %s", + inet_fmt(src, s1)); return; } - if (datalen < 0 || datalen > 12) - { - log(LOG_WARNING, 0, - "received non-decipherable prune report from %s", inet_fmt(src, s1)); - return; - } + /* Check if enough data is present */ + if (datalen < 12) { + log(LOG_WARNING, 0, + "non-decipherable prune from %s", + inet_fmt(src, s1)); + return; + } for (i = 0; i< 4; i++) ((char *)&prun_src)[i] = *p++; @@ -755,7 +776,7 @@ void chkgrp_graft(vifi, mcastgrp) * ignore it ; don't graft back */ kt->kt_grpmems &= ~kt->kt_scope; - if (kt->kt_grpmems == NULL) + if (kt->kt_grpmems == 0) continue; /* set the flag for graft retransmission */ @@ -805,13 +826,15 @@ void accept_graft(src, dst, p, datalen) if ((vifi = find_vif(src, dst)) == NO_VIF) { log(LOG_INFO, 0, - "ignoring graft report from non-neighbor %s", inet_fmt(src, s1)); + "ignoring graft from non-neighbor %s", + inet_fmt(src, s1)); return; } - if (datalen < 0 || datalen > 8) { + if (datalen < 8) { log(LOG_WARNING, 0, - "received non-decipherable graft report from %s", inet_fmt(src, s1)); + "received non-decipherable graft from %s", + inet_fmt(src, s1)); return; } @@ -898,8 +921,10 @@ void send_graft_ack(kt, to) send_igmp(src, dst, IGMP_DVMRP, DVMRP_GRAFT_ACK, htonl(MROUTED_LEVEL), datalen); - log(LOG_DEBUG, 0, "send graft ack for src:%x, grp:%x to %x", - kt->kt_origin, kt->kt_mcastgrp, dst); + log(LOG_DEBUG, 0, "sent graft ack (%s, %s) to %s", + inet_fmt(kt->kt_origin, s1), inet_fmt(kt->kt_mcastgrp, s2), + inet_fmt(dst, s3)); + } /* @@ -934,8 +959,9 @@ void send_graft(kt) send_igmp(src, dst, IGMP_DVMRP, DVMRP_GRAFT, htonl(MROUTED_LEVEL), datalen); } - log(LOG_DEBUG, 0, "send graft for src:%x, grp:%x up to %x", - kt->kt_origin, kt->kt_mcastgrp, kt->kt_gateway); + log(LOG_DEBUG, 0, "sent graft (%s, %s) to %s", + inet_fmt(kt->kt_origin, s1), inet_fmt(kt->kt_mcastgrp, s2), + inet_fmt(kt->kt_gateway, s3)); } /* @@ -960,13 +986,15 @@ void accept_g_ack(src, dst, p, datalen) if ((vifi = find_vif(src, dst)) == NO_VIF) { log(LOG_INFO, 0, - "ignoring graft ack report from non-neighbor %s", inet_fmt(src, s1)); + "ignoring graft ack report from non-neighbor %s", + inet_fmt(src, s1)); return; } - if (datalen < 0 || datalen > 8) { + if (datalen < 8) { log(LOG_WARNING, 0, - "received non-decipherable graft ack report from %s", inet_fmt(src, s1)); + "received non-decipherable graft ack report from %s", + inet_fmt(src, s1)); return; } @@ -1036,10 +1064,6 @@ void age_table_entry() /* advance the timer for the kernel entry */ kt->kt_timer -= ROUTE_MAX_REPORT_DELAY; - /* decrement prune timer if need be */ - if (kt->kt_prsent_timer) - kt->kt_prsent_timer -= ROUTE_MAX_REPORT_DELAY; - /* retransmit graft if graft sent flag is still set */ if (kt->kt_grftsnt) { register int y; @@ -1052,24 +1076,35 @@ void age_table_entry() routers Now, if there are subordinate routers, then, what we - have to do is to decrement each and every router's + have to do is to decrement each and every router's prune time entry too and decide if we want to forward on that link basically */ for (prev_krl = (struct prunlst *)&kt->kt_rlist, - krl = prev_krl->rl_next; - krl; + krl = prev_krl->rl_next; krl; prev_krl = krl, krl = krl->rl_next) { + + /* decrement prune timer received from downstream routers */ if ((krl->rl_timer -= ROUTE_MAX_REPORT_DELAY) <= 0) { - log(LOG_DEBUG, 0, "forw again s %x g %x on vif %d", - kt->kt_origin, kt->kt_mcastgrp, krl->rl_vifi); + log(LOG_DEBUG, 0, "forw again (%s, %s) on vif %d", + inet_fmt(kt->kt_origin, s1), + inet_fmt(kt->kt_mcastgrp, s2), + krl->rl_vifi); + /* + * forwarding now, so entry is not pruned anymore + * reset the cache timer to a largish value also + */ + kt->kt_prsent_timer = 0; + + /* modify the kernel entry to forward packets */ if (!VIFM_ISSET(krl->rl_vifi, kt->kt_grpmems)) { VIFM_SET(krl->rl_vifi, kt->kt_grpmems); prun_add_ttls(kt); k_add_rg(kt); } + /* remove the router's prune entry and await new one */ kt->kt_prun_count--; prev_krl->rl_next = krl->rl_next; free((char *)krl); @@ -1089,8 +1124,9 @@ void age_table_entry() kt->kt_timer = CACHE_LIFETIME(cache_lifetime); } else { - log(LOG_DEBUG, 0, "age route s %x g %x", - kt->kt_origin, kt->kt_mcastgrp); + log(LOG_DEBUG, 0, "aging entry (%s, %s)", + inet_fmt(kt->kt_origin, s1), + inet_fmt(kt->kt_mcastgrp, s2)); k_del_rg(kt); prev_kt->kt_next = kt->kt_next; @@ -1293,8 +1329,8 @@ void mtrace(src, dst, group, data, no, datalen) * fill in initial response fields */ resp = (struct tr_resp *)p; - resp->tr_qarr = ((tp.tv_sec & 0xffff) << 16) + - ((tp.tv_usec >> 4) & 0xffff); + resp->tr_qarr = ((tp.tv_sec + JAN_1970) << 16) + + ((tp.tv_usec << 10) / 15625); resp->tr_vifin = 0; /* default values */ resp->tr_pktcnt = 0; /* default values */ @@ -1333,9 +1369,9 @@ void mtrace(src, dst, group, data, no, datalen) */ if (rt == NULL) { src = dst; /* the dst address of resp. pkt */ - resp->tr_inaddr = NULL; + resp->tr_inaddr = 0; resp->tr_rflags = TR_NO_RTE; - resp->tr_rmtaddr = NULL; + resp->tr_rmtaddr = 0; } else { /* get # of packets in on interface */ @@ -1360,14 +1396,14 @@ void mtrace(src, dst, group, data, no, datalen) */ printf("rcount:%d, no:%d\n", rcount, no); - if ((rcount + 1 == no) || (rt->rt_metric == 1)) + if ((rcount + 1 == no) || (rt == NULL) || (rt->rt_metric == 1)) dst = qry->tr_raddr; else dst = rt->rt_gateway; if (IN_MULTICAST(ntohl(dst))) { k_set_ttl(qry->tr_rttl); - send_igmp(src, dst, + send_igmp(INADDR_ANY, dst, IGMP_MTRACE_RESP, no, group, datalen + RLEN); k_set_ttl(1); diff --git a/usr.sbin/mrouted/vif.c b/usr.sbin/mrouted/vif.c index b71a043..75115ad 100644 --- a/usr.sbin/mrouted/vif.c +++ b/usr.sbin/mrouted/vif.c @@ -7,7 +7,7 @@ * Leland Stanford Junior University. * * - * $Id: vif.c,v 1.8 1994/08/24 23:54:45 thyagara Exp $ + * $Id: vif.c,v 1.2 1994/09/08 02:51:27 wollman Exp $ */ @@ -30,6 +30,7 @@ int udp_socket; /* Since the honkin' kernel doesn't support */ */ static void start_vif(); static void stop_vif(); +static void age_old_hosts(); /* * Initialize the virtual interfaces. @@ -155,6 +156,7 @@ static void start_vif(vifi) /* * Install the interface in the kernel's vif structure. */ + log(LOG_DEBUG, 0, "Installing vif %d in kernel\n", vifi); k_add_vif(vifi, &uvifs[vifi]); /* @@ -186,7 +188,7 @@ static void start_vif(vifi) */ v->uv_flags |= VIFF_QUERIER; send_igmp(src, allhosts_group, IGMP_HOST_MEMBERSHIP_QUERY, - GROUP_EXPIRE_TIME * 10 / ROUTE_MAX_REPORT_DELAY, 0, 0); + IGMP_MAX_HOST_REPORT_DELAY * IGMP_TIMER_SCALE, 0, 0); age_old_hosts(); } @@ -335,7 +337,7 @@ vifi_t find_vif(src, dst) } -age_old_hosts() +static void age_old_hosts() { register vifi_t vifi; register struct uvif *v; @@ -365,7 +367,7 @@ void query_groups() if (v->uv_flags & VIFF_QUERIER) { send_igmp(v->uv_lcl_addr, allhosts_group, IGMP_HOST_MEMBERSHIP_QUERY, - GROUP_EXPIRE_TIME * 10 / ROUTE_MAX_REPORT_DELAY, 0, 0); + IGMP_MAX_HOST_REPORT_DELAY * IGMP_TIMER_SCALE, 0, 0); } } age_old_hosts(); @@ -492,10 +494,10 @@ void leave_group_message( src, dst, group) g->al_timer = GROUP_EXPIRE_TIME / 10; send_igmp(v->uv_lcl_addr, g->al_addr, IGMP_HOST_MEMBERSHIP_QUERY, - IGMP_MAX_HOST_REPORT_DELAY * 10 / (2*TIMER_INTERVAL), - 0, 0); + GROUP_EXPIRE_TIME / 30 * IGMP_TIMER_SCALE, + g->al_addr, 0); g->al_query = SetQueryTimer(g, vifi, g->al_timer / 3 , - IGMP_MAX_HOST_REPORT_DELAY / 2); + GROUP_EXPIRE_TIME / 30 * IGMP_TIMER_SCALE); g->al_timerid = SetTimer(vifi, g); break; } @@ -642,7 +644,7 @@ void accept_neighbor_request2(src, dst) u_char *p, *ncount; struct listaddr *la; int datalen; - u_long temp_addr, us, them = src; + u_long us, them = src; /* Determine which of our addresses to use as the source of our response * to this query. @@ -783,7 +785,7 @@ int update_neighbor(vifi, addr, msgtype, p, datalen, level) { register struct uvif *v; register struct listaddr *n; - u_long genid; + u_long genid = 0; u_long router; int he_hears_me = TRUE; @@ -824,41 +826,48 @@ int update_neighbor(vifi, addr, msgtype, p, datalen, level) * Need to reset the prune state of the router if not. */ if (msgtype == DVMRP_PROBE) { - int i; - - if (datalen < 4) { - log(LOG_WARNING, 0, - "received truncated probe message from %s", - inet_fmt(addr, s1)); - return; - } - - for (i = 0; i < 4; i++) - ((char *)&genid)[i] = *p++; - datalen -=4; - /* - * loop through router list and check for one-way ifs. - */ + /* if mrouted level > 3.2, analyze further */ + if ((level&0xff) > 3 || + (((level&0xff) == 3) && (((level>>8)&0xff) > 2))) { - he_hears_me = FALSE; + int i; - while (datalen > 0) { if (datalen < 4) { log(LOG_WARNING, 0, "received truncated probe message from %s", inet_fmt(addr, s1)); - return; + return FALSE; } + for (i = 0; i < 4; i++) - ((char *)&router)[i] = *p++; - datalen -= 4; - if (router == v->uv_lcl_addr) { - he_hears_me = TRUE; - break; + ((char *)&genid)[i] = *p++; + datalen -=4; + + /* + * loop through router list and check for one-way ifs. + */ + + he_hears_me = FALSE; + + while (datalen > 0) { + if (datalen < 4) { + log(LOG_WARNING, 0, + "received truncated probe message from %s", + inet_fmt(addr, s1)); + return (FALSE); + } + for (i = 0; i < 4; i++) + ((char *)&router)[i] = *p++; + datalen -= 4; + if (router == v->uv_lcl_addr) { + he_hears_me = TRUE; + break; + } } } } + /* * Look for addr in list of neighbors; if found, reset its timer. */ @@ -882,14 +891,39 @@ int update_neighbor(vifi, addr, msgtype, p, datalen, level) reset_neighbor_state(vifi, addr); n->al_genid = genid; - /* need to do a full route report here */ - break; + n->al_pv = level & 0xff; + n->al_mv = (level >> 8) & 0xff; + + /* + * need to do a full route report here + * it gets done by accept_probe() + */ + return (TRUE); } + } - /* recurring probe - so no need to do a route report */ - return FALSE; + /* + * update the neighbors version and protocol number + * if changed => router went down and came up, + * so take action immediately. + */ + if ((n->al_pv != (level & 0xff)) || + ((n->al_mv != (level >> 8)) & 0xff)) { + log(LOG_DEBUG, 0, + "resetting neighbor %s [old:%d.%d, new:%d.%d]", + inet_fmt(addr, s1), + n->al_pv, n->al_mv, level&0xff, (level>>8)&0xff); + + n->al_pv = level & 0xff; + n->al_mv = (level >> 8) & 0xff; + + reset_neighbor_state(vifi, addr); } - break; + /* recurring probe - so no need to do a route report */ + if (msgtype == DVMRP_PROBE) + return (FALSE); + else + return (TRUE); } } @@ -1121,7 +1155,7 @@ cbk_t *cbk; register struct uvif *v = &uvifs[cbk->vifi]; send_igmp(v->uv_lcl_addr, cbk->g->al_addr, IGMP_HOST_MEMBERSHIP_QUERY, - cbk->q_time * 10 / TIMER_INTERVAL, 0, 0); + cbk->q_time, 0, 0); cbk->g->al_query = 0; free(cbk); } |