diff options
author | fenner <fenner@FreeBSD.org> | 1996-03-14 16:59:20 +0000 |
---|---|---|
committer | fenner <fenner@FreeBSD.org> | 1996-03-14 16:59:20 +0000 |
commit | fac8f2c92271b1198714685037e3dbf30a2e1e44 (patch) | |
tree | ec9b443bd0ff74f2785c4e2ce56cf5e48b21564f /sys/netinet | |
parent | 7638fb441233e9437baf702b256e44462f9a3ac2 (diff) | |
download | FreeBSD-src-fac8f2c92271b1198714685037e3dbf30a2e1e44.zip FreeBSD-src-fac8f2c92271b1198714685037e3dbf30a2e1e44.tar.gz |
IGMPv2 routines rewritten, to be more compact and to fully comply
with the IGMPv2 Internet Draft (including Router Alert IP option)
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/igmp.c | 375 | ||||
-rw-r--r-- | sys/netinet/igmp.h | 54 | ||||
-rw-r--r-- | sys/netinet/igmp_var.h | 24 | ||||
-rw-r--r-- | sys/netinet/in.h | 3 | ||||
-rw-r--r-- | sys/netinet/in_var.h | 10 | ||||
-rw-r--r-- | sys/netinet/ip.h | 3 |
6 files changed, 173 insertions, 296 deletions
diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index 95664b2..3311768 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * @(#)igmp.c 8.1 (Berkeley) 7/19/93 - * $Id: igmp.c,v 1.14 1995/12/02 19:37:52 bde Exp $ + * $Id: igmp.c,v 1.15 1995/12/09 20:43:51 phk Exp $ */ /* @@ -44,8 +44,9 @@ * Written by Steve Deering, Stanford, May 1988. * Modified by Rosen Sharma, Stanford, Aug 1994. * Modified by Bill Fenner, Xerox PARC, Feb 1995. + * Modified to fully comply to IGMPv2 by Bill Fenner, Oct 1995. * - * MULTICAST Revision: 3.3.1.2 + * MULTICAST Revision: 3.5.1.4 */ #include <sys/param.h> @@ -78,61 +79,38 @@ SYSCTL_STRUCT(_net_inet_igmp, IGMPCTL_STATS, stats, CTLFLAG_RD, static int igmp_timers_are_running; static u_long igmp_all_hosts_group; -static u_long igmp_local_group; -static u_long igmp_local_group_mask; +static u_long igmp_all_rtrs_group; +static struct mbuf *router_alert; static struct router_info *Head; -static void igmp_sendpkt(struct in_multi *, int); -static void igmp_sendleave(struct in_multi *); +static void igmp_sendpkt(struct in_multi *, int, unsigned long); void igmp_init() { + struct ipoption *ra; + /* * To avoid byte-swapping the same value over and over again. */ igmp_all_hosts_group = htonl(INADDR_ALLHOSTS_GROUP); - igmp_local_group = htonl(0xe0000000); /* 224.0.0.0 */ - igmp_local_group_mask = htonl(0xffffff00); /* ........^ */ + igmp_all_rtrs_group = htonl(INADDR_ALLRTRS_GROUP); igmp_timers_are_running = 0; - Head = (struct router_info *) 0; -} - -static int -fill_rti(inm) - struct in_multi *inm; -{ - register struct router_info *rti = Head; + /* + * Construct a Router Alert option to use in outgoing packets + */ + MGET(router_alert, M_DONTWAIT, MT_DATA); + ra = mtod(router_alert, struct ipoption *); + ra->ipopt_dst.s_addr = 0; + ra->ipopt_list[0] = IPOPT_RA; /* Router Alert Option */ + ra->ipopt_list[1] = 0x04; /* 4 bytes long */ + ra->ipopt_list[2] = 0x00; + ra->ipopt_list[3] = 0x00; + router_alert->m_len = sizeof(ra->ipopt_dst) + ra->ipopt_list[1]; -#ifdef IGMP_DEBUG - printf("[igmp.c, _fill_rti] --> entering \n"); -#endif - while (rti) { - if (rti->ifp == inm->inm_ifp) { - inm->inm_rti = rti; -#ifdef IGMP_DEBUG - printf("[igmp.c, _fill_rti] --> found old entry \n"); -#endif - if (rti->type == IGMP_OLD_ROUTER) - return IGMP_HOST_MEMBERSHIP_REPORT; - else - return IGMP_HOST_NEW_MEMBERSHIP_REPORT; - } - rti = rti->next; - } - MALLOC(rti, struct router_info *, sizeof *rti, M_MRTABLE, M_NOWAIT); - rti->ifp = inm->inm_ifp; - rti->type = IGMP_NEW_ROUTER; - rti->time = IGMP_AGE_THRESHOLD; - rti->next = Head; - Head = rti; - inm->inm_rti = rti; -#ifdef IGMP_DEBUG - printf("[igmp.c, _fill_rti] --> created new entry \n"); -#endif - return IGMP_HOST_NEW_MEMBERSHIP_REPORT; + Head = (struct router_info *) 0; } static struct router_info * @@ -145,19 +123,19 @@ find_rti(ifp) printf("[igmp.c, _find_rti] --> entering \n"); #endif while (rti) { - if (rti->ifp == ifp) { + if (rti->rti_ifp == ifp) { #ifdef IGMP_DEBUG printf("[igmp.c, _find_rti] --> found old entry \n"); #endif return rti; } - rti = rti->next; + rti = rti->rti_next; } MALLOC(rti, struct router_info *, sizeof *rti, M_MRTABLE, M_NOWAIT); - rti->ifp = ifp; - rti->type = IGMP_NEW_ROUTER; - rti->time = IGMP_AGE_THRESHOLD; - rti->next = Head; + rti->rti_ifp = ifp; + rti->rti_type = IGMP_V2_ROUTER; + rti->rti_time = 0; + rti->rti_next = Head; Head = rti; #ifdef IGMP_DEBUG printf("[igmp.c, _find_rti] --> created an entry \n"); @@ -220,115 +198,102 @@ igmp_input(m, iphlen) timer = igmp->igmp_code * PR_FASTHZ / IGMP_TIMER_SCALE; rti = find_rti(ifp); + /* + * In the IGMPv2 specification, there are 3 states and a flag. + * + * In Non-Member state, we simply don't have a membership record. + * In Delaying Member state, our timer is running (inm->inm_timer) + * In Idle Member state, our timer is not running (inm->inm_timer==0) + * + * The flag is inm->inm_state, it is set to IGMP_OTHERMEMBER if + * we have heard a report from another member, or IGMP_IREPORTEDLAST + * if I sent the last report. + */ switch (igmp->igmp_type) { - case IGMP_HOST_MEMBERSHIP_QUERY: + case IGMP_MEMBERSHIP_QUERY: ++igmpstat.igps_rcv_queries; if (ifp->if_flags & IFF_LOOPBACK) break; if (igmp->igmp_code == 0) { + /* + * Old router. Remember that the querier on this + * interface is old, and set the timer to the + * value in RFC 1112. + */ - rti->type = IGMP_OLD_ROUTER; rti->time = 0; + rti->rti_type = IGMP_V1_ROUTER; + rti->rti_time = 0; - /* - ** Do exactly as RFC 1112 says - */ + timer = IGMP_MAX_HOST_REPORT_DELAY * PR_FASTHZ; - if (ip->ip_dst.s_addr != igmp_all_hosts_group) { + if (ip->ip_dst.s_addr != igmp_all_hosts_group || + igmp->igmp_group.s_addr != 0) { ++igmpstat.igps_rcv_badqueries; m_freem(m); return; } - + } else { /* - * Start the timers in all of our membership records for - * the interface on which the query arrived, except those - * that are already running and those that belong to a - * "local" group (224.0.0.X). + * New router. Simply do the new validity check. */ - IN_FIRST_MULTI(step, inm); - while (inm != NULL) { - if (inm->inm_ifp == ifp - && inm->inm_timer == 0 - && ((inm->inm_addr.s_addr - & igmp_local_group_mask) - != igmp_local_group)) { - - inm->inm_state = IGMP_DELAYING_MEMBER; - inm->inm_timer = IGMP_RANDOM_DELAY( - IGMP_MAX_HOST_REPORT_DELAY * PR_FASTHZ ); - - igmp_timers_are_running = 1; - } - IN_NEXT_MULTI(step, inm); + + if (igmp->igmp_group.s_addr != 0 && + !IN_MULTICAST(ntohl(igmp->igmp_group.s_addr))) { + ++igmpstat.igps_rcv_badqueries; + m_freem(m); + return; } - } else { - /* - ** New Router - */ - - if (!(m->m_flags & M_MCAST)) { - ++igmpstat.igps_rcv_badqueries; - m_freem(m); - return; - } - - /* - * - Start the timers in all of our membership records - * that the query applies to for the interface on - * which the query arrived excl. those that belong - * to a "local" group (224.0.0.X) - * - For timers already running check if they need to - * be reset. - * - Use the igmp->igmp_code field as the maximum - * delay possible - */ - IN_FIRST_MULTI(step, inm); - while (inm != NULL) { + } + + /* + * - Start the timers in all of our membership records + * that the query applies to for the interface on + * which the query arrived excl. those that belong + * to the "all-hosts" group (224.0.0.1). + * - Restart any timer that is already running but has + * a value longer than the requested timeout. + * - Use the value specified in the query message as + * the maximum timeout. + */ + IN_FIRST_MULTI(step, inm); + while (inm != NULL) { if (inm->inm_ifp == ifp && - (inm->inm_addr.s_addr & igmp_local_group_mask) != - igmp_local_group && - (ip->ip_dst.s_addr == igmp_all_hosts_group || - ip->ip_dst.s_addr == inm->inm_addr.s_addr)) { - switch(inm->inm_state) { - case IGMP_IDLE_MEMBER: - case IGMP_LAZY_MEMBER: - case IGMP_AWAKENING_MEMBER: - inm->inm_timer = IGMP_RANDOM_DELAY(timer); - igmp_timers_are_running = 1; - inm->inm_state = IGMP_DELAYING_MEMBER; - break; - case IGMP_DELAYING_MEMBER: - if (inm->inm_timer > timer) { - inm->inm_timer = IGMP_RANDOM_DELAY(timer); - igmp_timers_are_running = 1; - inm->inm_state = IGMP_DELAYING_MEMBER; + inm->inm_addr.s_addr != igmp_all_hosts_group && + (igmp->igmp_group.s_addr == 0 || + igmp->igmp_group.s_addr == inm->inm_addr.s_addr)) { + if (inm->inm_timer == 0 || + inm->inm_timer > timer) { + inm->inm_timer = + IGMP_RANDOM_DELAY(timer); + igmp_timers_are_running = 1; } - break; - case IGMP_SLEEPING_MEMBER: - inm->inm_state = IGMP_AWAKENING_MEMBER; - break; - } } IN_NEXT_MULTI(step, inm); } - } break; - case IGMP_HOST_MEMBERSHIP_REPORT: + case IGMP_V1_MEMBERSHIP_REPORT: + case IGMP_V2_MEMBERSHIP_REPORT: /* - * an old report + * For fast leave to work, we have to know that we are the + * last person to send a report for this group. Reports + * can potentially get looped back if we are a multicast + * router, so discard reports sourced by me. */ + IFP_TO_IA(ifp, ia); + if (ia && ip->ip_src.s_addr == IA_SIN(ia)->sin_addr.s_addr) + break; + ++igmpstat.igps_rcv_reports; if (ifp->if_flags & IFF_LOOPBACK) break; - if (!IN_MULTICAST(ntohl(igmp->igmp_group.s_addr)) || - igmp->igmp_group.s_addr != ip->ip_dst.s_addr) { + if (!IN_MULTICAST(ntohl(igmp->igmp_group.s_addr))) { ++igmpstat.igps_rcv_badreports; m_freem(m); return; @@ -343,10 +308,8 @@ igmp_input(m, iphlen) * to compensate for the lack of any way for a process to * determine the arrival interface of an incoming packet. */ - if ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) == 0) { - IFP_TO_IA(ifp, ia); + if ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) == 0) if (ia) ip->ip_src.s_addr = htonl(ia->ia_subnet); - } /* * If we belong to the group being reported, stop @@ -355,92 +318,13 @@ igmp_input(m, iphlen) IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm); if (inm != NULL) { - inm->inm_timer = 0; - ++igmpstat.igps_rcv_ourreports; - - switch(inm->inm_state){ - case IGMP_IDLE_MEMBER: - case IGMP_LAZY_MEMBER: - case IGMP_AWAKENING_MEMBER: - case IGMP_SLEEPING_MEMBER: - inm->inm_state = IGMP_SLEEPING_MEMBER; - break; - case IGMP_DELAYING_MEMBER: - if (inm->inm_rti->type == IGMP_OLD_ROUTER) - inm->inm_state = IGMP_LAZY_MEMBER; - else - inm->inm_state = IGMP_SLEEPING_MEMBER; - break; - } - } - - break; + inm->inm_timer = 0; + ++igmpstat.igps_rcv_ourreports; - case IGMP_HOST_NEW_MEMBERSHIP_REPORT: - /* - * a new report - */ - - /* - * We can get confused and think there's someone - * else out there if we are a multicast router. - * For fast leave to work, we have to know that - * we are the only member. - */ - IFP_TO_IA(ifp, ia); - if (ia && ip->ip_src.s_addr == IA_SIN(ia)->sin_addr.s_addr) - break; - - ++igmpstat.igps_rcv_reports; - - if (ifp->if_flags & IFF_LOOPBACK) - break; - - if (!IN_MULTICAST(ntohl(igmp->igmp_group.s_addr)) || - igmp->igmp_group.s_addr != ip->ip_dst.s_addr) { - ++igmpstat.igps_rcv_badreports; - m_freem(m); - return; - } - - /* - * KLUDGE: if the IP source address of the report has an - * unspecified (i.e., zero) subnet number, as is allowed for - * a booting host, replace it with the correct subnet number - * so that a process-level multicast routing demon can - * determine which subnet it arrived from. This is necessary - * to compensate for the lack of any way for a process to - * determine the arrival interface of an incoming packet. - */ - if ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) == 0) { -/* #ifndef MROUTING XXX - I don't think the ifdef is necessary */ - IFP_TO_IA(ifp, ia); -/* #endif */ - if (ia) ip->ip_src.s_addr = htonl(ia->ia_subnet); - } - - /* - * If we belong to the group being reported, stop - * our timer for that group. - */ - IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm); - if (inm != NULL) { - inm->inm_timer = 0; - ++igmpstat.igps_rcv_ourreports; - - switch(inm->inm_state){ - case IGMP_DELAYING_MEMBER: - case IGMP_IDLE_MEMBER: - inm->inm_state = IGMP_LAZY_MEMBER; - break; - case IGMP_AWAKENING_MEMBER: - inm->inm_state = IGMP_LAZY_MEMBER; - break; - case IGMP_LAZY_MEMBER: - case IGMP_SLEEPING_MEMBER: - break; - } + inm->inm_state = IGMP_OTHERMEMBER; } + + break; } /* @@ -456,16 +340,16 @@ igmp_joingroup(inm) { int s = splnet(); - inm->inm_state = IGMP_IDLE_MEMBER; - - if ((inm->inm_addr.s_addr & igmp_local_group_mask) == igmp_local_group - || inm->inm_ifp->if_flags & IFF_LOOPBACK) + if (inm->inm_addr.s_addr == igmp_all_hosts_group + || inm->inm_ifp->if_flags & IFF_LOOPBACK) { inm->inm_timer = 0; - else { - igmp_sendpkt(inm,fill_rti(inm)); + inm->inm_state = IGMP_OTHERMEMBER; + } else { + inm->inm_rti = find_rti(inm->inm_ifp); + igmp_sendpkt(inm, inm->inm_rti->rti_type, 0); inm->inm_timer = IGMP_RANDOM_DELAY( IGMP_MAX_HOST_REPORT_DELAY*PR_FASTHZ); - inm->inm_state = IGMP_DELAYING_MEMBER; + inm->inm_state = IGMP_IREPORTEDLAST; igmp_timers_are_running = 1; } splx(s); @@ -475,20 +359,11 @@ void igmp_leavegroup(inm) struct in_multi *inm; { - switch(inm->inm_state) { - case IGMP_DELAYING_MEMBER: - case IGMP_IDLE_MEMBER: - if (((inm->inm_addr.s_addr & igmp_local_group_mask) - != igmp_local_group) - && !(inm->inm_ifp->if_flags & IFF_LOOPBACK)) - if (inm->inm_rti->type != IGMP_OLD_ROUTER) - igmp_sendleave(inm); - break; - case IGMP_LAZY_MEMBER: - case IGMP_AWAKENING_MEMBER: - case IGMP_SLEEPING_MEMBER: - break; - } + if (inm->inm_state == IGMP_IREPORTEDLAST && + inm->inm_addr.s_addr != igmp_all_hosts_group && + !(inm->inm_ifp->if_flags & IFF_LOOPBACK) && + inm->inm_rti->rti_type != IGMP_V1_ROUTER) + igmp_sendpkt(inm, IGMP_V2_LEAVE_GROUP, igmp_all_rtrs_group); } void @@ -513,13 +388,8 @@ igmp_fasttimo() if (inm->inm_timer == 0) { /* do nothing */ } else if (--inm->inm_timer == 0) { - if (inm->inm_state == IGMP_DELAYING_MEMBER) { - if (inm->inm_rti->type == IGMP_OLD_ROUTER) - igmp_sendpkt(inm, IGMP_HOST_MEMBERSHIP_REPORT); - else - igmp_sendpkt(inm, IGMP_HOST_NEW_MEMBERSHIP_REPORT); - inm->inm_state = IGMP_IDLE_MEMBER; - } + igmp_sendpkt(inm, inm->inm_rti->rti_type, 0); + inm->inm_state = IGMP_IREPORTEDLAST; } else { igmp_timers_are_running = 1; } @@ -538,12 +408,13 @@ igmp_slowtimo() printf("[igmp.c,_slowtimo] -- > entering \n"); #endif while (rti) { - rti->time ++; - if (rti->time >= IGMP_AGE_THRESHOLD){ - rti->type = IGMP_NEW_ROUTER; - rti->time = IGMP_AGE_THRESHOLD; + if (rti->rti_type == IGMP_V1_ROUTER) { + rti->rti_time++; + if (rti->rti_time >= IGMP_AGE_THRESHOLD) { + rti->rti_type = IGMP_V2_ROUTER; } - rti = rti->next; + } + rti = rti->rti_next; } #ifdef IGMP_DEBUG printf("[igmp.c,_slowtimo] -- > exiting \n"); @@ -552,9 +423,10 @@ igmp_slowtimo() } static void -igmp_sendpkt(inm, type) +igmp_sendpkt(inm, type, addr) struct in_multi *inm; int type; + unsigned long addr; { struct mbuf *m; struct igmp *igmp; @@ -591,7 +463,7 @@ igmp_sendpkt(inm, type) ip->ip_off = 0; ip->ip_p = IPPROTO_IGMP; ip->ip_src.s_addr = INADDR_ANY; - ip->ip_dst = igmp->igmp_group; + ip->ip_dst.s_addr = addr ? addr : igmp->igmp_group.s_addr; imo->imo_multicast_ifp = inm->inm_ifp; imo->imo_multicast_ttl = 1; @@ -602,15 +474,8 @@ igmp_sendpkt(inm, type) */ imo->imo_multicast_loop = (ip_mrouter != NULL); - ip_output(m, (struct mbuf *)0, (struct route *)0, 0, imo); + ip_output(m, router_alert, (struct route *)0, 0, imo); FREE(imo, M_IPMOPTS); ++igmpstat.igps_snd_reports; } - -static void -igmp_sendleave(inm) - struct in_multi *inm; -{ - igmp_sendpkt(inm, IGMP_HOST_LEAVE_MESSAGE); -} diff --git a/sys/netinet/igmp.h b/sys/netinet/igmp.h index a7038f3..71df6ca 100644 --- a/sys/netinet/igmp.h +++ b/sys/netinet/igmp.h @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * @(#)igmp.h 8.1 (Berkeley) 6/10/93 - * $Id: igmp.h,v 1.4 1994/09/06 22:42:17 wollman Exp $ + * $Id: igmp.h,v 1.6 1995/06/13 17:51:06 wollman Exp $ */ #ifndef _NETINET_IGMP_H_ @@ -46,7 +46,7 @@ * * Written by Steve Deering, Stanford, May 1988. * - * MULTICAST Revision: 3.3.1.2 + * MULTICAST Revision: 3.5.1.2 */ /* @@ -64,43 +64,33 @@ struct igmp { /* * Message types, including version number. */ -#define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* Host membership query */ -#define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Old membership report */ -#define IGMP_DVMRP 0x13 /* DVMRP routing message */ -#define IGMP_PIM 0x14 /* PIM routing message */ +#define IGMP_MEMBERSHIP_QUERY 0x11 /* membership query */ +#define IGMP_V1_MEMBERSHIP_REPORT 0x12 /* Ver. 1 membership report */ +#define IGMP_V2_MEMBERSHIP_REPORT 0x16 /* Ver. 2 membership report */ +#define IGMP_V2_LEAVE_GROUP 0x17 /* Leave-group message */ -#define IGMP_HOST_NEW_MEMBERSHIP_REPORT 0x16 /* New membership report */ +#define IGMP_DVMRP 0x13 /* DVMRP routing message */ +#define IGMP_PIM 0x14 /* PIM routing message */ -#define IGMP_HOST_LEAVE_MESSAGE 0x17 /* Leave-group message */ +#define IGMP_MTRACE_RESP 0x1e /* traceroute resp.(to sender)*/ +#define IGMP_MTRACE 0x1f /* mcast traceroute messages */ -#define IGMP_MTRACE_RESP 0x1e /* traceroute resp. (to sender) */ -#define IGMP_MTRACE 0x1f /* mcast traceroute messages */ +#define IGMP_MAX_HOST_REPORT_DELAY 10 /* max delay for response to */ + /* query (in seconds) according */ + /* to RFC1112 */ -#define IGMP_MAX_HOST_REPORT_DELAY 10 /* max delay for response to */ - /* query (in seconds) */ -#define IGMP_TIMER_SCALE 10 /* denotes that the igmp->timer filed */ - /*specifies time in tenths of seconds */ +#define IGMP_TIMER_SCALE 10 /* denotes that the igmp code field */ + /* specifies time in 10th of seconds*/ /* - * States for the IGMPv2 state table + * The following four defininitions are for backwards compatibility. + * They should be removed as soon as all applications are updated to + * use the new constant names. */ -#define IGMP_DELAYING_MEMBER 1 -#define IGMP_IDLE_MEMBER 2 -#define IGMP_LAZY_MEMBER 3 -#define IGMP_SLEEPING_MEMBER 4 -#define IGMP_AWAKENING_MEMBER 5 - -/* - * We must remember whether the querier is an old or a new router. - */ -#define IGMP_OLD_ROUTER 0 -#define IGMP_NEW_ROUTER 1 - -/* - * Revert to new router if we haven't heard from an old router in - * this amount of time. - */ -#define IGMP_AGE_THRESHOLD 540 +#define IGMP_HOST_MEMBERSHIP_QUERY IGMP_MEMBERSHIP_QUERY +#define IGMP_HOST_MEMBERSHIP_REPORT IGMP_V1_MEMBERSHIP_REPORT +#define IGMP_HOST_NEW_MEMBERSHIP_REPORT IGMP_V2_MEMBERSHIP_REPORT +#define IGMP_HOST_LEAVE_MESSAGE IGMP_V2_LEAVE_GROUP #endif /* _NETINET_IGMP_H_ */ diff --git a/sys/netinet/igmp_var.h b/sys/netinet/igmp_var.h index f11b46f..728c820 100644 --- a/sys/netinet/igmp_var.h +++ b/sys/netinet/igmp_var.h @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * @(#)igmp_var.h 8.1 (Berkeley) 7/19/93 - * $Id: igmp_var.h,v 1.7 1995/11/14 20:33:54 phk Exp $ + * $Id: igmp_var.h,v 1.8 1996/01/30 22:58:22 mpp Exp $ */ #ifndef _NETINET_IGMP_VAR_H_ @@ -47,7 +47,7 @@ * * Written by Steve Deering, Stanford, May 1988. * - * MULTICAST Revision: 3.3.1.1 + * MULTICAST Revision: 3.5.1.3 */ struct igmpstat { @@ -67,6 +67,26 @@ extern struct igmpstat igmpstat; #define IGMP_RANDOM_DELAY(X) (random() % (X) + 1) +/* + * States for IGMPv2's leave processing + */ +#define IGMP_OTHERMEMBER 0 +#define IGMP_IREPORTEDLAST 1 + +/* + * We must remember what version the subnet's querier is. + * We conveniently use the IGMP message type for the proper + * membership report to keep this state. + */ +#define IGMP_V1_ROUTER IGMP_V1_MEMBERSHIP_REPORT +#define IGMP_V2_ROUTER IGMP_V2_MEMBERSHIP_REPORT + +/* + * Revert to new router if we haven't heard from an old router in + * this amount of time. + */ +#define IGMP_AGE_THRESHOLD 540 + void igmp_init __P((void)); void igmp_input __P((struct mbuf *, int)); void igmp_joingroup __P((struct in_multi *)); diff --git a/sys/netinet/in.h b/sys/netinet/in.h index b557684..810dec8 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)in.h 8.3 (Berkeley) 1/3/94 - * $Id: in.h,v 1.14 1996/01/19 08:00:57 peter Exp $ + * $Id: in.h,v 1.15 1996/02/22 21:32:17 peter Exp $ */ #ifndef _NETINET_IN_H_ @@ -159,6 +159,7 @@ struct in_addr { #define INADDR_UNSPEC_GROUP (u_long)0xe0000000 /* 224.0.0.0 */ #define INADDR_ALLHOSTS_GROUP (u_long)0xe0000001 /* 224.0.0.1 */ +#define INADDR_ALLRTRS_GROUP (u_long)0xe0000002 /* 224.0.0.2 */ #define INADDR_MAX_LOCAL_GROUP (u_long)0xe00000ff /* 224.0.0.255 */ #define IN_LOOPBACKNET 127 /* official! */ diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index 5859c74..c71c85a 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)in_var.h 8.2 (Berkeley) 1/9/95 - * $Id: in_var.h,v 1.15 1996/01/09 08:26:07 davidg Exp $ + * $Id: in_var.h,v 1.16 1996/02/05 20:35:59 wollman Exp $ */ #ifndef _NETINET_IN_VAR_H_ @@ -137,10 +137,10 @@ extern int rtq_toomany; /* XXX */ */ struct router_info { - struct ifnet *ifp; - int type; /* type of router which is querier on this interface */ - int time; /* # of slow timeouts since last old query */ - struct router_info *next; + struct ifnet *rti_ifp; + int rti_type; /* type of router which is querier on this interface */ + int rti_time; /* # of slow timeouts since last old query */ + struct router_info *rti_next; }; /* diff --git a/sys/netinet/ip.h b/sys/netinet/ip.h index 8fb9d9a..dc8e645 100644 --- a/sys/netinet/ip.h +++ b/sys/netinet/ip.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ip.h 8.2 (Berkeley) 6/1/94 - * $Id: ip.h,v 1.6 1995/09/21 18:01:11 wollman Exp $ + * $Id: ip.h,v 1.7 1995/12/21 21:20:27 wollman Exp $ */ #ifndef _NETINET_IP_H_ @@ -119,6 +119,7 @@ struct ip { #define IPOPT_LSRR 131 /* loose source route */ #define IPOPT_SATID 136 /* satnet id */ #define IPOPT_SSRR 137 /* strict source route */ +#define IPOPT_RA 148 /* router alert */ /* * Offsets to fields in options other than EOL and NOP. |