X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/8f6c56a50524aa785f7e596d52dddfb331e18961..0a7de7458d150b5d4dffc935ba399be265ef0a1a:/bsd/net/multicast_list.c diff --git a/bsd/net/multicast_list.c b/bsd/net/multicast_list.c index 0f9604b42..15c87fd40 100644 --- a/bsd/net/multicast_list.c +++ b/bsd/net/multicast_list.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004-2010 Apple 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 @@ -11,10 +11,10 @@ * 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 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -22,7 +22,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ @@ -49,8 +49,8 @@ __private_extern__ void multicast_list_init(struct multicast_list * mc_list) { - SLIST_INIT(mc_list); - return; + SLIST_INIT(mc_list); + return; } /* @@ -62,20 +62,20 @@ multicast_list_init(struct multicast_list * mc_list) __private_extern__ int multicast_list_remove(struct multicast_list * mc_list) { - int error; - struct multicast_entry * mc; - int result = 0; + int error; + struct multicast_entry * mc; + int result = 0; - while ((mc = SLIST_FIRST(mc_list)) != NULL) { - error = ifnet_remove_multicast(mc->mc_ifma); - if (error != 0) { - result = error; + while ((mc = SLIST_FIRST(mc_list)) != NULL) { + error = ifnet_remove_multicast(mc->mc_ifma); + if (error != 0) { + result = error; + } + SLIST_REMOVE_HEAD(mc_list, mc_entries); + ifmaddr_release(mc->mc_ifma); + FREE(mc, M_DEVBUF); } - SLIST_REMOVE_HEAD(mc_list, mc_entries); - ifmaddr_release(mc->mc_ifma); - FREE(mc, M_DEVBUF); - } - return (result); + return result; } /* @@ -85,7 +85,7 @@ multicast_list_remove(struct multicast_list * mc_list) * "source_ifp", and saving the result in "mc_list" * * We build a new list of multicast addresses while programming the new list. - * If that completes successfully, we remove the old list, and return the + * If that completes successfully, we remove the old list, and return the * new list. * * If it fails, we remove what we've added to the new list, and @@ -93,59 +93,64 @@ multicast_list_remove(struct multicast_list * mc_list) */ __private_extern__ int multicast_list_program(struct multicast_list * mc_list, - struct ifnet * source_ifp, - struct ifnet * target_ifp) + struct ifnet * source_ifp, + struct ifnet * target_ifp) { - int alen; - int error = 0; - int i; - struct multicast_entry * mc = NULL; - struct multicast_list new_mc_list; - struct sockaddr_dl source_sdl; - ifmultiaddr_t * source_multicast_list; - struct sockaddr_dl target_sdl; + int alen; + int error = 0; + int i; + struct multicast_entry * mc = NULL; + struct multicast_list new_mc_list; + struct sockaddr_dl source_sdl; + ifmultiaddr_t * source_multicast_list; + struct sockaddr_dl target_sdl; - alen = target_ifp->if_addrlen; - bzero((char *)&target_sdl, sizeof(target_sdl)); - target_sdl.sdl_len = sizeof(target_sdl); - target_sdl.sdl_family = AF_LINK; - target_sdl.sdl_type = target_ifp->if_type; - target_sdl.sdl_alen = alen; - target_sdl.sdl_index = target_ifp->if_index; + alen = target_ifp->if_addrlen; + bzero((char *)&target_sdl, sizeof(target_sdl)); + target_sdl.sdl_len = sizeof(target_sdl); + target_sdl.sdl_family = AF_LINK; + target_sdl.sdl_type = target_ifp->if_type; + target_sdl.sdl_alen = alen; + target_sdl.sdl_index = target_ifp->if_index; - /* build a new list */ - multicast_list_init(&new_mc_list); - error = ifnet_get_multicast_list(source_ifp, &source_multicast_list); - if (error != 0) { - printf("multicast_list_program: " - "ifnet_get_multicast_list(%s%d) failed, %d\n", - source_ifp->if_name, source_ifp->if_unit, error); - return (error); - } - for (i = 0; source_multicast_list[i] != NULL; i++) { - if (ifmaddr_address(source_multicast_list[i], - (struct sockaddr *)&source_sdl, - sizeof(source_sdl)) != 0 - || source_sdl.sdl_family != AF_LINK) { - continue; + /* build a new list */ + multicast_list_init(&new_mc_list); + error = ifnet_get_multicast_list(source_ifp, &source_multicast_list); + if (error != 0) { + printf("multicast_list_program: " + "ifnet_get_multicast_list(%s%d) failed, %d\n", + source_ifp->if_name, source_ifp->if_unit, error); + return error; + } + for (i = 0; source_multicast_list[i] != NULL; i++) { + if (ifmaddr_address(source_multicast_list[i], + (struct sockaddr *)&source_sdl, + sizeof(source_sdl)) != 0 + || source_sdl.sdl_family != AF_LINK) { + continue; + } + mc = _MALLOC(sizeof(struct multicast_entry), M_DEVBUF, M_WAITOK); + if (mc == NULL) { + error = ENOBUFS; + break; + } + bcopy(LLADDR(&source_sdl), LLADDR(&target_sdl), alen); + error = ifnet_add_multicast(target_ifp, (struct sockaddr *)&target_sdl, + &mc->mc_ifma); + if (error != 0) { + FREE(mc, M_DEVBUF); + break; + } + SLIST_INSERT_HEAD(&new_mc_list, mc, mc_entries); } - mc = _MALLOC(sizeof(struct multicast_entry), M_DEVBUF, M_WAITOK); - bcopy(LLADDR(&source_sdl), LLADDR(&target_sdl), alen); - error = ifnet_add_multicast(target_ifp, (struct sockaddr *)&target_sdl, - &mc->mc_ifma); if (error != 0) { - FREE(mc, M_DEVBUF); - break; + /* restore previous state */ + (void)multicast_list_remove(&new_mc_list); + } else { + /* remove the old entries, and return the new list */ + (void)multicast_list_remove(mc_list); + *mc_list = new_mc_list; } - SLIST_INSERT_HEAD(&new_mc_list, mc, mc_entries); - } - if (error != 0) { - /* restore previous state */ - (void)multicast_list_remove(&new_mc_list); - } else { - /* remove the old entries, and return the new list */ - (void)multicast_list_remove(mc_list); - *mc_list = new_mc_list; - } - return (error); + ifnet_free_multicast_list(source_multicast_list); + return error; }