Deleted Added
full compact
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
79static struct router_info *find_rti(struct ifnet *ifp);
79static struct router_info *
80 find_rti(struct ifnet *ifp);
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()
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;
126{
125 struct router_info *rti = Head;
127 register struct router_info *rti = Head;
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;
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;
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;
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;
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()
381{
376 struct in_multi *inm;
382 register struct in_multi *inm;
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()
413{
414 int s = splnet();
409 struct router_info *rti = Head;
415 register struct router_info *rti = Head;
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 */
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;
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 ---