2 * Copyright (c) 2004-2009 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 * 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 #if !TARGET_OS_IPHONE && INCLUDE_APPLETALK
427 static selections appletalkConfigMethods
[] = {
428 { CFSTR("node") , &kSCValNetAppleTalkConfigMethodNode
, 0 },
429 { CFSTR("router") , &kSCValNetAppleTalkConfigMethodRouter
, 0 },
430 { CFSTR("seedrouter"), &kSCValNetAppleTalkConfigMethodSeedRouter
, 0 },
436 __doAppleTalkConfigMethod(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
438 CFStringRef configMethod
;
440 configMethod
= CFDictionaryGetValue(newConfiguration
, key
);
441 if (!CFEqual(key
, kSCValNetAppleTalkConfigMethodSeedRouter
)) {
442 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetAppleTalkSeedZones
);
443 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetAppleTalkSeedNetworkRange
);
451 __doAppleTalkNetworkRange(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
454 SCPrint(TRUE
, stdout
, CFSTR("network range not specified\n"));
458 if (strlen(argv
[0]) > 0) {
461 CFNumberRef range
[2];
463 range
[0] = _copy_number(argv
[0]);
464 if (range
[0] == NULL
) {
465 SCPrint(TRUE
, stdout
, CFSTR("invalid start of range\n"));
469 cp
= strchr(argv
[0], '-');
471 range
[1] = _copy_number(cp
);
472 if (range
[1] == NULL
) {
474 SCPrint(TRUE
, stdout
, CFSTR("invalid end of range\n"));
478 range
[1] = CFRetain(range
[0]);
481 array
= CFArrayCreate(NULL
,
482 (const void **)range
,
483 sizeof(range
)/sizeof(range
[0]),
484 &kCFTypeArrayCallBacks
);
488 CFDictionarySetValue(newConfiguration
, key
, array
);
491 CFDictionaryRemoveValue(newConfiguration
, key
);
498 static options appletalkOptions
[] = {
499 { "ConfigMethod" , "configuration method"
500 , isChooseOne
, &kSCPropNetAppleTalkConfigMethod
, __doAppleTalkConfigMethod
, (void *)appletalkConfigMethods
},
501 { "config" , "configuration method"
502 , isChooseOne
, &kSCPropNetAppleTalkConfigMethod
, __doAppleTalkConfigMethod
, (void *)appletalkConfigMethods
},
503 { "DefaultZone" , "zone" , isString
, &kSCPropNetAppleTalkDefaultZone
, NULL
, NULL
},
504 { "NodeID" , "node" , isNumber
, &kSCPropNetAppleTalkNodeID
, NULL
, NULL
},
505 { "node" , "node" , isNumber
, &kSCPropNetAppleTalkNodeID
, NULL
, NULL
},
506 { "NetworkID" , "network", isNumber
, &kSCPropNetAppleTalkNetworkID
, NULL
, NULL
},
507 { "network" , "network", isNumber
, &kSCPropNetAppleTalkNetworkID
, NULL
, NULL
},
508 { "SeedNetworkRange", "range" , isOther
, &kSCPropNetAppleTalkSeedNetworkRange
, __doAppleTalkNetworkRange
, NULL
},
509 { "SeedZones" , "zone" , isStringArray
, &kSCPropNetAppleTalkSeedZones
, NULL
, NULL
},
511 { "?" , NULL
, isHelp
, NULL
, NULL
,
512 "\nAppleTalk configuration commands\n\n"
513 " set protocol config {Node|Router|SeedRouter}\n"
514 " set protocol defaultzone zone\n"
515 " set protocol node id\n"
516 " set protocol network id\n"
519 "\n w/config=Router\n"
521 "\n w/config=SeedRouter\n"
522 " set protocol seednetworkrange low[-high]\n"
523 " set protocol seedzones zone[,zone-2]\n"
526 #define N_APPLETALK_OPTIONS (sizeof(appletalkOptions) / sizeof(appletalkOptions[0]))
530 set_protocol_appletalk(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
534 ok
= _process_options(appletalkOptions
, N_APPLETALK_OPTIONS
, argc
, argv
, newConfiguration
);
539 #endif // !TARGET_OS_IPHONE && INCLUDE_APPLETALK
547 __cleanupDomainName(CFStringRef domain
)
549 CFMutableStringRef newDomain
;
551 newDomain
= CFStringCreateMutableCopy(NULL
, 0, domain
);
552 CFStringTrimWhitespace(newDomain
);
553 CFStringTrim(newDomain
, CFSTR("."));
554 if (CFStringGetLength(newDomain
) == 0) {
555 CFRelease(newDomain
);
564 __doDNSDomain(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
567 SCPrint(TRUE
, stdout
, CFSTR("DNS domain name not specified\n"));
571 if (strlen(argv
[0]) > 0) {
575 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
576 domain
= __cleanupDomainName(str
);
579 if (domain
!= NULL
) {
580 CFDictionarySetValue(newConfiguration
, key
, domain
);
583 SCPrint(TRUE
, stdout
, CFSTR("invalid DNS domain name\n"));
587 CFDictionaryRemoveValue(newConfiguration
, key
);
595 __doDNSDomainArray(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
597 CFMutableArrayRef domains
;
600 SCPrint(TRUE
, stdout
, CFSTR("DNS search domain name(s) not specified\n"));
604 domains
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
606 if (strlen(argv
[0]) > 0) {
610 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
611 array
= CFStringCreateArrayBySeparatingStrings(NULL
, str
, CFSTR(","));
616 CFIndex n
= CFArrayGetCount(array
);
618 for (i
= 0; i
< n
; i
++) {
621 domain
= __cleanupDomainName(CFArrayGetValueAtIndex(array
, i
));
622 if (domain
!= NULL
) {
623 CFArrayAppendValue(domains
, domain
);
628 SCPrint(TRUE
, stdout
, CFSTR("invalid DNS search domain name\n"));
636 if (CFArrayGetCount(domains
) > 0) {
637 CFDictionarySetValue(newConfiguration
, key
, domains
);
639 CFDictionaryRemoveValue(newConfiguration
, key
);
648 __doDNSServerAddresses(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
650 CFMutableArrayRef servers
;
653 SCPrint(TRUE
, stdout
, CFSTR("DNS name server address(es) not specified\n"));
657 servers
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
659 if (strlen(argv
[0]) > 0) {
665 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
666 array
= CFStringCreateArrayBySeparatingStrings(NULL
, str
, CFSTR(","));
669 n
= (array
!= NULL
) ? CFArrayGetCount(array
) : 0;
670 for (i
= 0; i
< n
; i
++) {
673 if (_SC_cfstring_to_cstring(CFArrayGetValueAtIndex(array
, i
),
676 kCFStringEncodingUTF8
) != NULL
) {
679 server
= __copyIPv4Address(str
);
680 if (server
== NULL
) {
681 server
= __copyIPv6Address(str
);
683 if (server
!= NULL
) {
684 CFArrayAppendValue(servers
, server
);
690 SCPrint(TRUE
, stdout
, CFSTR("invalid DNS name server address\n"));
695 if (array
!= NULL
) CFRelease(array
);
698 if (CFArrayGetCount(servers
) > 0) {
699 CFDictionarySetValue(newConfiguration
, key
, servers
);
701 CFDictionaryRemoveValue(newConfiguration
, key
);
709 static options dnsOptions
[] = {
710 { "DomainName" , "domain" , isOther
, &kSCPropNetDNSDomainName
, __doDNSDomain
, NULL
},
711 { "domain" , "domain" , isOther
, &kSCPropNetDNSDomainName
, __doDNSDomain
, NULL
},
712 { "SearchDomains" , "search" , isOther
, &kSCPropNetDNSSearchDomains
, __doDNSDomainArray
, NULL
},
713 { "search" , "search" , isOther
, &kSCPropNetDNSSearchDomains
, __doDNSDomainArray
, NULL
},
714 { "ServerAddresses", "address", isOther
, &kSCPropNetDNSServerAddresses
, __doDNSServerAddresses
, NULL
},
715 { "nameserver" , "address", isOther
, &kSCPropNetDNSServerAddresses
, __doDNSServerAddresses
, NULL
},
716 { "nameservers" , "address", isOther
, &kSCPropNetDNSServerAddresses
, __doDNSServerAddresses
, NULL
},
718 { "?" , NULL
, isHelp
, NULL
, NULL
,
719 "\nDNS configuration commands\n\n"
720 " set protocol search domain-name[,domain-name-2]\n"
721 " set protocol nameserver x1.x1.x1.x1[,x2.x2.x2.x2]\n"
724 #define N_DNS_OPTIONS (sizeof(dnsOptions) / sizeof(dnsOptions[0]))
728 set_protocol_dns(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
732 ok
= _process_options(dnsOptions
, N_DNS_OPTIONS
, argc
, argv
, newConfiguration
);
741 #define allowIPv4Address 1<<1 // allow address
742 #define allowIPv4Netmask 1<<2 // allow subnet mask
743 #define allowIPv4Router 1<<3 // allow router
744 #define allowIPv4DHCPClientID 1<<4 // allow DCHP Client ID
746 static selections ipv4ConfigMethods
[] = {
747 { CFSTR("BOOTP") , &kSCValNetIPv4ConfigMethodBOOTP
, 0 },
748 { CFSTR("DHCP") , &kSCValNetIPv4ConfigMethodDHCP
, allowIPv4DHCPClientID
},
749 { CFSTR("INFORM") , &kSCValNetIPv4ConfigMethodINFORM
, allowIPv4Address
},
750 { CFSTR("LinkLocal"), &kSCValNetIPv4ConfigMethodLinkLocal
, 0 },
751 { CFSTR("Manual") , &kSCValNetIPv4ConfigMethodManual
, allowIPv4Address
|allowIPv4Netmask
|allowIPv4Router
},
752 { CFSTR("PPP") , &kSCValNetIPv4ConfigMethodPPP
, allowIPv4Address
|selectionNotAvailable
},
758 __doIPv4ConfigMethod(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
764 method
= CFDictionaryGetValue(newConfiguration
, key
);
765 methodIndex
= _find_selection(method
, (selections
*)ipv4ConfigMethods
, &flags
);
766 if (methodIndex
!= kCFNotFound
) {
767 if (!(flags
& allowIPv4Address
)) {
768 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv4Addresses
);
770 if (!(flags
& allowIPv4Netmask
)) {
771 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv4SubnetMasks
);
773 if (!(flags
& allowIPv4Router
)) {
774 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv4Router
);
776 if (!(flags
& allowIPv4DHCPClientID
)) {
777 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv4DHCPClientID
);
780 SCPrint(TRUE
, stdout
, CFSTR("unknown configuration method\n"));
789 __doIPv4Addresses(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
791 Boolean useArray
= (info
== (void *)FALSE
) ? FALSE
: TRUE
;
793 if (strlen(argv
[0]) > 0) {
796 address
= __copyIPv4Address(argv
[0]);
797 if (address
!= NULL
) {
799 CFArrayRef addresses
;
801 addresses
= CFArrayCreate(NULL
, (const void **)&address
, 1, &kCFTypeArrayCallBacks
);
802 CFDictionarySetValue(newConfiguration
, key
, addresses
);
803 CFRelease(addresses
);
805 CFDictionarySetValue(newConfiguration
, key
, address
);
812 CFDictionaryRemoveValue(newConfiguration
, key
);
819 static options ipv4Options
[] = {
820 { "ConfigMethod", "configuration method"
821 , isChooseOne
, &kSCPropNetIPv4ConfigMethod
, __doIPv4ConfigMethod
, (void *)ipv4ConfigMethods
},
822 { "config" , "configuration method"
823 , isChooseOne
, &kSCPropNetIPv4ConfigMethod
, __doIPv4ConfigMethod
, (void *)ipv4ConfigMethods
},
824 { "Addresses" , "address" , isOther
, &kSCPropNetIPv4Addresses
, __doIPv4Addresses
, (void *)TRUE
},
825 { "address" , "address" , isOther
, &kSCPropNetIPv4Addresses
, __doIPv4Addresses
, (void *)TRUE
},
826 { "SubnetMasks" , "netmask" , isOther
, &kSCPropNetIPv4SubnetMasks
, __doIPv4Addresses
, (void *)TRUE
},
827 { "netmask" , "netmask" , isOther
, &kSCPropNetIPv4SubnetMasks
, __doIPv4Addresses
, (void *)TRUE
},
828 { "Router" , "address" , isOther
, &kSCPropNetIPv4Router
, __doIPv4Addresses
, (void *)FALSE
},
829 { "DHCPClientID", "client ID", isString
, &kSCPropNetIPv4DHCPClientID
, NULL
, NULL
},
831 { "?" , NULL
, isHelp
, NULL
, NULL
,
832 "\nIPv4 configuration commands\n\n"
833 " set protocol config {BOOTP|DHCP|INFORM|MANUAL}\n"
834 "\n w/config=BOOTP\n"
837 " set protocol dhcpclientid identifier\n"
838 "\n w/config=INFORM\n"
839 " set protocol address x.x.x.x\n"
840 "\n w/config=MANUAL\n"
841 " set protocol address x.x.x.x\n"
842 " set protocol netmask x.x.x.x\n"
843 " set protocol router x.x.x.x\n"
846 #define N_IPV4_OPTIONS (sizeof(ipv4Options) / sizeof(ipv4Options[0]))
850 set_protocol_ipv4(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
854 ok
= _process_options(ipv4Options
, N_IPV4_OPTIONS
, argc
, argv
, newConfiguration
);
860 // validate configuration
861 method
= CFDictionaryGetValue(newConfiguration
, kSCPropNetIPv4ConfigMethod
);
862 methodIndex
= _find_selection(method
, (selections
*)ipv4ConfigMethods
, &flags
);
863 if (methodIndex
== kCFNotFound
) {
864 SCPrint(TRUE
, stdout
, CFSTR("unknown configuration method\n"));
868 if (!(flags
& allowIPv4Address
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv4Addresses
)) {
869 SCPrint(TRUE
, stdout
,
870 CFSTR("IP address not allowed with %@ configuration\n"),
871 ipv4ConfigMethods
[methodIndex
].selection
);
875 if (!(flags
& allowIPv4Netmask
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv4SubnetMasks
)) {
876 SCPrint(TRUE
, stdout
,
877 CFSTR("Subnet mask not allowed with %@ configuration\n"),
878 ipv4ConfigMethods
[methodIndex
].selection
);
882 if (!(flags
& allowIPv4Router
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv4Router
)) {
883 SCPrint(TRUE
, stdout
,
884 CFSTR("Default route not allowed with %@ configuration\n"),
885 ipv4ConfigMethods
[methodIndex
].selection
);
889 if (!(flags
& allowIPv4DHCPClientID
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv4DHCPClientID
)) {
890 SCPrint(TRUE
, stdout
,
891 CFSTR("DHCP client ID not allowed with %@ configuration\n"),
892 ipv4ConfigMethods
[methodIndex
].selection
);
905 #define allowIPv6Address 1<<1 // allow address
906 #define allowIPv6PrefixLength 1<<2 // allow prefix length
907 #define allowIPv6Router 1<<3 // allow router
909 static selections ipv6ConfigMethods
[] = {
910 { CFSTR("Automatic") , & kSCValNetIPv6ConfigMethodAutomatic
, 0 },
911 { CFSTR("Manual") , & kSCValNetIPv6ConfigMethodManual
, allowIPv6Address
|allowIPv6PrefixLength
|allowIPv6Router
},
912 { CFSTR("RouterAdvertisement"), & kSCValNetIPv6ConfigMethodRouterAdvertisement
, allowIPv6Address
},
913 { CFSTR("6to4") , & kSCValNetIPv6ConfigMethod6to4
, 0 },
919 __doIPv6ConfigMethod(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
925 method
= CFDictionaryGetValue(newConfiguration
, key
);
926 methodIndex
= _find_selection(method
, (selections
*)ipv6ConfigMethods
, &flags
);
927 if (methodIndex
!= kCFNotFound
) {
928 if (!(flags
& allowIPv6Address
)) {
929 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv6Addresses
);
931 if (!(flags
& allowIPv6PrefixLength
)) {
932 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv6PrefixLength
);
934 if (!(flags
& allowIPv6Router
)) {
935 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPv6Router
);
938 SCPrint(TRUE
, stdout
, CFSTR("unknown configuration method\n"));
947 __doIPv6Addresses(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
949 Boolean useArray
= (info
== (void *)FALSE
) ? FALSE
: TRUE
;
951 if (strlen(argv
[0]) > 0) {
954 address
= __copyIPv6Address(argv
[0]);
955 if (address
!= NULL
) {
957 CFArrayRef addresses
;
959 addresses
= CFArrayCreate(NULL
, (const void **)&address
, 1, &kCFTypeArrayCallBacks
);
960 CFDictionarySetValue(newConfiguration
, key
, addresses
);
961 CFRelease(addresses
);
963 CFDictionarySetValue(newConfiguration
, key
, address
);
970 CFDictionaryRemoveValue(newConfiguration
, key
);
977 static options ipv6Options
[] = {
978 { "ConfigMethod", "configuration method"
979 , isChooseOne
, &kSCPropNetIPv6ConfigMethod
, __doIPv6ConfigMethod
, (void *)ipv6ConfigMethods
},
980 { "config" , "configuration method"
981 , isChooseOne
, &kSCPropNetIPv6ConfigMethod
, __doIPv6ConfigMethod
, (void *)ipv6ConfigMethods
},
982 { "Addresses" , "address" , isOther
, &kSCPropNetIPv6Addresses
, __doIPv6Addresses
, (void *)TRUE
},
983 { "address" , "address" , isOther
, &kSCPropNetIPv6Addresses
, __doIPv6Addresses
, (void *)TRUE
},
984 { "PrefixLength", "prefix length", isNumber
, &kSCPropNetIPv6PrefixLength
, NULL
, NULL
},
985 { "Router" , "address" , isOther
, &kSCPropNetIPv6Router
, __doIPv6Addresses
, (void *)FALSE
},
987 { "?" , NULL
, isHelp
, NULL
, NULL
,
988 "\nIPv6 configuration commands\n\n"
989 " set protocol config {Automatic|MANUAL}\n"
990 "\n w/config=Automatic\n"
992 "\n w/config=MANUAL\n"
993 " set protocol address x:x:x:x:x:x\n"
994 " set protocol router x:x:x:x:x:x\n"
995 " set protocol prefixlength n\n"
998 #define N_IPV6_OPTIONS (sizeof(ipv6Options) / sizeof(ipv6Options[0]))
1002 set_protocol_ipv6(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1006 ok
= _process_options(ipv6Options
, N_IPV6_OPTIONS
, argc
, argv
, newConfiguration
);
1010 CFIndex methodIndex
;
1012 // validate configuration
1013 method
= CFDictionaryGetValue(newConfiguration
, kSCPropNetIPv6ConfigMethod
);
1014 methodIndex
= _find_selection(method
, (selections
*)ipv6ConfigMethods
, &flags
);
1015 if (methodIndex
== kCFNotFound
) {
1016 SCPrint(TRUE
, stdout
, CFSTR("unknown configuration method\n"));
1020 if (!(flags
& allowIPv6Address
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv6Addresses
)) {
1021 SCPrint(TRUE
, stdout
,
1022 CFSTR("IP address not allowed with %@ configuration\n"),
1023 ipv6ConfigMethods
[methodIndex
].selection
);
1027 if (!(flags
& allowIPv6PrefixLength
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv6PrefixLength
)) {
1028 SCPrint(TRUE
, stdout
,
1029 CFSTR("Prefix length not allowed with %@ configuration\n"),
1030 ipv6ConfigMethods
[methodIndex
].selection
);
1034 if (!(flags
& allowIPv6Router
) && CFDictionaryContainsKey(newConfiguration
, kSCPropNetIPv6Router
)) {
1035 SCPrint(TRUE
, stdout
,
1036 CFSTR("Router not allowed with %@ configuration\n"),
1037 ipv6ConfigMethods
[methodIndex
].selection
);
1047 #pragma mark Proxies
1050 typedef const struct {
1052 const CFStringRef
*keyEnable
;
1053 const CFStringRef
*keyProxy
;
1054 const CFStringRef
*keyPort
;
1055 const CFStringRef
*keyURL
;
1058 static proxyKeys proxyKeys_FTP
= { "FTP" , &kSCPropNetProxiesFTPEnable
, &kSCPropNetProxiesFTPProxy
, &kSCPropNetProxiesFTPPort
, NULL
};
1059 static proxyKeys proxyKeys_Gopher
= { "Gopher", &kSCPropNetProxiesGopherEnable
, &kSCPropNetProxiesGopherProxy
, &kSCPropNetProxiesGopherPort
, NULL
};
1060 static proxyKeys proxyKeys_HTTP
= { "HTTP" , &kSCPropNetProxiesHTTPEnable
, &kSCPropNetProxiesHTTPProxy
, &kSCPropNetProxiesHTTPPort
, NULL
};
1061 static proxyKeys proxyKeys_HTTPS
= { "HTTPS" , &kSCPropNetProxiesHTTPSEnable
, &kSCPropNetProxiesHTTPSProxy
, &kSCPropNetProxiesHTTPSPort
, NULL
};
1062 static proxyKeys proxyKeys_RTSP
= { "RTSP" , &kSCPropNetProxiesRTSPEnable
, &kSCPropNetProxiesRTSPProxy
, &kSCPropNetProxiesRTSPPort
, NULL
};
1063 static proxyKeys proxyKeys_SOCKS
= { "SOCKS" , &kSCPropNetProxiesSOCKSEnable
, &kSCPropNetProxiesSOCKSProxy
, &kSCPropNetProxiesSOCKSPort
, NULL
};
1064 static proxyKeys proxyKeys_PAC
= { ".pac" , &kSCPropNetProxiesProxyAutoConfigEnable
, NULL
, NULL
, &kSCPropNetProxiesProxyAutoConfigURLString
};
1065 static proxyKeys proxyKeys_WPAD
= { "WPAD" , &kSCPropNetProxiesProxyAutoDiscoveryEnable
, NULL
, NULL
, NULL
};
1067 static proxyKeys
*currentProxy
= NULL
;
1070 static int __doProxySelect (CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
);
1071 static int __doProxyEnable (CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
);
1072 static int __doProxyHost (CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
);
1073 static int __doProxyPort (CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
);
1074 static int __doProxyURL (CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
);
1075 static int __doProxyFTPPassive(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
);
1078 static options proxyOptions
[] = {
1080 { "ExceptionsList" , "exceptions", isStringArray
, &kSCPropNetProxiesExceptionsList
, NULL
, NULL
},
1081 { "ExcludeSimpleHostnames", NULL
, isBoolean
, &kSCPropNetProxiesExcludeSimpleHostnames
, NULL
, NULL
},
1083 { "FTP" , NULL
, isOther
, NULL
, __doProxySelect
, (void *)&proxyKeys_FTP
},
1084 { "Gopher" , NULL
, isOther
, NULL
, __doProxySelect
, (void *)&proxyKeys_Gopher
},
1085 { "HTTP" , NULL
, isOther
, NULL
, __doProxySelect
, (void *)&proxyKeys_HTTP
},
1086 { "HTTPS" , NULL
, isOther
, NULL
, __doProxySelect
, (void *)&proxyKeys_HTTPS
},
1087 { "RTSP" , NULL
, isOther
, NULL
, __doProxySelect
, (void *)&proxyKeys_RTSP
},
1088 { "SOCKS" , NULL
, isOther
, NULL
, __doProxySelect
, (void *)&proxyKeys_SOCKS
},
1089 { "ProxyAutoConfig" , NULL
, isOther
, NULL
, __doProxySelect
, (void *)&proxyKeys_PAC
},
1090 { ".pac" , NULL
, isOther
, NULL
, __doProxySelect
, (void *)&proxyKeys_PAC
},
1091 { "ProxyAutoDiscovery" , NULL
, isOther
, NULL
, __doProxySelect
, (void *)&proxyKeys_WPAD
},
1092 { "WPAD" , NULL
, isOther
, NULL
, __doProxySelect
, (void *)&proxyKeys_WPAD
},
1094 { "disable" , NULL
, isOther
, NULL
, __doProxyEnable
, (void *)FALSE
},
1095 { "enable" , NULL
, isOther
, NULL
, __doProxyEnable
, (void *)TRUE
},
1096 { "proxy" , NULL
, isOther
, NULL
, __doProxyHost
, NULL
},
1097 { "host" , NULL
, isOther
, NULL
, __doProxyHost
, NULL
},
1098 { "port" , NULL
, isOther
, NULL
, __doProxyPort
, NULL
},
1099 { "url" , NULL
, isOther
, NULL
, __doProxyURL
, NULL
},
1100 // (ftp) proxy modifiers
1101 { "FTPPassive" , NULL
, isBoolean
, &kSCPropNetProxiesFTPPassive
, __doProxyFTPPassive
, NULL
},
1102 { "passive" , NULL
, isBoolean
, &kSCPropNetProxiesFTPPassive
, __doProxyFTPPassive
, NULL
},
1104 { "?" , NULL
, isHelp
, NULL
, NULL
,
1105 "\nProxy configuration commands\n\n"
1106 " set protocol ExceptionsList exception[,exception-2]\n"
1107 " set protocol ExcludeSimpleHostnames {enable|disable}\n"
1109 " set protocol ftp {enable|disable}\n"
1110 " set protocol ftp host proxy-host\n"
1111 " set protocol ftp port proxy-port\n"
1112 " set protocol ftp passive {enable|disable}\n"
1114 " set protocol http {enable|disable}\n"
1115 " set protocol http host proxy-host\n"
1116 " set protocol http port proxy-port\n"
1118 " set protocol https {enable|disable}\n"
1119 " set protocol https host proxy-host\n"
1120 " set protocol https port proxy-port\n"
1122 " set protocol rtsp {enable|disable}\n"
1123 " set protocol rtsp host proxy-host\n"
1124 " set protocol rtsp port proxy-port\n"
1126 " set protocol socks {enable|disable}\n"
1127 " set protocol socks host proxy-host\n"
1128 " set protocol socks port proxy-port\n"
1130 " set protocol .pac {enable|disable}\n"
1131 " set protocol .pac url .pac-url\n"
1133 " set protocol wpad {enable|disable}\n"
1136 #define N_PROXY_OPTIONS (sizeof(proxyOptions) / sizeof(proxyOptions[0]))
1140 __doProxySelect(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1145 SCPrint(TRUE
, stdout
, CFSTR("proxy option[s] not specified\n"));
1149 currentProxy
= (proxyKeys
*)info
;
1151 nextOption
= _find_option(argv
[0], proxyOptions
, N_PROXY_OPTIONS
);
1152 if ((nextOption
== kCFNotFound
) ||
1153 (proxyOptions
[nextOption
].handler
== __doProxySelect
)) {
1154 SCPrint(TRUE
, stdout
, CFSTR("%s proxy option[s] not specified\n"), currentProxy
->proxy
);
1163 __doProxyEnable(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1165 Boolean enabled
= (info
== (void *)FALSE
) ? FALSE
: TRUE
;
1167 if (currentProxy
== NULL
) {
1168 SCPrint(TRUE
, stdout
, CFSTR("proxy not specified\n"));
1172 if (currentProxy
->keyEnable
== NULL
) {
1173 SCPrint(TRUE
, stdout
, CFSTR("%s proxy cannot be %s\n"),
1174 currentProxy
->proxy
,
1175 enabled
? "enabled" : "disabled");
1181 CFDictionarySetValue(newConfiguration
, *(currentProxy
->keyEnable
), CFNumberRef_1
);
1183 CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyEnable
));
1185 if (currentProxy
->keyProxy
!= NULL
) {
1186 CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyProxy
));
1189 if (currentProxy
->keyPort
!= NULL
) {
1190 CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyPort
));
1193 if (currentProxy
->keyURL
!= NULL
) {
1194 CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyURL
));
1203 __proxy_enabled(CFDictionaryRef configuration
, const CFStringRef
*enableKey
)
1208 if (enableKey
== NULL
) {
1209 return TRUE
; // if proxy does not need to be enabled
1212 num
= CFDictionaryGetValue(configuration
, *enableKey
);
1213 if (!isA_CFNumber(num
) ||
1214 !CFNumberGetValue(num
, kCFNumberIntType
, &val
) ||
1216 return FALSE
; // if not enabled
1224 __doProxyHost(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1226 if (currentProxy
== NULL
) {
1227 SCPrint(TRUE
, stdout
, CFSTR("proxy not specified\n"));
1231 if (currentProxy
->keyProxy
== NULL
) {
1232 SCPrint(TRUE
, stdout
, CFSTR("%s proxy host cannot be specified\n"), currentProxy
->proxy
);
1236 if (!__proxy_enabled(newConfiguration
, currentProxy
->keyEnable
)) {
1237 SCPrint(TRUE
, stdout
, CFSTR("%s proxy not enabled\n"), currentProxy
->proxy
);
1242 SCPrint(TRUE
, stdout
, CFSTR("%s proxy host not specified\n"), currentProxy
->proxy
);
1246 if (strlen(argv
[0]) > 0) {
1249 host
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1250 CFDictionarySetValue(newConfiguration
, *(currentProxy
->keyProxy
), host
);
1253 CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyProxy
));
1261 __doProxyPort(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1263 if (currentProxy
== NULL
) {
1264 SCPrint(TRUE
, stdout
, CFSTR("proxy not specified\n"));
1268 if (currentProxy
->keyPort
== NULL
) {
1269 SCPrint(TRUE
, stdout
, CFSTR("%s proxy port cannot be specified\n"), currentProxy
->proxy
);
1273 if (!__proxy_enabled(newConfiguration
, currentProxy
->keyEnable
)) {
1274 SCPrint(TRUE
, stdout
, CFSTR("%s proxy not enabled\n"), currentProxy
->proxy
);
1279 SCPrint(TRUE
, stdout
, CFSTR("%s proxy port not specified\n"), currentProxy
->proxy
);
1283 if (strlen(argv
[0]) > 0) {
1287 num
= _copy_number(argv
[0]);
1288 if (!isA_CFNumber(num
) ||
1289 !CFNumberGetValue(num
, kCFNumberIntType
, &port
) ||
1290 (port
< 0) || (port
> 65535)) {
1291 SCPrint(TRUE
, stdout
, CFSTR("invalid %s proxy port number\n"), currentProxy
->proxy
);
1295 CFDictionarySetValue(newConfiguration
, *(currentProxy
->keyPort
), num
);
1298 CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyPort
));
1306 __doProxyURL(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1308 if (currentProxy
== NULL
) {
1309 SCPrint(TRUE
, stdout
, CFSTR("proxy not specified\n"));
1313 if (currentProxy
->keyURL
== NULL
) {
1314 SCPrint(TRUE
, stdout
, CFSTR("%s proxy URL cannot be specified\n"), currentProxy
->proxy
);
1318 if (!__proxy_enabled(newConfiguration
, currentProxy
->keyEnable
)) {
1319 SCPrint(TRUE
, stdout
, CFSTR("%s proxy not enabled\n"), currentProxy
->proxy
);
1324 SCPrint(TRUE
, stdout
, CFSTR("%s proxy URL not specified\n"), currentProxy
->proxy
);
1328 if (strlen(argv
[0]) > 0) {
1331 url
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1332 CFDictionarySetValue(newConfiguration
, *(currentProxy
->keyURL
), url
);
1335 CFDictionaryRemoveValue(newConfiguration
, *(currentProxy
->keyURL
));
1343 __doProxyFTPPassive(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1345 if (currentProxy
== NULL
) {
1346 SCPrint(TRUE
, stdout
, CFSTR("proxy not specified\n"));
1350 if (currentProxy
!= &proxyKeys_FTP
) {
1351 SCPrint(TRUE
, stdout
, CFSTR("passive can only be enable for FTP proxy\n"));
1360 set_protocol_proxies(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1364 ok
= _process_options(proxyOptions
, N_PROXY_OPTIONS
, argc
, argv
, newConfiguration
);
1373 #if !TARGET_OS_IPHONE
1377 __cleanupName(CFStringRef name
)
1379 CFMutableStringRef newName
;
1381 newName
= CFStringCreateMutableCopy(NULL
, 0, name
);
1382 CFStringTrimWhitespace(newName
);
1383 if (CFStringGetLength(newName
) == 0) {
1393 __doSMBName(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1396 SCPrint(TRUE
, stdout
, CFSTR("NetBIOS name not specified\n"));
1400 if (strlen(argv
[0]) > 0) {
1404 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1405 name
= __cleanupName(str
);
1409 CFDictionarySetValue(newConfiguration
, key
, name
);
1412 SCPrint(TRUE
, stdout
, CFSTR("invalid NetBIOS name\n"));
1416 CFDictionaryRemoveValue(newConfiguration
, key
);
1424 __doSMBWorkgroup(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1427 SCPrint(TRUE
, stdout
, CFSTR("Workgroup not specified\n"));
1431 if (strlen(argv
[0]) > 0) {
1435 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1436 name
= __cleanupName(str
);
1440 CFDictionarySetValue(newConfiguration
, key
, name
);
1443 SCPrint(TRUE
, stdout
, CFSTR("invalid Workgroup\n"));
1447 CFDictionaryRemoveValue(newConfiguration
, key
);
1455 __doSMBWINSAddresses(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1457 CFMutableArrayRef servers
;
1460 SCPrint(TRUE
, stdout
, CFSTR("WINS address(es) not specified\n"));
1464 servers
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1466 if (strlen(argv
[0]) > 0) {
1472 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1473 array
= CFStringCreateArrayBySeparatingStrings(NULL
, str
, CFSTR(","));
1476 n
= (array
!= NULL
) ? CFArrayGetCount(array
) : 0;
1477 for (i
= 0; i
< n
; i
++) {
1480 if (_SC_cfstring_to_cstring(CFArrayGetValueAtIndex(array
, i
),
1483 kCFStringEncodingUTF8
) != NULL
) {
1486 server
= __copyIPv4Address(str
);
1487 //if (server == NULL) {
1488 // server = __copyIPv6Address(str);
1490 if (server
!= NULL
) {
1491 CFArrayAppendValue(servers
, server
);
1497 SCPrint(TRUE
, stdout
, CFSTR("invalid WINS address\n"));
1502 if (array
!= NULL
) CFRelease(array
);
1505 if (CFArrayGetCount(servers
) > 0) {
1506 CFDictionarySetValue(newConfiguration
, key
, servers
);
1508 CFDictionaryRemoveValue(newConfiguration
, key
);
1516 static selections smbNodeTypes
[] = {
1517 { CFSTR("Broadcast"), &kSCValNetSMBNetBIOSNodeTypeBroadcast
, 0 },
1518 { CFSTR("Peer") , &kSCValNetSMBNetBIOSNodeTypePeer
, 0 },
1519 { CFSTR("Mixed") , &kSCValNetSMBNetBIOSNodeTypeMixed
, 0 },
1520 { CFSTR("Hybrid") , &kSCValNetSMBNetBIOSNodeTypeHybrid
, 0 },
1525 static options smbOptions
[] = {
1526 { "NetBIOSName" , "name" , isOther
, &kSCPropNetSMBNetBIOSName
, __doSMBName
, NULL
},
1527 { "name" , "name" , isOther
, &kSCPropNetSMBNetBIOSName
, __doSMBName
, NULL
},
1528 { "NetBIOSNodeType", "type" , isChooseOne
, &kSCPropNetSMBNetBIOSNodeType
, NULL
, (void *)smbNodeTypes
},
1529 { "type", "type" , isChooseOne
, &kSCPropNetSMBNetBIOSNodeType
, NULL
, (void *)smbNodeTypes
},
1530 { "Workgroup" , "workgroup", isOther
, &kSCPropNetSMBWorkgroup
, __doSMBWorkgroup
, NULL
},
1531 { "WINSAddresses" , "wins" , isOther
, &kSCPropNetSMBWINSAddresses
, __doSMBWINSAddresses
, NULL
},
1532 { "wins" , "wins" , isOther
, &kSCPropNetSMBWINSAddresses
, __doSMBWINSAddresses
, NULL
},
1534 { "?" , NULL
, isHelp
, NULL
, NULL
,
1535 "\nSMB configuration commands\n\n"
1536 " set protocol name NetBIOS-name\n"
1537 " set protocol type (Broadcast|Peer|Mixed|Hybrid)\n"
1538 " set protocol workgroup SMB-workgroup\n"
1539 " set protocol wins x1.x1.x1.x1[,x2.x2.x2.x2]\n"
1542 #define N_SMB_OPTIONS (sizeof(smbOptions) / sizeof(smbOptions[0]))
1546 set_protocol_smb(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1550 ok
= _process_options(smbOptions
, N_SMB_OPTIONS
, argc
, argv
, newConfiguration
);
1555 #endif // !TARGET_OS_IPHONE
1559 #pragma mark *Protocol*
1564 set_protocol(int argc
, char **argv
)
1566 CFDictionaryRef configuration
;
1567 CFMutableDictionaryRef newConfiguration
= NULL
;
1569 CFStringRef protocolType
;
1571 if (net_protocol
== NULL
) {
1572 SCPrint(TRUE
, stdout
, CFSTR("protocol not selected\n"));
1577 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1581 configuration
= SCNetworkProtocolGetConfiguration(net_protocol
);
1582 if (configuration
== NULL
) {
1583 newConfiguration
= CFDictionaryCreateMutable(NULL
,
1585 &kCFTypeDictionaryKeyCallBacks
,
1586 &kCFTypeDictionaryValueCallBacks
);
1588 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
1589 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
1592 protocolType
= SCNetworkProtocolGetProtocolType(net_protocol
);
1593 if (CFEqual(protocolType
, kSCNetworkProtocolTypeDNS
)) {
1594 ok
= set_protocol_dns(argc
, argv
, newConfiguration
);
1595 } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeIPv4
)) {
1596 ok
= set_protocol_ipv4(argc
, argv
, newConfiguration
);
1597 } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeIPv6
)) {
1598 ok
= set_protocol_ipv6(argc
, argv
, newConfiguration
);
1599 } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeProxies
)) {
1600 ok
= set_protocol_proxies(argc
, argv
, newConfiguration
);
1601 #if !TARGET_OS_IPHONE && INCLUDE_APPLETALK
1602 } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeAppleTalk
)) {
1603 ok
= set_protocol_appletalk(argc
, argv
, newConfiguration
);
1604 #endif // !TARGET_OS_IPHONE && INCLUDE_APPLETALK
1605 #if !TARGET_OS_IPHONE
1606 } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeSMB
)) {
1607 ok
= set_protocol_smb(argc
, argv
, newConfiguration
);
1608 #endif // !TARGET_OS_IPHONE
1610 SCPrint(TRUE
, stdout
, CFSTR("this protocols configuration cannot be changed\n"));
1617 if (((configuration
== NULL
) && (CFDictionaryGetCount(newConfiguration
) > 0)) ||
1618 ((configuration
!= NULL
) && !CFEqual(configuration
, newConfiguration
))) {
1619 if (!SCNetworkProtocolSetConfiguration(net_protocol
, newConfiguration
)) {
1620 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
1624 _prefs_changed
= TRUE
;
1629 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
1634 /* -------------------- */
1639 show_protocol(int argc
, char **argv
)
1641 CFDictionaryRef configuration
;
1642 SCNetworkProtocolRef protocol
= NULL
;
1643 CFStringRef protocolType
;
1646 protocol
= _find_protocol(argv
[0]);
1648 if (net_protocol
!= NULL
) {
1649 protocol
= net_protocol
;
1651 SCPrint(TRUE
, stdout
, CFSTR("protocol not selected\n"));
1656 if (protocol
== NULL
) {
1660 protocolType
= SCNetworkProtocolGetProtocolType(protocol
);
1661 SCPrint(TRUE
, stdout
, CFSTR("protocol type = %@\n"), protocolType
);
1663 configuration
= SCNetworkProtocolGetConfiguration(protocol
);
1664 if (configuration
!= NULL
) {
1665 SCPrint(TRUE
, stdout
, CFSTR("\n protocol configuration\n"));
1666 _show_entity(configuration
, CFSTR(""));
1670 SCPrint(TRUE
, stdout
, CFSTR("\n%@\n"), protocol
);
1677 /* -------------------- */
1682 show_protocols(int argc
, char **argv
)
1687 if (prefs
== NULL
) {
1688 SCPrint(TRUE
, stdout
, CFSTR("network configuration not open\n"));
1692 if (net_service
== NULL
) {
1693 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
1697 if (protocols
!= NULL
) CFRelease(protocols
);
1698 protocols
= SCNetworkServiceCopyProtocols(net_service
);
1699 if (protocols
== NULL
) {
1700 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
1704 n
= CFArrayGetCount(protocols
);
1706 CFMutableArrayRef sorted
;
1708 sorted
= CFArrayCreateMutableCopy(NULL
, 0, protocols
);
1709 CFArraySortValues(sorted
,
1713 CFRelease(protocols
);
1717 for (i
= 0; i
< n
; i
++) {
1718 SCNetworkProtocolRef protocol
;
1719 CFStringRef protocolType
;
1721 protocol
= CFArrayGetValueAtIndex(protocols
, i
);
1722 protocolType
= SCNetworkProtocolGetProtocolType(protocol
);
1724 SCPrint(TRUE
, stdout
, CFSTR("%c%2d: %@%*s :"),
1725 ((net_protocol
!= NULL
) && CFEqual(protocol
, net_protocol
)) ? '>' : ' ',
1728 sizeof("AppleTalk") - CFStringGetLength(protocolType
) - 1,
1731 if (SCNetworkProtocolGetEnabled(protocol
)) {
1732 CFStringRef description
;
1734 description
= _protocol_description(protocol
, FALSE
);
1735 SCPrint(TRUE
, stdout
, CFSTR(" %@"), description
);
1736 CFRelease(description
);
1738 SCPrint(TRUE
, stdout
, CFSTR(" *DISABLED*"));
1740 SCPrint(TRUE
, stdout
, CFSTR("\n"));
1747 /* -------------------- */
1752 _protocol_description(SCNetworkProtocolRef protocol
, Boolean skipEmpty
)
1754 CFDictionaryRef configuration
;
1755 CFMutableStringRef description
= NULL
;
1756 CFStringRef protocolType
;
1758 description
= CFStringCreateMutable(NULL
, 0);
1760 if (!SCNetworkProtocolGetEnabled(protocol
)) {
1764 configuration
= SCNetworkProtocolGetConfiguration(protocol
);
1765 if (configuration
== NULL
) {
1769 protocolType
= SCNetworkProtocolGetProtocolType(protocol
);
1770 if (CFEqual(protocolType
, kSCNetworkProtocolTypeDNS
)) {
1775 domain
= CFDictionaryGetValue(configuration
, kSCPropNetDNSDomainName
);
1776 if (isA_CFString(domain
)) {
1777 CFStringAppendFormat(description
,
1783 search
= CFDictionaryGetValue(configuration
, kSCPropNetDNSSearchDomains
);
1784 if (isA_CFArray(search
)) {
1787 str
= CFStringCreateByCombiningStrings(NULL
, search
, CFSTR(","));
1788 CFStringAppendFormat(description
,
1790 CFSTR("%ssearch=%@"),
1791 CFStringGetLength(description
) > 0 ? ", " : "",
1796 servers
= CFDictionaryGetValue(configuration
, kSCPropNetDNSServerAddresses
);
1797 if (isA_CFArray(servers
)) {
1800 str
= CFStringCreateByCombiningStrings(NULL
, servers
, CFSTR(","));
1801 CFStringAppendFormat(description
,
1803 CFSTR("%sservers=%@"),
1804 CFStringGetLength(description
) > 0 ? ", " : "",
1808 } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeIPv4
)) {
1811 method
= CFDictionaryGetValue(configuration
, kSCPropNetIPv4ConfigMethod
);
1812 if (isA_CFString(method
)) {
1813 CFArrayRef addresses
;
1815 addresses
= CFDictionaryGetValue(configuration
, kSCPropNetIPv4Addresses
);
1816 if (CFEqual(method
, kSCValNetIPv4ConfigMethodINFORM
) &&
1817 isA_CFArray(addresses
)) {
1818 CFStringAppendFormat(description
,
1820 CFSTR("%@, address=%@"),
1822 CFArrayGetValueAtIndex(addresses
, 0));
1823 } else if (CFEqual(method
, kSCValNetIPv4ConfigMethodManual
) &&
1824 isA_CFArray(addresses
)) {
1825 CFStringAppendFormat(description
,
1827 CFSTR("%@, address=%@"),
1829 CFArrayGetValueAtIndex(addresses
, 0));
1831 CFStringAppendFormat(description
,
1837 } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeIPv6
)) {
1840 method
= CFDictionaryGetValue(configuration
, kSCPropNetIPv6ConfigMethod
);
1841 if (isA_CFString(method
)) {
1842 CFStringAppendFormat(description
,
1847 } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeProxies
)) {
1849 static proxyKeys
*keys
[] = { &proxyKeys_FTP
, &proxyKeys_Gopher
, &proxyKeys_HTTP
, &proxyKeys_HTTPS
,
1850 &proxyKeys_RTSP
, &proxyKeys_SOCKS
, &proxyKeys_PAC
, &proxyKeys_WPAD
};
1852 for (i
= 0; i
< sizeof(keys
)/sizeof(keys
[0]); i
++) {
1853 proxyKeys
*currentProxy
= keys
[i
];
1855 if (!__proxy_enabled(configuration
, currentProxy
->keyEnable
)) {
1859 if (((currentProxy
->keyProxy
!= NULL
) &&
1860 !CFDictionaryContainsKey(configuration
, *(currentProxy
->keyProxy
))) ||
1861 ((currentProxy
->keyURL
!= NULL
) &&
1862 !CFDictionaryContainsKey(configuration
, *(currentProxy
->keyURL
)))) {
1866 CFStringAppendFormat(description
,
1869 CFStringGetLength(description
) > 0 ? ", " : "",
1870 currentProxy
->proxy
);
1872 #if !TARGET_OS_IPHONE && INCLUDE_APPLETALK
1873 } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeAppleTalk
)) {
1876 method
= CFDictionaryGetValue(configuration
, kSCPropNetAppleTalkConfigMethod
);
1877 if (isA_CFString(method
)) {
1878 CFStringAppendFormat(description
,
1883 #endif // !TARGET_OS_IPHONE && INCLUDE_APPLETALK
1884 #if !TARGET_OS_IPHONE
1885 } else if (CFEqual(protocolType
, kSCNetworkProtocolTypeSMB
)) {
1888 CFStringRef workgroup
;
1890 name
= CFDictionaryGetValue(configuration
, kSCPropNetSMBNetBIOSName
);
1891 if (isA_CFString(name
)) {
1892 CFStringAppendFormat(description
,
1894 CFSTR("NetBIOS name=%@"),
1898 workgroup
= CFDictionaryGetValue(configuration
, kSCPropNetSMBWorkgroup
);
1899 if (isA_CFString(workgroup
)) {
1900 CFStringAppendFormat(description
,
1902 CFSTR("Workgroup=%@"),
1906 servers
= CFDictionaryGetValue(configuration
, kSCPropNetSMBWINSAddresses
);
1907 if (isA_CFArray(servers
)) {
1910 str
= CFStringCreateByCombiningStrings(NULL
, servers
, CFSTR(","));
1911 CFStringAppendFormat(description
,
1913 CFSTR("%sWINS servers=%@"),
1914 CFStringGetLength(description
) > 0 ? ", " : "",
1918 #endif // !TARGET_OS_IPHONE
1923 if (skipEmpty
&& CFStringGetLength(description
) == 0) {
1924 CFRelease(description
);