2  * Copyright (c) 2003-2007 Apple Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   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 
  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. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25  * Modification History 
  27  * November 28, 2005            Allan Nathanson <ajn@apple.com> 
  30  * November 14, 2003            Allan Nathanson <ajn@apple.com> 
  35 #include <CoreFoundation/CoreFoundation.h> 
  36 #include <CoreFoundation/CFRuntime.h> 
  38 #include <SystemConfiguration/SystemConfiguration.h> 
  39 #include "SCNetworkConfigurationInternal.h" 
  40 #include <SystemConfiguration/SCValidation.h> 
  41 #include <SystemConfiguration/SCPrivate.h> 
  46 #include <sys/types.h> 
  47 #include <sys/ioctl.h> 
  48 #include <sys/socket.h> 
  49 #include <net/ethernet.h> 
  50 #define KERNEL_PRIVATE 
  52 #include <net/if_var.h> 
  54 #include <net/if_vlan_var.h> 
  55 #include <net/if_types.h> 
  57 #include <SystemConfiguration/VLANConfiguration.h> 
  59 /* ---------- VLAN support ---------- */ 
  66         s 
= socket(AF_INET
, SOCK_DGRAM
, 0); 
  68                 SCLog(TRUE
, LOG_ERR
, CFSTR("socket() failed: %s"), strerror(errno
)); 
  76         CFMutableArrayRef       vlans
; 
  77         SCPreferencesRef        prefs
; 
  78 } addContext
, *addContextRef
; 
  82 add_configured_interface(const void *key
, const void *value
, void *context
) 
  84         SCNetworkInterfacePrivateRef    interfacePrivate
; 
  85         addContextRef                   myContext       
= (addContextRef
)context
; 
  86         SCVLANInterfaceRef              vlan
; 
  87         CFStringRef                     vlan_if         
= (CFStringRef
)key
; 
  88         CFDictionaryRef                 vlan_info       
= (CFDictionaryRef
)value
; 
  89         CFStringRef                     vlan_name
; 
  90         CFDictionaryRef                 vlan_options
; 
  91         SCNetworkInterfaceRef           vlan_physical
; 
  92         CFStringRef                     vlan_physical_if
; 
  95         vlan_physical_if 
