2 * Copyright (c) 2004-2011, 2013-2016 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 an [Apple] pre-configured / hidden interface by its BSD name
278 selected
= _SCNetworkInterfaceCreateWithBSDName(NULL
, select_name
, kIncludeNoVirtualInterfaces
);
279 if (selected
!= NULL
) {
283 // try to select the interface by its interface type
285 for (i
= 0; i
< n
; i
++) {
286 SCNetworkInterfaceRef interface
;
287 CFStringRef interfaceType
;
289 interface
= CFArrayGetValueAtIndex(myInterfaces
, i
);
290 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
291 if (CFEqual(select_name
, interfaceType
)) {
292 if (selected
== NULL
) {
293 selected
= interface
;
295 // if multiple interfaces match
297 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
303 if (selected
!= NULL
) {
312 // try to select the interface by its index
315 val
= strtol(str
, &end
, 10);
316 if ((*str
!= '\0') &&
317 ((*end
== '\0') || (*end
== '.')) &&
319 if ((val
> 0) && (val
<= n
)) {
320 selected
= CFArrayGetValueAtIndex(myInterfaces
, val
- 1);
324 val
= strtol(str
, &end
, 10);
325 if ((*str
!= '\0') && (*end
== '\0') && (errno
== 0)) {
327 selected
= SCNetworkInterfaceGetInterface(selected
);
328 if (selected
== NULL
) {
338 if (selected
!= NULL
) {
342 SCPrint(TRUE
, stdout
, CFSTR("no match\n"));
346 if (select_name
!= NULL
) CFRelease(select_name
);
351 /* -------------------- */
356 create_interface(int argc
, char **argv
)
358 SCNetworkInterfaceRef interface
;
359 CFStringRef interfaceName
;
360 CFStringRef interfaceType
;
361 SCNetworkInterfaceRef new_interface
;
364 SCPrint(TRUE
, stdout
, CFSTR("what interface type?\n"));
368 interfaceType
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
372 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
373 SCPrint(TRUE
, stdout
, CFSTR("bond creation not yet supported\n"));
376 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
377 SCPrint(TRUE
, stdout
, CFSTR("bridge creation not yet supported\n"));
380 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
381 SCPrint(TRUE
, stdout
, CFSTR("vlan creation not yet supported\n"));
386 if (net_interface
== NULL
) {
387 SCPrint(TRUE
, stdout
, CFSTR("no network interface selected\n"));
391 interface
= net_interface
;
393 interface
= _find_interface(argc
, argv
, NULL
);
396 if (interface
== NULL
) {
400 new_interface
= SCNetworkInterfaceCreateWithInterface(interface
, interfaceType
);
401 if (new_interface
== NULL
) {
402 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
406 if (new_interfaces
== NULL
) {
407 new_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
409 CFArrayAppendValue(new_interfaces
, new_interface
);
411 if (net_interface
!= NULL
) CFRelease(net_interface
);
412 net_interface
= new_interface
;
414 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(net_interface
);
415 if (interfaceName
== NULL
) {
416 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
418 if (interfaceName
== NULL
) {
419 interfaceName
= SCNetworkInterfaceGetInterfaceType(net_interface
);
421 SCPrint(TRUE
, stdout
, CFSTR("interface \"%@\" created and selected\n"), interfaceName
);
425 CFRelease(interfaceType
);
430 /* -------------------- */
435 select_interface(int argc
, char **argv
)
437 SCNetworkInterfaceRef interface
;
439 interface
= _find_interface(argc
, argv
, NULL
);
440 if (interface
!= NULL
) {
441 CFStringRef interfaceName
;
443 if (net_interface
!= NULL
) CFRelease(net_interface
);
444 net_interface
= CFRetain(interface
);
446 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
447 if (interfaceName
== NULL
) {
448 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
450 if (interfaceName
== NULL
) {
451 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
454 SCPrint(TRUE
, stdout
, CFSTR("interface \"%@\" selected\n"), interfaceName
);
461 /* -------------------- */
466 _show_interface(SCNetworkInterfaceRef interface
, CFStringRef prefix
, Boolean showChild
)
468 CFDictionaryRef configuration
;
469 CFStringRef if_bsd_name
;
470 CFStringRef if_localized_name
;
471 CFStringRef if_mac_address
;
473 Boolean isPhysicalEthernet
;
474 CFArrayRef supported
;
476 if_localized_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
477 if (if_localized_name
!= NULL
) {
478 SCPrint(TRUE
, stdout
, CFSTR("%@ name = %@\n"), prefix
, if_localized_name
);
481 if_bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
482 if (if_bsd_name
!= NULL
) {
483 SCPrint(TRUE
, stdout
, CFSTR("%@ interface name = %@\n"), prefix
, if_bsd_name
);
486 if_type
= SCNetworkInterfaceGetInterfaceType(interface
);
487 SCPrint(TRUE
, stdout
, CFSTR("%@ type = %@\n"), prefix
, if_type
);
489 if_mac_address
= SCNetworkInterfaceGetHardwareAddressString(interface
);
490 if (if_mac_address
!= NULL
) {
491 SCPrint(TRUE
, stdout
, CFSTR("%@ address = %@\n"), prefix
, if_mac_address
);
494 configuration
= SCNetworkInterfaceGetConfiguration(interface
);
495 if ((configuration
!= NULL
) &&
496 CFDictionaryContainsKey(configuration
, kSCResvInactive
)) {
497 configuration
= NULL
;
500 if (if_bsd_name
!= NULL
) {
501 CFArrayRef available
;
502 CFDictionaryRef active
;
503 CFDictionaryRef cap_current
;
507 CFDictionaryRef qosPolicy
;
509 cap_current
= SCNetworkInterfaceCopyCapability(interface
, NULL
);
510 if (cap_current
!= NULL
) {
512 CFArrayRef cap_names
;
513 CFMutableArrayRef cap_sorted
;
517 n
= CFDictionaryGetCount(cap_current
);
518 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFStringRef
), 0);
519 CFDictionaryGetKeysAndValues(cap_current
, keys
, NULL
);
520 cap_names
= CFArrayCreate(NULL
, keys
, n
, &kCFTypeArrayCallBacks
);
521 CFAllocatorDeallocate(NULL
, keys
);
523 cap_sorted
= CFArrayCreateMutableCopy(NULL
, 0, cap_names
);
524 CFRelease(cap_names
);
526 CFArraySortValues(cap_sorted
, CFRangeMake(0, n
), (CFComparatorFunction
)CFStringCompare
, NULL
);
528 SCPrint(TRUE
, stdout
, CFSTR("%@ capabilities = "), prefix
);
529 for (i
= 0; i
< n
; i
++) {
530 CFStringRef cap_name
;
532 CFNumberRef val
= NULL
;
534 cap_name
= CFArrayGetValueAtIndex(cap_sorted
, i
);
535 if (configuration
!= NULL
) {
536 val
= CFDictionaryGetValue(configuration
, cap_name
);
538 if (!isA_CFNumber(val
)) {
539 val
= CFDictionaryGetValue(cap_current
, cap_name
);
542 SCPrint(TRUE
, stdout
, CFSTR("%s%@%c"),
545 (CFNumberGetValue(val
, kCFNumberIntType
, &cap_val
) &&
546 (cap_val
!= 0)) ? '+' : '-');
548 SCPrint(TRUE
, stdout
, CFSTR("\n"));
550 CFRelease(cap_sorted
);
551 CFRelease(cap_current
);
554 if (SCNetworkInterfaceCopyMTU(interface
, &mtu_cur
, &mtu_min
, &mtu_max
)) {
555 char isCurrent
= '*';
557 if (configuration
!= NULL
) {
561 num
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMTU
);
562 if (isA_CFNumber(num
) &&
563 CFNumberGetValue(num
, kCFNumberIntType
, &mtu_req
)) {
564 if (mtu_cur
!= mtu_req
) {
571 SCPrint(TRUE
, stdout
, CFSTR("%@ mtu %c = %d (%d < n < %d)\n"),
579 if (SCNetworkInterfaceCopyMediaOptions(interface
, NULL
, &active
, &available
, TRUE
)) {
580 char isCurrent
= ' ';
581 CFArrayRef options
= NULL
;
582 CFArrayRef options_req
= NULL
;
583 CFStringRef subtype
= NULL
;
584 CFStringRef subtype_req
= NULL
;
586 if (configuration
!= NULL
) {
587 subtype_req
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMediaSubType
);
588 options_req
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMediaOptions
);
591 if (subtype_req
== NULL
) {
592 subtype_req
= CFSTR("autoselect");
595 if (active
!= NULL
) {
596 subtype
= CFDictionaryGetValue(active
, kSCPropNetEthernetMediaSubType
);
597 options
= CFDictionaryGetValue(active
, kSCPropNetEthernetMediaOptions
);
600 if (subtype
!= NULL
) {
601 if (((subtype_req
!= NULL
) &&
602 CFEqual(subtype
, subtype_req
)) &&
603 ((options
== options_req
) ||
604 ((options
!= NULL
) &&
605 (options_req
!= NULL
) &&
606 CFEqual(options
, options_req
)))
609 } else if ((subtype_req
== NULL
) ||
610 ((subtype_req
!= NULL
) &&
611 CFEqual(subtype_req
, CFSTR("autoselect")))) {
612 // if requested subtype not specified or "autoselect"
617 if (subtype_req
!= NULL
) {
618 SCPrint(TRUE
, stdout
, CFSTR("%@ media %c = %@"),
623 if ((options_req
!= NULL
) &&
624 (CFArrayGetCount(options_req
) > 0)) {
625 CFStringRef options_str
;
627 options_str
= CFStringCreateByCombiningStrings(NULL
, options_req
, CFSTR(","));
628 SCPrint(TRUE
, stdout
, CFSTR(" <%@>"), options_str
);
629 CFRelease(options_str
);
632 SCPrint(TRUE
, stdout
, CFSTR("\n"));
635 SCPrint(TRUE
, stdout
, CFSTR("\n"));
637 if (available
!= NULL
) {
642 subtypes
= SCNetworkInterfaceCopyMediaSubTypes(available
);
643 n_subtypes
= (subtypes
!= NULL
) ? CFArrayGetCount(subtypes
) : 0;
644 for (i
= 0; i
< n_subtypes
; i
++) {
646 CFIndex n_subtype_options
;
648 CFArrayRef subtype_options
;
650 subtype
= CFArrayGetValueAtIndex(subtypes
, i
);
651 subtype_options
= SCNetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
652 n_subtype_options
= (subtype_options
!= NULL
) ? CFArrayGetCount(subtype_options
) : 0;
653 for (j
= 0; j
< n_subtype_options
; j
++) {
654 char isCurrent
= ' ';
657 options
= CFArrayGetValueAtIndex(subtype_options
, j
);
659 if (((subtype_req
!= NULL
) &&
660 CFEqual(subtype
, subtype_req
)) &&
661 ((options
== options_req
) ||
662 ((options
!= NULL
) &&
663 (options_req
!= NULL
) &&
664 CFEqual(options
, options_req
)))
669 SCPrint(TRUE
, stdout
, CFSTR("%@ %s %c = %@"),
671 ((i
== 0) && (j
== 0)) ? "supported media" : " ",
675 if ((options
!= NULL
) &&
676 (CFArrayGetCount(options
) > 0)) {
677 CFStringRef options_str
;
679 options_str
= CFStringCreateByCombiningStrings(NULL
, options
, CFSTR(","));
680 SCPrint(TRUE
, stdout
, CFSTR(" <%@>"), options_str
);
681 CFRelease(options_str
);
684 SCPrint(TRUE
, stdout
, CFSTR("\n"));
686 if (subtype_options
!= NULL
) CFRelease(subtype_options
);
688 if (subtypes
!= NULL
) CFRelease(subtypes
);
691 SCPrint(TRUE
, stdout
, CFSTR("\n"));
694 qosPolicy
= SCNetworkInterfaceGetQoSMarkingPolicy(interface
);
695 if (qosPolicy
!= NULL
) {
697 CFArrayRef bundleIDs
;
698 Boolean needComma
= FALSE
;
700 SCPrint(TRUE
, stdout
, CFSTR("%@ qos marking ="), prefix
);
702 bVal
= CFDictionaryGetValue(qosPolicy
, kSCPropNetQoSMarkingEnabled
);
703 if ((bVal
!= NULL
) && isA_CFBoolean(bVal
)) {
704 SCPrint(TRUE
, stdout
, CFSTR(" %senabled"),
705 CFBooleanGetValue(bVal
) ? "" : "!");
709 bVal
= CFDictionaryGetValue(qosPolicy
, kSCPropNetQoSMarkingAppleAudioVideoCalls
);
710 if ((bVal
!= NULL
) && isA_CFBoolean(bVal
)) {
711 SCPrint(TRUE
, stdout
, CFSTR("%s %sapple-av"),
712 needComma
? "," : "",
713 CFBooleanGetValue(bVal
) ? "" : "!");
717 bundleIDs
= CFDictionaryGetValue(qosPolicy
, kSCPropNetQoSMarkingWhitelistedAppIdentifiers
);
718 if ((bundleIDs
!= NULL
) && CFArrayGetCount(bundleIDs
)) {
719 CFIndex n
= CFArrayGetCount(bundleIDs
);
721 SCPrint(TRUE
, stdout
, CFSTR("%s applications = ("),
722 needComma
? "," : "");
723 for (CFIndex i
= 0; i
< n
; i
++) {
724 CFStringRef bundleID
;
726 bundleID
= CFArrayGetValueAtIndex(bundleIDs
, i
);
727 if (!isA_CFString(bundleID
)) {
728 bundleID
= CFSTR("--invalid-bundle-id--");
730 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
734 SCPrint(TRUE
, stdout
, CFSTR(")"));
737 SCPrint(TRUE
, stdout
, CFSTR("\n"));
741 supported
= SCNetworkInterfaceGetSupportedInterfaceTypes(interface
);
742 SCPrint(TRUE
, stdout
, CFSTR("%@ supported interfaces = "), prefix
);
743 if (supported
!= NULL
) {
745 CFIndex n
= CFArrayGetCount(supported
);
747 for (i
= 0; i
< n
; i
++) {
748 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
749 (i
== 0) ? "" : ", ",
750 CFArrayGetValueAtIndex(supported
, i
));
753 SCPrint(TRUE
, stdout
, CFSTR("\n"));
755 supported
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
);
756 SCPrint(TRUE
, stdout
, CFSTR("%@ supported protocols = "), prefix
);
757 if (supported
!= NULL
) {
759 CFIndex n
= CFArrayGetCount(supported
);
761 for (i
= 0; i
< n
; i
++) {
762 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
763 (i
== 0) ? "" : ", ",
764 CFArrayGetValueAtIndex(supported
, i
));
767 SCPrint(TRUE
, stdout
, CFSTR("\n"));
769 isPhysicalEthernet
= _SCNetworkInterfaceIsPhysicalEthernet(interface
);
770 SCPrint(TRUE
, stdout
, CFSTR("%@ is%s physical ethernet\n"),
772 isPhysicalEthernet
? "" : " not");
774 if (_SCNetworkInterfaceIsApplePreconfigured(interface
)) {
775 SCPrint(TRUE
, stdout
, CFSTR("%@ is pre-configured\n"), prefix
);
778 if (configuration
!= NULL
) {
779 CFMutableDictionaryRef effective
;
781 effective
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
783 // remove known (and already reported) interface configuration keys
784 if (CFDictionaryContainsKey(effective
, kSCResvInactive
)) {
785 CFDictionaryRemoveAllValues(effective
);
787 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMTU
);
788 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMediaSubType
);
789 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMediaOptions
);
791 if (CFDictionaryGetCount(effective
) > 0) {
792 SCPrint(TRUE
, stdout
, CFSTR("\n%@ per-interface configuration\n"), prefix
);
793 _show_entity(effective
, prefix
);
796 CFRelease(effective
);
799 if (CFEqual(if_type
, kSCNetworkInterfaceTypePPP
)) {
800 SCNetworkInterfaceRef childInterface
;
802 childInterface
= SCNetworkInterfaceGetInterface(interface
);
803 if (childInterface
!= NULL
) {
804 CFStringRef childInterfaceType
;
806 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
807 if (CFEqual(childInterfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
808 CFDictionaryRef ipsec_configuration
;
810 ipsec_configuration
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
811 if (isA_CFDictionary(ipsec_configuration
) &&
812 (CFDictionaryGetCount(ipsec_configuration
) > 0)) {
813 SCPrint(TRUE
, stdout
, CFSTR("\n%@ per-interface IPSec configuration\n"), prefix
);
814 _show_entity(ipsec_configuration
, prefix
);
821 SCPrint(TRUE
, stdout
, CFSTR("\n%@\n"), interface
);
824 interface
= SCNetworkInterfaceGetInterface(interface
);
825 if (interface
!= NULL
) {
826 CFStringRef newPrefix
;
828 newPrefix
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@ "), prefix
);
829 SCPrint(TRUE
, stdout
, CFSTR("\n%@child interface\n"), newPrefix
);
830 _show_interface(interface
, newPrefix
, showChild
);
831 CFRelease(newPrefix
);
838 /* -------------------- */
842 validateMediaOptions(SCNetworkInterfaceRef interface
, CFMutableDictionaryRef newConfiguration
)
849 mtu
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMTU
);
850 if (isA_CFNumber(mtu
)) {
855 if (!SCNetworkInterfaceCopyMTU(interface
, NULL
, &mtu_min
, &mtu_max
)) {
856 SCPrint(TRUE
, stdout
, CFSTR("cannot set MTU\n"));
860 if (!CFNumberGetValue(mtu
, kCFNumberIntType
, &mtu_val
) ||
861 (mtu_val
< mtu_min
) ||
862 (mtu_val
> mtu_max
)) {
863 SCPrint(TRUE
, stdout
, CFSTR("mtu out of range\n"));
868 subtype
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMediaSubType
);
869 options
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMediaOptions
);
871 if (subtype
!= NULL
) {
872 CFArrayRef available
= NULL
;
873 CFArrayRef config_options
= options
;
874 CFArrayRef subtypes
= NULL
;
875 CFArrayRef subtype_options
= NULL
;
879 if (options
== NULL
) {
880 config_options
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
883 if (!SCNetworkInterfaceCopyMediaOptions(interface
, NULL
, NULL
, &available
, FALSE
)) {
884 SCPrint(TRUE
, stdout
, CFSTR("media type / options not available\n"));
888 if (available
== NULL
) {
892 subtypes
= SCNetworkInterfaceCopyMediaSubTypes(available
);
893 if ((subtypes
== NULL
) ||
894 !CFArrayContainsValue(subtypes
,
895 CFRangeMake(0, CFArrayGetCount(subtypes
)),
897 SCPrint(TRUE
, stdout
, CFSTR("media type not valid\n"));
901 subtype_options
= SCNetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
902 if ((subtype_options
== NULL
) ||
903 !CFArrayContainsValue(subtype_options
,
904 CFRangeMake(0, CFArrayGetCount(subtype_options
)),
906 SCPrint(TRUE
, stdout
, CFSTR("media options not valid for \"%@\"\n"), subtype
);
910 if (options
== NULL
) {
911 CFDictionarySetValue(newConfiguration
, kSCPropNetEthernetMediaOptions
, config_options
);
918 if (available
!= NULL
) CFRelease(available
);
919 if (subtypes
!= NULL
) CFRelease(subtypes
);
920 if (subtype_options
!= NULL
) CFRelease(subtype_options
);
921 if (options
== NULL
) CFRelease(config_options
);
923 if (options
!= NULL
) {
924 SCPrint(TRUE
, stdout
, CFSTR("media type and options must both be specified\n"));
933 /* -------------------- */
938 show_interfaces(int argc
, char **argv
)
943 if (interfaces
!= NULL
) CFRelease(interfaces
);
944 interfaces
= _copy_interfaces();
945 if (interfaces
== NULL
) {
949 n
= CFArrayGetCount(interfaces
);
950 for (i
= 0; i
< n
; i
++) {
951 CFIndex childIndex
= 0;
952 SCNetworkInterfaceRef interface
;
954 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
956 CFStringRef interfaceName
;
959 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
960 if (interfaceName
== NULL
) {
961 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
963 if (interfaceName
== NULL
) {
964 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
968 if ((net_interface
!= NULL
) && CFEqual(interface
, net_interface
)) {
972 if (childIndex
== 0) {
973 SCPrint(TRUE
, stdout
, CFSTR("%c%2ld: %@\n"),
978 SCPrint(TRUE
, stdout
, CFSTR("%c%2ld.%ld: %@\n"),
986 CFMutableStringRef desc
;
987 CFMutableDictionaryRef formatOptions
;
989 desc
= CFStringCreateMutable(NULL
, 0);
991 formatOptions
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
992 CFDictionarySetValue(formatOptions
, CFSTR("PREFIX1"), CFSTR(""));
993 CFDictionarySetValue(formatOptions
, CFSTR("PREFIX2"), CFSTR("$$"));
994 CFStringAppendFormat(desc
, formatOptions
, CFSTR("%@"), interface
);
995 CFRelease(formatOptions
);
997 // cleanup SCNetworkInterface details
998 CFStringFindAndReplace(desc
,
1001 CFRangeMake(0, CFStringGetLength(desc
)),
1003 CFStringFindAndReplace(desc
,
1006 CFRangeMake(0, CFStringGetLength(desc
)),
1008 CFStringFindAndReplace(desc
,
1011 CFRangeMake(CFStringGetLength(desc
) - 1, 1),
1012 kCFCompareBackwards
|kCFCompareAnchored
);
1014 // additional cleanup for Bond, Bridge, VLAN options
1015 CFStringFindAndReplace(desc
,
1018 CFRangeMake(0, CFStringGetLength(desc
)),
1020 CFStringFindAndReplace(desc
,
1023 CFRangeMake(0, CFStringGetLength(desc
)),
1025 CFStringFindAndReplace(desc
,
1028 CFRangeMake(0, CFStringGetLength(desc
)),
1031 SCPrint(TRUE
, stdout
, CFSTR("\n %@\n\n"), desc
);
1035 interface
= SCNetworkInterfaceGetInterface(interface
);
1037 } while (interface
!= NULL
);
1044 /* -------------------- */
1048 __doRank(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1050 SCNetworkInterfaceRef interface
;
1051 CFStringRef interfaceName
;
1053 SCNetworkServicePrimaryRank rank
= kSCNetworkServicePrimaryRankDefault
;
1054 SCDynamicStoreRef store
;
1057 SCPrint(TRUE
, stdout
,
1058 CFSTR("%s not specified\n"),
1059 description
!= NULL
? description
: "rank");
1063 if (strlen(argv
[0]) == 0) {
1064 rank
= kSCNetworkServicePrimaryRankDefault
;
1065 } else if ((strcasecmp(argv
[0], "First") == 0)) {
1066 rank
= kSCNetworkServicePrimaryRankFirst
;
1067 } else if ((strcasecmp(argv
[0], "Last") == 0)) {
1068 rank
= kSCNetworkServicePrimaryRankLast
;
1069 } else if ((strcasecmp(argv
[0], "Never") == 0)) {
1070 rank
= kSCNetworkServicePrimaryRankNever
;
1071 } else if ((strcasecmp(argv
[0], "Scoped") == 0)) {
1072 rank
= kSCNetworkServicePrimaryRankScoped
;
1074 SCPrint(TRUE
, stdout
, CFSTR("invalid rank\n"));
1078 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1079 if (interfaceName
== NULL
) {
1080 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1084 store
= SCDynamicStoreCreate(NULL
, CFSTR("scutil --net"), NULL
, NULL
);
1085 interface
= _SCNetworkInterfaceCopyActive(store
, interfaceName
);
1087 if (interface
== NULL
) {
1088 SCPrint(TRUE
, stdout
, CFSTR("No active interface\n"));
1092 ok
= SCNetworkInterfaceSetPrimaryRank(interface
, rank
);
1093 CFRelease(interface
);
1095 SCPrint(TRUE
, stdout
, CFSTR("could not update per-interface rank\n"));
1103 /* -------------------- */
1107 _replaceOne(const void *key
, const void *value
, void *context
)
1109 CFMutableDictionaryRef newConfiguration
= (CFMutableDictionaryRef
)context
;
1111 CFDictionarySetValue(newConfiguration
, key
, value
);
1117 updateInterfaceConfiguration(CFMutableDictionaryRef newConfiguration
)
1119 CFDictionaryRef configuration
;
1121 CFDictionaryRemoveAllValues(newConfiguration
);
1123 configuration
= SCNetworkInterfaceGetConfiguration(net_interface
);
1124 if (configuration
!= NULL
) {
1125 CFDictionaryApplyFunction(configuration
, _replaceOne
, (void *)newConfiguration
);
1133 #pragma mark QoS Marking Policy options
1136 static options qosOptions
[] = {
1137 { "enabled" , NULL
, isBool
, &kSCPropNetQoSMarkingEnabled
, NULL
, NULL
},
1138 { "apple-av" , NULL
, isBool
, &kSCPropNetQoSMarkingAppleAudioVideoCalls
, NULL
, NULL
},
1139 { "bundle-ids", NULL
, isStringArray
, &kSCPropNetQoSMarkingWhitelistedAppIdentifiers
, NULL
, NULL
},
1141 { "?" , NULL
, isHelp
, NULL
, NULL
,
1142 "\nQoS marking policy commands\n\n"
1143 " set interface qos [enabled {yes|no}]\n"
1144 " set interface qos [apple-av {yes|no}]\n"
1145 " set interface qos [bundle-ids bundle-id[,bundle-id]]\n"
1148 #define N_QOS_OPTIONS (sizeof(qosOptions) / sizeof(qosOptions[0]))
1152 __doQoSMarking(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1154 CFStringRef interfaceName
;
1155 CFMutableDictionaryRef newPolicy
;
1157 CFDictionaryRef policy
;
1160 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1164 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1165 if (interfaceName
== NULL
) {
1166 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1170 policy
= SCNetworkInterfaceGetQoSMarkingPolicy(net_interface
);
1171 if (policy
!= NULL
) {
1172 newPolicy
= CFDictionaryCreateMutableCopy(NULL
, 0, policy
);
1173 CFDictionaryRemoveValue(newPolicy
, kSCResvInactive
);
1175 newPolicy
= CFDictionaryCreateMutable(NULL
,
1177 &kCFTypeDictionaryKeyCallBacks
,
1178 &kCFTypeDictionaryValueCallBacks
);
1181 ok
= _process_options(qosOptions
, N_QOS_OPTIONS
, argc
, argv
, newPolicy
);
1186 if (((policy
== NULL
) && (CFDictionaryGetCount(newPolicy
) > 0)) ||
1187 ((policy
!= NULL
) && !CFEqual(policy
, newPolicy
))) {
1188 if (!SCNetworkInterfaceSetQoSMarkingPolicy(net_interface
, newPolicy
)) {
1189 if (SCError() == kSCStatusNoKey
) {
1190 SCPrint(TRUE
, stdout
, CFSTR("could not update per-interface QoS marking policy\n"));
1192 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
1197 _prefs_changed
= TRUE
;
1202 if (newPolicy
!= NULL
) CFRelease(newPolicy
);
1208 #pragma mark Bond options
1211 static options bondOptions
[] = {
1212 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1213 // xxx { "+device" , ... },
1214 // xxx { "-device" , ... },
1216 { "?" , NULL
, isHelp
, NULL
, NULL
,
1217 "\nBond configuration commands\n\n"
1218 " set interface [mtu n] [media type] [mediaopts opts]\n"
1221 #define N_BOND_OPTIONS (sizeof(bondOptions) / sizeof(bondOptions[0]))
1225 set_interface_bond(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1227 CFStringRef interfaceName
;
1230 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1231 if (interfaceName
== NULL
) {
1232 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1236 ok
= _process_options(bondOptions
, N_BOND_OPTIONS
, argc
, argv
, newConfiguration
);
1238 // validate configuration
1239 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1249 #pragma mark Bridge options
1252 static options bridgeOptions
[] = {
1253 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1254 // xxx { "+device" , ... },
1255 // xxx { "-device" , ... },
1257 { "?" , NULL
, isHelp
, NULL
, NULL
,
1258 "\nBridge configuration commands\n\n"
1259 " set interface [mtu n] [media type] [mediaopts opts]\n"
1262 #define N_BRIDGE_OPTIONS (sizeof(bridgeOptions) / sizeof(bridgeOptions[0]))
1266 set_interface_bridge(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1268 CFStringRef interfaceName
;
1271 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1272 if (interfaceName
== NULL
) {
1273 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1277 ok
= _process_options(bridgeOptions
, N_BRIDGE_OPTIONS
, argc
, argv
, newConfiguration
);
1279 // validate configuration
1280 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1290 #pragma mark AirPort options
1293 static options airportOptions
[] = {
1294 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1295 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
1296 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
1298 { "rank" , NULL
, isOther
, NULL
, __doRank
, NULL
},
1300 { "qos" , NULL
, isOther
, NULL
, __doQoSMarking
, NULL
},
1302 { "?" , NULL
, isHelp
, NULL
, NULL
,
1303 "\nAirPort configuration commands\n\n"
1304 " set interface [mtu n] [media type] [mediaopts opts]\n"
1305 " set interface [rank [{First|Last|Never|Scoped}]]\n"
1306 " set interface [qos <qos-options>]]\n"
1309 #define N_AIRPORT_OPTIONS (sizeof(airportOptions) / sizeof(airportOptions[0]))
1313 set_interface_airport(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1315 CFStringRef interfaceName
;
1318 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1319 if (interfaceName
== NULL
) {
1320 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1324 ok
= _process_options(airportOptions
, N_AIRPORT_OPTIONS
, argc
, argv
, newConfiguration
);
1326 // validate configuration
1327 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1337 #pragma mark Ethernet options
1341 __doCapability(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1346 SCPrint(TRUE
, stdout
,
1347 CFSTR("%s not specified\n"),
1348 description
!= NULL
? description
: "enable/disable");
1352 if (strlen(argv
[0]) == 0) {
1353 ok
= SCNetworkInterfaceSetCapability(net_interface
, key
, NULL
);
1354 } else if ((strcasecmp(argv
[0], "disable") == 0) ||
1355 (strcasecmp(argv
[0], "no" ) == 0) ||
1356 (strcasecmp(argv
[0], "off" ) == 0) ||
1357 (strcasecmp(argv
[0], "0" ) == 0)) {
1358 ok
= SCNetworkInterfaceSetCapability(net_interface
, key
, CFNumberRef_0
);
1359 } else if ((strcasecmp(argv
[0], "enable") == 0) ||
1360 (strcasecmp(argv
[0], "yes" ) == 0) ||
1361 (strcasecmp(argv
[0], "on" ) == 0) ||
1362 (strcasecmp(argv
[0], "1" ) == 0)) {
1363 ok
= SCNetworkInterfaceSetCapability(net_interface
, key
, CFNumberRef_1
);
1365 SCPrint(TRUE
, stdout
, CFSTR("invalid value\n"));
1370 updateInterfaceConfiguration(newConfiguration
);
1372 SCPrint(TRUE
, stdout
,
1373 CFSTR("%@ not updated: %s\n"),
1375 SCErrorString(SCError()));
1383 static options ethernetOptions
[] = {
1384 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1385 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
1386 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
1388 { "av" , NULL
, isOther
, &kSCPropNetEthernetCapabilityAV
, __doCapability
, NULL
},
1389 { "lro" , NULL
, isOther
, &kSCPropNetEthernetCapabilityLRO
, __doCapability
, NULL
},
1390 { "rxcsum" , NULL
, isOther
, &kSCPropNetEthernetCapabilityRXCSUM
, __doCapability
, NULL
},
1391 { "tso" , NULL
, isOther
, &kSCPropNetEthernetCapabilityTSO
, __doCapability
, NULL
},
1392 { "txcsum" , NULL
, isOther
, &kSCPropNetEthernetCapabilityTXCSUM
, __doCapability
, NULL
},
1394 { "rank" , NULL
, isOther
, NULL
, __doRank
, NULL
},
1396 { "qos" , NULL
, isOther
, NULL
, __doQoSMarking
, NULL
},
1398 { "?" , NULL
, isHelp
, NULL
, NULL
,
1399 "\nEthernet configuration commands\n\n"
1400 " set interface [mtu n] [media type] [mediaopts opts]\n"
1401 " set interface [rank [{First|Last|Never|Scoped}]]\n"
1402 " set interface [qos [<qos-options>]]\n"
1405 #define N_ETHERNET_OPTIONS (sizeof(ethernetOptions) / sizeof(ethernetOptions[0]))
1409 set_interface_ethernet(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1411 CFStringRef interfaceName
;
1414 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1415 if (interfaceName
== NULL
) {
1416 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1420 ok
= _process_options(ethernetOptions
, N_ETHERNET_OPTIONS
, argc
, argv
, newConfiguration
);
1422 // validate configuration
1423 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1433 #pragma mark IPSec options
1437 __doIPSecSharedSecret(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1439 CFStringRef encryptionType
;
1442 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret not specified\n"));
1446 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetIPSecSharedSecretEncryption
);
1447 if (strlen(argv
[0]) > 0) {
1448 if (encryptionType
== NULL
) {
1449 #ifdef INLINE_PASSWORDS_USE_CFSTRING
1452 pw
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1453 #else // INLINE_PASSWORDS_USE_CFSTRING
1455 CFMutableDataRef pw
;
1458 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1459 n
= CFStringGetLength(str
);
1460 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
1461 CFDataSetLength(pw
, n
* sizeof(UniChar
));
1462 /* ALIGN: CF aligns to at least >8 bytes */
1463 CFStringGetCharacters(str
,
1465 (UniChar
*)(void *)CFDataGetMutableBytePtr(pw
));
1467 #endif // INLINE_PASSWORDS_USE_CFSTRING
1469 CFDictionarySetValue(newConfiguration
, key
, pw
);
1471 } else if (CFEqual(encryptionType
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1476 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1477 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
1478 ok
= SCNetworkInterfaceSetPassword(net_interface
,
1479 kSCNetworkInterfacePasswordTypeIPSecSharedSecret
,
1485 updateInterfaceConfiguration(newConfiguration
);
1490 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret type \"%@\" not supported\n"), encryptionType
);
1494 if (encryptionType
== NULL
) {
1495 CFDictionaryRemoveValue(newConfiguration
, key
);
1496 } else if (CFEqual(encryptionType
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1498 ok
= SCNetworkInterfaceRemovePassword(net_interface
, kSCNetworkInterfacePasswordTypeIPSecSharedSecret
);
1500 updateInterfaceConfiguration(newConfiguration
);
1505 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret type \"%@\" not supported\n"), encryptionType
);
1515 __doIPSecSharedSecretType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1518 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret type mode not specified\n"));
1522 if (strlen(argv
[0]) > 0) {
1523 if (strcasecmp(argv
[0], "keychain") == 0) {
1524 CFDictionarySetValue(newConfiguration
, key
, kSCValNetIPSecSharedSecretEncryptionKeychain
);
1526 SCPrint(TRUE
, stdout
, CFSTR("invalid shared secret type\n"));
1530 CFDictionaryRemoveValue(newConfiguration
, key
);
1533 // encryption type changed, reset shared secret
1534 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPSecSharedSecret
);
1541 __doIPSecXAuthPassword(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1543 CFStringRef encryptionType
;
1546 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuth password not specified\n"));
1550 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetIPSecXAuthPasswordEncryption
);
1551 if (strlen(argv
[0]) > 0) {
1552 if (encryptionType
== NULL
) {
1553 #ifdef INLINE_PASSWORDS_USE_CFSTRING
1556 pw
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1557 #else // INLINE_PASSWORDS_USE_CFSTRING
1559 CFMutableDataRef pw
;
1562 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1563 n
= CFStringGetLength(str
);
1564 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
1565 CFDataSetLength(pw
, n
* sizeof(UniChar
));
1566 /* ALIGN: CF aligns to at least >8 byte boundries */
1567 CFStringGetCharacters(str
,
1569 (UniChar
*)(void *)CFDataGetMutableBytePtr(pw
));
1571 #endif // INLINE_PASSWORDS_USE_CFSTRING
1573 CFDictionarySetValue(newConfiguration
, key
, pw
);
1575 } else if (CFEqual(encryptionType
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
1580 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1581 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
1582 ok
= SCNetworkInterfaceSetPassword(net_interface
,
1583 kSCNetworkInterfacePasswordTypeIPSecXAuth
,
1589 updateInterfaceConfiguration(newConfiguration
);
1594 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuthPassword type \"%@\" not supported\n"), encryptionType
);
1598 if (encryptionType
== NULL
) {
1599 CFDictionaryRemoveValue(newConfiguration
, key
);
1600 } else if (CFEqual(encryptionType
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
1603 ok
= SCNetworkInterfaceRemovePassword(net_interface
, kSCNetworkInterfacePasswordTypeIPSecXAuth
);
1605 updateInterfaceConfiguration(newConfiguration
);
1610 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuthPassword type \"%@\" not supported\n"), encryptionType
);
1620 __doIPSecXAuthPasswordType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1623 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuth password type mode not specified\n"));
1627 if (strlen(argv
[0]) > 0) {
1628 if (strcasecmp(argv
[0], "keychain") == 0) {
1629 CFDictionarySetValue(newConfiguration
, key
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
1631 SCPrint(TRUE
, stdout
, CFSTR("invalid XAuth password type\n"));
1635 CFDictionaryRemoveValue(newConfiguration
, key
);
1638 // encryption type changed, reset XAuthPassword
1639 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPSecXAuthPassword
);
1645 static CF_RETURNS_RETAINED CFStringRef
1646 __cleanupDomainName(CFStringRef domain
)
1648 CFMutableStringRef newDomain
;
1650 newDomain
= CFStringCreateMutableCopy(NULL
, 0, domain
);
1651 CFStringTrimWhitespace(newDomain
);
1652 CFStringTrim(newDomain
, CFSTR("."));
1653 if (CFStringGetLength(newDomain
) == 0) {
1654 CFRelease(newDomain
);
1663 __doOnDemandDomains(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1665 CFMutableArrayRef domains
;
1668 SCPrint(TRUE
, stdout
, CFSTR("OnDemand domain name(s) not specified\n"));
1672 domains
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1674 if (strlen(argv
[0]) > 0) {
1678 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1679 array
= CFStringCreateArrayBySeparatingStrings(NULL
, str
, CFSTR(","));
1682 if (array
!= NULL
) {
1684 CFIndex n
= CFArrayGetCount(array
);
1686 for (i
= 0; i
< n
; i
++) {
1689 domain
= __cleanupDomainName(CFArrayGetValueAtIndex(array
, i
));
1690 if (domain
!= NULL
) {
1691 CFArrayAppendValue(domains
, domain
);
1696 SCPrint(TRUE
, stdout
, CFSTR("invalid OnDemand domain name\n"));
1704 if (CFArrayGetCount(domains
) > 0) {
1705 CFDictionarySetValue(newConfiguration
, key
, domains
);
1707 CFDictionaryRemoveValue(newConfiguration
, key
);
1715 static options ipsecOnDemandOptions
[] = {
1716 { "OnDemandMatchDomainsAlways" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1717 { "always" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1718 { "OnDemandMatchDomainsOnRetry", "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1719 { "retry" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1720 { "OnDemandMatchDomainsNever" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1721 { "never" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1723 { "?" , NULL
, isHelp
, NULL
, NULL
,
1724 "\nOnDemandMatch configuration commands\n\n"
1725 " set interface OnDemandMatch [always domain-name[,domain-name]]\n"
1726 " set interface OnDemandMatch [retry domain-name[,domain-name]]\n"
1727 " set interface OnDemandMatch [never domain-name[,domain-name]]\n"
1730 #define N_IPSEC_ONDEMAND_OPTIONS (sizeof(ipsecOnDemandOptions) / sizeof(ipsecOnDemandOptions[0]))
1734 __doIPSecOnDemandMatch(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1739 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1743 ok
= _process_options(ipsecOnDemandOptions
, N_IPSEC_ONDEMAND_OPTIONS
, argc
, argv
, newConfiguration
);
1754 static selections ipsecAuthenticationMethodSelections
[] = {
1755 { CFSTR("SharedSecret"), &kSCValNetIPSecAuthenticationMethodSharedSecret
, 0 },
1756 { CFSTR("Certificate") , &kSCValNetIPSecAuthenticationMethodCertificate
, 0 },
1757 { CFSTR("Hybrid") , &kSCValNetIPSecAuthenticationMethodHybrid
, 0 },
1762 static selections ipsecLocalIdentifierTypeSelections
[] = {
1763 { CFSTR("KeyID") , &kSCValNetIPSecLocalIdentifierTypeKeyID
, 0 },
1768 static options ipsecOptions
[] = {
1769 { "AuthenticationMethod" , NULL
, isChooseOne
, &kSCPropNetIPSecAuthenticationMethod
, NULL
, (void *)ipsecAuthenticationMethodSelections
},
1770 { "LocalIdentifier" , NULL
, isString
, &kSCPropNetIPSecLocalIdentifier
, NULL
, NULL
},
1771 { "group" , NULL
, isString
, &kSCPropNetIPSecLocalIdentifier
, NULL
, NULL
},
1772 { "LocalIdentifierType" , NULL
, isChooseOne
, &kSCPropNetIPSecLocalIdentifierType
, NULL
, (void *)ipsecLocalIdentifierTypeSelections
},
1773 { "RemoteAddress" , NULL
, isString
, &kSCPropNetIPSecRemoteAddress
, NULL
, NULL
},
1774 { "SharedSecret" , NULL
, isOther
, &kSCPropNetIPSecSharedSecret
, __doIPSecSharedSecret
, NULL
},
1775 { "SharedSecretEncryption" , NULL
, isOther
, &kSCPropNetIPSecSharedSecretEncryption
, __doIPSecSharedSecretType
, NULL
},
1778 { "XAuthEnabled" , NULL
, isBoolean
, &kSCPropNetIPSecXAuthEnabled
, NULL
, NULL
},
1779 { "XAuthName" , NULL
, isString
, &kSCPropNetIPSecXAuthName
, NULL
, NULL
},
1780 { "XAuthPassword" , NULL
, isOther
, &kSCPropNetIPSecXAuthPassword
, __doIPSecXAuthPassword
, NULL
},
1781 { "XAuthPasswordEncryption", NULL
, isOther
, &kSCPropNetIPSecXAuthPasswordEncryption
, __doIPSecXAuthPasswordType
, NULL
},
1783 // --- OnDemand: ---
1784 { "OnDemandEnabled" , NULL
, isBoolean
, &kSCPropNetIPSecOnDemandEnabled
, NULL
, NULL
},
1785 { "OnDemandMatch" , NULL
, isOther
, NULL
, __doIPSecOnDemandMatch
, NULL
},
1787 { "?" , NULL
, isHelp
, NULL
, NULL
,
1788 "\nIPSec configuration commands\n\n"
1789 " set interface [AuthenticationMethod {SharedSecret|Certificate|Hybrid}]\n"
1790 " set interface [LocalIdentifier group]\n"
1791 " set interface [LocalIdentifierType {KeyID}]\n"
1792 " set interface [RemoteAddress name-or-address]\n"
1793 " set interface [SharedSecret secret]\n"
1794 " set interface [SharedSecretEncryption {Keychain}]\n"
1795 " set interface [XAuthEnabled {enable|disable}]\n"
1796 " set interface [XAuthPassword password]\n"
1797 " set interface [XAuthPasswordEncryption {Keychain}]\n"
1798 " set interface [OnDemandEnabled {enable|disable}]\n"
1799 " set interface [OnDemandMatch <match-options>]\n"
1802 #define N_IPSEC_OPTIONS (sizeof(ipsecOptions) / sizeof(ipsecOptions[0]))
1806 set_interface_ipsec(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1810 ok
= _process_options(ipsecOptions
, N_IPSEC_OPTIONS
, argc
, argv
, newConfiguration
);
1816 #pragma mark FireWire options
1819 static options firewireOptions
[] = {
1820 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1821 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
1822 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
1824 { "?" , NULL
, isHelp
, NULL
, NULL
,
1825 "\nFireWire configuration commands\n\n"
1826 " set interface [mtu n] [media type] [mediaopts opts]\n"
1829 #define N_FIREWIRE_OPTIONS (sizeof(firewireOptions) / sizeof(firewireOptions[0]))
1833 set_interface_firewire(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1835 CFStringRef interfaceName
;
1838 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1839 if (interfaceName
== NULL
) {
1840 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1844 ok
= _process_options(firewireOptions
, N_FIREWIRE_OPTIONS
, argc
, argv
, newConfiguration
);
1846 // validate configuration
1847 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1857 #pragma mark Modem options
1860 static selections modemDialSelections
[] = {
1861 { CFSTR("ignore"), &kSCValNetModemDialModeIgnoreDialTone
, 0 },
1862 { CFSTR("manual"), &kSCValNetModemDialModeManual
, 0 },
1863 { CFSTR("wait") , &kSCValNetModemDialModeWaitForDialTone
, 0 },
1867 static options modemOptions
[] = {
1868 { "ConnectionPersonality" , "NULL" , isString
, &kSCPropNetModemConnectionPersonality
, NULL
, NULL
},
1869 { "DeviceModel" , "model" , isString
, &kSCPropNetModemDeviceModel
, NULL
, NULL
},
1870 { "DeviceVendor" , "vendor", isString
, &kSCPropNetModemDeviceVendor
, NULL
, NULL
},
1871 { "ConnectionScript" , "script", isString
, &kSCPropNetModemConnectionScript
, NULL
, NULL
},
1872 { "DialMode" , "mode" , isChooseOne
, &kSCPropNetModemDialMode
, NULL
, (void *)modemDialSelections
},
1873 { "CallWaiting" , NULL
, isBoolean
, &kSCPropNetModemHoldEnabled
, NULL
, NULL
},
1874 { "CallWaitingAlert" , NULL
, isBoolean
, &kSCPropNetModemHoldCallWaitingAudibleAlert
, NULL
, NULL
},
1875 { "CallWaitingDisconnectOnAnswer", NULL
, isBoolean
, &kSCPropNetModemHoldDisconnectOnAnswer
, NULL
, NULL
},
1876 { "DataCompression" , NULL
, isBoolean
, &kSCPropNetModemDataCompression
, NULL
, NULL
},
1877 { "ErrorCorrection" , NULL
, isBoolean
, &kSCPropNetModemErrorCorrection
, NULL
, NULL
},
1878 { "HoldReminder" , NULL
, isBoolean
, &kSCPropNetModemHoldReminder
, NULL
, NULL
},
1879 { "HoldReminderTime" , "time" , isNumber
, &kSCPropNetModemHoldReminderTime
, NULL
, NULL
},
1880 { "PulseDial" , NULL
, isBoolean
, &kSCPropNetModemPulseDial
, NULL
, NULL
},
1881 { "Speaker" , NULL
, isBoolean
, &kSCPropNetModemSpeaker
, NULL
, NULL
},
1883 { "?" , NULL
, isHelp
, NULL
, NULL
,
1884 "\nModem configuration commands\n\n"
1885 " set interface [DeviceVendor vendor]\n"
1886 " set interface [DeviceModel model]\n"
1887 " set interface [ConnectionPersonality personality]\n"
1889 " set interface [ConnectionScript connection-script]\n"
1891 " set interface [CallWaiting {enable|disable}]\n"
1892 " set interface [CallWaitingAlert {enable|disable}]\n"
1893 " set interface [CallWaitingDisconnectOnAnswer {enable|disable}]\n"
1894 " set interface [DialMode {ignore|wait}]\n"
1895 " set interface [DataCompression {enable|disable}]\n"
1896 " set interface [ErrorCorrection {enable|disable}]\n"
1897 " set interface [HoldReminder {enable|disable}]\n"
1898 " set interface [HoldReminderTime n]\n"
1899 " set interface [PulseDial {enable|disable}]\n"
1900 " set interface [Speaker {enable|disable}]\n"
1903 #define N_MODEM_OPTIONS (sizeof(modemOptions) / sizeof(modemOptions[0]))
1907 set_interface_modem(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1911 ok
= _process_options(modemOptions
, N_MODEM_OPTIONS
, argc
, argv
, newConfiguration
);
1917 #pragma mark PPP options
1921 __doPPPAuthPW(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1923 CFStringRef encryptionType
;
1926 SCPrint(TRUE
, stdout
, CFSTR("PPP password not specified\n"));
1930 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetPPPAuthPasswordEncryption
);
1931 if (strlen(argv
[0]) > 0) {
1932 if (encryptionType
== NULL
) {
1933 #ifdef INLINE_PASSWORDS_USE_CFSTRING
1936 pw
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1937 #else // INLINE_PASSWORDS_USE_CFSTRING
1939 CFMutableDataRef pw
;
1942 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1943 n
= CFStringGetLength(str
);
1944 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
1945 CFDataSetLength(pw
, n
* sizeof(UniChar
));
1946 /* ALIGN: CF aligns to at least >8 byte boundries */
1947 CFStringGetCharacters(str
,
1949 (UniChar
*)(void *)CFDataGetMutableBytePtr(pw
));
1951 #endif // INLINE_PASSWORDS_USE_CFSTRING
1953 CFDictionarySetValue(newConfiguration
, key
, pw
);
1955 } else if (CFEqual(encryptionType
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1960 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1961 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
1962 ok
= SCNetworkInterfaceSetPassword(net_interface
,
1963 kSCNetworkInterfacePasswordTypePPP
,
1969 updateInterfaceConfiguration(newConfiguration
);
1974 SCPrint(TRUE
, stdout
, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType
);
1978 if (encryptionType
== NULL
) {
1979 CFDictionaryRemoveValue(newConfiguration
, key
);
1980 } else if (CFEqual(encryptionType
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1983 ok
= SCNetworkInterfaceRemovePassword(net_interface
, kSCNetworkInterfacePasswordTypePPP
);
1985 updateInterfaceConfiguration(newConfiguration
);
1990 SCPrint(TRUE
, stdout
, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType
);
2000 __doPPPAuthPWType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2003 SCPrint(TRUE
, stdout
, CFSTR("PPP password type mode not specified\n"));
2007 if (strlen(argv
[0]) > 0) {
2008 if (strcasecmp(argv
[0], "keychain") == 0) {
2009 CFDictionarySetValue(newConfiguration
, key
, kSCValNetPPPAuthPasswordEncryptionKeychain
);
2011 SCPrint(TRUE
, stdout
, CFSTR("invalid password type\n"));
2015 CFDictionaryRemoveValue(newConfiguration
, key
);
2018 // encryption type changed, reset password
2019 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetPPPAuthPassword
);
2025 static options l2tp_ipsecOptions
[] = {
2026 { "SharedSecret" , NULL
, isOther
, &kSCPropNetIPSecSharedSecret
, __doIPSecSharedSecret
, NULL
},
2027 { "SharedSecretEncryption", NULL
, isOther
, &kSCPropNetIPSecSharedSecretEncryption
, __doIPSecSharedSecretType
, NULL
},
2029 { "?" , NULL
, isHelp
, NULL
, NULL
,
2030 "\nIPSec configuration commands\n\n"
2031 " set interface ipsec [SharedSecret secret]\n"
2032 " set interface ipsec [SharedSecretEncryption {Keychain}]\n"
2035 #define N_L2TP_IPSEC_OPTIONS (sizeof(l2tp_ipsecOptions) / sizeof(l2tp_ipsecOptions[0]))
2039 __doPPPIPSec(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newPPPConfiguration
)
2041 SCNetworkInterfaceRef childInterface
;
2042 CFStringRef childInterfaceType
;
2043 CFDictionaryRef configuration
;
2044 CFMutableDictionaryRef newConfiguration
;
2048 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
2052 childInterface
= SCNetworkInterfaceGetInterface(net_interface
);
2053 if (childInterface
== NULL
) {
2054 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
2058 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
2059 if (!CFEqual(childInterfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2060 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
2064 configuration
= SCNetworkInterfaceGetExtendedConfiguration(net_interface
, kSCEntNetIPSec
);
2065 if (configuration
== NULL
) {
2066 newConfiguration
= CFDictionaryCreateMutable(NULL
,
2068 &kCFTypeDictionaryKeyCallBacks
,
2069 &kCFTypeDictionaryValueCallBacks
);
2071 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
2072 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
2075 ok
= _process_options(l2tp_ipsecOptions
, N_L2TP_IPSEC_OPTIONS
, argc
, argv
, newConfiguration
);
2080 if (((configuration
== NULL
) && (CFDictionaryGetCount(newConfiguration
) > 0)) ||
2081 ((configuration
!= NULL
) && !CFEqual(configuration
, newConfiguration
))) {
2082 if (!SCNetworkInterfaceSetExtendedConfiguration(net_interface
, kSCEntNetIPSec
, newConfiguration
)) {
2083 if (SCError() == kSCStatusNoKey
) {
2084 SCPrint(TRUE
, stdout
, CFSTR("could not update per-service interface configuration\n"));
2086 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
2091 _prefs_changed
= TRUE
;
2096 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
2102 static options pppOnDemandOptions
[] = {
2103 { "OnDemandMatchDomainsAlways" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
2104 { "always" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
2105 { "OnDemandMatchDomainsOnRetry", "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
2106 { "retry" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
2107 { "OnDemandMatchDomainsNever" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
2108 { "never" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
2110 { "?" , NULL
, isHelp
, NULL
, NULL
,
2111 "\nOnDemandMatch configuration commands\n\n"
2112 " set interface OnDemand always domain-name[,domain-name]\n"
2113 " set interface OnDemand retry domain-name[,domain-name]\n"
2114 " set interface OnDemand never domain-name[,domain-name]\n"
2117 #define N_PPP_ONDEMAND_OPTIONS (sizeof(pppOnDemandOptions) / sizeof(pppOnDemandOptions[0]))
2121 __doPPPOnDemandMatch(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2126 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
2130 ok
= _process_options(pppOnDemandOptions
, N_PPP_ONDEMAND_OPTIONS
, argc
, argv
, newConfiguration
);
2142 static selections authPromptSelections
[] = {
2143 { CFSTR("before"), &kSCValNetPPPAuthPromptBefore
, 0 },
2144 { CFSTR("after") , &kSCValNetPPPAuthPromptAfter
, 0 },
2149 static selections authProtocolSelections
[] = {
2150 { CFSTR("CHAP") , &kSCValNetPPPAuthProtocolCHAP
, 0 },
2151 { CFSTR("EAP") , &kSCValNetPPPAuthProtocolEAP
, 0 },
2152 { CFSTR("MSCHAP1"), &kSCValNetPPPAuthProtocolMSCHAP1
, 0 },
2153 { CFSTR("MSCHAP2"), &kSCValNetPPPAuthProtocolMSCHAP2
, 0 },
2154 { CFSTR("PAP") , &kSCValNetPPPAuthProtocolPAP
, 0 },
2159 static options pppOptions
[] = {
2160 { "ACSP" , NULL
, isBoolean
, &kSCPropNetPPPACSPEnabled
, NULL
, NULL
},
2161 { "ConnectTime" , "?time" , isNumber
, &kSCPropNetPPPConnectTime
, NULL
, NULL
},
2162 { "DialOnDemand" , NULL
, isBoolean
, &kSCPropNetPPPDialOnDemand
, NULL
, NULL
},
2163 { "DisconnectOnFastUserSwitch", NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnFastUserSwitch
, NULL
, NULL
},
2164 { "DisconnectOnIdle" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnIdle
, NULL
, NULL
},
2165 { "DisconnectOnIdleTimer" , "timeout" , isNumber
, &kSCPropNetPPPDisconnectOnIdleTimer
, NULL
, NULL
},
2166 { "DisconnectOnLogout" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnLogout
, NULL
, NULL
},
2167 { "DisconnectOnSleep" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnSleep
, NULL
, NULL
},
2168 { "DisconnectTime" , "?time" , isNumber
, &kSCPropNetPPPDisconnectTime
, NULL
, NULL
},
2169 { "IdleReminder" , NULL
, isBoolean
, &kSCPropNetPPPIdleReminder
, NULL
, NULL
},
2170 { "IdleReminderTimer" , "time" , isNumber
, &kSCPropNetPPPIdleReminderTimer
, NULL
, NULL
},
2171 { "Logfile" , "path" , isString
, &kSCPropNetPPPLogfile
, NULL
, NULL
},
2172 { "Plugins" , "plugin" , isStringArray
, &kSCPropNetPPPPlugins
, NULL
, NULL
},
2173 { "RetryConnectTime" , "time" , isNumber
, &kSCPropNetPPPRetryConnectTime
, NULL
, NULL
},
2174 { "SessionTimer" , "time" , isNumber
, &kSCPropNetPPPSessionTimer
, NULL
, NULL
},
2175 { "UseSessionTimer" , NULL
, isBoolean
, &kSCPropNetPPPUseSessionTimer
, NULL
, NULL
},
2176 { "VerboseLogging" , NULL
, isBoolean
, &kSCPropNetPPPVerboseLogging
, NULL
, NULL
},
2179 { "AuthEAPPlugins" , "plugin" , isStringArray
, &kSCPropNetPPPAuthEAPPlugins
, NULL
, NULL
},
2180 { "AuthName" , "account" , isString
, &kSCPropNetPPPAuthName
, NULL
, NULL
},
2181 { "Account" , "account" , isString
, &kSCPropNetPPPAuthName
, NULL
, NULL
},
2182 { "AuthPassword" , "password" , isOther
, &kSCPropNetPPPAuthPassword
, __doPPPAuthPW
, NULL
},
2183 { "Password" , "password" , isOther
, &kSCPropNetPPPAuthPassword
, __doPPPAuthPW
, NULL
},
2184 { "AuthPasswordEncryption" , "type" , isOther
, &kSCPropNetPPPAuthPasswordEncryption
, __doPPPAuthPWType
, NULL
},
2185 { "AuthPrompt" , "before/after", isChooseOne
, &kSCPropNetPPPAuthPrompt
, NULL
, (void *)authPromptSelections
},
2186 { "AuthProtocol" , "protocol" , isChooseMultiple
, &kSCPropNetPPPAuthProtocol
, NULL
, (void *)authProtocolSelections
},
2189 { "CommRemoteAddress" , "phone#" , isString
, &kSCPropNetPPPCommRemoteAddress
, NULL
, NULL
},
2190 { "Number" , "phone#" , isString
, &kSCPropNetPPPCommRemoteAddress
, NULL
, NULL
},
2191 { "CommAlternateRemoteAddress", "phone#" , isString
, &kSCPropNetPPPCommAlternateRemoteAddress
, NULL
, NULL
},
2192 { "CommConnectDelay" , "time" , isNumber
, &kSCPropNetPPPCommConnectDelay
, NULL
, NULL
},
2193 { "CommDisplayTerminalWindow" , NULL
, isBoolean
, &kSCPropNetPPPCommDisplayTerminalWindow
, NULL
, NULL
},
2194 { "CommRedialCount" , "retry count" , isNumber
, &kSCPropNetPPPCommRedialCount
, NULL
, NULL
},
2195 { "CommRedialEnabled" , NULL
, isBoolean
, &kSCPropNetPPPCommRedialEnabled
, NULL
, NULL
},
2196 { "CommRedialInterval" , "retry delay" , isNumber
, &kSCPropNetPPPCommRedialInterval
, NULL
, NULL
},
2197 { "CommTerminalScript" , "script" , isString
, &kSCPropNetPPPCommTerminalScript
, NULL
, NULL
},
2198 { "CommUseTerminalScript" , NULL
, isBoolean
, &kSCPropNetPPPCommUseTerminalScript
, NULL
, NULL
},
2201 { "CCPEnabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPEnabled
, NULL
, NULL
},
2202 { "CCPMPPE40Enabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPMPPE40Enabled
, NULL
, NULL
},
2203 { "CCPMPPE128Enabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPMPPE128Enabled
, NULL
, NULL
},
2206 { "IPCPCompressionVJ" , NULL
, isBoolean
, &kSCPropNetPPPIPCPCompressionVJ
, NULL
, NULL
},
2207 { "IPCPUsePeerDNS" , NULL
, isBoolean
, &kSCPropNetPPPIPCPUsePeerDNS
, NULL
, NULL
},
2210 { "LCPEchoEnabled" , NULL
, isBoolean
, &kSCPropNetPPPLCPEchoEnabled
, NULL
, NULL
},
2211 { "LCPEchoFailure" , NULL
, isNumber
, &kSCPropNetPPPLCPEchoFailure
, NULL
, NULL
},
2212 { "LCPEchoInterval" , NULL
, isNumber
, &kSCPropNetPPPLCPEchoInterval
, NULL
, NULL
},
2213 { "LCPCompressionACField" , NULL
, isBoolean
, &kSCPropNetPPPLCPCompressionACField
, NULL
, NULL
},
2214 { "LCPCompressionPField" , NULL
, isBoolean
, &kSCPropNetPPPLCPCompressionPField
, NULL
, NULL
},
2215 { "LCPMRU" , NULL
, isNumber
, &kSCPropNetPPPLCPMRU
, NULL
, NULL
},
2216 { "LCPMTU" , NULL
, isNumber
, &kSCPropNetPPPLCPMTU
, NULL
, NULL
},
2217 { "LCPReceiveACCM" , NULL
, isNumber
, &kSCPropNetPPPLCPReceiveACCM
, NULL
, NULL
},
2218 { "LCPTransmitACCM" , NULL
, isNumber
, &kSCPropNetPPPLCPTransmitACCM
, NULL
, NULL
},
2221 { "IPSec" , NULL
, isOther
, NULL
, __doPPPIPSec
, NULL
},
2224 // --- OnDemand: ---
2225 { "OnDemandEnabled" , NULL
, isBoolean
, &kSCPropNetPPPOnDemandEnabled
, NULL
, NULL
},
2226 { "OnDemandMatch" , NULL
, isOther
, NULL
, __doPPPOnDemandMatch
, NULL
},
2230 { "?" , NULL
, isHelp
, NULL
, NULL
,
2231 "\nPPP configuration commands\n\n"
2232 " set interface [Account account]\n"
2233 " set interface [Password password]\n"
2234 " set interface [Number telephone-number]\n"
2235 " set interface [AlternateNumber telephone-number]\n"
2236 " set interface [IdleReminder {enable|disable}]\n"
2237 " set interface [IdleReminderTimer time-in-seconds]\n"
2238 " set interface [DisconnectOnIdle {enable|disable}]\n"
2239 " set interface [DisconnectOnIdleTimer time-in-seconds]\n"
2240 " set interface [DisconnectOnLogout {enable|disable}]\n"
2241 " set interface [IPSec <ipsec-options>]\n"
2243 " set interface [OnDemandEnabled {enable|disable}]\n"
2244 " set interface [OnDemandMatch <match-options>]\n"
2248 #define N_PPP_OPTIONS (sizeof(pppOptions) / sizeof(pppOptions[0]))
2252 set_interface_ppp(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2256 ok
= _process_options(pppOptions
, N_PPP_OPTIONS
, argc
, argv
, newConfiguration
);
2262 #pragma mark VLAN options
2266 set_interface_vlan(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2268 // xxxxx ("device", "tag")
2269 SCPrint(TRUE
, stdout
, CFSTR("vlan interface management not yet supported\n"));
2275 #pragma mark VPN options
2279 __doVPNAuthPW(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2281 CFStringRef encryptionType
;
2284 SCPrint(TRUE
, stdout
, CFSTR("VPN password not specified\n"));
2288 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetVPNAuthPasswordEncryption
);
2289 if (strlen(argv
[0]) > 0) {
2290 if (encryptionType
== NULL
) {
2291 #ifdef INLINE_PASSWORDS_USE_CFSTRING
2294 pw
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
2295 #else // INLINE_PASSWORDS_USE_CFSTRING
2297 CFMutableDataRef pw
;
2300 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
2301 n
= CFStringGetLength(str
);
2302 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
2303 CFDataSetLength(pw
, n
* sizeof(UniChar
));
2304 CFStringGetCharacters(str
,
2306 (UniChar
*)(void *)CFDataGetMutableBytePtr(pw
));
2308 #endif // INLINE_PASSWORDS_USE_CFSTRING
2310 CFDictionarySetValue(newConfiguration
, key
, pw
);
2312 } else if (CFEqual(encryptionType
, kSCValNetVPNAuthPasswordEncryptionKeychain
)) {
2317 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
2318 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
2319 ok
= SCNetworkInterfaceSetPassword(net_interface
,
2320 kSCNetworkInterfacePasswordTypeVPN
,
2326 updateInterfaceConfiguration(newConfiguration
);
2331 SCPrint(TRUE
, stdout
, CFSTR("VPN password type \"%@\" not supported\n"), encryptionType
);
2335 if (encryptionType
== NULL
) {
2336 CFDictionaryRemoveValue(newConfiguration
, key
);
2337 } else if (CFEqual(encryptionType
, kSCValNetVPNAuthPasswordEncryptionKeychain
)) {
2340 ok
= SCNetworkInterfaceRemovePassword(net_interface
, kSCNetworkInterfacePasswordTypeVPN
);
2342 updateInterfaceConfiguration(newConfiguration
);
2347 SCPrint(TRUE
, stdout
, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType
);
2357 __doVPNAuthPWType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2360 SCPrint(TRUE
, stdout
, CFSTR("VPN password type mode not specified\n"));
2364 if (strlen(argv
[0]) > 0) {
2365 if (strcasecmp(argv
[0], "keychain") == 0) {
2366 CFDictionarySetValue(newConfiguration
, key
, kSCValNetVPNAuthPasswordEncryptionKeychain
);
2367 } else if (strcasecmp(argv
[0], "prompt") == 0) {
2368 CFDictionarySetValue(newConfiguration
, key
, kSCValNetVPNAuthPasswordEncryptionPrompt
);
2370 SCPrint(TRUE
, stdout
, CFSTR("invalid password type\n"));
2374 CFDictionaryRemoveValue(newConfiguration
, key
);
2377 // encryption type changed, reset password
2378 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetVPNAuthPassword
);
2384 static selections vpnAuthenticationMethodSelections
[] = {
2385 { CFSTR("Password") , &kSCValNetVPNAuthenticationMethodPassword
, 0 },
2386 { CFSTR("Certificate") , &kSCValNetVPNAuthenticationMethodCertificate
, 0 },
2391 static options vpnOptions
[] = {
2392 { "AuthName" , "account" , isString
, &kSCPropNetVPNAuthName
, NULL
, NULL
},
2393 { "Account" , "account" , isString
, &kSCPropNetVPNAuthName
, NULL
, NULL
},
2394 { "AuthPassword" , "password" , isOther
, &kSCPropNetVPNAuthPassword
, __doVPNAuthPW
, NULL
},
2395 { "Password" , "password" , isOther
, &kSCPropNetVPNAuthPassword
, __doVPNAuthPW
, NULL
},
2396 { "AuthPasswordEncryption" , "type" , isOther
, &kSCPropNetVPNAuthPasswordEncryption
, __doVPNAuthPWType
, NULL
},
2397 { "AuthenticationMethod" , NULL
, isChooseOne
, &kSCPropNetVPNAuthenticationMethod
, NULL
, (void *)vpnAuthenticationMethodSelections
},
2398 { "ConnectTime" , "?time" , isNumber
, &kSCPropNetVPNConnectTime
, NULL
, NULL
},
2399 { "DisconnectOnFastUserSwitch", NULL
, isBoolean
, &kSCPropNetVPNDisconnectOnFastUserSwitch
, NULL
, NULL
},
2400 { "DisconnectOnIdle" , NULL
, isBoolean
, &kSCPropNetVPNDisconnectOnIdle
, NULL
, NULL
},
2401 { "DisconnectOnIdleTimer" , "timeout" , isNumber
, &kSCPropNetVPNDisconnectOnIdleTimer
, NULL
, NULL
},
2402 { "DisconnectOnLogout" , NULL
, isBoolean
, &kSCPropNetVPNDisconnectOnLogout
, NULL
, NULL
},
2403 { "DisconnectOnSleep" , NULL
, isBoolean
, &kSCPropNetVPNDisconnectOnSleep
, NULL
, NULL
},
2404 { "Logfile" , "path" , isString
, &kSCPropNetVPNLogfile
, NULL
, NULL
},
2405 { "MTU" , NULL
, isNumber
, &kSCPropNetVPNMTU
, NULL
, NULL
},
2406 { "RemoteAddress" , "server" , isString
, &kSCPropNetVPNRemoteAddress
, NULL
, NULL
},
2407 { "Server" , "server" , isString
, &kSCPropNetVPNRemoteAddress
, NULL
, NULL
},
2408 { "VerboseLogging" , NULL
, isBoolean
, &kSCPropNetVPNVerboseLogging
, NULL
, NULL
},
2411 { "?" , NULL
, isHelp
, NULL
, NULL
,
2412 "\nVPN configuration commands\n\n"
2413 " set interface [Server server]\n"
2414 " set interface [Account account]\n"
2415 " set interface [Password password]\n"
2418 #define N_VPN_OPTIONS (sizeof(vpnOptions) / sizeof(vpnOptions[0]))
2422 set_interface_vpn(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2426 ok
= _process_options(vpnOptions
, N_VPN_OPTIONS
, argc
, argv
, newConfiguration
);
2432 #pragma mark [more] Interface management
2437 set_interface(int argc
, char **argv
)
2439 CFDictionaryRef configuration
;
2440 CFStringRef interfaceType
;
2441 CFMutableDictionaryRef newConfiguration
= NULL
;
2444 if (net_interface
== NULL
) {
2445 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
2450 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
2454 configuration
= SCNetworkInterfaceGetConfiguration(net_interface
);
2455 if (configuration
!= NULL
) {
2456 configuration
= CFDictionaryCreateCopy(NULL
, configuration
);
2457 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
2458 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
2460 newConfiguration
= CFDictionaryCreateMutable(NULL
,
2462 &kCFTypeDictionaryKeyCallBacks
,
2463 &kCFTypeDictionaryValueCallBacks
);
2466 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
2468 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeEthernet
)) {
2469 ok
= set_interface_ethernet(argc
, argv
, newConfiguration
);
2470 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeFireWire
)) {
2471 ok
= set_interface_firewire(argc
, argv
, newConfiguration
);
2472 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
2473 ok
= set_interface_ipsec(argc
, argv
, newConfiguration
);
2474 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeModem
)) {
2475 ok
= set_interface_modem(argc
, argv
, newConfiguration
);
2476 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIEEE80211
)) {
2477 ok
= set_interface_airport(argc
, argv
, newConfiguration
);
2478 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2479 ok
= set_interface_ppp(argc
, argv
, newConfiguration
);
2480 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
2481 ok
= set_interface_bond(argc
, argv
, newConfiguration
);
2482 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
2483 ok
= set_interface_bridge(argc
, argv
, newConfiguration
);
2484 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
2485 ok
= set_interface_vlan(argc
, argv
, newConfiguration
);
2486 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
2487 ok
= set_interface_vpn(argc
, argv
, newConfiguration
);
2489 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
2496 if (((configuration
== NULL
) && (CFDictionaryGetCount(newConfiguration
) > 0)) ||
2497 ((configuration
!= NULL
) && !CFEqual(configuration
, newConfiguration
))) {
2498 if (!SCNetworkInterfaceSetConfiguration(net_interface
, newConfiguration
)) {
2499 if (SCError() == kSCStatusNoKey
) {
2500 SCPrint(TRUE
, stdout
, CFSTR("could not update per-service interface configuration\n"));
2502 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
2507 _prefs_changed
= TRUE
;
2512 if (configuration
!= NULL
) CFRelease(configuration
);
2513 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
2518 /* -------------------- */
2523 show_interface(int argc
, char **argv
)
2525 SCNetworkInterfaceRef interface
;
2528 interface
= _find_interface(argc
, argv
, NULL
);
2530 if (net_interface
!= NULL
) {
2531 interface
= net_interface
;
2533 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
2538 if (interface
!= NULL
) {
2539 _show_interface(interface
, CFSTR(""), TRUE
);
2546 /* -------------------- */
2550 CF_RETURNS_RETAINED CFStringRef
2551 _interface_description(SCNetworkInterfaceRef interface
)
2553 CFMutableStringRef description
;
2554 CFStringRef if_bsd_name
;
2555 CFStringRef if_type
;
2557 description
= CFStringCreateMutable(NULL
, 0);
2559 if_type
= SCNetworkInterfaceGetInterfaceType(interface
);
2560 CFStringAppend(description
, if_type
);
2562 if_bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
2563 if (if_bsd_name
!= NULL
) {
2564 CFStringAppendFormat(description
, NULL
, CFSTR(" (%@)"), if_bsd_name
);
2567 interface
= SCNetworkInterfaceGetInterface(interface
);
2568 while ((interface
!= NULL
) &&
2569 !CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
2570 CFStringRef childDescription
;
2572 childDescription
= _interface_description(interface
);
2573 CFStringAppendFormat(description
, NULL
, CFSTR(" / %@"), childDescription
);
2574 CFRelease(childDescription
);
2576 interface
= SCNetworkInterfaceGetInterface(interface
);