1/* 2 * Copyright (c) 2009-2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * linklocal_v6.c 26 * - this service only gets instantiated if the ConfigMethod is set explicitly 27 * to LinkLocal 28 * - its only purpose is to act as a placeholder and to publish the 29 * corresponding IPv6 link-local address for the service 30 * - the rest of linklocal is handled by the service management code in 31 * ipconfigd.c 32 */ 33 34/* 35 * Modification History 36 * 37 * October 6, 2009 Dieter Siegmund (dieter@apple.com) 38 * - created 39 */ 40#include <stdlib.h> 41#include <unistd.h> 42#include <string.h> 43#include <sys/types.h> 44 45#include "ipconfigd_threads.h" 46#include "globals.h" 47#include "symbol_scope.h" 48 49STATIC void 50linklocal_v6_address_changed(ServiceRef service_p, 51 inet6_addrlist_t * addr_list_p) 52{ 53 inet6_addrinfo_t * linklocal_p = NULL; 54 55 linklocal_p = inet6_addrlist_get_linklocal(addr_list_p); 56 if (linklocal_p != NULL) { 57 if ((linklocal_p->addr_flags & IN6_IFF_NOTREADY) != 0) { 58 linklocal_p = NULL; 59 } 60 } 61 if (linklocal_p == NULL) { 62 service_publish_failure(service_p, 63 ipconfig_status_resource_unavailable_e); 64 } 65 else { 66 ServicePublishSuccessIPv6(service_p, linklocal_p, 1, NULL, 0, NULL, 67 NULL); 68 } 69 return; 70} 71 72PRIVATE_EXTERN ipconfig_status_t 73linklocal_v6_thread(ServiceRef service_p, IFEventID_t evid, void * event_data) 74{ 75 interface_t * if_p = service_interface(service_p); 76 77 switch (evid) { 78 case IFEventID_start_e: { 79 inet6_addrlist_t addrs; 80 81 my_log(LOG_DEBUG, "%s %s: START", ServiceGetMethodString(service_p), 82 if_name(if_p)); 83 inet6_addrlist_copy(&addrs, if_link_index(if_p)); 84 linklocal_v6_address_changed(service_p, &addrs); 85 inet6_addrlist_free(&addrs); 86 break; 87 } 88 case IFEventID_stop_e: 89 my_log(LOG_DEBUG, "%s %s: STOP", ServiceGetMethodString(service_p), 90 if_name(if_p)); 91 break; 92 case IFEventID_ipv6_address_changed_e: 93 linklocal_v6_address_changed(service_p, event_data); 94 break; 95 default: 96 break; 97 } 98 99 return (ipconfig_status_success_e); 100} 101