= CFDictionaryGetValue(vlan_info
, kSCPropVirtualNetworkInterfacesVLANInterface
); 
  96         if (!isA_CFString(vlan_physical_if
)) { 
  97                 // if prefs are confused 
 101         vlan_tag 
= CFDictionaryGetValue(vlan_info
, kSCPropVirtualNetworkInterfacesVLANTag
); 
 102         if (!isA_CFNumber(vlan_tag
)) { 
 103                 // if prefs are confused 
 107         // create the VLAN interface 
 108         vlan 
= (SCVLANInterfaceRef
)_SCVLANInterfaceCreatePrivate(NULL
, vlan_if
); 
 110         // set physical interface and tag 
 111         vlan_physical 
= _SCNetworkInterfaceCreateWithBSDName(NULL
, vlan_physical_if
, 
 112                                                              kIncludeBondInterfaces
); 
 113         SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan
, vlan_physical
, vlan_tag
); 
 114         CFRelease(vlan_physical
); 
 117         vlan_name 
= CFDictionaryGetValue(vlan_info
, kSCPropUserDefinedName
); 
 118         if (isA_CFString(vlan_name
)) { 
 119                 SCVLANInterfaceSetLocalizedDisplayName(vlan
, vlan_name
); 
 123         vlan_options 
= CFDictionaryGetValue(vlan_info
, kSCPropVirtualNetworkInterfacesVLANOptions
); 
 124         if (isA_CFDictionary(vlan_options
)) { 
 125                 SCVLANInterfaceSetOptions(vlan
, vlan_options
); 
 128         // estabish link to the stored configuration 
 129         interfacePrivate 
= (SCNetworkInterfacePrivateRef
)vlan
; 
 130         interfacePrivate
->prefs 
= CFRetain(myContext
->prefs
); 
 132         CFArrayAppendValue(myContext
->vlans
, vlan
); 
 140 add_legacy_configuration(addContextRef myContext
) 
 144         SCPreferencesRef                prefs
; 
 147 #define VLAN_PREFERENCES_ID             CFSTR("VirtualNetworkInterfaces.plist") 
 148 #define VLAN_PREFERENCES_VLANS          CFSTR("VLANs") 
 149 #define __kVLANInterface_interface      CFSTR("interface")      // e.g. vlan0, vlan1, ... 
 150 #define __kVLANInterface_device         CFSTR("device")         // e.g. en0, en1, ... 
 151 #define __kVLANInterface_tag            CFSTR("tag")            // e.g. 1 <= tag <= 4094 
 152 #define __kVLANInterface_options        CFSTR("options")        // e.g. UserDefinedName 
 154         prefs 
= SCPreferencesCreate(NULL
, CFSTR("SCVLANInterfaceCopyAll"), VLAN_PREFERENCES_ID
); 
 159         vlans 
= SCPreferencesGetValue(prefs
, VLAN_PREFERENCES_VLANS
); 
 160         if ((vlans 
!= NULL
) && !isA_CFArray(vlans
)) { 
 161                 CFRelease(prefs
);       // if the prefs are confused 
 165         n 
= (vlans 
!= NULL
) ? CFArrayGetCount(vlans
) : 0; 
 166         for (i 
= 0; i 
< n
; i
++) { 
 167                 CFDictionaryRef                 dict
; 
 168                 SCNetworkInterfacePrivateRef    interfacePrivate
; 
 170                 CFDictionaryRef                 options
; 
 172                 SCVLANInterfaceRef              vlan
; 
 174                 CFDictionaryRef                 vlan_dict
; 
 175                 SCNetworkInterfaceRef           vlan_physical
; 
 176                 CFStringRef                     vlan_physical_if
; 
 177                 CFNumberRef                     vlan_tag
; 
 179                 vlan_dict 
= CFArrayGetValueAtIndex(vlans
, i
); 
 180                 if (!isA_CFDictionary(vlan_dict
)) { 
 181                         continue;       // if the prefs are confused 
 184                 vlan_if 
= CFDictionaryGetValue(vlan_dict
, __kVLANInterface_interface
); 
 185                 if (!isA_CFString(vlan_if
)) { 
 186                         continue;       // if the prefs are confused 
 189                 vlan_physical_if 
= CFDictionaryGetValue(vlan_dict
, __kVLANInterface_device
); 
 190                 if (!isA_CFString(vlan_physical_if
)) { 
 191                         continue;       // if the prefs are confused 
 194                 vlan_tag 
= CFDictionaryGetValue(vlan_dict
, __kVLANInterface_tag
); 
 195                 if (!isA_CFNumber(vlan_tag
)) { 
 196                         continue;       // if the prefs are confused 
 199                 // check if this VLAN interface has already been allocated 
 200                 path 
= CFStringCreateWithFormat(NULL
, 
 203                                                 kSCPrefVirtualNetworkInterfaces
, 
 204                                                 kSCNetworkInterfaceTypeVLAN
, 
 206                 dict 
= SCPreferencesPathGetValue(myContext
->prefs
, path
); 
 208                         // if VLAN interface name not available 
 213                 // add a placeholder for the VLAN in the stored preferences 
 214                 dict 
= CFDictionaryCreate(NULL
, 
 216                                           &kCFTypeDictionaryKeyCallBacks
, 
 217                                           &kCFTypeDictionaryValueCallBacks
); 
 218                 ok 
= SCPreferencesPathSetValue(myContext
->prefs
, path
, dict
); 
 222                         // if the VLAN could not be saved 
 226                 // create the VLAN interface 
 227                 vlan 
= (SCVLANInterfaceRef
)_SCVLANInterfaceCreatePrivate(NULL
, vlan_if
); 
 229                 // estabish link to the stored configuration 
 230                 interfacePrivate 
= (SCNetworkInterfacePrivateRef
)vlan
; 
 231                 interfacePrivate
->prefs 
= CFRetain(myContext
->prefs
); 
 233                 // set the interface and tag (which updates the stored preferences) 
 234                 vlan_physical 
= _SCNetworkInterfaceCreateWithBSDName(NULL
, vlan_physical_if
, 
 235                                                                      kIncludeBondInterfaces
); 
 236                 SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan
, vlan_physical
, vlan_tag
); 
 237                 CFRelease(vlan_physical
); 
 239                 // set display name (which updates the stored preferences) 
 240                 options 
= CFDictionaryGetValue(vlan_dict
, __kVLANInterface_options
); 
 241                 if (isA_CFDictionary(options
)) { 
 242                         CFStringRef     vlan_name
; 
 244                         vlan_name 
= CFDictionaryGetValue(options
, CFSTR("VLAN Name")); 
 245                         if (isA_CFString(vlan_name
)) { 
 246                                 SCVLANInterfaceSetLocalizedDisplayName(vlan
, vlan_name
); 
 250                 CFArrayAppendValue(myContext
->vlans
, vlan
); 
 259 static SCVLANInterfaceRef
 
 260 findVLANInterfaceAndTag(SCPreferencesRef prefs
, SCNetworkInterfaceRef physical
, CFNumberRef tag
) 
 264         SCVLANInterfaceRef      vlan    
= NULL
; 
 267         vlans 
= SCVLANInterfaceCopyAll(prefs
); 
 269         n 
= CFArrayGetCount(vlans
); 
 270         for (i 
= 0; i 
< n
; i
++) { 
 271                 SCVLANInterfaceRef      config_vlan
; 
 272                 SCNetworkInterfaceRef   config_physical
; 
 273                 CFNumberRef             config_tag
; 
 275                 config_vlan     
= CFArrayGetValueAtIndex(vlans
, i
); 
 276                 config_physical 
= SCVLANInterfaceGetPhysicalInterface(config_vlan
); 
 277                 config_tag      
= SCVLANInterfaceGetTag(config_vlan
); 
 279                 if ((config_physical 
!= NULL
) && (config_tag 
!= NULL
)) { 
 280                         if (!CFEqual(physical
, config_physical
)) { 
 281                                 // if this VLAN has a different physical interface 
 285                         if (!CFEqual(tag
, config_tag
)) { 
 286                                 // if this VLAN has a different tag 
 290                         vlan 
= CFRetain(config_vlan
); 
 301 #pragma mark SCVLANInterface APIs 
 305 SCVLANInterfaceCopyAll(SCPreferencesRef prefs
) 
 308         CFDictionaryRef         dict
; 
 311         context
.vlans 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 312         context
.prefs 
= prefs
; 
 314         path 
= CFStringCreateWithFormat(NULL
, 
 317                                         kSCPrefVirtualNetworkInterfaces
, 
 318                                         kSCNetworkInterfaceTypeVLAN
); 
 319         dict 
= SCPreferencesPathGetValue(prefs
, path
); 
 320         if (isA_CFDictionary(dict
)) { 
 321                 CFDictionaryApplyFunction(dict
, add_configured_interface
, &context
); 
 323                 // no VLAN configuration, upgrade from legacy configuration 
 324                 dict 
= CFDictionaryCreate(NULL
, 
 326                                           &kCFTypeDictionaryKeyCallBacks
, 
 327                                           &kCFTypeDictionaryValueCallBacks
); 
 328                 (void) SCPreferencesPathSetValue(prefs
, path
, dict
); 
 331                 add_legacy_configuration(&context
); 
 335         return context
.vlans
; 
 340 addAvailableInterfaces(CFMutableArrayRef available
, CFArrayRef interfaces
, 
 346         n 
= CFArrayGetCount(interfaces
); 
 347         for (i 
= 0; i 
< n
; i
++) { 
 348                 SCNetworkInterfaceRef           interface
; 
 349                 SCNetworkInterfacePrivateRef    interfacePrivate
; 
 351                 interface 
= CFArrayGetValueAtIndex(interfaces
, i
); 
 352                 interfacePrivate 
= (SCNetworkInterfacePrivateRef
)interface
; 
 355                     && CFSetContainsValue(exclude
, interface
)) { 
 356                         // exclude this interface 
 359                 if (interfacePrivate
->supportsVLAN
) { 
 360                         // if this interface is available 
 361                         CFArrayAppendValue(available
, interface
); 
 370 SCVLANInterfaceCopyAvailablePhysicalInterfaces() 
 372         CFMutableArrayRef       available
; 
 373         CFArrayRef              bond_interfaces 
= NULL
; 
 374         CFMutableSetRef         exclude 
= NULL
; 
 375         CFArrayRef              interfaces
; 
 376         SCPreferencesRef        prefs
; 
 378         available 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 380         prefs 
= SCPreferencesCreate(NULL
, CFSTR("SCVLANInterfaceCopyAvailablePhysicalInterfaces"), NULL
); 
 382                 bond_interfaces 
= SCBondInterfaceCopyAll(prefs
); 
 384                 if (bond_interfaces 
!= NULL
) { 
 385                         exclude 
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
); 
 386                         __SCBondInterfaceListCopyMembers(bond_interfaces
, exclude
); 
 390         // add real interfaces that aren't part of a bond 
 391         interfaces 
= __SCNetworkInterfaceCopyAll_IONetworkInterface(); 
 392         if (interfaces 
!= NULL
) { 
 393                 addAvailableInterfaces(available
, interfaces
, exclude
); 
 394                 CFRelease(interfaces
); 
 397         // add bond interfaces 
 398         if (bond_interfaces 
!= NULL
) { 
 399                 addAvailableInterfaces(available
, bond_interfaces
, NULL
); 
 400                 CFRelease(bond_interfaces
); 
 402         if (exclude 
!= NULL
) { 
 411 _SCVLANInterfaceCopyActive(void) 
 413         struct ifaddrs          
*ifap
; 
 416         CFMutableArrayRef       vlans   
= NULL
; 
 418         if (getifaddrs(&ifap
) == -1) { 
 419                 SCLog(TRUE
, LOG_ERR
, CFSTR("getifaddrs() failed: %s"), strerror(errno
)); 
 420                 _SCErrorSet(kSCStatusFailed
); 
 424         s 
= inet_dgram_socket(); 
 430         vlans 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 432         for (ifp 
= ifap
; ifp 
!= NULL
; ifp 
= ifp
->ifa_next
) { 
 433                 struct if_data          
*if_data
; 
 435                 SCVLANInterfaceRef      vlan
; 
 437                 SCNetworkInterfaceRef   vlan_physical
; 
 438                 CFStringRef             vlan_physical_if
; 
 439                 CFNumberRef             vlan_tag
; 
 440                 char                    vlr_parent
[IFNAMSIZ 
+ 1]; 
 444                 if_data 
= (struct if_data 
*)ifp
->ifa_data
; 
 446                     || ifp
->ifa_addr
->sa_family 
!= AF_LINK
 
 447                     || if_data
->ifi_type 
!= IFT_L2VLAN
) { 
 451                 bzero(&ifr
, sizeof(ifr
)); 
 452                 bzero(&vreq
, sizeof(vreq
)); 
 453                 strncpy(ifr
.ifr_name
, ifp
->ifa_name
, sizeof(ifr
.ifr_name
)); 
 454                 ifr
.ifr_data 
= (caddr_t
)&vreq
; 
 456                 if (ioctl(s
, SIOCGIFVLAN
, (caddr_t
)&ifr
) == -1) { 
 457                         SCLog(TRUE
, LOG_ERR
, CFSTR("ioctl() failed: %s"), strerror(errno
)); 
 460                         _SCErrorSet(kSCStatusFailed
); 
 464                 // create the VLAN interface 
 465                 vlan_if 
= CFStringCreateWithCString(NULL
, ifp
->ifa_name
, kCFStringEncodingASCII
); 
 466                 vlan    
= (SCVLANInterfaceRef
)_SCVLANInterfaceCreatePrivate(NULL
, vlan_if
); 
 469                 // set the physical interface and tag 
 470                 bzero(&vlr_parent
, sizeof(vlr_parent
)); 
 471                 bcopy(vreq
.vlr_parent
, vlr_parent
, IFNAMSIZ
); 
 472                 vlan_physical_if 
= CFStringCreateWithCString(NULL
, vlr_parent
, kCFStringEncodingASCII
); 
 473                 vlan_physical 
= _SCNetworkInterfaceCreateWithBSDName(NULL
, vlan_physical_if
, 
 474                                                                      kIncludeBondInterfaces
); 
 475                 CFRelease(vlan_physical_if
); 
 477                 vlr_tag  
= vreq
.vlr_tag
; 
 478                 vlan_tag 
= CFNumberCreate(NULL
, kCFNumberIntType
, &vlr_tag
); 
 480                 SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan
, vlan_physical
, vlan_tag
); 
 481                 CFRelease(vlan_physical
); 
 485                 CFArrayAppendValue(vlans
, vlan
); 
 498 SCVLANInterfaceCreate(SCPreferencesRef prefs
, SCNetworkInterfaceRef physical
, CFNumberRef tag
) 
 500         CFAllocatorRef                  allocator
; 
 502         SCNetworkInterfacePrivateRef    interfacePrivate
; 
 503         SCVLANInterfaceRef              vlan
; 
 506                 _SCErrorSet(kSCStatusInvalidArgument
); 
 510         if (!isA_SCNetworkInterface(physical
)) { 
 511                 _SCErrorSet(kSCStatusInvalidArgument
); 
 515         interfacePrivate 
= (SCNetworkInterfacePrivateRef
)physical
; 
 516         if (!interfacePrivate
->supportsVLAN
) { 
 517                 _SCErrorSet(kSCStatusInvalidArgument
); 
 521         if (isA_CFNumber(tag
)) { 
 524                 CFNumberGetValue(tag
, kCFNumberIntType
, &tag_val
); 
 525                 if ((tag_val 
< 1) || (tag_val 
> 4094)) { 
 526                         _SCErrorSet(kSCStatusInvalidArgument
); 
 530                 _SCErrorSet(kSCStatusInvalidArgument
); 
 534         // make sure that physical interface and tag are not used 
 535         vlan 
= findVLANInterfaceAndTag(prefs
, physical
, tag
); 
 538                 _SCErrorSet(kSCStatusKeyExists
); 
 542         allocator 
= CFGetAllocator(prefs
); 
 544         // create a new VLAN using an unused interface name 
 545         for (i 
= 0; vlan 
== NULL
; i
++) { 
 546                 CFDictionaryRef                 dict
; 
 551                 vlan_if 
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("vlan%d"), i
); 
 552                 path    
= CFStringCreateWithFormat(allocator
, 
 555                                                    kSCPrefVirtualNetworkInterfaces
, 
 556                                                    kSCNetworkInterfaceTypeVLAN
, 
 558                 dict 
= SCPreferencesPathGetValue(prefs
, path
); 
 560                         // if VLAN interface name not available 
 566                 // add the VLAN to the stored preferences 
 567                 dict 
= CFDictionaryCreate(allocator
, 
 569                                           &kCFTypeDictionaryKeyCallBacks
, 
 570                                           &kCFTypeDictionaryValueCallBacks
); 
 571                 ok 
= SCPreferencesPathSetValue(prefs
, path
, dict
); 
 575                         // if the VLAN could not be saved 
 577                         _SCErrorSet(kSCStatusFailed
); 
 581                 // create the SCVLANInterfaceRef 
 582                 vlan 
= (SCVLANInterfaceRef
)_SCVLANInterfaceCreatePrivate(allocator
, vlan_if
); 
 585                 // estabish link to the stored configuration 
 586                 interfacePrivate 
= (SCNetworkInterfacePrivateRef
)vlan
; 
 587                 interfacePrivate
->prefs 
= CFRetain(prefs
); 
 589                 // set physical interface and tag 
 590                 SCVLANInterfaceSetPhysicalInterfaceAndTag(vlan
, physical
, tag
); 
 598 SCVLANInterfaceRemove(SCVLANInterfaceRef vlan
) 
 601         SCNetworkInterfacePrivateRef    interfacePrivate        
= (SCNetworkInterfacePrivateRef
)vlan
; 
 605         if (!isA_SCVLANInterface(vlan
)) { 
 606                 _SCErrorSet(kSCStatusInvalidArgument
); 
 610         if (interfacePrivate
->prefs 
== NULL
) { 
 611                 _SCErrorSet(kSCStatusInvalidArgument
); 
 615         vlan_if 
= SCNetworkInterfaceGetBSDName(vlan
); 
 616         path    
= CFStringCreateWithFormat(NULL
, 
 619                                            kSCPrefVirtualNetworkInterfaces
, 
 620                                            kSCNetworkInterfaceTypeVLAN
, 
 622         ok 
= SCPreferencesPathRemoveValue(interfacePrivate
->prefs
, path
); 
 629 SCNetworkInterfaceRef
 
 630 SCVLANInterfaceGetPhysicalInterface(SCVLANInterfaceRef vlan
) 
 632         SCNetworkInterfacePrivateRef    interfacePrivate        
= (SCNetworkInterfacePrivateRef
)vlan
; 
 634         if (!isA_SCVLANInterface(vlan
)) { 
 635                 _SCErrorSet(kSCStatusInvalidArgument
); 
 639         return interfacePrivate
->vlan
.interface
; 
 644 SCVLANInterfaceGetTag(SCVLANInterfaceRef vlan
) 
 646         SCNetworkInterfacePrivateRef    interfacePrivate        
= (SCNetworkInterfacePrivateRef
)vlan
; 
 648         if (!isA_SCVLANInterface(vlan
)) { 
 649                 _SCErrorSet(kSCStatusInvalidArgument
); 
 653         return interfacePrivate
->vlan
.tag
; 
 658 SCVLANInterfaceGetOptions(SCVLANInterfaceRef vlan
) 
 660         SCNetworkInterfacePrivateRef    interfacePrivate        
= (SCNetworkInterfacePrivateRef
)vlan
; 
 662         if (!isA_SCVLANInterface(vlan
)) { 
 663                 _SCErrorSet(kSCStatusInvalidArgument
); 
 667         return interfacePrivate
->vlan
.options
; 
 672 SCVLANInterfaceSetPhysicalInterfaceAndTag(SCVLANInterfaceRef vlan
, SCNetworkInterfaceRef physical
, CFNumberRef tag
) 
 674         SCNetworkInterfacePrivateRef    interfacePrivate
; 
 677         if (!isA_SCVLANInterface(vlan
)) { 
 678                 _SCErrorSet(kSCStatusInvalidArgument
); 
 682         if (!isA_SCNetworkInterface(physical
)) { 
 683                 _SCErrorSet(kSCStatusInvalidArgument
); 
 687         interfacePrivate 
= (SCNetworkInterfacePrivateRef
)physical
; 
 688         if (!interfacePrivate
->supportsVLAN
) { 
 689                 _SCErrorSet(kSCStatusInvalidArgument
); 
 693         if (isA_CFNumber(tag
)) { 
 696                 CFNumberGetValue(tag
, kCFNumberIntType
, &tag_val
); 
 697                 if ((tag_val 
< 1) || (tag_val 
> 4094)) { 
 698                         _SCErrorSet(kSCStatusInvalidArgument
); 
 702                 _SCErrorSet(kSCStatusInvalidArgument
); 
 706         interfacePrivate 
= (SCNetworkInterfacePrivateRef
)vlan
; 
 707         if (interfacePrivate
->prefs 
!= NULL
) { 
 708                 SCVLANInterfaceRef      config_vlan
; 
 709                 CFDictionaryRef         dict
; 
 710                 CFMutableDictionaryRef  newDict
; 
 713                 // make sure that physical interface and tag are not used 
 714                 config_vlan 
= findVLANInterfaceAndTag(interfacePrivate
->prefs
, physical
, tag
); 
 715                 if (config_vlan 
!= NULL
) { 
 716                         if (!CFEqual(vlan
, config_vlan
)) { 
 717                                 CFRelease(config_vlan
); 
 718                                 _SCErrorSet(kSCStatusKeyExists
); 
 721                         CFRelease(config_vlan
); 
 724                 // set interface/tag in the stored preferences 
 725                 path 
= CFStringCreateWithFormat(NULL
, 
 728                                                 kSCPrefVirtualNetworkInterfaces
, 
 729                                                 kSCNetworkInterfaceTypeVLAN
, 
 730                                                 interfacePrivate
->entity_device
); 
 731                 dict 
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
); 
 732                 if (!isA_CFDictionary(dict
)) { 
 733                         // if the prefs are confused 
 735                         _SCErrorSet(kSCStatusFailed
); 
 739                 newDict 
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
); 
 740                 CFDictionarySetValue(newDict
, 
 741                                      kSCPropVirtualNetworkInterfacesVLANInterface
, 
 742                                      SCNetworkInterfaceGetBSDName(physical
)); 
 743                 CFDictionarySetValue(newDict
, kSCPropVirtualNetworkInterfacesVLANTag
, tag
); 
 744                 ok 
= SCPreferencesPathSetValue(interfacePrivate
->prefs
, path
, newDict
); 
 750                 // set physical interface 
 751                 if (interfacePrivate
->vlan
.interface 
!= NULL
) 
 752                         CFRelease(interfacePrivate
->vlan
.interface
); 
 753                 interfacePrivate
->vlan
.interface 
= CFRetain(physical
); 
 756                 if (interfacePrivate
->vlan
.tag 
!= NULL
) 
 757                         CFRelease(interfacePrivate
->vlan
.tag
); 
 758                 interfacePrivate
->vlan
.tag 
= CFRetain(tag
); 
 766 SCVLANInterfaceSetLocalizedDisplayName(SCVLANInterfaceRef vlan
, CFStringRef newName
) 
 768         SCNetworkInterfacePrivateRef    interfacePrivate        
= (SCNetworkInterfacePrivateRef
)vlan
; 
 771         if (!isA_SCVLANInterface(vlan
)) { 
 772                 _SCErrorSet(kSCStatusInvalidArgument
); 
 776         if ((newName 
!= NULL
) && !isA_CFString(newName
)) { 
 777                 _SCErrorSet(kSCStatusInvalidArgument
); 
 781         // set name in the stored preferences 
 782         if (interfacePrivate
->prefs 
!= NULL
) { 
 783                 CFDictionaryRef         dict
; 
 784                 CFMutableDictionaryRef  newDict
; 
 787                 path 
= CFStringCreateWithFormat(NULL
, 
 790                                                 kSCPrefVirtualNetworkInterfaces
, 
 791                                                 kSCNetworkInterfaceTypeVLAN
, 
 792                                                 interfacePrivate
->entity_device
); 
 793                 dict 
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
); 
 794                 if (!isA_CFDictionary(dict
)) { 
 795                         // if the prefs are confused 
 797                         _SCErrorSet(kSCStatusFailed
); 
 801                 newDict 
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
); 
 802                 if (newName 
!= NULL
) { 
 803                         CFDictionarySetValue(newDict
, kSCPropUserDefinedName
, newName
); 
 805                         CFDictionaryRemoveValue(newDict
, kSCPropUserDefinedName
); 
 807                 ok 
= SCPreferencesPathSetValue(interfacePrivate
->prefs
, path
, newDict
); 
 812         // set name in the SCVLANInterfaceRef 
 814                 if (interfacePrivate
->localized_name 
!= NULL
) { 
 815                         CFRelease(interfacePrivate
->localized_name
); 
 816                         interfacePrivate
->localized_name 
= NULL
; 
 818                 if (newName 
!= NULL
) { 
 819                         interfacePrivate
->localized_name 
= CFStringCreateCopy(NULL
, newName
); 
 828 SCVLANInterfaceSetOptions(SCVLANInterfaceRef vlan
, CFDictionaryRef newOptions
) 
 830         SCNetworkInterfacePrivateRef    interfacePrivate        
= (SCNetworkInterfacePrivateRef
)vlan
; 
 833         if (!isA_SCVLANInterface(vlan
)) { 
 834                 _SCErrorSet(kSCStatusInvalidArgument
); 
 838         if ((newOptions 
!= NULL
) && !isA_CFDictionary(newOptions
)) { 
 839                 _SCErrorSet(kSCStatusInvalidArgument
); 
 843         // set options in the stored preferences 
 844         if (interfacePrivate
->prefs 
!= NULL
) { 
 845                 CFDictionaryRef         dict
; 
 846                 CFMutableDictionaryRef  newDict
; 
 849                 path 
= CFStringCreateWithFormat(NULL
, 
 852                                                 kSCPrefVirtualNetworkInterfaces
, 
 853                                                 kSCNetworkInterfaceTypeVLAN
, 
 854                                                 interfacePrivate
->entity_device
); 
 855                 dict 
= SCPreferencesPathGetValue(interfacePrivate
->prefs
, path
); 
 856                 if (!isA_CFDictionary(dict
)) { 
 857                         // if the prefs are confused 
 859                         _SCErrorSet(kSCStatusFailed
); 
 863                 newDict 
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
); 
 864                 if (newOptions 
!= NULL
) { 
 865                         CFDictionarySetValue(newDict
, kSCPropVirtualNetworkInterfacesVLANOptions
, newOptions
); 
 867                         CFDictionaryRemoveValue(newDict
, kSCPropVirtualNetworkInterfacesVLANOptions
); 
 869                 ok 
= SCPreferencesPathSetValue(interfacePrivate
->prefs
, path
, newDict
); 
 874         // set options in the SCVLANInterfaceRef 
 876                 if (interfacePrivate
->vlan
.options 
!= NULL
) { 
 877                         CFRelease(interfacePrivate
->vlan
.options
); 
 878                         interfacePrivate
->vlan
.options 
= NULL
; 
 880                 if (newOptions 
!= NULL
) { 
 881                         interfacePrivate
->vlan
.options 
= CFDictionaryCreateCopy(NULL
, newOptions
); 
 890 #pragma mark SCVLANInterface management 
 894 __vlan_set(int s
, CFStringRef interface_if
, CFStringRef physical_if
, CFNumberRef tag
) 
 900         bzero(&ifr
, sizeof(ifr
)); 
 901         bzero(&vreq
, sizeof(vreq
)); 
 904         (void) _SC_cfstring_to_cstring(interface_if
, 
 906                                        sizeof(ifr
.ifr_name
), 
 907                                        kCFStringEncodingASCII
); 
 908         ifr
.ifr_data 
= (caddr_t
)&vreq
; 
 910         // physical interface 
 911         (void) _SC_cfstring_to_cstring(physical_if
, 
 913                                        sizeof(vreq
.vlr_parent
), 
 914                                        kCFStringEncodingASCII
); 
 917         CFNumberGetValue(tag
, kCFNumberIntType
, &tag_val
); 
 918         vreq
.vlr_tag 
= tag_val
; 
 920         // update physical interface and tag 
 921         if (ioctl(s
, SIOCSIFVLAN
, (caddr_t
)&ifr
) == -1) { 
 922                 SCLog(TRUE
, LOG_ERR
, CFSTR("ioctl(SIOCSIFVLAN) failed: %s"), strerror(errno
)); 
 923                 _SCErrorSet(kSCStatusFailed
); 
 932 __vlan_clear(int s
, CFStringRef interface_if
) 
 937         bzero(&ifr
, sizeof(ifr
)); 
 938         bzero(&vreq
, sizeof(vreq
)); 
 941         (void) _SC_cfstring_to_cstring(interface_if
, 
 943                                        sizeof(ifr
.ifr_name
), 
 944                                        kCFStringEncodingASCII
); 
 945         ifr
.ifr_data 
= (caddr_t
)&vreq
; 
 947         // clear physical interface 
 948         bzero(&vreq
.vlr_parent
, sizeof(vreq
.vlr_parent
)); 
 953         // update physical interface and tag 
 954         if (ioctl(s
, SIOCSIFVLAN
, (caddr_t
)&ifr
) == -1) { 
 955                 SCLog(TRUE
, LOG_ERR
, CFSTR("ioctl(SIOCSIFVLAN) failed: %s"), strerror(errno
)); 
 956                 _SCErrorSet(kSCStatusFailed
); 
 965 _SCVLANInterfaceUpdateConfiguration(SCPreferencesRef prefs
) 
 967         CFArrayRef                      active          
= NULL
; 
 968         CFArrayRef                      config          
= NULL
; 
 969         CFMutableDictionaryRef          devices         
= NULL
; 
 977                 _SCErrorSet(kSCStatusInvalidArgument
); 
 981         /* configured VLANs */ 
 982         config 
= SCVLANInterfaceCopyAll(prefs
); 
 983         nConfig 
= CFArrayGetCount(config
); 
 985         /* physical interfaces */ 
 986         devices 
= CFDictionaryCreateMutable(NULL
, 
 988                                             &kCFTypeDictionaryKeyCallBacks
, 
 989                                             &kCFTypeDictionaryValueCallBacks
); 
 992         active  
= _SCVLANInterfaceCopyActive(); 
 993         nActive 
= CFArrayGetCount(active
); 
 995         /* remove any no-longer-configured VLAN interfaces */ 
 996         for (i 
= 0; i 
< nActive
; i
++) { 
 997                 SCVLANInterfaceRef      a_vlan
; 
 998                 CFStringRef             a_vlan_if
; 
1000                 Boolean                 found   
= FALSE
; 
1002                 a_vlan    
= CFArrayGetValueAtIndex(active
, i
); 
1003                 a_vlan_if 
= SCNetworkInterfaceGetBSDName(a_vlan
); 
1005                 for (j 
= 0; j 
< nConfig
; j
++) { 
1006                         SCVLANInterfaceRef      c_vlan
; 
1007                         CFStringRef             c_vlan_if
; 
1009                         c_vlan    
= CFArrayGetValueAtIndex(config
, j
); 
1010                         c_vlan_if 
= SCNetworkInterfaceGetBSDName(c_vlan
); 
1012                         if (CFEqual(a_vlan_if
, c_vlan_if
)) { 
1019                         // remove VLAN interface 
1021                                 s 
= inet_dgram_socket(); 
1028                         if (!__destroyInterface(s
, a_vlan_if
)) { 
1035         /* create (and update) configured VLAN interfaces */ 
1036         for (i 
= 0; i 
< nConfig
; i
++) { 
1037                 SCVLANInterfaceRef      c_vlan
; 
1038                 CFStringRef             c_vlan_if
; 
1039                 SCNetworkInterfaceRef   c_vlan_physical
; 
1040                 Boolean                 found           
= FALSE
; 
1042                 CFBooleanRef            supported
; 
1044                 c_vlan          
= CFArrayGetValueAtIndex(config
, i
); 
1045                 c_vlan_if       
= SCNetworkInterfaceGetBSDName(c_vlan
); 
1046                 c_vlan_physical 
= SCVLANInterfaceGetPhysicalInterface(c_vlan
); 
1048                 if (c_vlan_physical 
== NULL
) { 
1051                 // determine if the physical interface supports VLANs 
1052                 supported 
= CFDictionaryGetValue(devices
, c_vlan_physical
); 
1053                 if (supported 
== NULL
) { 
1054                         SCNetworkInterfacePrivateRef    c_vlan_physicalPrivate  
= (SCNetworkInterfacePrivateRef
)c_vlan_physical
; 
1056                         supported 
= c_vlan_physicalPrivate
->supportsVLAN 
? kCFBooleanTrue
 
1058                         CFDictionaryAddValue(devices
, c_vlan_physical
, supported
); 
1061                 for (j 
= 0; j 
< nActive
; j
++) { 
1062                         SCVLANInterfaceRef      a_vlan
; 
1063                         CFStringRef             a_vlan_if
; 
1065                         a_vlan    
= CFArrayGetValueAtIndex(active
, j
); 
1066                         a_vlan_if 
= SCNetworkInterfaceGetBSDName(a_vlan
); 
1068                         if (CFEqual(c_vlan_if
, a_vlan_if
)) { 
1069                                 if (!CFEqual(c_vlan
, a_vlan
)) { 
1070                                         // update VLAN interface 
1072                                                 s 
= inet_dgram_socket(); 
1080                                         if (!CFBooleanGetValue(supported
) 
1081                                             || !__vlan_clear(s
, c_vlan_if
) 
1082                                             || !__vlan_set(s
, c_vlan_if
, 
1083                                                            SCNetworkInterfaceGetBSDName(c_vlan_physical
), 
1084                                                            SCVLANInterfaceGetTag(c_vlan
))) { 
1085                                                 // something went wrong, try to blow the VLAN away 
1086                                                 if (!CFBooleanGetValue(supported
)) { 
1087                                                         _SCErrorSet(kSCStatusFailed
); 
1089                                                 (void)__destroyInterface(s
, c_vlan_if
); 
1099                 if (!found 
&& CFBooleanGetValue(supported
)) { 
1100                         // if the physical interface supports VLANs, add new interface 
1104                                 s 
= inet_dgram_socket(); 
1112                         created 
= __createInterface(s
, c_vlan_if
); 
1116                                            SCNetworkInterfaceGetBSDName(c_vlan_physical
), 
1117                                            SCVLANInterfaceGetTag(c_vlan
))) { 
1119                                         // something went wrong, try to blow the VLAN away 
1120                                         (void)__destroyInterface(s
, c_vlan_if
); 
1132         if (active
)     CFRelease(active
); 
1133         if (config
)     CFRelease(config
); 
1134         if (devices
)    CFRelease(devices
); 
1135         if (s 
!= -1)    (void) close(s
); 
1142 #pragma mark Deprecated SPIs (remove when no longer referenced) 
1145 /* ---------- VLAN "device" ---------- */ 
1148 IsVLANSupported(CFStringRef device
) 
1150         return __SCNetworkInterfaceSupportsVLAN(device
); 
1153 /* ---------- VLANInterface ---------- */ 
1157         /* base CFType information */ 
1158         CFRuntimeBase                   cfBase
; 
1160         /* vlan interface configuration */ 
1161         CFStringRef                     ifname
;         // e.g. vlan0, vlan1, ... 
1162         CFStringRef                     device
;         // e.g. en0, en1, ... 
1163         CFNumberRef                     tag
;            // e.g. 1 <= tag <= 4094 
1164         CFDictionaryRef                 options
;        // e.g. UserDefinedName 
1166 } VLANInterfacePrivate
, * VLANInterfacePrivateRef
; 
1169 static CFStringRef      
__VLANInterfaceCopyDescription  (CFTypeRef cf
); 
1170 static void             __VLANInterfaceDeallocate       (CFTypeRef cf
); 
1171 static Boolean          
__VLANInterfaceEqual            (CFTypeRef cf1
, CFTypeRef cf2
); 
1174 static const CFRuntimeClass __VLANInterfaceClass 
= { 
1176         "VLANInterface",                        // className 
1179         __VLANInterfaceDeallocate
,              // dealloc 
1180         __VLANInterfaceEqual
,                   // equal 
1182         NULL
,                                   // copyFormattingDesc 
1183         __VLANInterfaceCopyDescription          
// copyDebugDesc 
1187 static CFTypeID         __kVLANInterfaceTypeID  
= _kCFRuntimeNotATypeID
; 
1190 static pthread_once_t   vlanInterface_init      
= PTHREAD_ONCE_INIT
; 
1194 __VLANInterfaceCopyDescription(CFTypeRef cf
) 
1196         CFAllocatorRef          allocator       
= CFGetAllocator(cf
); 
1197         CFMutableStringRef      result
; 
1198         VLANInterfacePrivateRef vlanPrivate     
= (VLANInterfacePrivateRef
)cf
; 
1200         result 
= CFStringCreateMutable(allocator
, 0); 
1201         CFStringAppendFormat(result
, NULL
, CFSTR("<VLANInterface %p [%p]> {"), cf
, allocator
); 
1202         CFStringAppendFormat(result
, NULL
, CFSTR("if = %@"), vlanPrivate
->ifname
); 
1203         CFStringAppendFormat(result
, NULL
, CFSTR(", device = %@"), vlanPrivate
->device
); 
1204         CFStringAppendFormat(result
, NULL
, CFSTR(", tag = %@"), vlanPrivate
->tag
); 
1205         if (vlanPrivate
->options 
!= NULL
) { 
1206                 CFStringAppendFormat(result
, NULL
, CFSTR(", options = %@"), vlanPrivate
->options
); 
1208         CFStringAppendFormat(result
, NULL
, CFSTR("}")); 
1215 __VLANInterfaceDeallocate(CFTypeRef cf
) 
1217         VLANInterfacePrivateRef vlanPrivate     
= (VLANInterfacePrivateRef
)cf
; 
1219         /* release resources */ 
1221         CFRelease(vlanPrivate
->ifname
); 
1222         CFRelease(vlanPrivate
->device
); 
1223         CFRelease(vlanPrivate
->tag
); 
1224         if (vlanPrivate
->options
)       CFRelease(vlanPrivate
->options
); 
1231 __VLANInterfaceEquiv(CFTypeRef cf1
, CFTypeRef cf2
) 
1233         VLANInterfacePrivateRef vlan1   
= (VLANInterfacePrivateRef
)cf1
; 
1234         VLANInterfacePrivateRef vlan2   
= (VLANInterfacePrivateRef
)cf2
; 
1239         if (!CFEqual(vlan1
->ifname
, vlan2
->ifname
)) 
1240                 return FALSE
;   // if not the same interface 
1242         if (!CFEqual(vlan1
->device
, vlan2
->device
)) 
1243                 return FALSE
;   // if not the same device 
1245         if (!CFEqual(vlan1
->tag
, vlan2
->tag
)) 
1246                 return FALSE
;   // if not the same tag 
1253 __VLANInterfaceEqual(CFTypeRef cf1
, CFTypeRef cf2
) 
1255         VLANInterfacePrivateRef vlan1   
= (VLANInterfacePrivateRef
)cf1
; 
1256         VLANInterfacePrivateRef vlan2   
= (VLANInterfacePrivateRef
)cf2
; 
1258         if (!__VLANInterfaceEquiv(vlan1
, vlan2
)) 
1259                 return FALSE
;   // if not the same VLAN interface/device/tag 
1261         if (vlan1
->options 
!= vlan2
->options
) { 
1262                 // if the options may differ 
1263                 if ((vlan1
->options 
!= NULL
) && (vlan2
->options 
!= NULL
)) { 
1264                         // if both VLANs have options 
1265                         if (!CFEqual(vlan1
->options
, vlan2
->options
)) { 
1266                                 // if the options are not equal 
1270                         // if only one VLAN has options 
1280 __VLANInterfaceInitialize(void) 
1282         __kVLANInterfaceTypeID 
= _CFRuntimeRegisterClass(&__VLANInterfaceClass
); 
1287 static __inline__ CFTypeRef
 
1288 isA_VLANInterface(CFTypeRef obj
) 
1290         return (isA_CFType(obj
, VLANInterfaceGetTypeID())); 
1295 VLANInterfaceGetTypeID(void) 
1297         pthread_once(&vlanInterface_init
, __VLANInterfaceInitialize
);   /* initialize runtime */ 
1298         return __kVLANInterfaceTypeID
; 
1302 static VLANInterfaceRef
 
1303 __VLANInterfaceCreatePrivate(CFAllocatorRef     allocator
, 
1307                              CFDictionaryRef    options
) 
1309         VLANInterfacePrivateRef         vlanPrivate
; 
1312         /* initialize runtime */ 
1313         pthread_once(&vlanInterface_init
, __VLANInterfaceInitialize
); 
1316         size        
= sizeof(VLANInterfacePrivate
) - sizeof(CFRuntimeBase
); 
1317         vlanPrivate 
= (VLANInterfacePrivateRef
)_CFRuntimeCreateInstance(allocator
, 
1318                                                                         __kVLANInterfaceTypeID
, 
1325         /* establish the vlan */ 
1327         vlanPrivate
->ifname  
= CFStringCreateCopy(allocator
, ifname
); 
1328         vlanPrivate
->device  
= CFStringCreateCopy(allocator
, device
); 
1329         vlanPrivate
->tag     
= CFRetain(tag
); 
1330         if (options 
!= NULL
) { 
1331                 vlanPrivate
->options 
= CFDictionaryCreateCopy(allocator
, options
); 
1333                 vlanPrivate
->options 
= NULL
; 
1336         return (VLANInterfaceRef
)vlanPrivate
; 
1341 VLANInterfaceGetInterface(VLANInterfaceRef vlan
) 
1343         VLANInterfacePrivateRef vlanPrivate     
= (VLANInterfacePrivateRef
)vlan
; 
1344         CFStringRef             vlan_if         
= NULL
; 
1346         if (isA_VLANInterface(vlan
)) { 
1347                 vlan_if 
= vlanPrivate
->ifname
; 
1355 VLANInterfaceGetDevice(VLANInterfaceRef vlan
) 
1357         VLANInterfacePrivateRef vlanPrivate     
= (VLANInterfacePrivateRef
)vlan
; 
1358         CFStringRef             vlan_device     
= NULL
; 
1360         if (isA_VLANInterface(vlan
)) { 
1361                 vlan_device 
= vlanPrivate
->device
; 
1369 VLANInterfaceSetDevice(VLANInterfaceRef vlan
, CFStringRef newDevice
) 
1371         VLANInterfacePrivateRef vlanPrivate     
= (VLANInterfacePrivateRef
)vlan
; 
1373         if (isA_VLANInterface(vlan
)) { 
1374                 CFAllocatorRef  allocator       
= CFGetAllocator(vlan
); 
1376                 CFRelease(vlanPrivate
->device
); 
1377                 vlanPrivate
->device 
= CFStringCreateCopy(allocator
, newDevice
); 
1385 VLANInterfaceGetTag(VLANInterfaceRef vlan
) 
1387         VLANInterfacePrivateRef vlanPrivate     
= (VLANInterfacePrivateRef
)vlan
; 
1388         CFNumberRef             vlan_tag        
= NULL
; 
1390         if (isA_VLANInterface(vlan
)) { 
1391                 vlan_tag 
= vlanPrivate
->tag
; 
1399 VLANInterfaceSetTag(VLANInterfaceRef vlan
, CFNumberRef newTag
) 
1401         VLANInterfacePrivateRef vlanPrivate     
= (VLANInterfacePrivateRef
)vlan
; 
1403         if (isA_VLANInterface(vlan
)) { 
1404                 CFRelease(vlanPrivate
->tag
); 
1405                 vlanPrivate
->tag 
= CFRetain(newTag
); 
1413 VLANInterfaceGetOptions(VLANInterfaceRef vlan
) 
1415         VLANInterfacePrivateRef vlanPrivate     
= (VLANInterfacePrivateRef
)vlan
; 
1416         CFDictionaryRef         vlan_options    
= NULL
; 
1418         if (isA_VLANInterface(vlan
)) { 
1419                 vlan_options 
= vlanPrivate
->options
; 
1422         return vlan_options
; 
1427 VLANInterfaceSetOptions(VLANInterfaceRef vlan
, CFDictionaryRef newOptions
) 
1429         VLANInterfacePrivateRef vlanPrivate     
= (VLANInterfacePrivateRef
)vlan
; 
1431         if (isA_VLANInterface(vlan
)) { 
1432                 CFAllocatorRef  allocator       
= CFGetAllocator(vlan
); 
1434                 if (vlanPrivate
->options
)       CFRelease(vlanPrivate
->options
); 
1435                 if (newOptions 
!= NULL
) { 
1436                         vlanPrivate
->options 
= CFDictionaryCreateCopy(allocator
, newOptions
); 
1438                         vlanPrivate
->options 
= NULL
; 
1446 /* ---------- VLANPreferences ---------- */ 
1450         /* base CFType information */ 
1451         CFRuntimeBase                   cfBase
; 
1454         pthread_mutex_t                 lock
; 
1456         /* underlying preferences */ 
1457         SCPreferencesRef                prefs
; 
1459         /* base VLANs (before any commits) */ 
1462 } VLANPreferencesPrivate
, * VLANPreferencesPrivateRef
; 
1465 static CFStringRef      
__VLANPreferencesCopyDescription        (CFTypeRef cf
); 
1466 static void             __VLANPreferencesDeallocate             (CFTypeRef cf
); 
1469 static const CFRuntimeClass __VLANPreferencesClass 
= { 
1471         "VLANPreferences",                      // className 
1474         __VLANPreferencesDeallocate
,            // dealloc 
1477         NULL
,                                   // copyFormattingDesc 
1478         __VLANPreferencesCopyDescription        
// copyDebugDesc 
1482 static CFTypeID         __kVLANPreferencesTypeID        
= _kCFRuntimeNotATypeID
; 
1485 static pthread_once_t   vlanPreferences_init            
= PTHREAD_ONCE_INIT
; 
1489 __VLANPreferencesCopyDescription(CFTypeRef cf
) 
1491         CFAllocatorRef                  allocator       
= CFGetAllocator(cf
); 
1495         VLANPreferencesPrivateRef       prefsPrivate    
= (VLANPreferencesPrivateRef
)cf
; 
1496         CFMutableStringRef              result
; 
1498         result 
= CFStringCreateMutable(allocator
, 0); 
1499         CFStringAppendFormat(result
, NULL
, CFSTR("<VLANPreferences %p [%p]> {"), cf
, allocator
); 
1501         keys 
= SCPreferencesCopyKeyList(prefsPrivate
->prefs
); 
1502         n 
= CFArrayGetCount(keys
); 
1503         for (i 
= 0; i 
< n
; i
++) { 
1505                 CFPropertyListRef       val
; 
1507                 key 
= CFArrayGetValueAtIndex(keys
, i
); 
1508                 val 
= SCPreferencesGetValue(prefsPrivate
->prefs
, key
); 
1510                 CFStringAppendFormat(result
, NULL
, CFSTR("%@ : %@"), key
, val
); 
1514         CFStringAppendFormat(result
, NULL
, CFSTR(" }")); 
1524 __VLANPreferencesDeallocate(CFTypeRef cf
) 
1526         VLANPreferencesPrivateRef       prefsPrivate    
= (VLANPreferencesPrivateRef
)cf
; 
1528         /* release resources */ 
1530         pthread_mutex_destroy(&prefsPrivate
->lock
); 
1532         if (prefsPrivate
->prefs
)        CFRelease(prefsPrivate
->prefs
); 
1533         if (prefsPrivate
->vlBase
)       CFRelease(prefsPrivate
->vlBase
); 
1540 __VLANPreferencesInitialize(void) 
1542         __kVLANPreferencesTypeID 
= _CFRuntimeRegisterClass(&__VLANPreferencesClass
); 
1547 static __inline__ CFTypeRef
 
1548 isA_VLANPreferences(CFTypeRef obj
) 
1550         return (isA_CFType(obj
, VLANPreferencesGetTypeID())); 
1555 _VLANPreferencesCopyActiveInterfaces() 
1557         CFArrayCallBacks        callbacks
; 
1558         struct ifaddrs          
*ifap
; 
1559         struct ifaddrs          
*ifp
; 
1561         CFMutableArrayRef       vlans   
= NULL
; 
1563         if (getifaddrs(&ifap
) == -1) { 
1564                 SCLog(TRUE
, LOG_ERR
, CFSTR("getifaddrs() failed: %s"), strerror(errno
)); 
1565                 _SCErrorSet(kSCStatusFailed
); 
1569         s 
= inet_dgram_socket(); 
1575         callbacks 
= kCFTypeArrayCallBacks
; 
1576         callbacks
.equal 
= __VLANInterfaceEquiv
; 
1577         vlans 
= CFArrayCreateMutable(NULL
, 0, &callbacks
); 
1579         for (ifp 
= ifap
; ifp 
!= NULL
; ifp 
= ifp
->ifa_next
) { 
1580                 switch (ifp
->ifa_addr
->sa_family
) { 
1583                                 struct if_data          
*if_data
; 
1586                                 VLANInterfaceRef        vlan
; 
1587                                 CFStringRef             vlan_if
; 
1588                                 char                    vlr_parent
[IFNAMSIZ 
+ 1]; 
1590                                 struct vlanreq          vreq
; 
1592                                 if_data 
= (struct if_data 
*)ifp
->ifa_data
; 
1593                                 if (if_data 
== NULL
) { 
1594                                         break;  // if no interface data 
1597                                 if (if_data
->ifi_type 
!= IFT_L2VLAN
) { 
1598                                         break;  // if not VLAN 
1601                                 bzero(&ifr
, sizeof(ifr
)); 
1602                                 bzero(&vreq
, sizeof(vreq
)); 
1603                                 strncpy(ifr
.ifr_name
, ifp
->ifa_name
, sizeof(ifr
.ifr_name
)); 
1604                                 ifr
.ifr_data 
= (caddr_t
)&vreq
; 
1606                                 if (ioctl(s
, SIOCGIFVLAN
, (caddr_t
)&ifr
) == -1) { 
1607                                         SCLog(TRUE
, LOG_ERR
, CFSTR("ioctl() failed: %s"), strerror(errno
)); 
1610                                         _SCErrorSet(kSCStatusFailed
); 
1613                                 vlr_tag 
= vreq
.vlr_tag
; 
1614                                 bzero(&vlr_parent
, sizeof(vlr_parent
)); 
1615                                 bcopy(vreq
.vlr_parent
, vlr_parent
, IFNAMSIZ
); 
1617                                 vlan_if 
= CFStringCreateWithCString(NULL
, ifp
->ifa_name
, kCFStringEncodingASCII
); 
1618                                 device  
= CFStringCreateWithCString(NULL
, vlr_parent
, kCFStringEncodingASCII
); 
1619                                 tag     
= CFNumberCreate(NULL
, kCFNumberIntType
, &vlr_tag
); 
1620                                 vlan    
= __VLANInterfaceCreatePrivate(NULL
, vlan_if
, device
, tag
, NULL
); 
1621                                 CFArrayAppendValue(vlans
, vlan
); 
1643 findVLAN(CFArrayRef vlans
, CFStringRef device
, CFNumberRef tag
) 
1645         CFIndex found   
= kCFNotFound
; 
1649         n 
= isA_CFArray(vlans
) ? CFArrayGetCount(vlans
) : 0; 
1650         for (i 
= 0; i 
< n
; i
++) { 
1651                 CFDictionaryRef vlan_dict
; 
1652                 CFStringRef     vlan_device
; 
1653                 CFStringRef     vlan_if
; 
1654                 CFNumberRef     vlan_tag
; 
1656                 vlan_dict 
= CFArrayGetValueAtIndex(vlans
, i
); 
1657                 if (!isA_CFDictionary(vlan_dict
)) { 
1658                         continue;       // if the prefs are confused 
1661                 vlan_if 
= CFDictionaryGetValue(vlan_dict
, __kVLANInterface_interface
); 
1662                 if (!isA_CFString(vlan_if
)) { 
1663                         continue;       // if the prefs are confused 
1666                 vlan_device 
= CFDictionaryGetValue(vlan_dict
, __kVLANInterface_device
); 
1667                 if (isA_CFString(vlan_device
)) { 
1668                         if (!CFEqual(device
, vlan_device
)) { 
1669                                 continue;       // if not a match 
1673                 vlan_tag 
= CFDictionaryGetValue(vlan_dict
, __kVLANInterface_tag
); 
1674                 if (isA_CFNumber(vlan_tag
)) { 
1675                         if (!CFEqual(tag
, vlan_tag
)) { 
1676                                 continue;       // if not a match 
1680                 // if we have found a match 
1690 setConfigurationChanged(VLANPreferencesRef prefs
) 
1692         VLANPreferencesPrivateRef       prefsPrivate    
= (VLANPreferencesPrivateRef
)prefs
; 
1695          * to facilitate device configuration we will take 
1696          * a snapshot of the VLAN preferences before any 
1697          * changes are made.  Then, when the changes are 
1698          * applied we can compare what we had to what we 
1699          * want and configured the system accordingly. 
1701         if (prefsPrivate
->vlBase 
== NULL
) { 
1702                 prefsPrivate
->vlBase 
= VLANPreferencesCopyInterfaces(prefs
); 
1710 VLANPreferencesGetTypeID(void) 
1712         pthread_once(&vlanPreferences_init
, __VLANPreferencesInitialize
);       /* initialize runtime */ 
1713         return __kVLANPreferencesTypeID
; 
1718 VLANPreferencesCreate(CFAllocatorRef allocator
) 
1721         CFStringRef                     bundleID        
= NULL
; 
1722         CFStringRef                     name            
= CFSTR("VLANConfiguration"); 
1723         VLANPreferencesPrivateRef       prefsPrivate
; 
1726         /* initialize runtime */ 
1727         pthread_once(&vlanPreferences_init
, __VLANPreferencesInitialize
); 
1729         /* allocate preferences */ 
1730         size         
= sizeof(VLANPreferencesPrivate
) - sizeof(CFRuntimeBase
); 
1731         prefsPrivate 
= (VLANPreferencesPrivateRef
)_CFRuntimeCreateInstance(allocator
, 
1732                                                                            __kVLANPreferencesTypeID
, 
1735         if (prefsPrivate 
== NULL
) { 
1739         /* establish the prefs */ 
1741         pthread_mutex_init(&prefsPrivate
->lock
, NULL
); 
1743         bundle 
= CFBundleGetMainBundle(); 
1745                 bundleID 
= CFBundleGetIdentifier(bundle
); 
1751                         url 
= CFBundleCopyExecutableURL(bundle
); 
1753                                 bundleID 
= CFURLCopyPath(url
); 
1760                 CFStringRef     fullName
; 
1762                 if (CFEqual(bundleID
, CFSTR("/"))) { 
1763                         CFRelease(bundleID
); 
1764                         bundleID 
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("(%d)"), getpid()); 
1767                 fullName 
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("%@:%@"), bundleID
, name
); 
1769                 CFRelease(bundleID
); 
1774         prefsPrivate
->prefs 
= SCPreferencesCreate(allocator
, name
, VLAN_PREFERENCES_ID
); 
1777         prefsPrivate
->vlBase 
= NULL
; 
1779         return (VLANPreferencesRef
)prefsPrivate
; 
1784 VLANPreferencesCopyInterfaces(VLANPreferencesRef prefs
) 
1786         CFAllocatorRef                  allocator
; 
1787         CFArrayCallBacks                callbacks
; 
1790         VLANPreferencesPrivateRef       prefsPrivate    
= (VLANPreferencesPrivateRef
)prefs
; 
1791         CFMutableArrayRef               result
; 
1794         if (!isA_VLANPreferences(prefs
)) { 
1795                 _SCErrorSet(kSCStatusInvalidArgument
); 
1799         allocator 
= CFGetAllocator(prefs
); 
1800         callbacks 
= kCFTypeArrayCallBacks
; 
1801         callbacks
.equal 
= __VLANInterfaceEquiv
; 
1802         result 
= CFArrayCreateMutable(allocator
, 0, &callbacks
); 
1804         vlans 
= SCPreferencesGetValue(prefsPrivate
->prefs
, VLAN_PREFERENCES_VLANS
); 
1805         n 
= isA_CFArray(vlans
) ? CFArrayGetCount(vlans
) : 0; 
1806         for (i 
= 0; i 
< n
; i
++) { 
1807                 CFDictionaryRef         vlan_dict
; 
1809                 CFDictionaryRef         options
; 
1811                 VLANInterfaceRef        vlan
; 
1812                 CFStringRef             vlan_if
; 
1814                 vlan_dict 
= CFArrayGetValueAtIndex(vlans
, i
); 
1815                 if (!isA_CFDictionary(vlan_dict
)) { 
1816                         continue;       // if the prefs are confused 
1819                 vlan_if 
= CFDictionaryGetValue(vlan_dict
, __kVLANInterface_interface
); 
1820                 if (!isA_CFString(vlan_if
)) { 
1821                         continue;       // if the prefs are confused 
1825                 device 
= CFDictionaryGetValue(vlan_dict
, __kVLANInterface_device
); 
1826                 if (!isA_CFString(device
)) { 
1827                         continue;       // if the prefs are confused 
1830                 tag 
= CFDictionaryGetValue(vlan_dict
, __kVLANInterface_tag
); 
1831                 if (!isA_CFNumber(tag
)) { 
1832                         continue;       // if the prefs are confused 
1835                 options 
= CFDictionaryGetValue(vlan_dict
, __kVLANInterface_options
); 
1836                 if ((options 
!= NULL
) && !isA_CFDictionary(options
)) { 
1837                         continue;       // if the prefs are confused 
1840                 vlan 
= __VLANInterfaceCreatePrivate(allocator
, vlan_if
, device
, tag
, options
); 
1841                 CFArrayAppendValue(result
, vlan
); 
1850 VLANPreferencesAddInterface(VLANPreferencesRef  prefs
, 
1853                             CFDictionaryRef     options
) 
1855         CFArrayRef                      active_vlans
; 
1856         CFAllocatorRef                  allocator
; 
1857         CFArrayRef                      config_vlans
; 
1862         VLANInterfaceRef                newVlan         
= NULL
; 
1863         VLANPreferencesPrivateRef       prefsPrivate    
= (VLANPreferencesPrivateRef
)prefs
; 
1865         if (!isA_VLANPreferences(prefs
)) { 
1866                 _SCErrorSet(kSCStatusInvalidArgument
); 
1870         if (!isA_CFString(device
)) { 
1871                 _SCErrorSet(kSCStatusInvalidArgument
); 
1875         if (isA_CFNumber(tag
)) { 
1878                 CFNumberGetValue(tag
, kCFNumberIntType
, &tag_val
); 
1879                 if ((tag_val 
< 1) || (tag_val 
> 4094)) { 
1880                         _SCErrorSet(kSCStatusInvalidArgument
); 
1884                 _SCErrorSet(kSCStatusInvalidArgument
); 
1888         if ((options 
!= NULL
) && !isA_CFDictionary(options
)) { 
1889                 _SCErrorSet(kSCStatusInvalidArgument
); 
1893         pthread_mutex_lock(&prefsPrivate
->lock
); 
1895         /* get "configured" VLANs (and check to ensure we are not creating a duplicate) */ 
1896         config_vlans 
= SCPreferencesGetValue(prefsPrivate
->prefs
, VLAN_PREFERENCES_VLANS
); 
1897         nConfig      
= isA_CFArray(config_vlans
) ? CFArrayGetCount(config_vlans
) : 0; 
1899         dup_if 
= findVLAN(config_vlans
, device
, tag
); 
1900         if (dup_if 
!= kCFNotFound
) { 
1901                 // sorry, you can't add a vlan using the same device/tag */ 
1902                 _SCErrorSet(kSCStatusKeyExists
); 
1906         /* get "active" VLANs */ 
1907         active_vlans 
= _VLANPreferencesCopyActiveInterfaces(); 
1908         nActive      
= isA_CFArray(active_vlans
) ? CFArrayGetCount(active_vlans
) : 0; 
1910         /* create a new vlan using an unused interface name */ 
1911         allocator 
= CFGetAllocator(prefs
); 
1913         for (i 
= 0; newVlan 
== NULL
; i
++) { 
1915                 CFMutableDictionaryRef  newDict
; 
1916                 CFMutableArrayRef       newVlans
; 
1917                 CFStringRef             vlan_if
; 
1919                 vlan_if 
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("vlan%d"), i
); 
1921                 for (j 
= 0; j 
< nActive
; j
++) { 
1922                         CFStringRef             active_if
; 
1923                         VLANInterfaceRef        active_vlan
; 
1925                         active_vlan 
= CFArrayGetValueAtIndex(active_vlans
, j
); 
1926                         active_if   
= VLANInterfaceGetInterface(active_vlan
); 
1928                         if (CFEqual(vlan_if
, active_if
)) { 
1929                                 goto next_if
;   // if VLAN interface name not available 
1933                 for (j 
= 0; j 
< nConfig
; j
++) { 
1934                         CFDictionaryRef config
; 
1935                         CFStringRef     config_if
; 
1937                         config 
= CFArrayGetValueAtIndex(config_vlans
, j
); 
1938                         if (!isA_CFDictionary(config
)) { 
1939                                 continue;       // if the prefs are confused 
1942                         config_if 
= CFDictionaryGetValue(config
, __kVLANInterface_interface
); 
1943                         if (!isA_CFString(config_if
)) { 
1944                                 continue;       // if the prefs are confused 
1947                         if (CFEqual(vlan_if
, config_if
)) { 
1948                                 goto next_if
;   // if VLAN interface name not available 
1952                 /* create the vlan */ 
1954                 newDict 
= CFDictionaryCreateMutable(allocator
, 
1956                                                     &kCFTypeDictionaryKeyCallBacks
, 
1957                                                     &kCFTypeDictionaryValueCallBacks
); 
1958                 CFDictionaryAddValue(newDict
, __kVLANInterface_interface
, vlan_if
); 
1959                 CFDictionaryAddValue(newDict
, __kVLANInterface_device
,    device
); 
1960                 CFDictionaryAddValue(newDict
, __kVLANInterface_tag
,       tag
); 
1961                 if (options 
!= NULL
) { 
1962                         CFDictionaryAddValue(newDict
, __kVLANInterface_options
, options
); 
1965                 /* create the accessor handle to be returned */ 
1967                 newVlan 
= __VLANInterfaceCreatePrivate(allocator
, vlan_if
, device
, tag
, options
); 
1969                 /* yes, we're going to be changing the configuration */ 
1970                 setConfigurationChanged(prefs
); 
1972                 /* save in the prefs */ 
1975                         newVlans 
= CFArrayCreateMutable(allocator
, 0, &kCFTypeArrayCallBacks
); 
1977                         newVlans 
= CFArrayCreateMutableCopy(allocator
, 0, config_vlans
); 
1979                 CFArrayAppendValue(newVlans
, newDict
); 
1982                 (void) SCPreferencesSetValue(prefsPrivate
->prefs
, VLAN_PREFERENCES_VLANS
, newVlans
); 
1983                 CFRelease(newVlans
); 
1989         CFRelease(active_vlans
); 
1993         pthread_mutex_unlock(&prefsPrivate
->lock
); 
1995         return (VLANInterfaceRef
) newVlan
; 
2000 VLANPreferencesUpdateInterface(VLANPreferencesRef       prefs
, 
2001                                VLANInterfaceRef         vlan
, 
2002                                CFStringRef              newDevice
, 
2004                                CFDictionaryRef          newOptions
) 
2006         CFAllocatorRef                  allocator
; 
2009         CFMutableDictionaryRef          newDict
; 
2010         CFMutableArrayRef               newVlans
; 
2012         VLANPreferencesPrivateRef       prefsPrivate    
= (VLANPreferencesPrivateRef
)prefs
; 
2014         CFStringRef                     vlan_if
; 
2016         if (!isA_VLANPreferences(prefs
)) { 
2017                 _SCErrorSet(kSCStatusInvalidArgument
); 
2021         if (!isA_VLANInterface(vlan
)) { 
2022                 _SCErrorSet(kSCStatusInvalidArgument
); 
2026         if ((newDevice 
!= NULL
) && !isA_CFString(newDevice
)) { 
2027                 _SCErrorSet(kSCStatusInvalidArgument
); 
2031         if (newTag 
!= NULL
) { 
2032                 if (isA_CFNumber(newTag
)) { 
2035                         CFNumberGetValue(newTag
, kCFNumberIntType
, &tag_val
); 
2036                         if ((tag_val 
< 1) || (tag_val 
> 4094)) { 
2037                                 _SCErrorSet(kSCStatusInvalidArgument
); 
2041                         _SCErrorSet(kSCStatusInvalidArgument
); 
2046         if ((newOptions 
!= NULL
) 
2047             && !isA_CFDictionary(newOptions
) && (newOptions 
!= (CFDictionaryRef
)kCFNull
)) { 
2048                 _SCErrorSet(kSCStatusInvalidArgument
); 
2052         pthread_mutex_lock(&prefsPrivate
->lock
); 
2054         vlan_if 
= VLANInterfaceGetInterface(vlan
); 
2056         vlans 
= SCPreferencesGetValue(prefsPrivate
->prefs
, VLAN_PREFERENCES_VLANS
); 
2057         if (!isA_CFArray(vlans
)) { 
2058                 goto done
;      // if the prefs are confused 
2061         cur_if 
= findVLAN(vlans
, 
2062                           VLANInterfaceGetDevice(vlan
), 
2063                           VLANInterfaceGetTag   (vlan
)); 
2064         if (cur_if 
== kCFNotFound
) { 
2065                 _SCErrorSet(kSCStatusNoKey
); 
2069         dup_if 
= findVLAN(vlans
, 
2070                           newDevice 
!= NULL 
? newDevice 
: VLANInterfaceGetDevice(vlan
), 
2071                           newTag    
!= NULL 
? newTag    
: VLANInterfaceGetTag   (vlan
)); 
2072         if (dup_if 
!= kCFNotFound
) { 
2073                 // if the same device/tag has already been defined 
2074                 if (cur_if 
!= dup_if
) { 
2076                          * sorry, you can't update another vlan that is using 
2077                          * the same device/tag 
2079                         _SCErrorSet(kSCStatusKeyExists
); 
2084         /* update the vlan */ 
2086         if (newDevice 
!= NULL
) { 
2087                 VLANInterfaceSetDevice(vlan
, newDevice
); 
2089                 newDevice 
= VLANInterfaceGetDevice(vlan
); 
2092         if (newTag 
!= NULL
) { 
2093                 VLANInterfaceSetTag(vlan
, newTag
); 
2095                 newTag 
= VLANInterfaceGetTag(vlan
); 
2098         if (newOptions 
!= NULL
) { 
2099                 if (newOptions 
!= (CFDictionaryRef
)kCFNull
) { 
2100                         VLANInterfaceSetOptions(vlan
, newOptions
); 
2102                         VLANInterfaceSetOptions(vlan
, NULL
); 
2106                 newOptions 
= VLANInterfaceGetOptions(vlan
); 
2109         /* update the prefs */ 
2111         allocator 
= CFGetAllocator(prefs
); 
2112         newDict 
= CFDictionaryCreateMutable(allocator
, 
2114                                             &kCFTypeDictionaryKeyCallBacks
, 
2115                                             &kCFTypeDictionaryValueCallBacks
); 
2116         CFDictionaryAddValue(newDict
, __kVLANInterface_interface
, vlan_if
); 
2117         CFDictionaryAddValue(newDict
, __kVLANInterface_device
,    newDevice
); 
2118         CFDictionaryAddValue(newDict
, __kVLANInterface_tag
,       newTag
); 
2119         if (newOptions 
!= NULL
) { 
2120                 CFDictionaryAddValue(newDict
, __kVLANInterface_options
, newOptions
); 
2123         /* yes, we're going to be changing the configuration */ 
2124         setConfigurationChanged(prefs
); 
2126         /* update the prefs */ 
2128         newVlans 
= CFArrayCreateMutableCopy(allocator
, 0, vlans
); 
2129         CFArraySetValueAtIndex(newVlans
, cur_if
, newDict
); 
2132         (void) SCPreferencesSetValue(prefsPrivate
->prefs
, VLAN_PREFERENCES_VLANS
, newVlans
); 
2133         CFRelease(newVlans
); 
2139         pthread_mutex_unlock(&prefsPrivate
->lock
); 
2146 VLANPreferencesRemoveInterface(VLANPreferencesRef       prefs
, 
2147                                VLANInterfaceRef         vlan
) 
2149         CFAllocatorRef                  allocator
; 
2151         CFMutableArrayRef               newVlans
; 
2153         VLANPreferencesPrivateRef       prefsPrivate    
= (VLANPreferencesPrivateRef
)prefs
; 
2156         if (!isA_VLANPreferences(prefs
)) { 
2157                 _SCErrorSet(kSCStatusInvalidArgument
); 
2161         if (!isA_VLANInterface(vlan
)) { 
2162                 _SCErrorSet(kSCStatusInvalidArgument
); 
2166         pthread_mutex_lock(&prefsPrivate
->lock
); 
2168         vlans 
= SCPreferencesGetValue(prefsPrivate
->prefs
, VLAN_PREFERENCES_VLANS
); 
2169         if (!isA_CFArray(vlans
)) { 
2170                 _SCErrorSet(kSCStatusNoKey
); 
2171                 goto done
;      // if the prefs are confused 
2174         cur_if 
= findVLAN(vlans
, 
2175                           VLANInterfaceGetDevice(vlan
), 
2176                           VLANInterfaceGetTag   (vlan
)); 
2177         if (cur_if 
== kCFNotFound
) { 
2178                 _SCErrorSet(kSCStatusNoKey
); 
2182         /* yes, we're going to be changing the configuration */ 
2183         setConfigurationChanged(prefs
); 
2185         /* remove the vlan */ 
2187         allocator 
= CFGetAllocator(prefs
); 
2188         newVlans 
= CFArrayCreateMutableCopy(allocator
, 0, vlans
); 
2189         CFArrayRemoveValueAtIndex(newVlans
, cur_if
); 
2191         (void) SCPreferencesSetValue(prefsPrivate
->prefs
, VLAN_PREFERENCES_VLANS
, newVlans
); 
2192         CFRelease(newVlans
); 
2198         pthread_mutex_unlock(&prefsPrivate
->lock
); 
2205 VLANPreferencesCommitChanges(VLANPreferencesRef prefs
) 
2208         VLANPreferencesPrivateRef       prefsPrivate    
= (VLANPreferencesPrivateRef
)prefs
; 
2210         if (!isA_VLANPreferences(prefs
)) { 
2211                 _SCErrorSet(kSCStatusInvalidArgument
); 
2215         ok 
= SCPreferencesCommitChanges(prefsPrivate
->prefs
); 
2220         if (prefsPrivate
->vlBase 
!= NULL
)  { 
2221                 CFRelease(prefsPrivate
->vlBase
); 
2222                 prefsPrivate
->vlBase 
= NULL
; 
2230 _VLANPreferencesUpdateConfiguration(VLANPreferencesRef prefs
) 
2237 VLANPreferencesApplyChanges(VLANPreferencesRef prefs
) 
2239         SCPreferencesRef                defaultPrefs
; 
2241         VLANPreferencesPrivateRef       prefsPrivate    
= (VLANPreferencesPrivateRef
)prefs
; 
2243         if (!isA_VLANPreferences(prefs
)) { 
2244                 _SCErrorSet(kSCStatusInvalidArgument
); 
2248         pthread_mutex_lock(&prefsPrivate
->lock
); 
2250         /* apply the preferences */ 
2251         ok 
= SCPreferencesApplyChanges(prefsPrivate
->prefs
); 
2256         /* apply the VLAN configuration */ 
2257         defaultPrefs 
= SCPreferencesCreate(NULL
, CFSTR("VLANPreferencesApplyChanges"), NULL
); 
2260                  * Note: In an ideal world, we'd simply call SCPreferencesApplyChanges() 
2261                  *       Unfortunately, it's possible that the caller (e.g NetworkCfgTool) 
2262                  *       is holding the lock on the default prefs and since "Apply" attempts 
2263                  *       to grab the lock we could end up in a deadlock situation. 
2265 #include "SCPreferencesInternal.h" 
2266                 SCPreferencesPrivateRef         defaultPrefsPrivate
; 
2268                 defaultPrefsPrivate 
= (SCPreferencesPrivateRef
)defaultPrefs
; 
2270                 pthread_mutex_lock(&defaultPrefsPrivate
->lock
); 
2271                 if (defaultPrefsPrivate
->session 
== NULL
) { 
2272                         __SCPreferencesAddSession(defaultPrefs
); 
2274                 pthread_mutex_unlock(&defaultPrefsPrivate
->lock
); 
2276                 ok 
= SCDynamicStoreNotifyValue(defaultPrefsPrivate
->session
, defaultPrefsPrivate
->sessionKeyApply
); 
2278         CFRelease(defaultPrefs
); 
2285         pthread_mutex_unlock(&prefsPrivate
->lock
);