2  * Copyright (c) 2004-2006 Apple Computer, 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  * August 5, 2004                       Allan Nathanson <ajn@apple.com> 
  34 #include "net_protocol.h" 
  37 #include <sys/types.h> 
  38 #include <sys/socket.h> 
  40 #include <netinet/in.h> 
  41 #include <arpa/inet.h> 
  44 /* -------------------- */ 
  49 _compare_protocols(const void *val1
, const void *val2
, void *context
) 
  51         SCNetworkProtocolRef    p1      
= (SCNetworkProtocolRef
)val1
; 
  52         SCNetworkProtocolRef    p2      
= (SCNetworkProtocolRef
)val2
; 
  56         type1 
= SCNetworkProtocolGetProtocolType(p1
); 
  57         type2 
= SCNetworkProtocolGetProtocolType(p2
); 
  59         return CFStringCompare(type1
, type2
, 0); 
  64 __copyIPv4Address(const char *arg
) 
  67         struct sockaddr_in      sin
; 
  69         bzero(&sin
, sizeof(sin
)); 
  70         sin
.sin_len    
= sizeof(sin
); 
  71         sin
.sin_family 
= AF_INET
; 
  72         if (inet_aton(arg
, &sin
.sin_addr
) != 1) { 
  76         _SC_sockaddr_to_string((struct sockaddr 
*)&sin
, buf
, sizeof(buf
)); 
  77         return CFStringCreateWithCString(NULL
, buf
, kCFStringEncodingUTF8
); 
  82 __copyIPv6Address(const char *arg
) 
  86         struct sockaddr_in6     sin6
; 
  88         bzero(&sin6
, sizeof(sin6
)); 
  89         sin6
.sin6_len    
= sizeof(sin6
); 
  90         sin6
.sin6_family 
= AF_INET6
; 
  91         if (inet_pton(AF_INET6
, arg
, &sin6
.sin6_addr
) != 1) { 
  97                 sin6
.sin6_scope_id 
= if_nametoindex(p 
+ 1); 
 100         _SC_sockaddr_to_string((struct sockaddr 
*)&sin6
, buf
, sizeof(buf
)); 
 101         return CFStringCreateWithCString(NULL
, buf
, kCFStringEncodingUTF8
); 
 105 /* -------------------- */ 
 108 static SCNetworkProtocolRef
 
 109 _find_protocol(char *match
) 
 111         Boolean                 allowIndex      
= TRUE
; 
 114         CFStringRef             select_name     
= NULL
; 
 115         SCNetworkProtocolRef    selected        
= NULL
; 
 117         if (protocols 
== NULL
) { 
 118                 if (net_service 
== NULL
) { 
 119                         SCPrint(TRUE
, stdout
, CFSTR("network service not selected\n")); 
 123                 protocols 
= SCNetworkServiceCopyProtocols(net_service
); 
 124                 if (protocols 
== NULL
) { 
 125                         SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError())); 
 129                 n 
= CFArrayGetCount(protocols
); 
 131                         CFMutableArrayRef       sorted
; 
 133                         sorted 
= CFArrayCreateMutableCopy(NULL
, 0, protocols
); 
 134                         CFArraySortValues(sorted
, 
 138                         CFRelease(protocols
); 
 145         // try to select the protocol by its protocol type 
 147         select_name 
= CFStringCreateWithCString(NULL
, match
, kCFStringEncodingUTF8
); 
 149         n 
= CFArrayGetCount(protocols
); 
 150         for (i 
= 0; i 
< n
; i
++) { 
 151                 SCNetworkProtocolRef    protocol
; 
 154                 protocol 
= CFArrayGetValueAtIndex(protocols
, i
); 
 155                 type     
= SCNetworkProtocolGetProtocolType(protocol
); 
 156                 if (CFStringCompare(select_name
, type
, kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) { 
 167                 // try to select the protocol by its index 
 170                 val 
= strtol(str
, &end
, 10); 
 171                 if ((*str 
!= '\0') && (*end 
== '\0') && (errno 
== 0)) { 
 172                         if ((val 
> 0) && (val 
<= n
)) { 
 173                                 selected 
= CFArrayGetValueAtIndex(protocols
, val 
- 1); 
 178         if (selected 
!= NULL
) { 
 182         SCPrint(TRUE
, stdout
, CFSTR("no match, which protocol?\n")); 
 186         if (select_name 
!= NULL
) CFRelease(select_name
); 
 191 /* -------------------- */ 
 196 create_protocol(int argc
, char **argv
) 
 198         SCNetworkInterfaceRef   interface
; 
 199         CFStringRef             protocolType
; 
 201         if ((argc 
< 1) || (strlen(argv
[0]) == 0)) { 
 202                 SCPrint(TRUE
, stdout
, CFSTR("what protocol type?\n")); 
 206         if (net_service 
== NULL
) { 
 207                 SCPrint(TRUE
, stdout
, CFSTR("network service not selected\n")); 
 211         protocolType 
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
); 
 213         interface 
= SCNetworkServiceGetInterface(net_service
); 
 214         if (interface 
!= NULL
) { 
 215                 CFArrayRef      supported
; 
 219                 supported 
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
); 
 220                 n 
= (supported 
!= NULL
) ? CFArrayGetCount(supported
) : 0; 
 221                 for (i 
= 0; i 
< n
; i
++) { 
 222                         CFStringRef     supportedType
; 
 224                         supportedType 
= CFArrayGetValueAtIndex(supported
, i
); 
 225                         if (CFStringCompare(protocolType
, 
 227                                             kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) { 
 228                                 CFRelease(protocolType
); 
 229                                 protocolType 
= CFRetain(supportedType
); 
 235         if (!SCNetworkServiceAddProtocolType(net_service
, protocolType
)) { 
 236                 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError())); 
 240         _prefs_changed 
= TRUE
; 
 242         if (protocols 
!= NULL
) { 
 243                 CFRelease(protocols
); 
 247         if (net_protocol 
!= NULL
) CFRelease(net_protocol
); 
 248 //      net_protocol = NULL; 
 250         net_protocol 
= SCNetworkServiceCopyProtocol(net_service
, protocolType
); 
 251         if (net_protocol 
== NULL
) { 
 252                 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError())); 
 256         SCPrint(TRUE
, stdout
, 
 257                 CFSTR("protocol \"%@\" selected\n"), 
 262         CFRelease(protocolType
); 
 267 /* -------------------- */ 
 272 disable_protocol(int argc
, char **argv
) 
 274         SCNetworkProtocolRef    protocol        
= NULL
; 
 277                 protocol 
= _find_protocol(argv
[0]); 
 279                 if (net_protocol 
!= NULL
) { 
 280                         protocol 
= net_protocol
; 
 282                         SCPrint(TRUE
, stdout
, CFSTR("protocol not selected\n")); 
 287         if (protocol 
== NULL
) { 
 291         if (!SCNetworkProtocolSetEnabled(protocol
, FALSE
)) { 
 292                 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError())); 
 296         _prefs_changed 
= TRUE
; 
 302 /* -------------------- */ 
 307 enable_protocol(int argc
, char **argv
) 
 309         SCNetworkProtocolRef    protocol        
= NULL
; 
 312                 protocol 
= _find_protocol(argv
[0]); 
 314                 if (net_protocol 
!= NULL
) { 
 315                         protocol 
= net_protocol
; 
 317                         SCPrint(TRUE
, stdout
, CFSTR("protocol not selected\n")); 
 322         if (protocol 
== NULL
) { 
 326         if (!SCNetworkProtocolSetEnabled(protocol
, TRUE
)) { 
 327                 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError())); 
 331         _prefs_changed 
= TRUE
; 
 337 /* -------------------- */ 
 342 remove_protocol(int argc
, char **argv
) 
 344         SCNetworkProtocolRef    protocol        
= NULL
; 
 345         CFStringRef             protocolType
; 
 348                 protocol 
= _find_protocol(argv
[0]); 
 350                 if (net_protocol 
!= NULL
) { 
 351                         protocol 
= net_protocol
; 
 353                         SCPrint(TRUE
, stdout
, CFSTR("protocol not selected\n")); 
 358         if (protocol 
== NULL
) { 
 364         protocolType 
= SCNetworkProtocolGetProtocolType(protocol
); 
 365         if (!SCNetworkServiceRemoveProtocolType(net_service
, protocolType
)) { 
 366                 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError())); 
 370         _prefs_changed 
= TRUE
; 
 372         SCPrint(TRUE
, stdout
, 
 373                 CFSTR("protocol \"%@\" removed\n"), 
 376         if ((net_protocol 
!= NULL
) && CFEqual(protocol
, net_protocol
)) { 
 377                 CFRelease(net_protocol
); 
 379                 SCPrint(TRUE
, stdout
, CFSTR("& no protocol selected\n")); 
 382         if (protocols 
!= NULL
) { 
 383                 CFRelease(protocols
); 
 394 /* -------------------- */ 
 399 select_protocol(int argc
, char **argv
) 
 401         SCNetworkProtocolRef    protocol
; 
 403         protocol 
= _find_protocol(argv
[0]); 
 405         if (protocol 
== NULL
) { 
 409         if (net_protocol 
!= NULL
) CFRelease(net_protocol
); 
 410         net_protocol 
= CFRetain(protocol
); 
 412         SCPrint(TRUE
, stdout
, 
 413                 CFSTR("protocol \"%@\" selected\n"), 
 414                 SCNetworkProtocolGetProtocolType(protocol
)); 
 421 #pragma mark AppleTalk 
 424 static selections appletalkConfigMethods
[] = { 
 425         { CFSTR("node")      , &kSCValNetAppleTalkConfigMethodNode      
, 0 }, 
 426         { CFSTR("router")    , &kSCValNetAppleTalkConfigMethodRouter    
, 0 }, 
 427         { CFSTR("seedrouter"), &kSCValNetAppleTalkConfigMethodSeedRouter
, 0 }, 
 433 __doAppleTalkConfigMethod(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 435         CFStringRef     configMethod
; 
 437         configMethod 
= CFDictionaryGetValue(newConfiguration
, key
); 
 438         if (!CFEqual(key
, kSCValNetAppleTalkConfigMethodSeedRouter
)) { 
 439                 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetAppleTalkSeedZones
); 
 440                 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetAppleTalkSeedNetworkRange
); 
 448 __doAppleTalkNetworkRange(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 451                 SCPrint(TRUE
, stdout
, CFSTR("network range not specified\n")); 
 455         if (strlen(argv
[0]) > 0) { 
 458                 CFNumberRef     range
[2]; 
 460                 range
[0] = _copy_number(argv
[0]); 
 461                 if (range
[0] == NULL
) { 
 462                         SCPrint(TRUE
, stdout
, CFSTR("invalid start of range\n")); 
 466                 cp 
= strchr(argv
[0], '-'); 
 468                         range
[1] = _copy_number(cp
); 
 469                         if (range
[1] == NULL
) { 
 471                                 SCPrint(TRUE
, stdout
, CFSTR("invalid end of range\n")); 
 475                         range
[1] = CFRetain(range
[0]); 
 478                 array 
= CFArrayCreate(NULL
, 
 479                                       (const void **)range
, 
 480                                       sizeof(range
)/sizeof(range
[0]), 
 481                                       &kCFTypeArrayCallBacks
); 
 485                 CFDictionarySetValue(newConfiguration
, key
, array
); 
 488                 CFDictionaryRemoveValue(newConfiguration
, key
); 
 495 static options appletalkOptions
[] = { 
 496         { "ConfigMethod"    , "configuration method" 
 497                                        , isChooseOne  
, &kSCPropNetAppleTalkConfigMethod    
, __doAppleTalkConfigMethod
, (void *)appletalkConfigMethods 
}, 
 498         {   "config"        , "configuration method" 
 499                                        , isChooseOne  
, &kSCPropNetAppleTalkConfigMethod    
, __doAppleTalkConfigMethod
, (void *)appletalkConfigMethods 
}, 
 500         { "DefaultZone"     , "zone"   , isString     
, &kSCPropNetAppleTalkDefaultZone     
, NULL                     
, NULL                           
}, 
 501         { "NodeID"          , "node"   , isNumber     
, &kSCPropNetAppleTalkNodeID          
, NULL                     
, NULL                           
}, 
 502         {   "node"          , "node"   , isNumber     
, &kSCPropNetAppleTalkNodeID          
, NULL                     
, NULL                           
}, 
 503         { "NetworkID"       , "network", isNumber     
, &kSCPropNetAppleTalkNetworkID       
, NULL                     
, NULL                           
}, 
 504         {   "network"       , "network", isNumber     
, &kSCPropNetAppleTalkNetworkID       
, NULL                     
, NULL                           
}, 
 505         { "SeedNetworkRange", "range"  , isOther      
, &kSCPropNetAppleTalkSeedNetworkRange
, __doAppleTalkNetworkRange
, NULL                           
}, 
 506         { "SeedZones"       , "zone"   , isStringArray
, &kSCPropNetAppleTalkSeedZones       
, NULL                     
, NULL                           
}, 
 508         { "?"               , NULL   
, isHelp       
, NULL                                
, NULL                     
, 
 509             "\nAppleTalk configuration commands\n\n" 
 510             " set protocol config {Node|Router|SeedRouter}\n" 
 511             " set protocol defaultzone zone\n" 
 512             " set protocol node id\n" 
 513             " set protocol network id\n" 
 516             "\n w/config=Router\n" 
 518             "\n w/config=SeedRouter\n" 
 519             "   set protocol seednetworkrange low[-high]\n" 
 520             "   set protocol seedzones zone[,zone-2]\n" 
 523 #define N_APPLETALK_OPTIONS     (sizeof(appletalkOptions) / sizeof(appletalkOptions[0])) 
 527 set_protocol_appletalk(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 531         ok 
= _process_options(appletalkOptions
, N_APPLETALK_OPTIONS
, argc
, argv
, newConfiguration
); 
 541 __cleanupDomainName(CFStringRef domain
) 
 543         CFMutableStringRef      newDomain
; 
 545         newDomain 
= CFStringCreateMutableCopy(NULL
, 0, domain
); 
 546         CFStringTrimWhitespace(newDomain
); 
 547         CFStringTrim(newDomain
, CFSTR(".")); 
 548         if (CFStringGetLength(newDomain
) == 0) { 
 549                 CFRelease(newDomain
); 
 558 __doDNSDomain(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 561                 SCPrint(TRUE
, stdout
, CFSTR("DNS domain name not specified\n")); 
 565         if (strlen(argv
[0]) > 0) { 
 569                 str 
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
); 
 570                 domain 
= __cleanupDomainName(str
); 
 573                 if (domain 
!= NULL
) { 
 574                         CFDictionarySetValue(newConfiguration
, key
, domain
); 
 577                         SCPrint(TRUE
, stdout
, CFSTR("invalid DNS domain name\n")); 
 581                 CFDictionaryRemoveValue(newConfiguration
, key
); 
 589 __doDNSDomainArray(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 591         CFMutableArrayRef       domains
; 
 594                 SCPrint(TRUE
, stdout
, CFSTR("DNS search domain name(s) not specified\n")); 
 598         domains 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 600         if (strlen(argv
[0]) > 0) { 
 604                 str 
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
); 
 605                 array 
= CFStringCreateArrayBySeparatingStrings(NULL
, str
, CFSTR(",")); 
 610                         CFIndex n       
= CFArrayGetCount(array
); 
 612                         for (i 
= 0; i 
< n
; i
++) { 
 615                                 domain 
= __cleanupDomainName(CFArrayGetValueAtIndex(array
, i
)); 
 616                                 if (domain 
!= NULL
) { 
 617                                         CFArrayAppendValue(domains
, domain
); 
 622                                         SCPrint(TRUE
, stdout
, CFSTR("invalid DNS search domain name\n")); 
 630         if (CFArrayGetCount(domains
) > 0) { 
 631                 CFDictionarySetValue(newConfiguration
, key
, domains
); 
 633                 CFDictionaryRemoveValue(newConfiguration
, key
); 
 642 __doDNSServerAddresses(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 644         CFMutableArrayRef       servers
; 
 647                 SCPrint(TRUE
, stdout
, CFSTR("DNS name server address(es) not specified\n")); 
 651         servers 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 653         if (strlen(argv
[0]) > 0) { 
 659                 str 
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
); 
 660                 array 
= CFStringCreateArrayBySeparatingStrings(NULL
, str
, CFSTR(",")); 
 663                 n 
= (array 
!= NULL
) ? CFArrayGetCount(array
) : 0; 
 664                 for (i 
= 0; i 
< n
; i
++) { 
 667                         if (_SC_cfstring_to_cstring(CFArrayGetValueAtIndex(array
, i
), 
 670                                                     kCFStringEncodingUTF8
) != NULL
) { 
 673                                 server 
= __copyIPv4Address(str
); 
 674                                 if (server 
== NULL
) { 
 675                                         server 
= __copyIPv6Address(str
); 
 677                                 if (server 
!= NULL
) { 
 678                                         CFArrayAppendValue(servers
, server
); 
 684                         SCPrint(TRUE
, stdout
, CFSTR("invalid DNS name server address\n")); 
 689                 if (array 
!= NULL
) CFRelease(array
); 
 692         if (CFArrayGetCount(servers
) > 0) { 
 693                 CFDictionarySetValue(newConfiguration
, key
, servers
); 
 695                 CFDictionaryRemoveValue(newConfiguration
, key
); 
 703 static options dnsOptions
[] = { 
 704         { "DomainName"     , "domain" , isOther
, &kSCPropNetDNSDomainName     
, __doDNSDomain         
, NULL 
}, 
 705         {   "domain"       , "domain" , isOther
, &kSCPropNetDNSDomainName     
, __doDNSDomain         
, NULL 
}, 
 706         { "SearchDomains"  , "search" , isOther
, &kSCPropNetDNSSearchDomains  
, __doDNSDomainArray    
, NULL 
}, 
 707         {   "search"       , "search" , isOther
, &kSCPropNetDNSSearchDomains  
, __doDNSDomainArray    
, NULL 
}, 
 708         { "ServerAddresses", "address", isOther
, &kSCPropNetDNSServerAddresses
, __doDNSServerAddresses
, NULL 
}, 
 709         {   "nameserver"   , "address", isOther
, &kSCPropNetDNSServerAddresses
, __doDNSServerAddresses
, NULL 
}, 
 710         {   "nameservers"  , "address", isOther
, &kSCPropNetDNSServerAddresses
, __doDNSServerAddresses
, NULL 
}, 
 712         { "?"              , NULL     
, isHelp 
, NULL                         
, NULL
, 
 713             "\nDNS configuration commands\n\n" 
 714             " set protocol search domain-name[,domain-name-2]\n" 
 715             " set protocol nameserver x1.x1.x1.x1[,x2.x2.x2.x2]" 
 718 #define N_DNS_OPTIONS   (sizeof(dnsOptions) / sizeof(dnsOptions[0])) 
 722 set_protocol_dns(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 726         ok 
= _process_options(dnsOptions
, N_DNS_OPTIONS
, argc
, argv
, newConfiguration
); 
 735 #define allowIPv4Address        1<<1    // allow address 
 736 #define allowIPv4Netmask        1<<2    // allow subnet mask 
 737 #define allowIPv4Router         1<<3    // allow router 
 738 #define allowIPv4DHCPClientID   1<<4    // allow DCHP Client ID 
 740 static selections ipv4ConfigMethods
[] = { 
 741         { CFSTR("BOOTP")    , &kSCValNetIPv4ConfigMethodBOOTP    
, 0                                                 }, 
 742         { CFSTR("DHCP")     , &kSCValNetIPv4ConfigMethodDHCP     
, allowIPv4DHCPClientID                             
}, 
 743         { CFSTR("INFORM")   , &kSCValNetIPv4ConfigMethodINFORM   
, allowIPv4Address                                  
}, 
 744         { CFSTR("LinkLocal"), &kSCValNetIPv4ConfigMethodLinkLocal
, 0                                                 }, 
 745         { CFSTR("Manual")   , &kSCValNetIPv4ConfigMethodManual   
, allowIPv4Address
|allowIPv4Netmask
|allowIPv4Router 
}, 
 746         { CFSTR("PPP")      , &kSCValNetIPv4ConfigMethodPPP      
, allowIPv4Address
|selectionNotAvailable            
}, 
 752 __doIPv4ConfigMethod(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 758         method 
= CFDictionaryGetValue(newConfiguration
, key
); 
 759         methodIndex 
= _find_selection(method
, (selections 
*)ipv4ConfigMethods
, &flags
); 
 760         if (methodIndex 
!= kCFNotFound
) { 
 761                 if (!(flags 
& allowIPv4Address
)) { 
 762                         CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv4Addresses
); 
 764                 if (!(flags 
& allowIPv4Netmask
)) { 
 765                         CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv4SubnetMasks
); 
 767                 if (!(flags 
& allowIPv4Router
)) { 
 768                         CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv4Router
); 
 770                 if (!(flags 
& allowIPv4DHCPClientID
)) { 
 771                         CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv4DHCPClientID
); 
 774                 SCPrint(TRUE
, stdout
, CFSTR("unknown configuration method\n")); 
 783 __doIPv4Addresses(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 785         Boolean useArray        
= (info 
== (void *)FALSE
) ? FALSE 
: TRUE
; 
 787         if (strlen(argv
[0]) > 0) { 
 790                 address 
= __copyIPv4Address(argv
[0]); 
 791                 if (address 
!= NULL
) { 
 793                                 CFArrayRef      addresses
; 
 795                                 addresses 
= CFArrayCreate(NULL
, (const void **)&address
, 1, &kCFTypeArrayCallBacks
); 
 796                                 CFDictionarySetValue(newConfiguration
, key
, addresses
); 
 797                                 CFRelease(addresses
); 
 799                                 CFDictionarySetValue(newConfiguration
, key
, address
); 
 806                 CFDictionaryRemoveValue(newConfiguration
, key
); 
 813 static options ipv4Options
[] = { 
 814         { "ConfigMethod", "configuration method" 
 815                                      , isChooseOne   
, &kSCPropNetIPv4ConfigMethod
, __doIPv4ConfigMethod
, (void *)ipv4ConfigMethods 
}, 
 816         {   "config"    , "configuration method" 
 817                                      , isChooseOne   
, &kSCPropNetIPv4ConfigMethod
, __doIPv4ConfigMethod
, (void *)ipv4ConfigMethods 
}, 
 818         { "Addresses"   , "address"  , isOther       
, &kSCPropNetIPv4Addresses   
, __doIPv4Addresses   
, (void *)TRUE              
}, 
 819         {   "address"   , "address"  , isOther       
, &kSCPropNetIPv4Addresses   
, __doIPv4Addresses   
, (void *)TRUE              
}, 
 820         { "SubnetMasks" , "netmask"  , isOther       
, &kSCPropNetIPv4SubnetMasks 
, __doIPv4Addresses   
, (void *)TRUE              
}, 
 821         {   "netmask"   , "netmask"  , isOther       
, &kSCPropNetIPv4SubnetMasks 
, __doIPv4Addresses   
, (void *)TRUE              
}, 
 822         { "Router"      , "address"  , isOther       
, &kSCPropNetIPv4Router      
, __doIPv4Addresses   
, (void *)FALSE             
}, 
 823         { "DHCPClientID", "client ID", isString      
, &kSCPropNetIPv4DHCPClientID
, NULL                
, NULL                      
}, 
 825         { "?"           , NULL       
, isHelp        
, NULL                       
, NULL                
, 
 826             "\nIPv4 configuration commands\n\n" 
 827             " set protocol config {BOOTP|DHCP|INFORM|MANUAL}\n" 
 828             "\n w/config=BOOTP\n" 
 831             "   set protocol dhcpclientid identifier\n" 
 832             "\n w/config=INFORM\n" 
 833             "   set protocol address x.x.x.x\n" 
 834             "\n w/config=MANUAL\n" 
 835             "   set protocol address x.x.x.x\n" 
 836             "   set protocol netmask x.x.x.x\n" 
 837             "   set protocol router  x.x.x.x\n" 
 840 #define N_IPV4_OPTIONS  (sizeof(ipv4Options) / sizeof(ipv4Options[0])) 
 844 set_protocol_ipv4(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 848         ok 
= _process_options(ipv4Options
, N_IPV4_OPTIONS
, argc
, argv
, newConfiguration
); 
 854                 // validate configuration 
 855                 method 
= CFDictionaryGetValue(newConfiguration
, kSCPropNetIPv4ConfigMethod
); 
 856                 methodIndex 
= _find_selection(method
, (selections 
*)ipv4ConfigMethods
, &flags
); 
 857                 if (methodIndex 
== kCFNotFound
) { 
 858                         SCPrint(TRUE
, stdout
, CFSTR("unknown configuration method\n")); 
 862                 if (!(flags 
& allowIPv4Address
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv4Addresses
)) { 
 863                         SCPrint(TRUE
, stdout
, 
 864                                 CFSTR("IP address not allowed with %@ configuration\n"), 
 865                                 ipv4ConfigMethods
[methodIndex
].selection
); 
 869                 if (!(flags 
& allowIPv4Netmask
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv4SubnetMasks
)) { 
 870                         SCPrint(TRUE
, stdout
, 
 871                                 CFSTR("Subnet mask not allowed with %@ configuration\n"), 
 872                                 ipv4ConfigMethods
[methodIndex
].selection
); 
 876                 if (!(flags 
& allowIPv4Router
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv4Router
)) { 
 877                         SCPrint(TRUE
, stdout
, 
 878                                 CFSTR("Default route not allowed with %@ configuration\n"), 
 879                                 ipv4ConfigMethods
[methodIndex
].selection
); 
 883                 if (!(flags 
& allowIPv4DHCPClientID
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv4DHCPClientID
)) { 
 884                         SCPrint(TRUE
, stdout
, 
 885                                 CFSTR("DHCP client ID not allowed with %@ configuration\n"), 
 886                                 ipv4ConfigMethods
[methodIndex
].selection
); 
 899 #define allowIPv6Address        1<<1    // allow address 
 900 #define allowIPv6PrefixLength   1<<2    // allow prefix length 
 901 #define allowIPv6Router         1<<3    // allow router 
 903 static selections ipv6ConfigMethods
[] = { 
 904         { CFSTR("Automatic")          , & kSCValNetIPv6ConfigMethodAutomatic          
, 0                                                      }, 
 905         { CFSTR("Manual")             , & kSCValNetIPv6ConfigMethodManual             
, allowIPv6Address
|allowIPv6PrefixLength
|allowIPv6Router 
}, 
 906         { CFSTR("RouterAdvertisement"), & kSCValNetIPv6ConfigMethodRouterAdvertisement
, allowIPv6Address                                       
}, 
 907         { CFSTR("6to4")               , & kSCValNetIPv6ConfigMethod6to4               
, 0                                                      }, 
 913 __doIPv6ConfigMethod(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 919         method 
= CFDictionaryGetValue(newConfiguration
, key
); 
 920         methodIndex 
= _find_selection(method
, (selections 
*)ipv6ConfigMethods
, &flags
); 
 921         if (methodIndex 
!= kCFNotFound
) { 
 922                 if (!(flags 
& allowIPv6Address
)) { 
 923                         CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv6Addresses
); 
 925                 if (!(flags 
& allowIPv6PrefixLength
)) { 
 926                         CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv6PrefixLength
); 
 928                 if (!(flags 
& allowIPv6Router
)) { 
 929                         CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv6Router
); 
 932                 SCPrint(TRUE
, stdout
, CFSTR("unknown configuration method\n")); 
 941 __doIPv6Addresses(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 943         Boolean useArray        
= (info 
== (void *)FALSE
) ? FALSE 
: TRUE
; 
 945         if (strlen(argv
[0]) > 0) { 
 948                 address 
= __copyIPv6Address(argv
[0]); 
 949                 if (address 
!= NULL
) { 
 951                                 CFArrayRef      addresses
; 
 953                                 addresses 
= CFArrayCreate(NULL
, (const void **)&address
, 1, &kCFTypeArrayCallBacks
); 
 954                                 CFDictionarySetValue(newConfiguration
, key
, addresses
); 
 955                                 CFRelease(addresses
); 
 957                                 CFDictionarySetValue(newConfiguration
, key
, address
); 
 964                 CFDictionaryRemoveValue(newConfiguration
, key
); 
 972 __doIPv6PrefixLength(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
 977         num 
= CFDictionaryGetValue(newConfiguration
, kSCPropNetPPPAuthPasswordEncryption
); 
 978         if (isA_CFNumber(num
) && 
 979             CFNumberGetValue(num
, kCFNumberIntType
, &prefixLength
) && 
 980             (prefixLength 
>= 0) && (prefixLength 
<= (sizeof(struct in6_addr
) * 8))) { 
 988 static options ipv6Options
[] = { 
 989         { "ConfigMethod", "configuration method" 
 990                                          , isChooseOne
, &kSCPropNetIPv6ConfigMethod
, __doIPv6ConfigMethod
, (void *)ipv6ConfigMethods 
}, 
 991         {   "config"    , "configuration method" 
 992                                          , isChooseOne
, &kSCPropNetIPv6ConfigMethod
, __doIPv6ConfigMethod
, (void *)ipv6ConfigMethods 
}, 
 993         { "Addresses"   , "address"      , isOther    
, &kSCPropNetIPv6Addresses   
, __doIPv6Addresses   
, (void *)TRUE              
}, 
 994         {   "address"   , "address"      , isOther    
, &kSCPropNetIPv6Addresses   
, __doIPv6Addresses   
, (void *)TRUE              
}, 
 995         { "PrefixLength", "prefix length", isNumber   
, &kSCPropNetIPv6PrefixLength
, __doIPv6PrefixLength
, NULL                      
}, 
 996         { "Router"      , "address"      , isOther    
, &kSCPropNetIPv6Router      
, __doIPv6Addresses   
, (void *)FALSE             
}, 
 998         { "?"           , NULL           
, isHelp     
, NULL                       
, NULL                
, 
 999             "\nIPv6 configuration commands\n\n" 
1000             " set protocol config {Automatic|MANUAL}\n" 
1001             "\n w/config=Automatic\n" 
1003             "\n w/config=MANUAL\n" 
1004             "   set protocol address x:x:x:x:x:x\n" 
1005             "   set protocol router  x:x:x:x:x:x\n" 
1006             "   set protocol prefixlength n\n" 
1009 #define N_IPV6_OPTIONS  (sizeof(ipv6Options) / sizeof(ipv6Options[0])) 
1013 set_protocol_ipv6(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
1017         ok 
= _process_options(ipv6Options
, N_IPV6_OPTIONS
, argc
, argv
, newConfiguration
); 
1021                 CFIndex         methodIndex
; 
1023                 // validate configuration 
1024                 method 
= CFDictionaryGetValue(newConfiguration
, kSCPropNetIPv6ConfigMethod
); 
1025                 methodIndex 
= _find_selection(method
, (selections 
*)ipv6ConfigMethods
, &flags
); 
1026                 if (methodIndex 
== kCFNotFound
) { 
1027                         SCPrint(TRUE
, stdout
, CFSTR("unknown configuration method\n")); 
1031                 if (!(flags 
& allowIPv6Address
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv6Addresses
)) { 
1032                         SCPrint(TRUE
, stdout
, 
1033                                 CFSTR("IP address not allowed with %@ configuration\n"), 
1034                                 ipv6ConfigMethods
[methodIndex
].selection
); 
1038                 if (!(flags 
& allowIPv6PrefixLength
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv6PrefixLength
)) { 
1039                         SCPrint(TRUE
, stdout
, 
1040                                 CFSTR("Prefix length not allowed with %@ configuration\n"), 
1041                                 ipv6ConfigMethods
[methodIndex
].selection
); 
1045                 if (!(flags 
& allowIPv6Router
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv6Router
)) { 
1046                         SCPrint(TRUE
, stdout
, 
1047                                 CFSTR("Router not allowed with %@ configuration\n"), 
1048                                 ipv6ConfigMethods
[methodIndex
].selection
); 
1058 #pragma mark Proxies 
1061 typedef const struct { 
1063         const CFStringRef       
*keyEnable
; 
1064         const CFStringRef       
*keyProxy
; 
1065         const CFStringRef       
*keyPort
; 
1066         const CFStringRef       
*keyURL
; 
1069 static proxyKeys proxyKeys_FTP    
= { "FTP"   , &kSCPropNetProxiesFTPEnable               
, &kSCPropNetProxiesFTPProxy   
, &kSCPropNetProxiesFTPPort   
, NULL                                       
}; 
1070 static proxyKeys proxyKeys_Gopher 
= { "Gopher", &kSCPropNetProxiesGopherEnable            
, &kSCPropNetProxiesGopherProxy
, &kSCPropNetProxiesGopherPort
, NULL                                       
}; 
1071 static proxyKeys proxyKeys_HTTP   
= { "HTTP"  , &kSCPropNetProxiesHTTPEnable              
, &kSCPropNetProxiesHTTPProxy  
, &kSCPropNetProxiesHTTPPort  
, NULL                                       
}; 
1072 static proxyKeys proxyKeys_HTTPS  
= { "HTTPS" , &kSCPropNetProxiesHTTPSEnable             
, &kSCPropNetProxiesHTTPSProxy 
, &kSCPropNetProxiesHTTPSPort 
, NULL                                       
}; 
1073 static proxyKeys proxyKeys_RTSP   
= { "RTSP"  , &kSCPropNetProxiesRTSPEnable              
, &kSCPropNetProxiesRTSPProxy  
, &kSCPropNetProxiesRTSPPort  
, NULL                                       
}; 
1074 static proxyKeys proxyKeys_SOCKS  
= { "SOCKS" , &kSCPropNetProxiesSOCKSEnable             
, &kSCPropNetProxiesSOCKSProxy 
, &kSCPropNetProxiesSOCKSPort 
, NULL                                       
}; 
1075 static proxyKeys proxyKeys_PAC    
= { ".pac"  , &kSCPropNetProxiesProxyAutoConfigEnable   
, NULL                         
, NULL                        
, &kSCPropNetProxiesProxyAutoConfigURLString 
}; 
1076 static proxyKeys proxyKeys_WPAD   
= { "WPAD"  , &kSCPropNetProxiesProxyAutoDiscoveryEnable
, NULL                         
, NULL                        
, NULL                                       
}; 
1078 static proxyKeys        
*currentProxy   
= NULL
; 
1081 static int __doProxySelect    (CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
); 
1082 static int __doProxyEnable    (CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
); 
1083 static int __doProxyHost      (CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
); 
1084 static int __doProxyPort      (CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
); 
1085 static int __doProxyURL       (CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
); 
1086 static int __doProxyFTPPassive(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
); 
1089 static options proxyOptions
[] = { 
1091         { "ExceptionsList"        , "exceptions", isStringArray
, &kSCPropNetProxiesExceptionsList        
, NULL              
, NULL                      
}, 
1092         { "ExcludeSimpleHostnames", NULL        
, isBoolean    
, &kSCPropNetProxiesExcludeSimpleHostnames
, NULL              
, NULL                      
}, 
1094         { "FTP"                   , NULL        
, isOther      
, NULL                                    
, __doProxySelect   
, (void *)&proxyKeys_FTP    
}, 
1095         { "Gopher"                , NULL        
, isOther      
, NULL                                    
, __doProxySelect   
, (void *)&proxyKeys_Gopher 
}, 
1096         { "HTTP"                  , NULL        
, isOther      
, NULL                                    
, __doProxySelect   
, (void *)&proxyKeys_HTTP   
}, 
1097         { "HTTPS"                 , NULL        
, isOther      
, NULL                                    
, __doProxySelect   
, (void *)&proxyKeys_HTTPS  
}, 
1098         { "RTSP"                  , NULL        
, isOther      
, NULL                                    
, __doProxySelect   
, (void *)&proxyKeys_RTSP   
}, 
1099         { "SOCKS"                 , NULL        
, isOther      
, NULL                                    
, __doProxySelect   
, (void *)&proxyKeys_SOCKS  
}, 
1100         { "ProxyAutoConfig"       , NULL        
, isOther      
, NULL                                    
, __doProxySelect   
, (void *)&proxyKeys_PAC    
}, 
1101         {   ".pac"                , NULL        
, isOther      
, NULL                                    
, __doProxySelect   
, (void *)&proxyKeys_PAC    
}, 
1102         { "ProxyAutoDiscovery"    , NULL        
, isOther      
, NULL                                    
, __doProxySelect   
, (void *)&proxyKeys_WPAD   
}, 
1103         {   "WPAD"                , NULL        
, isOther      
, NULL                                    
, __doProxySelect   
, (void *)&proxyKeys_WPAD   
}, 
1105         { "disable"               , NULL        
, isOther      
, NULL                                    
, __doProxyEnable    
, (void *)FALSE             
}, 
1106         { "enable"                , NULL        
, isOther      
, NULL                                    
, __doProxyEnable    
, (void *)TRUE              
}, 
1107         { "proxy"                 , NULL        
, isOther      
, NULL                                    
, __doProxyHost      
, NULL                      
}, 
1108         {   "host"                , NULL        
, isOther      
, NULL                                    
, __doProxyHost      
, NULL                      
}, 
1109         { "port"                  , NULL        
, isOther      
, NULL                                    
, __doProxyPort      
, NULL                      
}, 
1110         { "url"                   , NULL        
, isOther      
, NULL                                    
, __doProxyURL       
, NULL                      
}, 
1111         // (ftp) proxy modifiers 
1112         { "FTPPassive"            , NULL        
, isBoolean    
, &kSCPropNetProxiesFTPPassive            
, __doProxyFTPPassive
, NULL                      
}, 
1113         {   "passive"             , NULL        
, isBoolean    
, &kSCPropNetProxiesFTPPassive            
, __doProxyFTPPassive
, NULL                      
}, 
1115         { "?"                     , NULL        
, isHelp       
, NULL                                    
, NULL                
, 
1116             "\nProxy configuration commands\n\n" 
1117             " set protocol ExceptionsList exception[,exception-2]\n" 
1118             " set protocol ExcludeSimpleHostnames {enable|disable}\n" 
1120             " set protocol ftp {enable|disable}\n" 
1121             " set protocol ftp host proxy-host\n" 
1122             " set protocol ftp port proxy-port\n" 
1123             " set protocol ftp passive {enable|disable}\n" 
1125             " set protocol http {enable|disable}\n" 
1126             " set protocol http host proxy-host\n" 
1127             " set protocol http port proxy-port\n" 
1129             " set protocol https {enable|disable}\n" 
1130             " set protocol https host proxy-host\n" 
1131             " set protocol https port proxy-port\n" 
1133             " set protocol rtsp {enable|disable}\n" 
1134             " set protocol rtsp host proxy-host\n" 
1135             " set protocol rtsp port proxy-port\n" 
1137             " set protocol socks {enable|disable}\n" 
1138             " set protocol socks host proxy-host\n" 
1139             " set protocol socks port proxy-port\n" 
1141             " set protocol .pac {enable|disable}\n" 
1142             " set protocol .pac url .pac-url\n" 
1144             " set protocol wpad {enable|disable}\n" 
1147 #define N_PROXY_OPTIONS (sizeof(proxyOptions) / sizeof(proxyOptions[0])) 
1151 __doProxySelect(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
1156                 SCPrint(TRUE
, stdout
, CFSTR("proxy option[s] not specified\n")); 
1160         currentProxy 
= (proxyKeys 
*)info
; 
1162         nextOption 
= _find_option(argv
[0], proxyOptions
, N_PROXY_OPTIONS
); 
1163         if ((nextOption 
== kCFNotFound
) || 
1164             (proxyOptions
[nextOption
].handler 
== __doProxySelect
)) { 
1165                 SCPrint(TRUE
, stdout
, CFSTR("%s proxy option[s] not specified\n"), currentProxy
->proxy
); 
1174 __doProxyEnable(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
1176         Boolean enabled 
= (info 
== (void *)FALSE
) ? FALSE 
: TRUE
; 
1178         if (currentProxy 
== NULL
) { 
1179                 SCPrint(TRUE
, stdout
, CFSTR("proxy not specified\n")); 
1183         if (currentProxy
->keyEnable 
== NULL
) { 
1184                 SCPrint(TRUE
, stdout
, CFSTR("%s proxy cannot be %s\n"), 
1185                         currentProxy
->proxy
, 
1186                         enabled 
? "enabled" : "disabled"); 
1192                 CFDictionarySetValue(newConfiguration
, *(currentProxy
->keyEnable
), CFNumberRef_1
); 
1194                 CFDictionarySetValue(newConfiguration
, *(currentProxy
->keyEnable
), CFNumberRef_0
); 
1196                 if (currentProxy
->keyProxy 
!= NULL
) { 
1197                         CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyProxy
)); 
1200                 if (currentProxy
->keyPort 
!= NULL
) { 
1201                         CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyPort
)); 
1204                 if (currentProxy
->keyURL 
!= NULL
) { 
1205                         CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyURL
)); 
1214 __proxy_enabled(CFDictionaryRef configuration
, const CFStringRef 
*enableKey
) 
1219         if (enableKey 
== NULL
) { 
1220                 return TRUE
;    // if proxy does not need to be enabled 
1223         num 
= CFDictionaryGetValue(configuration
, *enableKey
); 
1224         if (!isA_CFNumber(num
) || 
1225             !CFNumberGetValue(num
, kCFNumberIntType
, &val
) || 
1227                 return FALSE
;   // if not enabled 
1235 __doProxyHost(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
1237         if (currentProxy 
== NULL
) { 
1238                 SCPrint(TRUE
, stdout
, CFSTR("proxy not specified\n")); 
1242         if (currentProxy
->keyProxy 
== NULL
) { 
1243                 SCPrint(TRUE
, stdout
, CFSTR("%s proxy host cannot be specified\n"), currentProxy
->proxy
); 
1247         if (!__proxy_enabled(newConfiguration
, currentProxy
->keyEnable
)) { 
1248                 SCPrint(TRUE
, stdout
, CFSTR("%s proxy not enabled\n"), currentProxy
->proxy
); 
1253                 SCPrint(TRUE
, stdout
, CFSTR("%s proxy host not specified\n"), currentProxy
->proxy
); 
1257         if (strlen(argv
[0]) > 0) { 
1260                 host 
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
); 
1261                 CFDictionarySetValue(newConfiguration
, *(currentProxy
->keyProxy
), host
); 
1264                 CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyProxy
)); 
1272 __doProxyPort(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
1274         if (currentProxy 
== NULL
) { 
1275                 SCPrint(TRUE
, stdout
, CFSTR("proxy not specified\n")); 
1279         if (currentProxy
->keyPort 
== NULL
) { 
1280                 SCPrint(TRUE
, stdout
, CFSTR("%s proxy port cannot be specified\n"), currentProxy
->proxy
); 
1284         if (!__proxy_enabled(newConfiguration
, currentProxy
->keyEnable
)) { 
1285                 SCPrint(TRUE
, stdout
, CFSTR("%s proxy not enabled\n"), currentProxy
->proxy
); 
1290                 SCPrint(TRUE
, stdout
, CFSTR("%s proxy port not specified\n"), currentProxy
->proxy
); 
1294         if (strlen(argv
[0]) > 0) { 
1298                 num 
= _copy_number(argv
[0]); 
1299                 if (!isA_CFNumber(num
) || 
1300                     !CFNumberGetValue(num
, kCFNumberIntType
, &port
) || 
1301                     (port 
< 0) || (port 
> 65535)) { 
1302                         SCPrint(TRUE
, stdout
, CFSTR("invalid %s proxy port number\n"), currentProxy
->proxy
); 
1306                 CFDictionarySetValue(newConfiguration
, *(currentProxy
->keyPort
), num
); 
1309                 CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyPort
)); 
1317 __doProxyURL(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
1319         if (currentProxy 
== NULL
) { 
1320                 SCPrint(TRUE
, stdout
, CFSTR("proxy not specified\n")); 
1324         if (currentProxy
->keyURL 
== NULL
) { 
1325                 SCPrint(TRUE
, stdout
, CFSTR("%s proxy URL cannot be specified\n"), currentProxy
->proxy
); 
1329         if (!__proxy_enabled(newConfiguration
, currentProxy
->keyEnable
)) { 
1330                 SCPrint(TRUE
, stdout
, CFSTR("%s proxy not enabled\n"), currentProxy
->proxy
); 
1335                 SCPrint(TRUE
, stdout
, CFSTR("%s proxy URL not specified\n"), currentProxy
->proxy
); 
1339         if (strlen(argv
[0]) > 0) { 
1342                 url 
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
); 
1343                 CFDictionarySetValue(newConfiguration
, *(currentProxy
->keyURL
), url
); 
1346                 CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyURL
)); 
1354 __doProxyFTPPassive(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
1356         if (currentProxy 
== NULL
) { 
1357                 SCPrint(TRUE
, stdout
, CFSTR("proxy not specified\n")); 
1361         if (currentProxy 
!= &proxyKeys_FTP
) { 
1362                 SCPrint(TRUE
, stdout
, CFSTR("passive can only be enable for FTP proxy\n")); 
1371 set_protocol_proxies(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
1375         ok 
= _process_options(proxyOptions
, N_PROXY_OPTIONS
, argc
, argv
, newConfiguration
); 
1385 __cleanupName(CFStringRef name
) 
1387         CFMutableStringRef      newName
; 
1389         newName 
= CFStringCreateMutableCopy(NULL
, 0, name
); 
1390         CFStringTrimWhitespace(newName
); 
1391         if (CFStringGetLength(newName
) == 0) { 
1401 __doSMBName(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
1404                 SCPrint(TRUE
, stdout
, CFSTR("NetBIOS name not specified\n")); 
1408         if (strlen(argv
[0]) > 0) { 
1412                 str 
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
); 
1413                 name 
= __cleanupName(str
); 
1417                         CFDictionarySetValue(newConfiguration
, key
, name
); 
1420                         SCPrint(TRUE
, stdout
, CFSTR("invalid NetBIOS name\n")); 
1424                 CFDictionaryRemoveValue(newConfiguration
, key
); 
1432 __doSMBWorkgroup(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
1435                 SCPrint(TRUE
, stdout
, CFSTR("Workgroup not specified\n")); 
1439         if (strlen(argv
[0]) > 0) { 
1443                 str 
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
); 
1444                 name 
= __cleanupName(str
); 
1448                         CFDictionarySetValue(newConfiguration
, key
, name
); 
1451                         SCPrint(TRUE
, stdout
, CFSTR("invalid Workgroup\n")); 
1455                 CFDictionaryRemoveValue(newConfiguration
, key
); 
1463 __doSMBWINSAddresses(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
1465         CFMutableArrayRef       servers
; 
1468                 SCPrint(TRUE
, stdout
, CFSTR("WINS address(es) not specified\n")); 
1472         servers 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
1474         if (strlen(argv
[0]) > 0) { 
1480                 str 
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
); 
1481                 array 
= CFStringCreateArrayBySeparatingStrings(NULL
, str
, CFSTR(",")); 
1484                 n 
= (array 
!= NULL
) ? CFArrayGetCount(array
) : 0; 
1485                 for (i 
= 0; i 
< n
; i
++) { 
1488                         if (_SC_cfstring_to_cstring(CFArrayGetValueAtIndex(array
, i
), 
1491                                                     kCFStringEncodingUTF8
) != NULL
) { 
1494                                 server 
= __copyIPv4Address(str
); 
1495                                 //if (server == NULL) { 
1496                                 //      server = __copyIPv6Address(str); 
1498                                 if (server 
!= NULL
) { 
1499                                         CFArrayAppendValue(servers
, server
); 
1505                         SCPrint(TRUE
, stdout
, CFSTR("invalid WINS address\n")); 
1510                 if (array 
!= NULL
) CFRelease(array
); 
1513         if (CFArrayGetCount(servers
) > 0) { 
1514                 CFDictionarySetValue(newConfiguration
, key
, servers
); 
1516                 CFDictionaryRemoveValue(newConfiguration
, key
); 
1524 static selections smbNodeTypes
[] = { 
1525         { CFSTR("Broadcast"), &kSCValNetSMBNetBIOSNodeTypeBroadcast
, 0 }, 
1526         { CFSTR("Peer")     , &kSCValNetSMBNetBIOSNodeTypePeer     
, 0 }, 
1527         { CFSTR("Mixed")    , &kSCValNetSMBNetBIOSNodeTypeMixed    
, 0 }, 
1528         { CFSTR("Hybrid")   , &kSCValNetSMBNetBIOSNodeTypeHybrid   
, 0 }, 
1533 static options smbOptions
[] = { 
1534         { "NetBIOSName"    , "name"     , isOther    
, &kSCPropNetSMBNetBIOSName    
, __doSMBName         
, NULL 
}, 
1535         {   "name"         , "name"     , isOther    
, &kSCPropNetSMBNetBIOSName    
, __doSMBName         
, NULL 
}, 
1536         { "NetBIOSNodeType", "type"     , isChooseOne
, &kSCPropNetSMBNetBIOSNodeType
, NULL                
, (void *)smbNodeTypes 
}, 
1537         {   "type",          "type"     , isChooseOne
, &kSCPropNetSMBNetBIOSNodeType
, NULL                
, (void *)smbNodeTypes 
}, 
1538         { "Workgroup"      , "workgroup", isOther    
, &kSCPropNetSMBWorkgroup      
, __doSMBWorkgroup    
, NULL 
}, 
1539         { "WINSAddresses"  , "wins"     , isOther    
, &kSCPropNetSMBWINSAddresses  
, __doSMBWINSAddresses
, NULL 
}, 
1540         {   "wins"         , "wins"     , isOther    
, &kSCPropNetSMBWINSAddresses  
, __doSMBWINSAddresses
, NULL 
}, 
1542         { "?"              , NULL       
, isHelp     
, NULL                         
, NULL
, 
1543             "\nSMB configuration commands\n\n" 
1544             " set protocol name NetBIOS-name\n" 
1545             " set protocol type (Broadcast|Peer|Mixed|Hybrid)\n" 
1546             " set protocol workgroup SMB-workgroup\n" 
1547             " set protocol wins x1.x1.x1.x1[,x2.x2.x2.x2]" 
1550 #define N_SMB_OPTIONS   (sizeof(smbOptions) / sizeof(smbOptions[0])) 
1554 set_protocol_smb(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
) 
1558         ok 
= _process_options(smbOptions
, N_SMB_OPTIONS
, argc
, argv
, newConfiguration
); 
1564 #pragma mark *Protocol* 
1569 set_protocol(int argc
, char **argv
) 
1571         CFDictionaryRef         configuration
; 
1572         CFMutableDictionaryRef  newConfiguration        
= NULL
; 
1574         CFStringRef             protocolType
; 
1576         if (net_protocol 
== NULL
) { 
1577                 SCPrint(TRUE
, stdout
, CFSTR("protocol not selected\n")); 
1582                 SCPrint(TRUE
, stdout
, CFSTR("set what?\n")); 
1586         configuration 
= SCNetworkProtocolGetConfiguration(net_protocol
); 
1587         if (configuration 
== NULL
) { 
1588                 newConfiguration 
= CFDictionaryCreateMutable(NULL
, 
1590                                                              &kCFTypeDictionaryKeyCallBacks
, 
1591                                                              &kCFTypeDictionaryValueCallBacks
); 
1593                 newConfiguration 
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
); 
1594                 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
); 
1597         protocolType 
= SCNetworkProtocolGetProtocolType(net_protocol
); 
1598         if (CFEqual(protocolType
, kSCNetworkProtocolTypeAppleTalk
)) { 
1599                 ok 
= set_protocol_appletalk(argc
, argv
, newConfiguration
); 
1600         } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeDNS
)) { 
1601                 ok 
= set_protocol_dns(argc
, argv
, newConfiguration
); 
1602         } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeIPv4
)) { 
1603                 ok 
= set_protocol_ipv4(argc
, argv
, newConfiguration
); 
1604         } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeIPv6
)) { 
1605                 ok 
= set_protocol_ipv6(argc
, argv
, newConfiguration
); 
1606         } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeProxies
)) { 
1607                 ok 
= set_protocol_proxies(argc
, argv
, newConfiguration
); 
1608         } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeSMB
)) { 
1609                 ok 
= set_protocol_smb(argc
, argv
, newConfiguration
); 
1611                 SCPrint(TRUE
, stdout
, CFSTR("this protocols configuration cannot be changed\n")); 
1618         if (((configuration 
== NULL
) && (CFDictionaryGetCount(newConfiguration
) > 0)) || 
1619             ((configuration 
!= NULL
) && !CFEqual(configuration
, newConfiguration
))) { 
1620                 if (!SCNetworkProtocolSetConfiguration(net_protocol
, newConfiguration
)) { 
1621                         SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError())); 
1625                 _prefs_changed 
= TRUE
; 
1630         if (newConfiguration 
!= NULL
) CFRelease(newConfiguration
); 
1635 /* -------------------- */ 
1640 show_protocol(int argc
, char **argv
) 
1642         CFDictionaryRef         configuration
; 
1643         SCNetworkProtocolRef    protocol        
= NULL
; 
1644         CFStringRef             protocolType
; 
1647                 protocol 
= _find_protocol(argv
[0]); 
1649                 if (net_protocol 
!= NULL
) { 
1650                         protocol 
= net_protocol
; 
1652                         SCPrint(TRUE
, stdout
, CFSTR("protocol not selected\n")); 
1657         if (protocol 
== NULL
) { 
1661         protocolType 
= SCNetworkProtocolGetProtocolType(protocol
); 
1662         SCPrint(TRUE
, stdout
, CFSTR("protocol type        = %@\n"), protocolType
); 
1664         configuration 
= SCNetworkProtocolGetConfiguration(protocol
); 
1665         if (configuration 
!= NULL
) { 
1666                 SCPrint(TRUE
, stdout
, CFSTR("\n  protocol configuration\n")); 
1667                 _show_entity(configuration
, CFSTR("")); 
1671                 SCPrint(TRUE
, stdout
, CFSTR("\n%@\n"), protocol
); 
1678 /* -------------------- */ 
1683 show_protocols(int argc
, char **argv
) 
1688         if (prefs 
== NULL
) { 
1689                 SCPrint(TRUE
, stdout
, CFSTR("network configuration not open\n")); 
1693         if (net_service 
== NULL
) { 
1694                 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n")); 
1698         if (protocols 
!= NULL
) CFRelease(protocols
); 
1699         protocols 
= SCNetworkServiceCopyProtocols(net_service
); 
1700         if (protocols 
== NULL
) { 
1701                 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError())); 
1705         n 
= CFArrayGetCount(protocols
); 
1707                 CFMutableArrayRef       sorted
; 
1709                 sorted 
= CFArrayCreateMutableCopy(NULL
, 0, protocols
); 
1710                 CFArraySortValues(sorted
, 
1714                 CFRelease(protocols
); 
1718         for (i 
= 0; i 
< n
; i
++) { 
1719                 SCNetworkProtocolRef    protocol
; 
1720                 CFStringRef             protocolType
; 
1722                 protocol     
= CFArrayGetValueAtIndex(protocols
, i
); 
1723                 protocolType 
= SCNetworkProtocolGetProtocolType(protocol
); 
1725                 SCPrint(TRUE
, stdout
, CFSTR("%c%2d: %@%*s :"), 
1726                         ((net_protocol 
!= NULL
) && CFEqual(protocol
, net_protocol
)) ? '>' : ' ', 
1729                         sizeof("AppleTalk") - CFStringGetLength(protocolType
) - 1, 
1732                 if (SCNetworkProtocolGetEnabled(protocol
)) { 
1733                         CFStringRef     description
; 
1735                         description 
= _protocol_description(protocol
, FALSE
); 
1736                         SCPrint(TRUE
, stdout
, CFSTR(" %@"), description
); 
1737                         CFRelease(description
); 
1739                         SCPrint(TRUE
, stdout
, CFSTR(" *DISABLED*")); 
1741                 SCPrint(TRUE
, stdout
, CFSTR("\n")); 
1748 /* -------------------- */ 
1753 _protocol_description(SCNetworkProtocolRef protocol
, Boolean skipEmpty
) 
1755         CFDictionaryRef         configuration
; 
1756         CFMutableStringRef      description     
= NULL
; 
1757         CFStringRef             protocolType
; 
1759         description 
= CFStringCreateMutable(NULL
, 0); 
1761         if (!SCNetworkProtocolGetEnabled(protocol
)) { 
1765         configuration 
= SCNetworkProtocolGetConfiguration(protocol
); 
1766         if (configuration 
== NULL
) { 
1770         protocolType 
= SCNetworkProtocolGetProtocolType(protocol
); 
1771         if (CFEqual(protocolType
, kSCNetworkProtocolTypeAppleTalk
)) { 
1774                 method 
= CFDictionaryGetValue(configuration
, kSCPropNetAppleTalkConfigMethod
); 
1775                 if (isA_CFString(method
)) { 
1776                         CFStringAppendFormat(description
, 
1781         } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeDNS
)) { 
1786                 domain  
= CFDictionaryGetValue(configuration
, kSCPropNetDNSDomainName
); 
1787                 if (isA_CFString(domain
)) { 
1788                         CFStringAppendFormat(description
, 
1794                 search 
= CFDictionaryGetValue(configuration
, kSCPropNetDNSSearchDomains
); 
1795                 if (isA_CFArray(search
)) { 
1798                         str 
= CFStringCreateByCombiningStrings(NULL
, search
, CFSTR(",")); 
1799                         CFStringAppendFormat(description
, 
1801                                              CFSTR("%ssearch=%@"), 
1802                                              CFStringGetLength(description
) > 0 ? ", " : "", 
1807                 servers 
= CFDictionaryGetValue(configuration
, kSCPropNetDNSServerAddresses
); 
1808                 if (isA_CFArray(servers
)) { 
1811                         str 
= CFStringCreateByCombiningStrings(NULL
, servers
, CFSTR(",")); 
1812                         CFStringAppendFormat(description
, 
1814                                              CFSTR("%sservers=%@"), 
1815                                              CFStringGetLength(description
) > 0 ? ", " : "", 
1819         } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeIPv4
)) { 
1822                 method 
= CFDictionaryGetValue(configuration
, kSCPropNetIPv4ConfigMethod
); 
1823                 if (isA_CFString(method
)) { 
1824                         CFArrayRef      addresses
; 
1826                         addresses 
= CFDictionaryGetValue(configuration
, kSCPropNetIPv4Addresses
); 
1827                         if (CFEqual(method
, kSCValNetIPv4ConfigMethodINFORM
) && 
1828                             isA_CFArray(addresses
)) { 
1829                                 CFStringAppendFormat(description
, 
1831                                                      CFSTR("%@, address=%@"), 
1833                                                      CFArrayGetValueAtIndex(addresses
, 0)); 
1834                         } else if (CFEqual(method
, kSCValNetIPv4ConfigMethodManual
) && 
1835                                    isA_CFArray(addresses
)) { 
1836                                 CFStringAppendFormat(description
, 
1838                                                      CFSTR("%@, address=%@"), 
1840                                                      CFArrayGetValueAtIndex(addresses
, 0)); 
1842                                 CFStringAppendFormat(description
, 
1848         } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeIPv6
)) { 
1851                 method 
= CFDictionaryGetValue(configuration
, kSCPropNetIPv6ConfigMethod
); 
1852                 if (isA_CFString(method
)) { 
1853                         CFStringAppendFormat(description
, 
1858         } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeProxies
)) { 
1860                 static proxyKeys        
*keys
[] = { &proxyKeys_FTP
,     &proxyKeys_Gopher
,      &proxyKeys_HTTP
,        &proxyKeys_HTTPS
, 
1861                                                     &proxyKeys_RTSP
,    &proxyKeys_SOCKS
,       &proxyKeys_PAC
,         &proxyKeys_WPAD 
}; 
1863                 for (i 
= 0; i 
< sizeof(keys
)/sizeof(keys
[0]); i
++) { 
1864                         proxyKeys       
*currentProxy   
= keys
[i
]; 
1866                         if (!__proxy_enabled(configuration
, currentProxy
->keyEnable
)) { 
1870                         if (((currentProxy
->keyProxy 
!= NULL
) && 
1871                              !CFDictionaryContainsKey(configuration
, *(currentProxy
->keyProxy
))) || 
1872                             ((currentProxy
->keyURL 
!= NULL
) && 
1873                              !CFDictionaryContainsKey(configuration
, *(currentProxy
->keyURL
)))) { 
1877                         CFStringAppendFormat(description
, 
1880                                              CFStringGetLength(description
) > 0 ? ", " : "", 
1881                                              currentProxy
->proxy
); 
1883         } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeSMB
)) { 
1886                 CFStringRef     workgroup
; 
1888                 name  
= CFDictionaryGetValue(configuration
, kSCPropNetSMBNetBIOSName
); 
1889                 if (isA_CFString(name
)) { 
1890                         CFStringAppendFormat(description
, 
1892                                              CFSTR("NetBIOS name=%@"), 
1896                 workgroup  
= CFDictionaryGetValue(configuration
, kSCPropNetSMBWorkgroup
); 
1897                 if (isA_CFString(workgroup
)) { 
1898                         CFStringAppendFormat(description
, 
1900                                              CFSTR("Workgroup=%@"), 
1904                 servers 
= CFDictionaryGetValue(configuration
, kSCPropNetSMBWINSAddresses
); 
1905                 if (isA_CFArray(servers
)) { 
1908                         str 
= CFStringCreateByCombiningStrings(NULL
, servers
, CFSTR(",")); 
1909                         CFStringAppendFormat(description
, 
1911                                              CFSTR("%sWINS servers=%@"), 
1912                                              CFStringGetLength(description
) > 0 ? ", " : "", 
1920         if (skipEmpty 
&& CFStringGetLength(description
) == 0) { 
1921                 CFRelease(description
);