Deleted Added
sdiff udiff text old ( 107022 ) new ( 107113 )
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 $
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);
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
95igmp_init(void)
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 *
123find_rti(struct ifnet *ifp)
124{
125 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
152igmp_input(struct mbuf *m, int off)
153{
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;
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
344igmp_joingroup(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
364igmp_leavegroup(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
374igmp_fasttimo(void)
375{
376 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
406igmp_slowtimo(void)
407{
408 int s = splnet();
409 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
429/*
430 * XXX fix this static var when we remove the network code from Giant.
431 */
432static struct route igmprt;
433
434static void
435igmp_sendpkt(struct in_multi *inm, int type, 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 ---