X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..36401178fd6817c043cc00b0c00c7f723e58efae:/bsd/netinet/igmp.c?ds=sidebyside diff --git a/bsd/netinet/igmp.c b/bsd/netinet/igmp.c index 58abc8d35..961549d60 100644 --- a/bsd/netinet/igmp.c +++ b/bsd/netinet/igmp.c @@ -1,16 +1,19 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER @@ -20,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * Copyright (c) 1988 Stephen Deering. @@ -60,6 +63,12 @@ * * @(#)igmp.c 8.1 (Berkeley) 7/19/93 */ +/* + * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ /* * Internet Group Management Protocol (IGMP) routines. @@ -92,12 +101,16 @@ #include #include +#if CONFIG_MACF_NET +#include +#endif + #ifndef __APPLE__ static MALLOC_DEFINE(M_IGMP, "igmp", "igmp state"); #endif static struct router_info * - find_rti __P((struct ifnet *ifp)); + find_rti(struct ifnet *ifp); static struct igmpstat igmpstat; @@ -110,10 +123,10 @@ static u_long igmp_all_rtrs_group; static struct mbuf *router_alert; static struct router_info *Head; -static void igmp_sendpkt __P((struct in_multi *, int, unsigned long)); +static void igmp_sendpkt(struct in_multi *, int, unsigned long); void -igmp_init() +igmp_init(void) { struct ipoption *ra; @@ -141,48 +154,52 @@ igmp_init() } static struct router_info * -find_rti(ifp) - struct ifnet *ifp; +find_rti( + struct ifnet *ifp) { - register struct router_info *rti = Head; - + struct router_info *rti = Head; + + #if IGMP_DEBUG printf("[igmp.c, _find_rti] --> entering \n"); #endif - while (rti) { - if (rti->rti_ifp == ifp) { + while (rti) { + if (rti->rti_ifp == ifp) { #if IGMP_DEBUG printf("[igmp.c, _find_rti] --> found old entry \n"); #endif - return rti; - } - rti = rti->rti_next; - } - + return rti; + } + rti = rti->rti_next; + } + MALLOC(rti, struct router_info *, sizeof *rti, M_IGMP, M_NOWAIT); - rti->rti_ifp = ifp; - rti->rti_type = IGMP_V2_ROUTER; - rti->rti_time = 0; - rti->rti_next = Head; - Head = rti; + if (rti != NULL) + { + rti->rti_ifp = ifp; + rti->rti_type = IGMP_V2_ROUTER; + rti->rti_time = 0; + rti->rti_next = Head; + Head = rti; + } #if IGMP_DEBUG - printf("[igmp.c, _find_rti] --> created an entry \n"); + if (rti) printf("[igmp.c, _find_rti] --> created an entry \n"); #endif - return rti; + return rti; } void -igmp_input(m, iphlen) - register struct mbuf *m; - register int iphlen; +igmp_input( + struct mbuf *m, + int iphlen) { - register struct igmp *igmp; - register struct ip *ip; - register int igmplen; - register struct ifnet *ifp = m->m_pkthdr.rcvif; - register int minlen; - register struct in_multi *inm; - register struct in_ifaddr *ia; + struct igmp *igmp; + struct ip *ip; + int igmplen; + struct ifnet *ifp = m->m_pkthdr.rcvif; + int minlen; + struct in_multi *inm; + struct in_ifaddr *ia; struct in_multistep step; struct router_info *rti; @@ -227,6 +244,10 @@ igmp_input(m, iphlen) if (timer == 0) timer = 1; rti = find_rti(ifp); + if (rti == NULL) { + m_freem(m); + return; + } /* * In the IGMPv2 specification, there are 3 states and a flag. @@ -288,6 +309,7 @@ igmp_input(m, iphlen) * - Use the value specified in the query message as * the maximum timeout. */ + lck_mtx_lock(rt_mtx); IN_FIRST_MULTI(step, inm); while (inm != NULL) { if (inm->inm_ifp == ifp && @@ -303,6 +325,7 @@ igmp_input(m, iphlen) } IN_NEXT_MULTI(step, inm); } + lck_mtx_unlock(rt_mtx); break; @@ -345,7 +368,9 @@ igmp_input(m, iphlen) * If we belong to the group being reported, stop * our timer for that group. */ + ifnet_lock_shared(ifp); IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm); + ifnet_lock_done(ifp); if (inm != NULL) { inm->inm_timer = 0; @@ -364,11 +389,9 @@ igmp_input(m, iphlen) rip_input(m, iphlen); } -void -igmp_joingroup(inm) - struct in_multi *inm; +int +igmp_joingroup(struct in_multi *inm) { - int s = splnet(); if (inm->inm_addr.s_addr == igmp_all_hosts_group || inm->inm_ifp->if_flags & IFF_LOOPBACK) { @@ -376,18 +399,18 @@ igmp_joingroup(inm) inm->inm_state = IGMP_OTHERMEMBER; } else { inm->inm_rti = find_rti(inm->inm_ifp); + if (inm->inm_rti == NULL) return ENOMEM; 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_IREPORTEDLAST; igmp_timers_are_running = 1; } - splx(s); + return 0; } void -igmp_leavegroup(inm) - struct in_multi *inm; +igmp_leavegroup(struct in_multi *inm) { if (inm->inm_state == IGMP_IREPORTEDLAST && inm->inm_addr.s_addr != igmp_all_hosts_group && @@ -397,11 +420,10 @@ igmp_leavegroup(inm) } void -igmp_fasttimo() +igmp_fasttimo(void) { - register struct in_multi *inm; + struct in_multi *inm; struct in_multistep step; - int s; /* * Quick check to see if any work needs to be done, in order @@ -411,7 +433,6 @@ igmp_fasttimo() if (!igmp_timers_are_running) return; - s = splnet(); igmp_timers_are_running = 0; IN_FIRST_MULTI(step, inm); while (inm != NULL) { @@ -425,14 +446,12 @@ igmp_fasttimo() } IN_NEXT_MULTI(step, inm); } - splx(s); } void -igmp_slowtimo() +igmp_slowtimo(void) { - int s = splnet(); - register struct router_info *rti = Head; + struct router_info *rti = Head; #if IGMP_DEBUG printf("[igmp.c,_slowtimo] -- > entering \n"); @@ -449,27 +468,26 @@ igmp_slowtimo() #if IGMP_DEBUG printf("[igmp.c,_slowtimo] -- > exiting \n"); #endif - splx(s); } static struct route igmprt; static void -igmp_sendpkt(inm, type, addr) - struct in_multi *inm; - int type; - unsigned long addr; +igmp_sendpkt(struct in_multi *inm, int type, unsigned long addr) { struct mbuf *m; struct igmp *igmp; struct ip *ip; struct ip_moptions imo; - MGETHDR(m, M_DONTWAIT, MT_HEADER); + MGETHDR(m, M_DONTWAIT, MT_HEADER); /* MAC-OK */ if (m == NULL) return; - m->m_pkthdr.rcvif = loif; + m->m_pkthdr.rcvif = lo_ifp; +#if CONFIG_MACF_NET + mac_mbuf_label_associate_linklayer(inm->inm_ifp, m); +#endif m->m_pkthdr.len = sizeof(struct ip) + IGMP_MINLEN; MH_ALIGN(m, IGMP_MINLEN + sizeof(struct ip)); m->m_data += sizeof(struct ip); @@ -495,18 +513,23 @@ igmp_sendpkt(inm, type, addr) imo.imo_multicast_ifp = inm->inm_ifp; imo.imo_multicast_ttl = 1; - imo.imo_multicast_vif = -1; + imo.imo_multicast_vif = -1; +#if MROUTING /* * Request loopback of the report if we are acting as a multicast * router, so that the process-level routing demon can hear it. */ imo.imo_multicast_loop = (ip_mrouter != NULL); +#else + imo.imo_multicast_loop = 0; +#endif /* * XXX * Do we have to worry about reentrancy here? Don't think so. */ - ip_output(m, router_alert, &igmprt, 0, &imo); + ip_output(m, router_alert, &igmprt, 0, &imo, NULL); ++igmpstat.igps_snd_reports; } +