igmp.c (107022) | igmp.c (107113) |
---|---|
1/* 2 * Copyright (c) 1988 Stephen Deering. 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Stephen Deering of Stanford University. 8 * --- 21 unchanged lines hidden (view full) --- 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)igmp.c 8.1 (Berkeley) 7/19/93 | 1/* 2 * Copyright (c) 1988 Stephen Deering. 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Stephen Deering of Stanford University. 8 * --- 21 unchanged lines hidden (view full) --- 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)igmp.c 8.1 (Berkeley) 7/19/93 |
38 * $FreeBSD: head/sys/netinet/igmp.c 107022 2002-11-17 17:04:19Z luigi $ | 38 * $FreeBSD: head/sys/netinet/igmp.c 107113 2002-11-20 19:00:54Z luigi $ |
39 */ 40 41/* 42 * Internet Group Management Protocol (IGMP) routines. 43 * 44 * Written by Steve Deering, Stanford, May 1988. 45 * Modified by Rosen Sharma, Stanford, Aug 1994. 46 * Modified by Bill Fenner, Xerox PARC, Feb 1995. --- 24 unchanged lines hidden (view full) --- 71#include <netinet/ip_var.h> 72#include <netinet/igmp.h> 73#include <netinet/igmp_var.h> 74 75#include <machine/in_cksum.h> 76 77static MALLOC_DEFINE(M_IGMP, "igmp", "igmp state"); 78 | 39 */ 40 41/* 42 * Internet Group Management Protocol (IGMP) routines. 43 * 44 * Written by Steve Deering, Stanford, May 1988. 45 * Modified by Rosen Sharma, Stanford, Aug 1994. 46 * Modified by Bill Fenner, Xerox PARC, Feb 1995. --- 24 unchanged lines hidden (view full) --- 71#include <netinet/ip_var.h> 72#include <netinet/igmp.h> 73#include <netinet/igmp_var.h> 74 75#include <machine/in_cksum.h> 76 77static MALLOC_DEFINE(M_IGMP, "igmp", "igmp state"); 78 |
79static struct router_info *find_rti(struct ifnet *ifp); | 79static struct router_info * 80 find_rti(struct ifnet *ifp); |
80 81static struct igmpstat igmpstat; 82 83SYSCTL_STRUCT(_net_inet_igmp, IGMPCTL_STATS, stats, CTLFLAG_RW, 84 &igmpstat, igmpstat, ""); 85 86static int igmp_timers_are_running; 87static u_long igmp_all_hosts_group; 88static u_long igmp_all_rtrs_group; 89static struct mbuf *router_alert; 90static struct router_info *Head; 91 92static void igmp_sendpkt(struct in_multi *, int, unsigned long); 93 94void | 81 82static struct igmpstat igmpstat; 83 84SYSCTL_STRUCT(_net_inet_igmp, IGMPCTL_STATS, stats, CTLFLAG_RW, 85 &igmpstat, igmpstat, ""); 86 87static int igmp_timers_are_running; 88static u_long igmp_all_hosts_group; 89static u_long igmp_all_rtrs_group; 90static struct mbuf *router_alert; 91static struct router_info *Head; 92 93static void igmp_sendpkt(struct in_multi *, int, unsigned long); 94 95void |
95igmp_init(void) | 96igmp_init() |
96{ 97 struct ipoption *ra; 98 99 /* 100 * To avoid byte-swapping the same value over and over again. 101 */ 102 igmp_all_hosts_group = htonl(INADDR_ALLHOSTS_GROUP); 103 igmp_all_rtrs_group = htonl(INADDR_ALLRTRS_GROUP); --- 11 unchanged lines hidden (view full) --- 115 ra->ipopt_list[2] = 0x00; 116 ra->ipopt_list[3] = 0x00; 117 router_alert->m_len = sizeof(ra->ipopt_dst) + ra->ipopt_list[1]; 118 119 Head = (struct router_info *) 0; 120} 121 122static struct router_info * | 97{ 98 struct ipoption *ra; 99 100 /* 101 * To avoid byte-swapping the same value over and over again. 102 */ 103 igmp_all_hosts_group = htonl(INADDR_ALLHOSTS_GROUP); 104 igmp_all_rtrs_group = htonl(INADDR_ALLRTRS_GROUP); --- 11 unchanged lines hidden (view full) --- 116 ra->ipopt_list[2] = 0x00; 117 ra->ipopt_list[3] = 0x00; 118 router_alert->m_len = sizeof(ra->ipopt_dst) + ra->ipopt_list[1]; 119 120 Head = (struct router_info *) 0; 121} 122 123static struct router_info * |
123find_rti(struct ifnet *ifp) | 124find_rti(ifp) 125 struct ifnet *ifp; |
124{ | 126{ |
125 struct router_info *rti = Head; | 127 register struct router_info *rti = Head; |
126 127#ifdef IGMP_DEBUG 128 printf("[igmp.c, _find_rti] --> entering \n"); 129#endif 130 while (rti) { 131 if (rti->rti_ifp == ifp) { 132#ifdef IGMP_DEBUG 133 printf("[igmp.c, _find_rti] --> found old entry \n"); --- 10 unchanged lines hidden (view full) --- 144 Head = rti; 145#ifdef IGMP_DEBUG 146 printf("[igmp.c, _find_rti] --> created an entry \n"); 147#endif 148 return rti; 149} 150 151void | 128 129#ifdef IGMP_DEBUG 130 printf("[igmp.c, _find_rti] --> entering \n"); 131#endif 132 while (rti) { 133 if (rti->rti_ifp == ifp) { 134#ifdef IGMP_DEBUG 135 printf("[igmp.c, _find_rti] --> found old entry \n"); --- 10 unchanged lines hidden (view full) --- 146 Head = rti; 147#ifdef IGMP_DEBUG 148 printf("[igmp.c, _find_rti] --> created an entry \n"); 149#endif 150 return rti; 151} 152 153void |
152igmp_input(struct mbuf *m, int off) | 154igmp_input(m, off) 155 register struct mbuf *m; 156 int off; |
153{ | 157{ |
154 int iphlen = off; 155 struct igmp *igmp; 156 struct ip *ip; 157 int igmplen; 158 struct ifnet *ifp = m->m_pkthdr.rcvif; 159 int minlen; 160 struct in_multi *inm; 161 struct in_ifaddr *ia; | 158 register int iphlen = off; 159 register struct igmp *igmp; 160 register struct ip *ip; 161 register int igmplen; 162 register struct ifnet *ifp = m->m_pkthdr.rcvif; 163 register int minlen; 164 register struct in_multi *inm; 165 register struct in_ifaddr *ia; |
162 struct in_multistep step; 163 struct router_info *rti; 164 165 int timer; /** timer value in the igmp query header **/ 166 167 ++igmpstat.igps_rcv_total; 168 169 ip = mtod(m, struct ip *); --- 166 unchanged lines hidden (view full) --- 336 /* 337 * Pass all valid IGMP packets up to any process(es) listening 338 * on a raw IGMP socket. 339 */ 340 rip_input(m, off); 341} 342 343void | 166 struct in_multistep step; 167 struct router_info *rti; 168 169 int timer; /** timer value in the igmp query header **/ 170 171 ++igmpstat.igps_rcv_total; 172 173 ip = mtod(m, struct ip *); --- 166 unchanged lines hidden (view full) --- 340 /* 341 * Pass all valid IGMP packets up to any process(es) listening 342 * on a raw IGMP socket. 343 */ 344 rip_input(m, off); 345} 346 347void |
344igmp_joingroup(struct in_multi *inm) | 348igmp_joingroup(inm) 349 struct in_multi *inm; |
345{ 346 int s = splnet(); 347 348 if (inm->inm_addr.s_addr == igmp_all_hosts_group 349 || inm->inm_ifp->if_flags & IFF_LOOPBACK) { 350 inm->inm_timer = 0; 351 inm->inm_state = IGMP_OTHERMEMBER; 352 } else { 353 inm->inm_rti = find_rti(inm->inm_ifp); 354 igmp_sendpkt(inm, inm->inm_rti->rti_type, 0); 355 inm->inm_timer = IGMP_RANDOM_DELAY( 356 IGMP_MAX_HOST_REPORT_DELAY*PR_FASTHZ); 357 inm->inm_state = IGMP_IREPORTEDLAST; 358 igmp_timers_are_running = 1; 359 } 360 splx(s); 361} 362 363void | 350{ 351 int s = splnet(); 352 353 if (inm->inm_addr.s_addr == igmp_all_hosts_group 354 || inm->inm_ifp->if_flags & IFF_LOOPBACK) { 355 inm->inm_timer = 0; 356 inm->inm_state = IGMP_OTHERMEMBER; 357 } else { 358 inm->inm_rti = find_rti(inm->inm_ifp); 359 igmp_sendpkt(inm, inm->inm_rti->rti_type, 0); 360 inm->inm_timer = IGMP_RANDOM_DELAY( 361 IGMP_MAX_HOST_REPORT_DELAY*PR_FASTHZ); 362 inm->inm_state = IGMP_IREPORTEDLAST; 363 igmp_timers_are_running = 1; 364 } 365 splx(s); 366} 367 368void |
364igmp_leavegroup(struct in_multi *inm) | 369igmp_leavegroup(inm) 370 struct in_multi *inm; |
365{ 366 if (inm->inm_state == IGMP_IREPORTEDLAST && 367 inm->inm_addr.s_addr != igmp_all_hosts_group && 368 !(inm->inm_ifp->if_flags & IFF_LOOPBACK) && 369 inm->inm_rti->rti_type != IGMP_V1_ROUTER) 370 igmp_sendpkt(inm, IGMP_V2_LEAVE_GROUP, igmp_all_rtrs_group); 371} 372 373void | 371{ 372 if (inm->inm_state == IGMP_IREPORTEDLAST && 373 inm->inm_addr.s_addr != igmp_all_hosts_group && 374 !(inm->inm_ifp->if_flags & IFF_LOOPBACK) && 375 inm->inm_rti->rti_type != IGMP_V1_ROUTER) 376 igmp_sendpkt(inm, IGMP_V2_LEAVE_GROUP, igmp_all_rtrs_group); 377} 378 379void |
374igmp_fasttimo(void) | 380igmp_fasttimo() |
375{ | 381{ |
376 struct in_multi *inm; | 382 register struct in_multi *inm; |
377 struct in_multistep step; 378 int s; 379 380 /* 381 * Quick check to see if any work needs to be done, in order 382 * to minimize the overhead of fasttimo processing. 383 */ 384 --- 13 unchanged lines hidden (view full) --- 398 igmp_timers_are_running = 1; 399 } 400 IN_NEXT_MULTI(step, inm); 401 } 402 splx(s); 403} 404 405void | 383 struct in_multistep step; 384 int s; 385 386 /* 387 * Quick check to see if any work needs to be done, in order 388 * to minimize the overhead of fasttimo processing. 389 */ 390 --- 13 unchanged lines hidden (view full) --- 404 igmp_timers_are_running = 1; 405 } 406 IN_NEXT_MULTI(step, inm); 407 } 408 splx(s); 409} 410 411void |
406igmp_slowtimo(void) | 412igmp_slowtimo() |
407{ 408 int s = splnet(); | 413{ 414 int s = splnet(); |
409 struct router_info *rti = Head; | 415 register struct router_info *rti = Head; |
410 411#ifdef IGMP_DEBUG 412 printf("[igmp.c,_slowtimo] -- > entering \n"); 413#endif 414 while (rti) { 415 if (rti->rti_type == IGMP_V1_ROUTER) { 416 rti->rti_time++; 417 if (rti->rti_time >= IGMP_AGE_THRESHOLD) { 418 rti->rti_type = IGMP_V2_ROUTER; 419 } 420 } 421 rti = rti->rti_next; 422 } 423#ifdef IGMP_DEBUG 424 printf("[igmp.c,_slowtimo] -- > exiting \n"); 425#endif 426 splx(s); 427} 428 | 416 417#ifdef IGMP_DEBUG 418 printf("[igmp.c,_slowtimo] -- > entering \n"); 419#endif 420 while (rti) { 421 if (rti->rti_type == IGMP_V1_ROUTER) { 422 rti->rti_time++; 423 if (rti->rti_time >= IGMP_AGE_THRESHOLD) { 424 rti->rti_type = IGMP_V2_ROUTER; 425 } 426 } 427 rti = rti->rti_next; 428 } 429#ifdef IGMP_DEBUG 430 printf("[igmp.c,_slowtimo] -- > exiting \n"); 431#endif 432 splx(s); 433} 434 |
429/* 430 * XXX fix this static var when we remove the network code from Giant. 431 */ | |
432static struct route igmprt; 433 434static void | 435static struct route igmprt; 436 437static void |
435igmp_sendpkt(struct in_multi *inm, int type, unsigned long addr) | 438igmp_sendpkt(inm, type, addr) 439 struct in_multi *inm; 440 int type; 441 unsigned long addr; |
436{ 437 struct mbuf *m; 438 struct igmp *igmp; 439 struct ip *ip; 440 struct ip_moptions imo; 441 442 MGETHDR(m, M_DONTWAIT, MT_HEADER); 443 if (m == NULL) --- 44 unchanged lines hidden --- | 442{ 443 struct mbuf *m; 444 struct igmp *igmp; 445 struct ip *ip; 446 struct ip_moptions imo; 447 448 MGETHDR(m, M_DONTWAIT, MT_HEADER); 449 if (m == NULL) --- 44 unchanged lines hidden --- |