2 * Copyright (c) 2004-2011, 2013, 2014 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>
32 #include <TargetConditionals.h>
39 #define INLINE_PASSWORDS_USE_CFSTRING
40 #endif // TARGET_OS_IPHONE
44 #pragma mark Interface management
50 CFMutableArrayRef interfaces
;
51 CFArrayRef real_interfaces
;
53 real_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(prefs
);
54 if (real_interfaces
== NULL
) {
55 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
59 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
61 // include real interfaces
62 CFArrayAppendArray(interfaces
,
64 CFRangeMake(0, CFArrayGetCount(real_interfaces
)));
65 CFRelease(real_interfaces
);
67 // include pseudo interfaces
68 CFArrayAppendValue(interfaces
, kSCNetworkInterfaceLoopback
);
69 CFArrayAppendValue(interfaces
, kSCNetworkInterfaceIPv4
);
71 // include interfaces that we have created
72 if (new_interfaces
!= NULL
) {
73 CFArrayAppendArray(interfaces
,
75 CFRangeMake(0, CFArrayGetCount(new_interfaces
)));
78 return (CFArrayRef
)interfaces
;
84 _find_interface(int argc
, char **argv
, int *nArgs
)
86 Boolean allowIndex
= TRUE
;
88 CFArrayRef myInterfaces
= interfaces
;
90 CFStringRef select_name
= NULL
;
91 SCNetworkInterfaceRef selected
= NULL
;
94 SCPrint(TRUE
, stdout
, CFSTR("no interface specified\n"));
98 if (nArgs
!= NULL
) *nArgs
= 1;
100 if (strcasecmp(argv
[0], "$child") == 0) {
101 if (net_interface
== NULL
) {
102 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
106 selected
= SCNetworkInterfaceGetInterface(net_interface
);
107 if(selected
== NULL
) {
108 SCPrint(TRUE
, stdout
, CFSTR("no child interface\n"));
112 } else if (strcasecmp(argv
[0], "$service") == 0) {
113 if (net_service
== NULL
) {
114 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
118 selected
= SCNetworkServiceGetInterface(net_service
);
119 if(selected
== NULL
) {
120 SCPrint(TRUE
, stdout
, CFSTR("no interface for service\n"));
126 #if !TARGET_OS_IPHONE
127 else if (strcasecmp(argv
[0], "$bond") == 0) {
128 CFStringRef interfaceType
;
130 if (net_interface
== NULL
) {
131 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
135 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
136 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
137 SCPrint(TRUE
, stdout
, CFSTR("interface not Bond\n"));
142 SCPrint(TRUE
, stdout
, CFSTR("no member interface specified\n"));
147 if (nArgs
!= NULL
) *nArgs
+= 1;
149 myInterfaces
= SCBondInterfaceGetMemberInterfaces(net_interface
);
150 if (myInterfaces
== NULL
) {
151 SCPrint(TRUE
, stdout
, CFSTR("no member interfaces\n"));
156 #endif // !TARGET_OS_IPHONE
158 else if (strcasecmp(argv
[0], "$bridge") == 0) {
159 CFStringRef interfaceType
;
161 if (net_interface
== NULL
) {
162 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
166 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
167 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
168 SCPrint(TRUE
, stdout
, CFSTR("interface not Bridge\n"));
173 SCPrint(TRUE
, stdout
, CFSTR("no member interface specified\n"));
178 if (nArgs
!= NULL
) *nArgs
+= 1;
180 myInterfaces
= SCBridgeInterfaceGetMemberInterfaces(net_interface
);
181 if (myInterfaces
== NULL
) {
182 SCPrint(TRUE
, stdout
, CFSTR("no member interfaces\n"));
188 else if (strcasecmp(argv
[0], "$vlan") == 0) {
189 CFStringRef interfaceType
;
191 if (net_interface
== NULL
) {
192 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
196 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
197 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
198 SCPrint(TRUE
, stdout
, CFSTR("interface not VLAN\n"));
202 selected
= SCVLANInterfaceGetPhysicalInterface(net_interface
);
203 if(selected
== NULL
) {
204 SCPrint(TRUE
, stdout
, CFSTR("no physical interface\n"));
210 if ((myInterfaces
== NULL
) && (interfaces
== NULL
)) {
211 interfaces
= _copy_interfaces();
212 if (interfaces
== NULL
) {
215 myInterfaces
= interfaces
;
219 // try to select the interface by its display name
221 select_name
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
223 n
= (myInterfaces
!= NULL
) ? CFArrayGetCount(myInterfaces
) : 0;
224 for (i
= 0; i
< n
; i
++) {
225 SCNetworkInterfaceRef interface
;
226 CFStringRef interfaceName
;
228 interface
= CFArrayGetValueAtIndex(myInterfaces
, i
);
229 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
230 if ((interfaceName
!= NULL
) && CFEqual(select_name
, interfaceName
)) {
231 if (selected
== NULL
) {
232 selected
= interface
;
234 // if multiple interfaces match
236 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
242 if (selected
!= NULL
) {
246 // try to select the interface by its BSD name
248 for (i
= 0; i
< n
; i
++) {
249 SCNetworkInterfaceRef interface
;
250 CFStringRef bsd_name
= NULL
;
252 interface
= CFArrayGetValueAtIndex(myInterfaces
, i
);
253 while ((interface
!= NULL
) && (bsd_name
== NULL
)) {
254 bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
255 if (bsd_name
== NULL
) {
256 interface
= SCNetworkInterfaceGetInterface(interface
);
260 if ((bsd_name
!= NULL
) && CFEqual(select_name
, bsd_name
)) {
261 if (selected
== NULL
) {
262 selected
= interface
;
264 // if multiple interfaces match
266 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
272 if (selected
!= NULL
) {
276 // try to select the interface by its interface type
278 for (i
= 0; i
< n
; i
++) {
279 SCNetworkInterfaceRef interface
;
280 CFStringRef interfaceType
;
282 interface
= CFArrayGetValueAtIndex(myInterfaces
, i
);
283 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
284 if (CFEqual(select_name
, interfaceType
)) {
285 if (selected
== NULL
) {
286 selected
= interface
;
288 // if multiple interfaces match
290 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
296 if (selected
!= NULL
) {
305 // try to select the interface by its index
308 val
= strtol(str
, &end
, 10);
309 if ((*str
!= '\0') &&
310 ((*end
== '\0') || (*end
== '.')) &&
312 if ((val
> 0) && (val
<= n
)) {
313 selected
= CFArrayGetValueAtIndex(myInterfaces
, val
- 1);
317 val
= strtol(str
, &end
, 10);
318 if ((*str
!= '\0') && (*end
== '\0') && (errno
== 0)) {
320 selected
= SCNetworkInterfaceGetInterface(selected
);
321 if (selected
== NULL
) {
331 if (selected
!= NULL
) {
335 SCPrint(TRUE
, stdout
, CFSTR("no match\n"));
339 if (select_name
!= NULL
) CFRelease(select_name
);
344 /* -------------------- */
349 create_interface(int argc
, char **argv
)
351 SCNetworkInterfaceRef interface
;
352 CFStringRef interfaceName
;
353 CFStringRef interfaceType
;
354 SCNetworkInterfaceRef new_interface
;
357 SCPrint(TRUE
, stdout
, CFSTR("what interface type?\n"));
361 interfaceType
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
365 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
366 SCPrint(TRUE
, stdout
, CFSTR("bond creation not yet supported\n"));
369 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
370 SCPrint(TRUE
, stdout
, CFSTR("bridge creation not yet supported\n"));
373 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
374 SCPrint(TRUE
, stdout
, CFSTR("vlan creation not yet supported\n"));
379 if (net_interface
== NULL
) {
380 SCPrint(TRUE
, stdout
, CFSTR("no network interface selected\n"));
384 interface
= net_interface
;
386 interface
= _find_interface(argc
, argv
, NULL
);
389 if (interface
== NULL
) {
393 new_interface
= SCNetworkInterfaceCreateWithInterface(interface
, interfaceType
);
394 if (new_interface
== NULL
) {
395 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
399 if (new_interfaces
== NULL
) {
400 new_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
402 CFArrayAppendValue(new_interfaces
, new_interface
);
404 if (net_interface
!= NULL
) CFRelease(net_interface
);
405 net_interface
= new_interface
;
407 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(net_interface
);
408 if (interfaceName
== NULL
) {
409 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
411 if (interfaceName
== NULL
) {
412 interfaceName
= SCNetworkInterfaceGetInterfaceType(net_interface
);
414 SCPrint(TRUE
, stdout
, CFSTR("interface \"%@\" created and selected\n"), interfaceName
);
418 CFRelease(interfaceType
);
423 /* -------------------- */
428 select_interface(int argc
, char **argv
)
430 SCNetworkInterfaceRef interface
;
432 interface
= _find_interface(argc
, argv
, NULL
);
433 if (interface
!= NULL
) {
434 CFStringRef interfaceName
;
436 if (net_interface
!= NULL
) CFRelease(net_interface
);
437 net_interface
= CFRetain(interface
);
439 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
440 if (interfaceName
== NULL
) {
441 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
443 if (interfaceName
== NULL
) {
444 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
447 SCPrint(TRUE
, stdout
, CFSTR("interface \"%@\" selected\n"), interfaceName
);
454 /* -------------------- */
459 _show_interface(SCNetworkInterfaceRef interface
, CFStringRef prefix
, Boolean showChild
)
461 CFDictionaryRef configuration
;
462 CFStringRef if_bsd_name
;
463 CFStringRef if_localized_name
;
464 CFStringRef if_mac_address
;
466 Boolean isPhysicalEthernet
;
467 CFArrayRef supported
;
469 if_localized_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
470 if (if_localized_name
!= NULL
) {
471 SCPrint(TRUE
, stdout
, CFSTR("%@ name = %@\n"), prefix
, if_localized_name
);
474 if_bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
475 if (if_bsd_name
!= NULL
) {
476 SCPrint(TRUE
, stdout
, CFSTR("%@ interface name = %@\n"), prefix
, if_bsd_name
);
479 if_type
= SCNetworkInterfaceGetInterfaceType(interface
);
480 SCPrint(TRUE
, stdout
, CFSTR("%@ type = %@\n"), prefix
, if_type
);
482 if_mac_address
= SCNetworkInterfaceGetHardwareAddressString(interface
);
483 if (if_mac_address
!= NULL
) {
484 SCPrint(TRUE
, stdout
, CFSTR("%@ address = %@\n"), prefix
, if_mac_address
);
487 configuration
= SCNetworkInterfaceGetConfiguration(interface
);
488 if ((configuration
!= NULL
) &&
489 CFDictionaryContainsKey(configuration
, kSCResvInactive
)) {
490 configuration
= NULL
;
493 if (if_bsd_name
!= NULL
) {
494 CFArrayRef available
;
495 CFDictionaryRef active
;
496 CFDictionaryRef cap_current
;
501 cap_current
= SCNetworkInterfaceCopyCapability(interface
, NULL
);
502 if (cap_current
!= NULL
) {
504 CFArrayRef cap_names
;
505 CFMutableArrayRef cap_sorted
;
509 n
= CFDictionaryGetCount(cap_current
);
510 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFStringRef
), 0);
511 CFDictionaryGetKeysAndValues(cap_current
, keys
, NULL
);
512 cap_names
= CFArrayCreate(NULL
, keys
, n
, &kCFTypeArrayCallBacks
);
513 CFAllocatorDeallocate(NULL
, keys
);
515 cap_sorted
= CFArrayCreateMutableCopy(NULL
, 0, cap_names
);
516 CFRelease(cap_names
);
518 CFArraySortValues(cap_sorted
, CFRangeMake(0, n
), (CFComparatorFunction
)CFStringCompare
, NULL
);
520 SCPrint(TRUE
, stdout
, CFSTR("%@ capabilities = "), prefix
);
521 for (i
= 0; i
< n
; i
++) {
522 CFStringRef cap_name
;
524 CFNumberRef val
= NULL
;
526 cap_name
= CFArrayGetValueAtIndex(cap_sorted
, i
);
527 if (configuration
!= NULL
) {
528 val
= CFDictionaryGetValue(configuration
, cap_name
);
530 if (!isA_CFNumber(val
)) {
531 val
= CFDictionaryGetValue(cap_current
, cap_name
);
534 SCPrint(TRUE
, stdout
, CFSTR("%s%@%c"),
537 (CFNumberGetValue(val
, kCFNumberIntType
, &cap_val
) &&
538 (cap_val
!= 0)) ? '+' : '-');
540 SCPrint(TRUE
, stdout
, CFSTR("\n"));
542 CFRelease(cap_sorted
);
543 CFRelease(cap_current
);
546 if (SCNetworkInterfaceCopyMTU(interface
, &mtu_cur
, &mtu_min
, &mtu_max
)) {
547 char isCurrent
= '*';
549 if (configuration
!= NULL
) {
553 num
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMTU
);
554 if (isA_CFNumber(num
)) {
555 CFNumberGetValue(num
, kCFNumberIntType
, &mtu_req
);
556 if (mtu_cur
!= mtu_req
) {
563 SCPrint(TRUE
, stdout
, CFSTR("%@ mtu %c = %d (%d < n < %d)\n"),
571 if (SCNetworkInterfaceCopyMediaOptions(interface
, NULL
, &active
, &available
, TRUE
)) {
572 char isCurrent
= ' ';
573 CFArrayRef options
= NULL
;
574 CFArrayRef options_req
= NULL
;
575 CFStringRef subtype
= NULL
;
576 CFStringRef subtype_req
= NULL
;
578 if (configuration
!= NULL
) {
579 subtype_req
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMediaSubType
);
580 options_req
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMediaOptions
);
583 if (subtype_req
== NULL
) {
584 subtype_req
= CFSTR("autoselect");
587 if (active
!= NULL
) {
588 subtype
= CFDictionaryGetValue(active
, kSCPropNetEthernetMediaSubType
);
589 options
= CFDictionaryGetValue(active
, kSCPropNetEthernetMediaOptions
);
592 if (subtype
!= NULL
) {
593 if (((subtype_req
!= NULL
) &&
594 CFEqual(subtype
, subtype_req
)) &&
595 ((options
== options_req
) ||
596 ((options
!= NULL
) &&
597 (options_req
!= NULL
) &&
598 CFEqual(options
, options_req
)))
601 } else if ((subtype_req
== NULL
) ||
602 ((subtype_req
!= NULL
) &&
603 CFEqual(subtype_req
, CFSTR("autoselect")))) {
604 // if requested subtype not specified or "autoselect"
609 if (subtype_req
!= NULL
) {
610 SCPrint(TRUE
, stdout
, CFSTR("%@ media %c = %@"),
615 if ((options_req
!= NULL
) &&
616 (CFArrayGetCount(options_req
) > 0)) {
617 CFStringRef options_str
;
619 options_str
= CFStringCreateByCombiningStrings(NULL
, options_req
, CFSTR(","));
620 SCPrint(TRUE
, stdout
, CFSTR(" <%@>"), options_str
);
621 CFRelease(options_str
);
624 SCPrint(TRUE
, stdout
, CFSTR("\n"));
627 SCPrint(TRUE
, stdout
, CFSTR("\n"));
629 if (available
!= NULL
) {
634 subtypes
= SCNetworkInterfaceCopyMediaSubTypes(available
);
635 n_subtypes
= (subtypes
!= NULL
) ? CFArrayGetCount(subtypes
) : 0;
636 for (i
= 0; i
< n_subtypes
; i
++) {
638 CFIndex n_subtype_options
;
640 CFArrayRef subtype_options
;
642 subtype
= CFArrayGetValueAtIndex(subtypes
, i
);
643 subtype_options
= SCNetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
644 n_subtype_options
= (subtype_options
!= NULL
) ? CFArrayGetCount(subtype_options
) : 0;
645 for (j
= 0; j
< n_subtype_options
; j
++) {
646 char isCurrent
= ' ';
649 options
= CFArrayGetValueAtIndex(subtype_options
, j
);
651 if (((subtype_req
!= NULL
) &&
652 CFEqual(subtype
, subtype_req
)) &&
653 ((options
== options_req
) ||
654 ((options
!= NULL
) &&
655 (options_req
!= NULL
) &&
656 CFEqual(options
, options_req
)))
661 SCPrint(TRUE
, stdout
, CFSTR("%@ %s %c = %@"),
663 ((i
== 0) && (j
== 0)) ? "supported media" : " ",
667 if ((options
!= NULL
) &&
668 (CFArrayGetCount(options
) > 0)) {
669 CFStringRef options_str
;
671 options_str
= CFStringCreateByCombiningStrings(NULL
, options
, CFSTR(","));
672 SCPrint(TRUE
, stdout
, CFSTR(" <%@>"), options_str
);
673 CFRelease(options_str
);
676 SCPrint(TRUE
, stdout
, CFSTR("\n"));
678 if (subtype_options
!= NULL
) CFRelease(subtype_options
);
680 if (subtypes
!= NULL
) CFRelease(subtypes
);
683 SCPrint(TRUE
, stdout
, CFSTR("\n"));
687 supported
= SCNetworkInterfaceGetSupportedInterfaceTypes(interface
);
688 SCPrint(TRUE
, stdout
, CFSTR("%@ supported interfaces = "), prefix
);
689 if (supported
!= NULL
) {
691 CFIndex n
= CFArrayGetCount(supported
);
693 for (i
= 0; i
< n
; i
++) {
694 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
695 (i
== 0) ? "" : ", ",
696 CFArrayGetValueAtIndex(supported
, i
));
699 SCPrint(TRUE
, stdout
, CFSTR("\n"));
701 supported
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
);
702 SCPrint(TRUE
, stdout
, CFSTR("%@ supported protocols = "), prefix
);
703 if (supported
!= NULL
) {
705 CFIndex n
= CFArrayGetCount(supported
);
707 for (i
= 0; i
< n
; i
++) {
708 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
709 (i
== 0) ? "" : ", ",
710 CFArrayGetValueAtIndex(supported
, i
));
713 SCPrint(TRUE
, stdout
, CFSTR("\n"));
715 isPhysicalEthernet
= _SCNetworkInterfaceIsPhysicalEthernet(interface
);
716 SCPrint(TRUE
, stdout
, CFSTR("%@ is physical ethernet = %s \n"),
717 prefix
, (isPhysicalEthernet
== TRUE
) ? "YES" : "NO");
719 if (configuration
!= NULL
) {
720 CFMutableDictionaryRef effective
;
722 effective
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
724 // remove known (and already reported) interface configuration keys
725 if (CFDictionaryContainsKey(effective
, kSCResvInactive
)) {
726 CFDictionaryRemoveAllValues(effective
);
728 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMTU
);
729 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMediaSubType
);
730 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMediaOptions
);
732 if (CFDictionaryGetCount(effective
) > 0) {
733 SCPrint(TRUE
, stdout
, CFSTR("\n%@ per-interface configuration\n"), prefix
);
734 _show_entity(effective
, prefix
);
737 CFRelease(effective
);
740 if (CFEqual(if_type
, kSCNetworkInterfaceTypePPP
)) {
741 SCNetworkInterfaceRef childInterface
;
743 childInterface
= SCNetworkInterfaceGetInterface(interface
);
744 if (childInterface
!= NULL
) {
745 CFStringRef childInterfaceType
;
747 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
748 if (CFEqual(childInterfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
749 CFDictionaryRef ipsec_configuration
;
751 ipsec_configuration
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
752 if (isA_CFDictionary(ipsec_configuration
) &&
753 (CFDictionaryGetCount(ipsec_configuration
) > 0)) {
754 SCPrint(TRUE
, stdout
, CFSTR("\n%@ per-interface IPSec configuration\n"), prefix
);
755 _show_entity(ipsec_configuration
, prefix
);
762 SCPrint(TRUE
, stdout
, CFSTR("\n%@\n"), interface
);
765 interface
= SCNetworkInterfaceGetInterface(interface
);
766 if (interface
!= NULL
) {
767 CFStringRef newPrefix
;
769 newPrefix
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@ "), prefix
);
770 SCPrint(TRUE
, stdout
, CFSTR("\n%@child interface\n"), newPrefix
);
771 _show_interface(interface
, newPrefix
, showChild
);
772 CFRelease(newPrefix
);
779 /* -------------------- */
783 validateMediaOptions(SCNetworkInterfaceRef interface
, CFMutableDictionaryRef newConfiguration
)
790 mtu
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMTU
);
791 if (isA_CFNumber(mtu
)) {
796 if (!SCNetworkInterfaceCopyMTU(interface
, NULL
, &mtu_min
, &mtu_max
)) {
797 SCPrint(TRUE
, stdout
, CFSTR("cannot set MTU\n"));
801 if (!CFNumberGetValue(mtu
, kCFNumberIntType
, &mtu_val
) ||
802 (mtu_val
< mtu_min
) ||
803 (mtu_val
> mtu_max
)) {
804 SCPrint(TRUE
, stdout
, CFSTR("mtu out of range\n"));
809 subtype
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMediaSubType
);
810 options
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMediaOptions
);
812 if (subtype
!= NULL
) {
813 CFArrayRef available
= NULL
;
814 CFArrayRef config_options
= options
;
815 CFArrayRef subtypes
= NULL
;
816 CFArrayRef subtype_options
= NULL
;
820 if (options
== NULL
) {
821 config_options
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
824 if (!SCNetworkInterfaceCopyMediaOptions(interface
, NULL
, NULL
, &available
, FALSE
)) {
825 SCPrint(TRUE
, stdout
, CFSTR("media type / options not available\n"));
829 if (available
== NULL
) {
833 subtypes
= SCNetworkInterfaceCopyMediaSubTypes(available
);
834 if ((subtypes
== NULL
) ||
835 !CFArrayContainsValue(subtypes
,
836 CFRangeMake(0, CFArrayGetCount(subtypes
)),
838 SCPrint(TRUE
, stdout
, CFSTR("media type not valid\n"));
842 subtype_options
= SCNetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
843 if ((subtype_options
== NULL
) ||
844 !CFArrayContainsValue(subtype_options
,
845 CFRangeMake(0, CFArrayGetCount(subtype_options
)),
847 SCPrint(TRUE
, stdout
, CFSTR("media options not valid for \"%@\"\n"), subtype
);
851 if (options
== NULL
) {
852 CFDictionarySetValue(newConfiguration
, kSCPropNetEthernetMediaOptions
, config_options
);
859 if (available
!= NULL
) CFRelease(available
);
860 if (subtypes
!= NULL
) CFRelease(subtypes
);
861 if (subtype_options
!= NULL
) CFRelease(subtype_options
);
862 if (options
== NULL
) CFRelease(config_options
);
864 if (options
!= NULL
) {
865 SCPrint(TRUE
, stdout
, CFSTR("media type and options must both be specified\n"));
874 /* -------------------- */
879 show_interfaces(int argc
, char **argv
)
884 if (interfaces
!= NULL
) CFRelease(interfaces
);
885 interfaces
= _copy_interfaces();
886 if (interfaces
== NULL
) {
890 n
= CFArrayGetCount(interfaces
);
891 for (i
= 0; i
< n
; i
++) {
892 CFIndex childIndex
= 0;
893 SCNetworkInterfaceRef interface
;
895 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
897 CFStringRef interfaceName
;
900 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
901 if (interfaceName
== NULL
) {
902 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
904 if (interfaceName
== NULL
) {
905 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
909 if ((net_interface
!= NULL
) && CFEqual(interface
, net_interface
)) {
913 if (childIndex
== 0) {
914 SCPrint(TRUE
, stdout
, CFSTR("%c%2ld: %@\n"),
919 SCPrint(TRUE
, stdout
, CFSTR("%c%2ld.%ld: %@\n"),
927 CFMutableStringRef desc
;
928 CFMutableDictionaryRef formatOptions
;
930 desc
= CFStringCreateMutable(NULL
, 0);
932 formatOptions
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
933 CFDictionarySetValue(formatOptions
, CFSTR("PREFIX1"), CFSTR(""));
934 CFDictionarySetValue(formatOptions
, CFSTR("PREFIX2"), CFSTR("$$"));
935 CFStringAppendFormat(desc
, formatOptions
, CFSTR("%@"), interface
);
936 CFRelease(formatOptions
);
938 // cleanup SCNetworkInterface details
939 CFStringFindAndReplace(desc
,
942 CFRangeMake(0, CFStringGetLength(desc
)),
944 CFStringFindAndReplace(desc
,
947 CFRangeMake(0, CFStringGetLength(desc
)),
949 CFStringFindAndReplace(desc
,
952 CFRangeMake(CFStringGetLength(desc
) - 1, 1),
953 kCFCompareBackwards
|kCFCompareAnchored
);
955 // additional cleanup for Bond, Bridge, VLAN options
956 CFStringFindAndReplace(desc
,
959 CFRangeMake(0, CFStringGetLength(desc
)),
961 CFStringFindAndReplace(desc
,
964 CFRangeMake(0, CFStringGetLength(desc
)),
966 CFStringFindAndReplace(desc
,
969 CFRangeMake(0, CFStringGetLength(desc
)),
972 SCPrint(TRUE
, stdout
, CFSTR("\n %@\n\n"), desc
);
976 interface
= SCNetworkInterfaceGetInterface(interface
);
978 } while (interface
!= NULL
);
985 /* -------------------- */
989 __doRank(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
991 SCNetworkInterfaceRef interface
;
992 CFStringRef interfaceName
;
994 SCNetworkServicePrimaryRank rank
= kSCNetworkServicePrimaryRankDefault
;
995 SCDynamicStoreRef store
;
998 SCPrint(TRUE
, stdout
,
999 CFSTR("%s not specified\n"),
1000 description
!= NULL
? description
: "rank");
1004 if (strlen(argv
[0]) == 0) {
1005 rank
= kSCNetworkServicePrimaryRankDefault
;
1006 } else if ((strcasecmp(argv
[0], "First") == 0)) {
1007 rank
= kSCNetworkServicePrimaryRankFirst
;
1008 } else if ((strcasecmp(argv
[0], "Last") == 0)) {
1009 rank
= kSCNetworkServicePrimaryRankLast
;
1010 } else if ((strcasecmp(argv
[0], "Never") == 0)) {
1011 rank
= kSCNetworkServicePrimaryRankNever
;
1012 } else if ((strcasecmp(argv
[0], "Scoped") == 0)) {
1013 rank
= kSCNetworkServicePrimaryRankScoped
;
1015 SCPrint(TRUE
, stdout
, CFSTR("invalid rank\n"));
1019 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1020 if (interfaceName
== NULL
) {
1021 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1025 store
= SCDynamicStoreCreate(NULL
, CFSTR("scutil --net"), NULL
, NULL
);
1026 interface
= _SCNetworkInterfaceCopyActive(store
, interfaceName
);
1028 if (interface
== NULL
) {
1029 SCPrint(TRUE
, stdout
, CFSTR("No active interface\n"));
1033 ok
= SCNetworkInterfaceSetPrimaryRank(interface
, rank
);
1034 CFRelease(interface
);
1036 SCPrint(TRUE
, stdout
, CFSTR("could not update per-interface rank\n"));
1044 /* -------------------- */
1048 _replaceOne(const void *key
, const void *value
, void *context
)
1050 CFMutableDictionaryRef newConfiguration
= (CFMutableDictionaryRef
)context
;
1052 CFDictionarySetValue(newConfiguration
, key
, value
);
1058 updateInterfaceConfiguration(CFMutableDictionaryRef newConfiguration
)
1060 CFDictionaryRef configuration
;
1062 CFDictionaryRemoveAllValues(newConfiguration
);
1064 configuration
= SCNetworkInterfaceGetConfiguration(net_interface
);
1065 if (configuration
!= NULL
) {
1066 CFDictionaryApplyFunction(configuration
, _replaceOne
, (void *)newConfiguration
);
1074 #pragma mark Bond options
1077 static options bondOptions
[] = {
1078 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1079 // xxx { "+device" , ... },
1080 // xxx { "-device" , ... },
1082 { "?" , NULL
, isHelp
, NULL
, NULL
,
1083 "\nBond configuration commands\n\n"
1084 " set interface [mtu n] [media type] [mediaopts opts]\n"
1087 #define N_BOND_OPTIONS (sizeof(bondOptions) / sizeof(bondOptions[0]))
1091 set_interface_bond(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1093 CFStringRef interfaceName
;
1096 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1097 if (interfaceName
== NULL
) {
1098 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1102 ok
= _process_options(bondOptions
, N_BOND_OPTIONS
, argc
, argv
, newConfiguration
);
1104 // validate configuration
1105 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1115 #pragma mark Bridge options
1118 static options bridgeOptions
[] = {
1119 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1120 // xxx { "+device" , ... },
1121 // xxx { "-device" , ... },
1123 { "?" , NULL
, isHelp
, NULL
, NULL
,
1124 "\nBridge configuration commands\n\n"
1125 " set interface [mtu n] [media type] [mediaopts opts]\n"
1128 #define N_BRIDGE_OPTIONS (sizeof(bridgeOptions) / sizeof(bridgeOptions[0]))
1132 set_interface_bridge(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1134 CFStringRef interfaceName
;
1137 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1138 if (interfaceName
== NULL
) {
1139 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1143 ok
= _process_options(bridgeOptions
, N_BRIDGE_OPTIONS
, argc
, argv
, newConfiguration
);
1145 // validate configuration
1146 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1156 #pragma mark AirPort options
1159 static options airportOptions
[] = {
1160 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1161 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
1162 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
1164 { "rank" , NULL
, isOther
, NULL
, __doRank
, NULL
},
1166 { "?" , NULL
, isHelp
, NULL
, NULL
,
1167 "\nAirPort configuration commands\n\n"
1168 " set interface [mtu n] [media type] [mediaopts opts]\n"
1171 #define N_AIRPORT_OPTIONS (sizeof(airportOptions) / sizeof(airportOptions[0]))
1175 set_interface_airport(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1177 CFStringRef interfaceName
;
1180 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1181 if (interfaceName
== NULL
) {
1182 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1186 ok
= _process_options(airportOptions
, N_AIRPORT_OPTIONS
, argc
, argv
, newConfiguration
);
1188 // validate configuration
1189 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1199 #pragma mark Ethernet options
1203 __doCapability(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1208 SCPrint(TRUE
, stdout
,
1209 CFSTR("%s not specified\n"),
1210 description
!= NULL
? description
: "enable/disable");
1214 if (strlen(argv
[0]) == 0) {
1215 ok
= SCNetworkInterfaceSetCapability(net_interface
, key
, NULL
);
1216 } else if ((strcasecmp(argv
[0], "disable") == 0) ||
1217 (strcasecmp(argv
[0], "no" ) == 0) ||
1218 (strcasecmp(argv
[0], "off" ) == 0) ||
1219 (strcasecmp(argv
[0], "0" ) == 0)) {
1220 ok
= SCNetworkInterfaceSetCapability(net_interface
, key
, CFNumberRef_0
);
1221 } else if ((strcasecmp(argv
[0], "enable") == 0) ||
1222 (strcasecmp(argv
[0], "yes" ) == 0) ||
1223 (strcasecmp(argv
[0], "on" ) == 0) ||
1224 (strcasecmp(argv
[0], "1" ) == 0)) {
1225 ok
= SCNetworkInterfaceSetCapability(net_interface
, key
, CFNumberRef_1
);
1227 SCPrint(TRUE
, stdout
, CFSTR("invalid value\n"));
1232 updateInterfaceConfiguration(newConfiguration
);
1234 SCPrint(TRUE
, stdout
,
1235 CFSTR("%@ not updated: %s\n"),
1237 SCErrorString(SCError()));
1245 static options ethernetOptions
[] = {
1246 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1247 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
1248 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
1250 { "av" , NULL
, isOther
, &kSCPropNetEthernetCapabilityAV
, __doCapability
, NULL
},
1251 { "lro" , NULL
, isOther
, &kSCPropNetEthernetCapabilityLRO
, __doCapability
, NULL
},
1252 { "rxcsum" , NULL
, isOther
, &kSCPropNetEthernetCapabilityRXCSUM
, __doCapability
, NULL
},
1253 { "tso" , NULL
, isOther
, &kSCPropNetEthernetCapabilityTSO
, __doCapability
, NULL
},
1254 { "txcsum" , NULL
, isOther
, &kSCPropNetEthernetCapabilityTXCSUM
, __doCapability
, NULL
},
1256 { "rank" , NULL
, isOther
, NULL
, __doRank
, NULL
},
1258 { "?" , NULL
, isHelp
, NULL
, NULL
,
1259 "\nEthernet configuration commands\n\n"
1260 " set interface [mtu n] [media type] [mediaopts opts]\n"
1263 #define N_ETHERNET_OPTIONS (sizeof(ethernetOptions) / sizeof(ethernetOptions[0]))
1267 set_interface_ethernet(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1269 CFStringRef interfaceName
;
1272 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1273 if (interfaceName
== NULL
) {
1274 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1278 ok
= _process_options(ethernetOptions
, N_ETHERNET_OPTIONS
, argc
, argv
, newConfiguration
);
1280 // validate configuration
1281 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1291 #pragma mark IPSec options
1295 __doIPSecSharedSecret(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1297 CFStringRef encryptionType
;
1300 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret not specified\n"));
1304 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetIPSecSharedSecretEncryption
);
1305 if (strlen(argv
[0]) > 0) {
1306 if (encryptionType
== NULL
) {
1307 #ifdef INLINE_PASSWORDS_USE_CFSTRING
1310 pw
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1311 #else // INLINE_PASSWORDS_USE_CFSTRING
1313 CFMutableDataRef pw
;
1316 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1317 n
= CFStringGetLength(str
);
1318 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
1319 CFDataSetLength(pw
, n
* sizeof(UniChar
));
1320 /* ALIGN: CF aligns to at least >8 bytes */
1321 CFStringGetCharacters(str
,
1323 (UniChar
*)(void *)CFDataGetMutableBytePtr(pw
));
1325 #endif // INLINE_PASSWORDS_USE_CFSTRING
1327 CFDictionarySetValue(newConfiguration
, key
, pw
);
1329 } else if (CFEqual(encryptionType
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1334 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1335 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
1336 ok
= SCNetworkInterfaceSetPassword(net_interface
,
1337 kSCNetworkInterfacePasswordTypeIPSecSharedSecret
,
1343 updateInterfaceConfiguration(newConfiguration
);
1348 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret type \"%@\" not supported\n"), encryptionType
);
1352 if (encryptionType
== NULL
) {
1353 CFDictionaryRemoveValue(newConfiguration
, key
);
1354 } else if (CFEqual(encryptionType
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1356 ok
= SCNetworkInterfaceRemovePassword(net_interface
, kSCNetworkInterfacePasswordTypeIPSecSharedSecret
);
1358 updateInterfaceConfiguration(newConfiguration
);
1363 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret type \"%@\" not supported\n"), encryptionType
);
1373 __doIPSecSharedSecretType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1376 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret type mode not specified\n"));
1380 if (strlen(argv
[0]) > 0) {
1381 if (strcasecmp(argv
[0], "keychain") == 0) {
1382 CFDictionarySetValue(newConfiguration
, key
, kSCValNetIPSecSharedSecretEncryptionKeychain
);
1384 SCPrint(TRUE
, stdout
, CFSTR("invalid shared secret type\n"));
1388 CFDictionaryRemoveValue(newConfiguration
, key
);
1391 // encryption type changed, reset shared secret
1392 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPSecSharedSecret
);
1399 __doIPSecXAuthPassword(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1401 CFStringRef encryptionType
;
1404 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuth password not specified\n"));
1408 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetIPSecXAuthPasswordEncryption
);
1409 if (strlen(argv
[0]) > 0) {
1410 if (encryptionType
== NULL
) {
1411 #ifdef INLINE_PASSWORDS_USE_CFSTRING
1414 pw
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1415 #else // INLINE_PASSWORDS_USE_CFSTRING
1417 CFMutableDataRef pw
;
1420 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1421 n
= CFStringGetLength(str
);
1422 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
1423 CFDataSetLength(pw
, n
* sizeof(UniChar
));
1424 /* ALIGN: CF aligns to at least >8 byte boundries */
1425 CFStringGetCharacters(str
,
1427 (UniChar
*)(void *)CFDataGetMutableBytePtr(pw
));
1429 #endif // INLINE_PASSWORDS_USE_CFSTRING
1431 CFDictionarySetValue(newConfiguration
, key
, pw
);
1433 } else if (CFEqual(encryptionType
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
1438 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1439 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
1440 ok
= SCNetworkInterfaceSetPassword(net_interface
,
1441 kSCNetworkInterfacePasswordTypeIPSecXAuth
,
1447 updateInterfaceConfiguration(newConfiguration
);
1452 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuthPassword type \"%@\" not supported\n"), encryptionType
);
1456 if (encryptionType
== NULL
) {
1457 CFDictionaryRemoveValue(newConfiguration
, key
);
1458 } else if (CFEqual(encryptionType
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
1461 ok
= SCNetworkInterfaceRemovePassword(net_interface
, kSCNetworkInterfacePasswordTypeIPSecXAuth
);
1463 updateInterfaceConfiguration(newConfiguration
);
1468 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuthPassword type \"%@\" not supported\n"), encryptionType
);
1478 __doIPSecXAuthPasswordType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1481 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuth password type mode not specified\n"));
1485 if (strlen(argv
[0]) > 0) {
1486 if (strcasecmp(argv
[0], "keychain") == 0) {
1487 CFDictionarySetValue(newConfiguration
, key
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
1489 SCPrint(TRUE
, stdout
, CFSTR("invalid XAuth password type\n"));
1493 CFDictionaryRemoveValue(newConfiguration
, key
);
1496 // encryption type changed, reset XAuthPassword
1497 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPSecXAuthPassword
);
1503 static CF_RETURNS_RETAINED CFStringRef
1504 __cleanupDomainName(CFStringRef domain
)
1506 CFMutableStringRef newDomain
;
1508 newDomain
= CFStringCreateMutableCopy(NULL
, 0, domain
);
1509 CFStringTrimWhitespace(newDomain
);
1510 CFStringTrim(newDomain
, CFSTR("."));
1511 if (CFStringGetLength(newDomain
) == 0) {
1512 CFRelease(newDomain
);
1521 __doOnDemandDomains(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1523 CFMutableArrayRef domains
;
1526 SCPrint(TRUE
, stdout
, CFSTR("OnDemand domain name(s) not specified\n"));
1530 domains
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1532 if (strlen(argv
[0]) > 0) {
1536 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1537 array
= CFStringCreateArrayBySeparatingStrings(NULL
, str
, CFSTR(","));
1540 if (array
!= NULL
) {
1542 CFIndex n
= CFArrayGetCount(array
);
1544 for (i
= 0; i
< n
; i
++) {
1547 domain
= __cleanupDomainName(CFArrayGetValueAtIndex(array
, i
));
1548 if (domain
!= NULL
) {
1549 CFArrayAppendValue(domains
, domain
);
1554 SCPrint(TRUE
, stdout
, CFSTR("invalid OnDemand domain name\n"));
1562 if (CFArrayGetCount(domains
) > 0) {
1563 CFDictionarySetValue(newConfiguration
, key
, domains
);
1565 CFDictionaryRemoveValue(newConfiguration
, key
);
1573 static options ipsecOnDemandOptions
[] = {
1574 { "OnDemandMatchDomainsAlways" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1575 { "always" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1576 { "OnDemandMatchDomainsOnRetry", "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1577 { "retry" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1578 { "OnDemandMatchDomainsNever" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1579 { "never" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1581 { "?" , NULL
, isHelp
, NULL
, NULL
,
1582 "\nOnDemandMatch configuration commands\n\n"
1583 " set interface OnDemandMatch always domain-name[,domain-name]\n"
1584 " set interface OnDemandMatch retry domain-name[,domain-name]\n"
1585 " set interface OnDemandMatch never domain-name[,domain-name]\n"
1588 #define N_IPSEC_ONDEMAND_OPTIONS (sizeof(ipsecOnDemandOptions) / sizeof(ipsecOnDemandOptions[0]))
1592 __doIPSecOnDemandMatch(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1597 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1601 ok
= _process_options(ipsecOnDemandOptions
, N_IPSEC_ONDEMAND_OPTIONS
, argc
, argv
, newConfiguration
);
1612 static selections ipsecAuthenticationMethodSelections
[] = {
1613 { CFSTR("SharedSecret"), &kSCValNetIPSecAuthenticationMethodSharedSecret
, 0 },
1614 { CFSTR("Certificate") , &kSCValNetIPSecAuthenticationMethodCertificate
, 0 },
1615 { CFSTR("Hybrid") , &kSCValNetIPSecAuthenticationMethodHybrid
, 0 },
1620 static selections ipsecLocalIdentifierTypeSelections
[] = {
1621 { CFSTR("KeyID") , &kSCValNetIPSecLocalIdentifierTypeKeyID
, 0 },
1626 static options ipsecOptions
[] = {
1627 { "AuthenticationMethod" , NULL
, isChooseOne
, &kSCPropNetIPSecAuthenticationMethod
, NULL
, (void *)ipsecAuthenticationMethodSelections
},
1628 { "LocalIdentifier" , NULL
, isString
, &kSCPropNetIPSecLocalIdentifier
, NULL
, NULL
},
1629 { "group" , NULL
, isString
, &kSCPropNetIPSecLocalIdentifier
, NULL
, NULL
},
1630 { "LocalIdentifierType" , NULL
, isChooseOne
, &kSCPropNetIPSecLocalIdentifierType
, NULL
, (void *)ipsecLocalIdentifierTypeSelections
},
1631 { "RemoteAddress" , NULL
, isString
, &kSCPropNetIPSecRemoteAddress
, NULL
, NULL
},
1632 { "SharedSecret" , NULL
, isOther
, &kSCPropNetIPSecSharedSecret
, __doIPSecSharedSecret
, NULL
},
1633 { "SharedSecretEncryption" , NULL
, isOther
, &kSCPropNetIPSecSharedSecretEncryption
, __doIPSecSharedSecretType
, NULL
},
1636 { "XAuthEnabled" , NULL
, isBoolean
, &kSCPropNetIPSecXAuthEnabled
, NULL
, NULL
},
1637 { "XAuthName" , NULL
, isString
, &kSCPropNetIPSecXAuthName
, NULL
, NULL
},
1638 { "XAuthPassword" , NULL
, isOther
, &kSCPropNetIPSecXAuthPassword
, __doIPSecXAuthPassword
, NULL
},
1639 { "XAuthPasswordEncryption", NULL
, isOther
, &kSCPropNetIPSecXAuthPasswordEncryption
, __doIPSecXAuthPasswordType
, NULL
},
1641 // --- OnDemand: ---
1642 { "OnDemandEnabled" , NULL
, isBoolean
, &kSCPropNetIPSecOnDemandEnabled
, NULL
, NULL
},
1643 { "OnDemandMatch" , NULL
, isOther
, NULL
, __doIPSecOnDemandMatch
, NULL
},
1645 { "?" , NULL
, isHelp
, NULL
, NULL
,
1646 "\nIPSec configuration commands\n\n"
1647 " set interface [AuthenticationMethod {SharedSecret|Certificate|Hybrid}]\n"
1648 " set interface [LocalIdentifier group]\n"
1649 " set interface [LocalIdentifierType {KeyID}]\n"
1650 " set interface [RemoteAddress name-or-address]\n"
1651 " set interface [SharedSecret secret]\n"
1652 " set interface [SharedSecretEncryption {Keychain}]\n"
1653 " set interface [XAuthEnabled {enable|disable}]\n"
1654 " set interface [XAuthPassword password]\n"
1655 " set interface [XAuthPasswordEncryption {Keychain}]\n"
1656 " set interface [OnDemandEnabled {enable|disable}]\n"
1657 " set interface [OnDemandMatch <match-options>]\n"
1660 #define N_IPSEC_OPTIONS (sizeof(ipsecOptions) / sizeof(ipsecOptions[0]))
1664 set_interface_ipsec(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1668 ok
= _process_options(ipsecOptions
, N_IPSEC_OPTIONS
, argc
, argv
, newConfiguration
);
1674 #pragma mark FireWire options
1677 static options firewireOptions
[] = {
1678 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1679 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
1680 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
1682 { "?" , NULL
, isHelp
, NULL
, NULL
,
1683 "\nFireWire configuration commands\n\n"
1684 " set interface [mtu n] [media type] [mediaopts opts]\n"
1687 #define N_FIREWIRE_OPTIONS (sizeof(firewireOptions) / sizeof(firewireOptions[0]))
1691 set_interface_firewire(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1693 CFStringRef interfaceName
;
1696 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1697 if (interfaceName
== NULL
) {
1698 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1702 ok
= _process_options(firewireOptions
, N_FIREWIRE_OPTIONS
, argc
, argv
, newConfiguration
);
1704 // validate configuration
1705 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1715 #pragma mark Modem options
1718 static selections modemDialSelections
[] = {
1719 { CFSTR("ignore"), &kSCValNetModemDialModeIgnoreDialTone
, 0 },
1720 { CFSTR("manual"), &kSCValNetModemDialModeManual
, 0 },
1721 { CFSTR("wait") , &kSCValNetModemDialModeWaitForDialTone
, 0 },
1725 static options modemOptions
[] = {
1726 { "ConnectionPersonality" , "NULL" , isString
, &kSCPropNetModemConnectionPersonality
, NULL
, NULL
},
1727 { "DeviceModel" , "model" , isString
, &kSCPropNetModemDeviceModel
, NULL
, NULL
},
1728 { "DeviceVendor" , "vendor", isString
, &kSCPropNetModemDeviceVendor
, NULL
, NULL
},
1729 { "ConnectionScript" , "script", isString
, &kSCPropNetModemConnectionScript
, NULL
, NULL
},
1730 { "DialMode" , "mode" , isChooseOne
, &kSCPropNetModemDialMode
, NULL
, (void *)modemDialSelections
},
1731 { "CallWaiting" , NULL
, isBoolean
, &kSCPropNetModemHoldEnabled
, NULL
, NULL
},
1732 { "CallWaitingAlert" , NULL
, isBoolean
, &kSCPropNetModemHoldCallWaitingAudibleAlert
, NULL
, NULL
},
1733 { "CallWaitingDisconnectOnAnswer", NULL
, isBoolean
, &kSCPropNetModemHoldDisconnectOnAnswer
, NULL
, NULL
},
1734 { "DataCompression" , NULL
, isBoolean
, &kSCPropNetModemDataCompression
, NULL
, NULL
},
1735 { "ErrorCorrection" , NULL
, isBoolean
, &kSCPropNetModemErrorCorrection
, NULL
, NULL
},
1736 { "HoldReminder" , NULL
, isBoolean
, &kSCPropNetModemHoldReminder
, NULL
, NULL
},
1737 { "HoldReminderTime" , "time" , isNumber
, &kSCPropNetModemHoldReminderTime
, NULL
, NULL
},
1738 { "PulseDial" , NULL
, isBoolean
, &kSCPropNetModemPulseDial
, NULL
, NULL
},
1739 { "Speaker" , NULL
, isBoolean
, &kSCPropNetModemSpeaker
, NULL
, NULL
},
1741 { "?" , NULL
, isHelp
, NULL
, NULL
,
1742 "\nModem configuration commands\n\n"
1743 " set interface [DeviceVendor vendor]\n"
1744 " set interface [DeviceModel model]\n"
1745 " set interface [ConnectionPersonality personality]\n"
1747 " set interface [ConnectionScript connection-script]\n"
1749 " set interface [CallWaiting {enable|disable}]\n"
1750 " set interface [CallWaitingAlert {enable|disable}]\n"
1751 " set interface [CallWaitingDisconnectOnAnswer {enable|disable}]\n"
1752 " set interface [DialMode {ignore|wait}]\n"
1753 " set interface [DataCompression {enable|disable}]\n"
1754 " set interface [ErrorCorrection {enable|disable}]\n"
1755 " set interface [HoldReminder {enable|disable}]\n"
1756 " set interface [HoldReminderTime n]\n"
1757 " set interface [PulseDial {enable|disable}]\n"
1758 " set interface [Speaker {enable|disable}]\n"
1761 #define N_MODEM_OPTIONS (sizeof(modemOptions) / sizeof(modemOptions[0]))
1765 set_interface_modem(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1769 ok
= _process_options(modemOptions
, N_MODEM_OPTIONS
, argc
, argv
, newConfiguration
);
1775 #pragma mark PPP options
1779 __doPPPAuthPW(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1781 CFStringRef encryptionType
;
1784 SCPrint(TRUE
, stdout
, CFSTR("PPP password not specified\n"));
1788 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetPPPAuthPasswordEncryption
);
1789 if (strlen(argv
[0]) > 0) {
1790 if (encryptionType
== NULL
) {
1791 #ifdef INLINE_PASSWORDS_USE_CFSTRING
1794 pw
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1795 #else // INLINE_PASSWORDS_USE_CFSTRING
1797 CFMutableDataRef pw
;
1800 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1801 n
= CFStringGetLength(str
);
1802 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
1803 CFDataSetLength(pw
, n
* sizeof(UniChar
));
1804 /* ALIGN: CF aligns to at least >8 byte boundries */
1805 CFStringGetCharacters(str
,
1807 (UniChar
*)(void *)CFDataGetMutableBytePtr(pw
));
1809 #endif // INLINE_PASSWORDS_USE_CFSTRING
1811 CFDictionarySetValue(newConfiguration
, key
, pw
);
1813 } else if (CFEqual(encryptionType
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1818 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1819 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
1820 ok
= SCNetworkInterfaceSetPassword(net_interface
,
1821 kSCNetworkInterfacePasswordTypePPP
,
1827 updateInterfaceConfiguration(newConfiguration
);
1832 SCPrint(TRUE
, stdout
, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType
);
1836 if (encryptionType
== NULL
) {
1837 CFDictionaryRemoveValue(newConfiguration
, key
);
1838 } else if (CFEqual(encryptionType
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1841 ok
= SCNetworkInterfaceRemovePassword(net_interface
, kSCNetworkInterfacePasswordTypePPP
);
1843 updateInterfaceConfiguration(newConfiguration
);
1848 SCPrint(TRUE
, stdout
, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType
);
1858 __doPPPAuthPWType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1861 SCPrint(TRUE
, stdout
, CFSTR("PPP password type mode not specified\n"));
1865 if (strlen(argv
[0]) > 0) {
1866 if (strcasecmp(argv
[0], "keychain") == 0) {
1867 CFDictionarySetValue(newConfiguration
, key
, kSCValNetPPPAuthPasswordEncryptionKeychain
);
1869 SCPrint(TRUE
, stdout
, CFSTR("invalid password type\n"));
1873 CFDictionaryRemoveValue(newConfiguration
, key
);
1876 // encryption type changed, reset password
1877 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetPPPAuthPassword
);
1883 static options l2tp_ipsecOptions
[] = {
1884 { "SharedSecret" , NULL
, isOther
, &kSCPropNetIPSecSharedSecret
, __doIPSecSharedSecret
, NULL
},
1885 { "SharedSecretEncryption", NULL
, isOther
, &kSCPropNetIPSecSharedSecretEncryption
, __doIPSecSharedSecretType
, NULL
},
1887 { "?" , NULL
, isHelp
, NULL
, NULL
,
1888 "\nIPSec configuration commands\n\n"
1889 " set interface ipsec [SharedSecret secret]\n"
1890 " set interface ipsec [SharedSecretEncryption {Keychain}]\n"
1893 #define N_L2TP_IPSEC_OPTIONS (sizeof(l2tp_ipsecOptions) / sizeof(l2tp_ipsecOptions[0]))
1897 __doPPPIPSec(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newPPPConfiguration
)
1899 SCNetworkInterfaceRef childInterface
;
1900 CFStringRef childInterfaceType
;
1901 CFDictionaryRef configuration
;
1902 CFMutableDictionaryRef newConfiguration
;
1906 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1910 childInterface
= SCNetworkInterfaceGetInterface(net_interface
);
1911 if (childInterface
== NULL
) {
1912 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
1916 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
1917 if (!CFEqual(childInterfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
1918 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
1922 configuration
= SCNetworkInterfaceGetExtendedConfiguration(net_interface
, kSCEntNetIPSec
);
1923 if (configuration
== NULL
) {
1924 newConfiguration
= CFDictionaryCreateMutable(NULL
,
1926 &kCFTypeDictionaryKeyCallBacks
,
1927 &kCFTypeDictionaryValueCallBacks
);
1929 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
1930 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
1933 ok
= _process_options(l2tp_ipsecOptions
, N_L2TP_IPSEC_OPTIONS
, argc
, argv
, newConfiguration
);
1938 if (((configuration
== NULL
) && (CFDictionaryGetCount(newConfiguration
) > 0)) ||
1939 ((configuration
!= NULL
) && !CFEqual(configuration
, newConfiguration
))) {
1940 if (!SCNetworkInterfaceSetExtendedConfiguration(net_interface
, kSCEntNetIPSec
, newConfiguration
)) {
1941 if (SCError() == kSCStatusNoKey
) {
1942 SCPrint(TRUE
, stdout
, CFSTR("could not update per-service interface configuration\n"));
1944 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
1949 _prefs_changed
= TRUE
;
1954 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
1960 static options pppOnDemandOptions
[] = {
1961 { "OnDemandMatchDomainsAlways" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1962 { "always" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1963 { "OnDemandMatchDomainsOnRetry", "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1964 { "retry" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1965 { "OnDemandMatchDomainsNever" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1966 { "never" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1968 { "?" , NULL
, isHelp
, NULL
, NULL
,
1969 "\nOnDemandMatch configuration commands\n\n"
1970 " set interface OnDemand always domain-name[,domain-name]\n"
1971 " set interface OnDemand retry domain-name[,domain-name]\n"
1972 " set interface OnDemand never domain-name[,domain-name]\n"
1975 #define N_PPP_ONDEMAND_OPTIONS (sizeof(pppOnDemandOptions) / sizeof(pppOnDemandOptions[0]))
1979 __doPPPOnDemandMatch(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1984 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1988 ok
= _process_options(pppOnDemandOptions
, N_PPP_ONDEMAND_OPTIONS
, argc
, argv
, newConfiguration
);
2000 static selections authPromptSelections
[] = {
2001 { CFSTR("before"), &kSCValNetPPPAuthPromptBefore
, 0 },
2002 { CFSTR("after") , &kSCValNetPPPAuthPromptAfter
, 0 },
2007 static selections authProtocolSelections
[] = {
2008 { CFSTR("CHAP") , &kSCValNetPPPAuthProtocolCHAP
, 0 },
2009 { CFSTR("EAP") , &kSCValNetPPPAuthProtocolEAP
, 0 },
2010 { CFSTR("MSCHAP1"), &kSCValNetPPPAuthProtocolMSCHAP1
, 0 },
2011 { CFSTR("MSCHAP2"), &kSCValNetPPPAuthProtocolMSCHAP2
, 0 },
2012 { CFSTR("PAP") , &kSCValNetPPPAuthProtocolPAP
, 0 },
2017 static options pppOptions
[] = {
2018 { "ACSP" , NULL
, isBoolean
, &kSCPropNetPPPACSPEnabled
, NULL
, NULL
},
2019 { "ConnectTime" , "?time" , isNumber
, &kSCPropNetPPPConnectTime
, NULL
, NULL
},
2020 { "DialOnDemand" , NULL
, isBoolean
, &kSCPropNetPPPDialOnDemand
, NULL
, NULL
},
2021 { "DisconnectOnFastUserSwitch", NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnFastUserSwitch
, NULL
, NULL
},
2022 { "DisconnectOnIdle" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnIdle
, NULL
, NULL
},
2023 { "DisconnectOnIdleTimer" , "timeout" , isNumber
, &kSCPropNetPPPDisconnectOnIdleTimer
, NULL
, NULL
},
2024 { "DisconnectOnLogout" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnLogout
, NULL
, NULL
},
2025 { "DisconnectOnSleep" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnSleep
, NULL
, NULL
},
2026 { "DisconnectTime" , "?time" , isNumber
, &kSCPropNetPPPDisconnectTime
, NULL
, NULL
},
2027 { "IdleReminder" , NULL
, isBoolean
, &kSCPropNetPPPIdleReminder
, NULL
, NULL
},
2028 { "IdleReminderTimer" , "time" , isNumber
, &kSCPropNetPPPIdleReminderTimer
, NULL
, NULL
},
2029 { "Logfile" , "path" , isString
, &kSCPropNetPPPLogfile
, NULL
, NULL
},
2030 { "Plugins" , "plugin" , isStringArray
, &kSCPropNetPPPPlugins
, NULL
, NULL
},
2031 { "RetryConnectTime" , "time" , isNumber
, &kSCPropNetPPPRetryConnectTime
, NULL
, NULL
},
2032 { "SessionTimer" , "time" , isNumber
, &kSCPropNetPPPSessionTimer
, NULL
, NULL
},
2033 { "UseSessionTimer" , NULL
, isBoolean
, &kSCPropNetPPPUseSessionTimer
, NULL
, NULL
},
2034 { "VerboseLogging" , NULL
, isBoolean
, &kSCPropNetPPPVerboseLogging
, NULL
, NULL
},
2037 { "AuthEAPPlugins" , "plugin" , isStringArray
, &kSCPropNetPPPAuthEAPPlugins
, NULL
, NULL
},
2038 { "AuthName" , "account" , isString
, &kSCPropNetPPPAuthName
, NULL
, NULL
},
2039 { "Account" , "account" , isString
, &kSCPropNetPPPAuthName
, NULL
, NULL
},
2040 { "AuthPassword" , "password" , isOther
, &kSCPropNetPPPAuthPassword
, __doPPPAuthPW
, NULL
},
2041 { "Password" , "password" , isOther
, &kSCPropNetPPPAuthPassword
, __doPPPAuthPW
, NULL
},
2042 { "AuthPasswordEncryption" , "type" , isOther
, &kSCPropNetPPPAuthPasswordEncryption
, __doPPPAuthPWType
, NULL
},
2043 { "AuthPrompt" , "before/after", isChooseOne
, &kSCPropNetPPPAuthPrompt
, NULL
, (void *)authPromptSelections
},
2044 { "AuthProtocol" , "protocol" , isChooseMultiple
, &kSCPropNetPPPAuthProtocol
, NULL
, (void *)authProtocolSelections
},
2047 { "CommRemoteAddress" , "phone#" , isString
, &kSCPropNetPPPCommRemoteAddress
, NULL
, NULL
},
2048 { "Number" , "phone#" , isString
, &kSCPropNetPPPCommRemoteAddress
, NULL
, NULL
},
2049 { "CommAlternateRemoteAddress", "phone#" , isString
, &kSCPropNetPPPCommAlternateRemoteAddress
, NULL
, NULL
},
2050 { "CommConnectDelay" , "time" , isNumber
, &kSCPropNetPPPCommConnectDelay
, NULL
, NULL
},
2051 { "CommDisplayTerminalWindow" , NULL
, isBoolean
, &kSCPropNetPPPCommDisplayTerminalWindow
, NULL
, NULL
},
2052 { "CommRedialCount" , "retry count" , isNumber
, &kSCPropNetPPPCommRedialCount
, NULL
, NULL
},
2053 { "CommRedialEnabled" , NULL
, isBoolean
, &kSCPropNetPPPCommRedialEnabled
, NULL
, NULL
},
2054 { "CommRedialInterval" , "retry delay" , isNumber
, &kSCPropNetPPPCommRedialInterval
, NULL
, NULL
},
2055 { "CommTerminalScript" , "script" , isString
, &kSCPropNetPPPCommTerminalScript
, NULL
, NULL
},
2056 { "CommUseTerminalScript" , NULL
, isBoolean
, &kSCPropNetPPPCommUseTerminalScript
, NULL
, NULL
},
2059 { "CCPEnabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPEnabled
, NULL
, NULL
},
2060 { "CCPMPPE40Enabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPMPPE40Enabled
, NULL
, NULL
},
2061 { "CCPMPPE128Enabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPMPPE128Enabled
, NULL
, NULL
},
2064 { "IPCPCompressionVJ" , NULL
, isBoolean
, &kSCPropNetPPPIPCPCompressionVJ
, NULL
, NULL
},
2065 { "IPCPUsePeerDNS" , NULL
, isBoolean
, &kSCPropNetPPPIPCPUsePeerDNS
, NULL
, NULL
},
2068 { "LCPEchoEnabled" , NULL
, isBoolean
, &kSCPropNetPPPLCPEchoEnabled
, NULL
, NULL
},
2069 { "LCPEchoFailure" , NULL
, isNumber
, &kSCPropNetPPPLCPEchoFailure
, NULL
, NULL
},
2070 { "LCPEchoInterval" , NULL
, isNumber
, &kSCPropNetPPPLCPEchoInterval
, NULL
, NULL
},
2071 { "LCPCompressionACField" , NULL
, isBoolean
, &kSCPropNetPPPLCPCompressionACField
, NULL
, NULL
},
2072 { "LCPCompressionPField" , NULL
, isBoolean
, &kSCPropNetPPPLCPCompressionPField
, NULL
, NULL
},
2073 { "LCPMRU" , NULL
, isNumber
, &kSCPropNetPPPLCPMRU
, NULL
, NULL
},
2074 { "LCPMTU" , NULL
, isNumber
, &kSCPropNetPPPLCPMTU
, NULL
, NULL
},
2075 { "LCPReceiveACCM" , NULL
, isNumber
, &kSCPropNetPPPLCPReceiveACCM
, NULL
, NULL
},
2076 { "LCPTransmitACCM" , NULL
, isNumber
, &kSCPropNetPPPLCPTransmitACCM
, NULL
, NULL
},
2079 { "IPSec" , NULL
, isOther
, NULL
, __doPPPIPSec
, NULL
},
2082 // --- OnDemand: ---
2083 { "OnDemandEnabled" , NULL
, isBoolean
, &kSCPropNetPPPOnDemandEnabled
, NULL
, NULL
},
2084 { "OnDemandMatch" , NULL
, isOther
, NULL
, __doPPPOnDemandMatch
, NULL
},
2088 { "?" , NULL
, isHelp
, NULL
, NULL
,
2089 "\nPPP configuration commands\n\n"
2090 " set interface [Account account]\n"
2091 " set interface [Password password]\n"
2092 " set interface [Number telephone-number]\n"
2093 " set interface [AlternateNumber telephone-number]\n"
2094 " set interface [IdleReminder {enable|disable}]\n"
2095 " set interface [IdleReminderTimer time-in-seconds]\n"
2096 " set interface [DisconnectOnIdle {enable|disable}]\n"
2097 " set interface [DisconnectOnIdleTimer time-in-seconds]\n"
2098 " set interface [DisconnectOnLogout {enable|disable}]\n"
2099 " set interface [IPSec <ipsec-options>]\n"
2101 " set interface [OnDemandEnabled {enable|disable}]\n"
2102 " set interface [OnDemandMatch <match-options>]\n"
2106 #define N_PPP_OPTIONS (sizeof(pppOptions) / sizeof(pppOptions[0]))
2110 set_interface_ppp(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2114 ok
= _process_options(pppOptions
, N_PPP_OPTIONS
, argc
, argv
, newConfiguration
);
2120 #pragma mark VLAN options
2124 set_interface_vlan(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2126 // xxxxx ("device", "tag")
2127 SCPrint(TRUE
, stdout
, CFSTR("vlan interface management not yet supported\n"));
2133 #pragma mark VPN options
2137 __doVPNAuthPW(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2139 CFStringRef encryptionType
;
2142 SCPrint(TRUE
, stdout
, CFSTR("VPN password not specified\n"));
2146 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetVPNAuthPasswordEncryption
);
2147 if (strlen(argv
[0]) > 0) {
2148 if (encryptionType
== NULL
) {
2149 #ifdef INLINE_PASSWORDS_USE_CFSTRING
2152 pw
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
2153 #else // INLINE_PASSWORDS_USE_CFSTRING
2155 CFMutableDataRef pw
;
2158 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
2159 n
= CFStringGetLength(str
);
2160 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
2161 CFDataSetLength(pw
, n
* sizeof(UniChar
));
2162 CFStringGetCharacters(str
,
2164 (UniChar
*)(void *)CFDataGetMutableBytePtr(pw
));
2166 #endif // INLINE_PASSWORDS_USE_CFSTRING
2168 CFDictionarySetValue(newConfiguration
, key
, pw
);
2170 } else if (CFEqual(encryptionType
, kSCValNetVPNAuthPasswordEncryptionKeychain
)) {
2175 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
2176 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
2177 ok
= SCNetworkInterfaceSetPassword(net_interface
,
2178 kSCNetworkInterfacePasswordTypeVPN
,
2184 updateInterfaceConfiguration(newConfiguration
);
2189 SCPrint(TRUE
, stdout
, CFSTR("VPN password type \"%@\" not supported\n"), encryptionType
);
2193 if (encryptionType
== NULL
) {
2194 CFDictionaryRemoveValue(newConfiguration
, key
);
2195 } else if (CFEqual(encryptionType
, kSCValNetVPNAuthPasswordEncryptionKeychain
)) {
2198 ok
= SCNetworkInterfaceRemovePassword(net_interface
, kSCNetworkInterfacePasswordTypeVPN
);
2200 updateInterfaceConfiguration(newConfiguration
);
2205 SCPrint(TRUE
, stdout
, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType
);
2215 __doVPNAuthPWType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2218 SCPrint(TRUE
, stdout
, CFSTR("VPN password type mode not specified\n"));
2222 if (strlen(argv
[0]) > 0) {
2223 if (strcasecmp(argv
[0], "keychain") == 0) {
2224 CFDictionarySetValue(newConfiguration
, key
, kSCValNetVPNAuthPasswordEncryptionKeychain
);
2225 } else if (strcasecmp(argv
[0], "prompt") == 0) {
2226 CFDictionarySetValue(newConfiguration
, key
, kSCValNetVPNAuthPasswordEncryptionPrompt
);
2228 SCPrint(TRUE
, stdout
, CFSTR("invalid password type\n"));
2232 CFDictionaryRemoveValue(newConfiguration
, key
);
2235 // encryption type changed, reset password
2236 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetVPNAuthPassword
);
2242 static selections vpnAuthenticationMethodSelections
[] = {
2243 { CFSTR("Password") , &kSCValNetVPNAuthenticationMethodPassword
, 0 },
2244 { CFSTR("Certificate") , &kSCValNetVPNAuthenticationMethodCertificate
, 0 },
2249 static options vpnOptions
[] = {
2250 { "AuthName" , "account" , isString
, &kSCPropNetVPNAuthName
, NULL
, NULL
},
2251 { "Account" , "account" , isString
, &kSCPropNetVPNAuthName
, NULL
, NULL
},
2252 { "AuthPassword" , "password" , isOther
, &kSCPropNetVPNAuthPassword
, __doVPNAuthPW
, NULL
},
2253 { "Password" , "password" , isOther
, &kSCPropNetVPNAuthPassword
, __doVPNAuthPW
, NULL
},
2254 { "AuthPasswordEncryption" , "type" , isOther
, &kSCPropNetVPNAuthPasswordEncryption
, __doVPNAuthPWType
, NULL
},
2255 { "AuthenticationMethod" , NULL
, isChooseOne
, &kSCPropNetVPNAuthenticationMethod
, NULL
, (void *)vpnAuthenticationMethodSelections
},
2256 { "ConnectTime" , "?time" , isNumber
, &kSCPropNetVPNConnectTime
, NULL
, NULL
},
2257 { "DisconnectOnFastUserSwitch", NULL
, isBoolean
, &kSCPropNetVPNDisconnectOnFastUserSwitch
, NULL
, NULL
},
2258 { "DisconnectOnIdle" , NULL
, isBoolean
, &kSCPropNetVPNDisconnectOnIdle
, NULL
, NULL
},
2259 { "DisconnectOnIdleTimer" , "timeout" , isNumber
, &kSCPropNetVPNDisconnectOnIdleTimer
, NULL
, NULL
},
2260 { "DisconnectOnLogout" , NULL
, isBoolean
, &kSCPropNetVPNDisconnectOnLogout
, NULL
, NULL
},
2261 { "DisconnectOnSleep" , NULL
, isBoolean
, &kSCPropNetVPNDisconnectOnSleep
, NULL
, NULL
},
2262 { "Logfile" , "path" , isString
, &kSCPropNetVPNLogfile
, NULL
, NULL
},
2263 { "MTU" , NULL
, isNumber
, &kSCPropNetVPNMTU
, NULL
, NULL
},
2264 { "RemoteAddress" , "server" , isString
, &kSCPropNetVPNRemoteAddress
, NULL
, NULL
},
2265 { "Server" , "server" , isString
, &kSCPropNetVPNRemoteAddress
, NULL
, NULL
},
2266 { "VerboseLogging" , NULL
, isBoolean
, &kSCPropNetVPNVerboseLogging
, NULL
, NULL
},
2269 { "?" , NULL
, isHelp
, NULL
, NULL
,
2270 "\nVPN configuration commands\n\n"
2271 " set interface [Server server]\n"
2272 " set interface [Account account]\n"
2273 " set interface [Password password]\n"
2276 #define N_VPN_OPTIONS (sizeof(vpnOptions) / sizeof(vpnOptions[0]))
2280 set_interface_vpn(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2284 ok
= _process_options(vpnOptions
, N_VPN_OPTIONS
, argc
, argv
, newConfiguration
);
2290 #pragma mark [more] Interface management
2295 set_interface(int argc
, char **argv
)
2297 CFDictionaryRef configuration
;
2298 CFStringRef interfaceType
;
2299 CFMutableDictionaryRef newConfiguration
= NULL
;
2302 if (net_interface
== NULL
) {
2303 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
2308 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
2312 configuration
= SCNetworkInterfaceGetConfiguration(net_interface
);
2313 if (configuration
!= NULL
) {
2314 configuration
= CFDictionaryCreateCopy(NULL
, configuration
);
2315 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
2316 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
2318 newConfiguration
= CFDictionaryCreateMutable(NULL
,
2320 &kCFTypeDictionaryKeyCallBacks
,
2321 &kCFTypeDictionaryValueCallBacks
);
2324 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
2326 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeEthernet
)) {
2327 ok
= set_interface_ethernet(argc
, argv
, newConfiguration
);
2328 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeFireWire
)) {
2329 ok
= set_interface_firewire(argc
, argv
, newConfiguration
);
2330 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
2331 ok
= set_interface_ipsec(argc
, argv
, newConfiguration
);
2332 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeModem
)) {
2333 ok
= set_interface_modem(argc
, argv
, newConfiguration
);
2334 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIEEE80211
)) {
2335 ok
= set_interface_airport(argc
, argv
, newConfiguration
);
2336 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2337 ok
= set_interface_ppp(argc
, argv
, newConfiguration
);
2338 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
2339 ok
= set_interface_bond(argc
, argv
, newConfiguration
);
2340 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
2341 ok
= set_interface_bridge(argc
, argv
, newConfiguration
);
2342 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
2343 ok
= set_interface_vlan(argc
, argv
, newConfiguration
);
2344 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
2345 ok
= set_interface_vpn(argc
, argv
, newConfiguration
);
2347 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
2354 if (((configuration
== NULL
) && (CFDictionaryGetCount(newConfiguration
) > 0)) ||
2355 ((configuration
!= NULL
) && !CFEqual(configuration
, newConfiguration
))) {
2356 if (!SCNetworkInterfaceSetConfiguration(net_interface
, newConfiguration
)) {
2357 if (SCError() == kSCStatusNoKey
) {
2358 SCPrint(TRUE
, stdout
, CFSTR("could not update per-service interface configuration\n"));
2360 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
2365 _prefs_changed
= TRUE
;
2370 if (configuration
!= NULL
) CFRelease(configuration
);
2371 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
2376 /* -------------------- */
2381 show_interface(int argc
, char **argv
)
2383 SCNetworkInterfaceRef interface
;
2386 interface
= _find_interface(argc
, argv
, NULL
);
2388 if (net_interface
!= NULL
) {
2389 interface
= net_interface
;
2391 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
2396 if (interface
!= NULL
) {
2397 _show_interface(interface
, CFSTR(""), TRUE
);
2404 /* -------------------- */
2408 CF_RETURNS_RETAINED CFStringRef
2409 _interface_description(SCNetworkInterfaceRef interface
)
2411 CFMutableStringRef description
;
2412 CFStringRef if_bsd_name
;
2413 CFStringRef if_type
;
2415 description
= CFStringCreateMutable(NULL
, 0);
2417 if_type
= SCNetworkInterfaceGetInterfaceType(interface
);
2418 CFStringAppend(description
, if_type
);
2420 if_bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
2421 if (if_bsd_name
!= NULL
) {
2422 CFStringAppendFormat(description
, NULL
, CFSTR(" (%@)"), if_bsd_name
);
2425 interface
= SCNetworkInterfaceGetInterface(interface
);
2426 while ((interface
!= NULL
) &&
2427 !CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
2428 CFStringRef childDescription
;
2430 childDescription
= _interface_description(interface
);
2431 CFStringAppendFormat(description
, NULL
, CFSTR(" / %@"), childDescription
);
2432 CFRelease(childDescription
);
2434 interface
= SCNetworkInterfaceGetInterface(interface
);