summaryrefslogtreecommitdiffstats
path: root/usr.sbin/mrouted
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1995-05-16 00:28:50 +0000
committerjkh <jkh@FreeBSD.org>1995-05-16 00:28:50 +0000
commit87a603cb4db64797ef2b3bfea6e637abf603a108 (patch)
tree568dda545a8895d56389de42401be9d79d1fb5ed /usr.sbin/mrouted
parente472db9bf5bf92db4b6e3d8bc71bbad2fe61eee3 (diff)
downloadFreeBSD-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.c14
-rw-r--r--usr.sbin/mrouted/defs.h4
-rw-r--r--usr.sbin/mrouted/igmp.c11
-rw-r--r--usr.sbin/mrouted/mrinfo.c21
-rw-r--r--usr.sbin/mrouted/mtrace.c56
-rw-r--r--usr.sbin/mrouted/prune.c172
-rw-r--r--usr.sbin/mrouted/vif.c110
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);
}
OpenPOWER on IntegriCloud