2 * Copyright (c) 2004-2011 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>
36 #include <SystemConfiguration/LinkConfiguration.h>
40 #pragma mark Interface management
46 CFMutableArrayRef interfaces
;
47 CFArrayRef real_interfaces
;
49 real_interfaces
= _SCNetworkInterfaceCopyAllWithPreferences(prefs
);
50 if (real_interfaces
== NULL
) {
51 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
55 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
57 // include real interfaces
58 CFArrayAppendArray(interfaces
,
60 CFRangeMake(0, CFArrayGetCount(real_interfaces
)));
61 CFRelease(real_interfaces
);
63 // include pseudo interfaces
64 CFArrayAppendValue(interfaces
, kSCNetworkInterfaceLoopback
);
65 CFArrayAppendValue(interfaces
, kSCNetworkInterfaceIPv4
);
67 // include interfaces that we have created
68 if (new_interfaces
!= NULL
) {
69 CFArrayAppendArray(interfaces
,
71 CFRangeMake(0, CFArrayGetCount(new_interfaces
)));
74 return (CFArrayRef
)interfaces
;
80 _find_interface(int argc
, char **argv
, int *nArgs
)
82 Boolean allowIndex
= TRUE
;
84 CFArrayRef myInterfaces
= interfaces
;
86 CFStringRef select_name
= NULL
;
87 SCNetworkInterfaceRef selected
= NULL
;
90 SCPrint(TRUE
, stdout
, CFSTR("no interface specified\n"));
94 if (nArgs
!= NULL
) *nArgs
= 1;
96 if (strcasecmp(argv
[0], "$child") == 0) {
97 if (net_interface
== NULL
) {
98 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
102 selected
= SCNetworkInterfaceGetInterface(net_interface
);
103 if(selected
== NULL
) {
104 SCPrint(TRUE
, stdout
, CFSTR("no child interface\n"));
108 } else if (strcasecmp(argv
[0], "$service") == 0) {
109 if (net_service
== NULL
) {
110 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
114 selected
= SCNetworkServiceGetInterface(net_service
);
115 if(selected
== NULL
) {
116 SCPrint(TRUE
, stdout
, CFSTR("no interface for service\n"));
122 else if (strcasecmp(argv
[0], "$bond") == 0) {
123 CFStringRef interfaceType
;
125 if (net_interface
== NULL
) {
126 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
130 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
131 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
132 SCPrint(TRUE
, stdout
, CFSTR("interface not Bond\n"));
137 SCPrint(TRUE
, stdout
, CFSTR("no member interface specified\n"));
142 if (nArgs
!= NULL
) *nArgs
+= 1;
144 myInterfaces
= SCBondInterfaceGetMemberInterfaces(net_interface
);
145 if (myInterfaces
== NULL
) {
146 SCPrint(TRUE
, stdout
, CFSTR("no member interfaces\n"));
152 else if (strcasecmp(argv
[0], "$bridge") == 0) {
153 CFStringRef interfaceType
;
155 if (net_interface
== NULL
) {
156 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
160 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
161 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
162 SCPrint(TRUE
, stdout
, CFSTR("interface not Bridge\n"));
167 SCPrint(TRUE
, stdout
, CFSTR("no member interface specified\n"));
172 if (nArgs
!= NULL
) *nArgs
+= 1;
174 myInterfaces
= SCBridgeInterfaceGetMemberInterfaces(net_interface
);
175 if (myInterfaces
== NULL
) {
176 SCPrint(TRUE
, stdout
, CFSTR("no member interfaces\n"));
182 else if (strcasecmp(argv
[0], "$vlan") == 0) {
183 CFStringRef interfaceType
;
185 if (net_interface
== NULL
) {
186 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
190 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
191 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
192 SCPrint(TRUE
, stdout
, CFSTR("interface not VLAN\n"));
196 selected
= SCVLANInterfaceGetPhysicalInterface(net_interface
);
197 if(selected
== NULL
) {
198 SCPrint(TRUE
, stdout
, CFSTR("no physical interface\n"));
204 if ((myInterfaces
== NULL
) && (interfaces
== NULL
)) {
205 interfaces
= _copy_interfaces();
206 if (interfaces
== NULL
) {
209 myInterfaces
= interfaces
;
213 // try to select the interface by its display name
215 select_name
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
217 n
= (myInterfaces
!= NULL
) ? CFArrayGetCount(myInterfaces
) : 0;
218 for (i
= 0; i
< n
; i
++) {
219 SCNetworkInterfaceRef interface
;
220 CFStringRef interfaceName
;
222 interface
= CFArrayGetValueAtIndex(myInterfaces
, i
);
223 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
224 if ((interfaceName
!= NULL
) && CFEqual(select_name
, interfaceName
)) {
225 if (selected
== NULL
) {
226 selected
= interface
;
228 // if multiple interfaces match
230 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
236 if (selected
!= NULL
) {
240 // try to select the interface by its BSD name
242 for (i
= 0; i
< n
; i
++) {
243 SCNetworkInterfaceRef interface
;
244 CFStringRef bsd_name
= NULL
;
246 interface
= CFArrayGetValueAtIndex(myInterfaces
, i
);
247 while ((interface
!= NULL
) && (bsd_name
== NULL
)) {
248 bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
249 if (bsd_name
== NULL
) {
250 interface
= SCNetworkInterfaceGetInterface(interface
);
254 if ((bsd_name
!= NULL
) && CFEqual(select_name
, bsd_name
)) {
255 if (selected
== NULL
) {
256 selected
= interface
;
258 // if multiple interfaces match
260 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
266 if (selected
!= NULL
) {
270 // try to select the interface by its interface type
272 for (i
= 0; i
< n
; i
++) {
273 SCNetworkInterfaceRef interface
;
274 CFStringRef interfaceType
;
276 interface
= CFArrayGetValueAtIndex(myInterfaces
, i
);
277 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
278 if (CFEqual(select_name
, interfaceType
)) {
279 if (selected
== NULL
) {
280 selected
= interface
;
282 // if multiple interfaces match
284 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
290 if (selected
!= NULL
) {
299 // try to select the interface by its index
302 val
= strtol(str
, &end
, 10);
303 if ((*str
!= '\0') &&
304 ((*end
== '\0') || (*end
== '.')) &&
306 if ((val
> 0) && (val
<= n
)) {
307 selected
= CFArrayGetValueAtIndex(myInterfaces
, val
- 1);
311 val
= strtol(str
, &end
, 10);
312 if ((*str
!= '\0') && (*end
== '\0') && (errno
== 0)) {
314 selected
= SCNetworkInterfaceGetInterface(selected
);
315 if (selected
== NULL
) {
325 if (selected
!= NULL
) {
329 SCPrint(TRUE
, stdout
, CFSTR("no match\n"));
333 if (select_name
!= NULL
) CFRelease(select_name
);
338 /* -------------------- */
343 create_interface(int argc
, char **argv
)
345 SCNetworkInterfaceRef interface
;
346 CFStringRef interfaceName
;
347 CFStringRef interfaceType
;
348 SCNetworkInterfaceRef new_interface
;
351 SCPrint(TRUE
, stdout
, CFSTR("what interface type?\n"));
355 interfaceType
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
359 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
360 SCPrint(TRUE
, stdout
, CFSTR("bond creation not yet supported\n"));
363 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
364 SCPrint(TRUE
, stdout
, CFSTR("bridge creation not yet supported\n"));
367 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
368 SCPrint(TRUE
, stdout
, CFSTR("vlan creation not yet supported\n"));
373 if (net_interface
== NULL
) {
374 SCPrint(TRUE
, stdout
, CFSTR("no network interface selected\n"));
378 interface
= net_interface
;
380 interface
= _find_interface(argc
, argv
, NULL
);
383 if (interface
== NULL
) {
387 new_interface
= SCNetworkInterfaceCreateWithInterface(interface
, interfaceType
);
388 if (new_interface
== NULL
) {
389 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
393 if (new_interfaces
== NULL
) {
394 new_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
396 CFArrayAppendValue(new_interfaces
, new_interface
);
398 if (net_interface
!= NULL
) CFRelease(net_interface
);
399 net_interface
= new_interface
;
401 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(net_interface
);
402 if (interfaceName
== NULL
) {
403 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
405 if (interfaceName
== NULL
) {
406 interfaceName
= SCNetworkInterfaceGetInterfaceType(net_interface
);
408 SCPrint(TRUE
, stdout
, CFSTR("interface \"%@\" created and selected\n"), interfaceName
);
412 CFRelease(interfaceType
);
417 /* -------------------- */
422 select_interface(int argc
, char **argv
)
424 SCNetworkInterfaceRef interface
;
426 interface
= _find_interface(argc
, argv
, NULL
);
427 if (interface
!= NULL
) {
428 CFStringRef interfaceName
;
430 if (net_interface
!= NULL
) CFRelease(net_interface
);
431 net_interface
= CFRetain(interface
);
433 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
434 if (interfaceName
== NULL
) {
435 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
437 if (interfaceName
== NULL
) {
438 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
441 SCPrint(TRUE
, stdout
, CFSTR("interface \"%@\" selected\n"), interfaceName
);
448 /* -------------------- */
453 _show_interface(SCNetworkInterfaceRef interface
, CFStringRef prefix
, Boolean showChild
)
455 CFDictionaryRef configuration
;
456 CFStringRef if_bsd_name
;
457 CFStringRef if_localized_name
;
458 CFStringRef if_mac_address
;
460 CFArrayRef supported
;
462 if_localized_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
463 if (if_localized_name
!= NULL
) {
464 SCPrint(TRUE
, stdout
, CFSTR("%@ name = %@\n"), prefix
, if_localized_name
);
467 if_bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
468 if (if_bsd_name
!= NULL
) {
469 SCPrint(TRUE
, stdout
, CFSTR("%@ interface name = %@\n"), prefix
, if_bsd_name
);
472 if_type
= SCNetworkInterfaceGetInterfaceType(interface
);
473 SCPrint(TRUE
, stdout
, CFSTR("%@ type = %@\n"), prefix
, if_type
);
475 if_mac_address
= SCNetworkInterfaceGetHardwareAddressString(interface
);
476 if (if_mac_address
!= NULL
) {
477 SCPrint(TRUE
, stdout
, CFSTR("%@ address = %@\n"), prefix
, if_mac_address
);
480 configuration
= SCNetworkInterfaceGetConfiguration(interface
);
481 if ((configuration
!= NULL
) &&
482 CFDictionaryContainsKey(configuration
, kSCResvInactive
)) {
483 configuration
= NULL
;
486 if (if_bsd_name
!= NULL
) {
487 CFArrayRef available
;
488 CFDictionaryRef active
;
489 CFDictionaryRef cap_current
;
494 cap_current
= SCNetworkInterfaceCopyCapability(interface
, NULL
);
495 if (cap_current
!= NULL
) {
497 CFArrayRef cap_names
;
498 CFMutableArrayRef cap_sorted
;
502 n
= CFDictionaryGetCount(cap_current
);
503 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFStringRef
), 0);
504 CFDictionaryGetKeysAndValues(cap_current
, keys
, NULL
);
505 cap_names
= CFArrayCreate(NULL
, keys
, n
, &kCFTypeArrayCallBacks
);
506 CFAllocatorDeallocate(NULL
, keys
);
508 cap_sorted
= CFArrayCreateMutableCopy(NULL
, 0, cap_names
);
509 CFRelease(cap_names
);
511 CFArraySortValues(cap_sorted
, CFRangeMake(0, n
), (CFComparatorFunction
)CFStringCompare
, NULL
);
513 SCPrint(TRUE
, stdout
, CFSTR("%@ capabilities = "), prefix
);
514 for (i
= 0; i
< n
; i
++) {
515 CFStringRef cap_name
;
517 CFNumberRef val
= NULL
;
519 cap_name
= CFArrayGetValueAtIndex(cap_sorted
, i
);
520 if (configuration
!= NULL
) {
521 val
= CFDictionaryGetValue(configuration
, cap_name
);
523 if (!isA_CFNumber(val
)) {
524 val
= CFDictionaryGetValue(cap_current
, cap_name
);
527 SCPrint(TRUE
, stdout
, CFSTR("%s%@%c"),
530 (CFNumberGetValue(val
, kCFNumberIntType
, &cap_val
) &&
531 (cap_val
!= 0)) ? '+' : '-');
533 SCPrint(TRUE
, stdout
, CFSTR("\n"));
535 CFRelease(cap_sorted
);
536 CFRelease(cap_current
);
539 if (SCNetworkInterfaceCopyMTU(interface
, &mtu_cur
, &mtu_min
, &mtu_max
)) {
540 char isCurrent
= '*';
542 if (configuration
!= NULL
) {
546 num
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMTU
);
547 if (isA_CFNumber(num
)) {
548 CFNumberGetValue(num
, kCFNumberIntType
, &mtu_req
);
549 if (mtu_cur
!= mtu_req
) {
556 SCPrint(TRUE
, stdout
, CFSTR("%@ mtu %c = %d (%d < n < %d)\n"),
564 if (SCNetworkInterfaceCopyMediaOptions(interface
, NULL
, &active
, &available
, TRUE
)) {
565 char isCurrent
= ' ';
566 CFArrayRef options
= NULL
;
567 CFArrayRef options_req
= NULL
;
568 CFStringRef subtype
= NULL
;
569 CFStringRef subtype_req
= NULL
;
571 if (configuration
!= NULL
) {
572 subtype_req
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMediaSubType
);
573 options_req
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMediaOptions
);
576 if (subtype_req
== NULL
) {
577 subtype_req
= CFSTR("autoselect");
580 if (active
!= NULL
) {
581 subtype
= CFDictionaryGetValue(active
, kSCPropNetEthernetMediaSubType
);
582 options
= CFDictionaryGetValue(active
, kSCPropNetEthernetMediaOptions
);
585 if (subtype
!= NULL
) {
586 if (((subtype_req
!= NULL
) &&
587 CFEqual(subtype
, subtype_req
)) &&
588 ((options
== options_req
) ||
589 ((options
!= NULL
) &&
590 (options_req
!= NULL
) &&
591 CFEqual(options
, options_req
)))
594 } else if ((subtype_req
== NULL
) ||
595 ((subtype_req
!= NULL
) &&
596 CFEqual(subtype_req
, CFSTR("autoselect")))) {
597 // if requested subtype not specified or "autoselect"
602 if (subtype_req
!= NULL
) {
603 SCPrint(TRUE
, stdout
, CFSTR("%@ media %c = %@"),
608 if ((options_req
!= NULL
) &&
609 (CFArrayGetCount(options_req
) > 0)) {
610 CFStringRef options_str
;
612 options_str
= CFStringCreateByCombiningStrings(NULL
, options_req
, CFSTR(","));
613 SCPrint(TRUE
, stdout
, CFSTR(" <%@>"), options_str
);
614 CFRelease(options_str
);
617 SCPrint(TRUE
, stdout
, CFSTR("\n"));
620 SCPrint(TRUE
, stdout
, CFSTR("\n"));
622 if (available
!= NULL
) {
627 subtypes
= SCNetworkInterfaceCopyMediaSubTypes(available
);
628 n_subtypes
= (subtypes
!= NULL
) ? CFArrayGetCount(subtypes
) : 0;
629 for (i
= 0; i
< n_subtypes
; i
++) {
631 CFIndex n_subtype_options
;
633 CFArrayRef subtype_options
;
635 subtype
= CFArrayGetValueAtIndex(subtypes
, i
);
636 subtype_options
= SCNetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
637 n_subtype_options
= (subtype_options
!= NULL
) ? CFArrayGetCount(subtype_options
) : 0;
638 for (j
= 0; j
< n_subtype_options
; j
++) {
639 char isCurrent
= ' ';
642 options
= CFArrayGetValueAtIndex(subtype_options
, j
);
644 if (((subtype_req
!= NULL
) &&
645 CFEqual(subtype
, subtype_req
)) &&
646 ((options
== options_req
) ||
647 ((options
!= NULL
) &&
648 (options_req
!= NULL
) &&
649 CFEqual(options
, options_req
)))
654 SCPrint(TRUE
, stdout
, CFSTR("%@ %s %c = %@"),
656 ((i
== 0) && (j
== 0)) ? "supported media" : " ",
660 if ((options
!= NULL
) &&
661 (CFArrayGetCount(options
) > 0)) {
662 CFStringRef options_str
;
664 options_str
= CFStringCreateByCombiningStrings(NULL
, options
, CFSTR(","));
665 SCPrint(TRUE
, stdout
, CFSTR(" <%@>"), options_str
);
666 CFRelease(options_str
);
669 SCPrint(TRUE
, stdout
, CFSTR("\n"));
671 if (subtype_options
!= NULL
) CFRelease(subtype_options
);
673 if (subtypes
!= NULL
) CFRelease(subtypes
);
676 SCPrint(TRUE
, stdout
, CFSTR("\n"));
680 supported
= SCNetworkInterfaceGetSupportedInterfaceTypes(interface
);
681 SCPrint(TRUE
, stdout
, CFSTR("%@ supported interfaces = "), prefix
);
682 if (supported
!= NULL
) {
684 CFIndex n
= CFArrayGetCount(supported
);
686 for (i
= 0; i
< n
; i
++) {
687 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
688 (i
== 0) ? "" : ", ",
689 CFArrayGetValueAtIndex(supported
, i
));
692 SCPrint(TRUE
, stdout
, CFSTR("\n"));
694 supported
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
);
695 SCPrint(TRUE
, stdout
, CFSTR("%@ supported protocols = "), prefix
);
696 if (supported
!= NULL
) {
698 CFIndex n
= CFArrayGetCount(supported
);
700 for (i
= 0; i
< n
; i
++) {
701 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
702 (i
== 0) ? "" : ", ",
703 CFArrayGetValueAtIndex(supported
, i
));
706 SCPrint(TRUE
, stdout
, CFSTR("\n"));
708 if (configuration
!= NULL
) {
709 CFMutableDictionaryRef effective
;
711 effective
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
713 // remove known (and already reported) interface configuration keys
714 if (CFDictionaryContainsKey(effective
, kSCResvInactive
)) {
715 CFDictionaryRemoveAllValues(effective
);
717 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMTU
);
718 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMediaSubType
);
719 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMediaOptions
);
721 if (CFDictionaryGetCount(effective
) > 0) {
722 SCPrint(TRUE
, stdout
, CFSTR("\n%@ per-interface configuration\n"), prefix
);
723 _show_entity(effective
, prefix
);
726 CFRelease(effective
);
729 if (CFEqual(if_type
, kSCNetworkInterfaceTypePPP
)) {
730 SCNetworkInterfaceRef childInterface
;
732 childInterface
= SCNetworkInterfaceGetInterface(interface
);
733 if (childInterface
!= NULL
) {
734 CFStringRef childInterfaceType
;
736 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
737 if (CFEqual(childInterfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
738 CFDictionaryRef ipsec_configuration
;
740 ipsec_configuration
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
741 if (isA_CFDictionary(ipsec_configuration
) &&
742 (CFDictionaryGetCount(ipsec_configuration
) > 0)) {
743 SCPrint(TRUE
, stdout
, CFSTR("\n%@ per-interface IPSec configuration\n"), prefix
);
744 _show_entity(ipsec_configuration
, prefix
);
751 SCPrint(TRUE
, stdout
, CFSTR("\n%@\n"), interface
);
754 interface
= SCNetworkInterfaceGetInterface(interface
);
755 if (interface
!= NULL
) {
756 CFStringRef newPrefix
;
758 newPrefix
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@ "), prefix
);
759 SCPrint(TRUE
, stdout
, CFSTR("\n%@child interface\n"), newPrefix
);
760 _show_interface(interface
, newPrefix
, showChild
);
761 CFRelease(newPrefix
);
768 /* -------------------- */
772 validateMediaOptions(SCNetworkInterfaceRef interface
, CFMutableDictionaryRef newConfiguration
)
779 mtu
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMTU
);
780 if (isA_CFNumber(mtu
)) {
785 if (!SCNetworkInterfaceCopyMTU(interface
, NULL
, &mtu_min
, &mtu_max
)) {
786 SCPrint(TRUE
, stdout
, CFSTR("cannot set MTU\n"));
790 if (!CFNumberGetValue(mtu
, kCFNumberIntType
, &mtu_val
) ||
791 (mtu_val
< mtu_min
) ||
792 (mtu_val
> mtu_max
)) {
793 SCPrint(TRUE
, stdout
, CFSTR("mtu out of range\n"));
798 subtype
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMediaSubType
);
799 options
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMediaOptions
);
801 if (subtype
!= NULL
) {
802 CFArrayRef available
= NULL
;
803 CFArrayRef config_options
= options
;
804 CFArrayRef subtypes
= NULL
;
805 CFArrayRef subtype_options
= NULL
;
809 if (options
== NULL
) {
810 config_options
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
813 if (!SCNetworkInterfaceCopyMediaOptions(interface
, NULL
, NULL
, &available
, FALSE
)) {
814 SCPrint(TRUE
, stdout
, CFSTR("media type / options not available\n"));
818 if (available
== NULL
) {
822 subtypes
= SCNetworkInterfaceCopyMediaSubTypes(available
);
823 if ((subtypes
== NULL
) ||
824 !CFArrayContainsValue(subtypes
,
825 CFRangeMake(0, CFArrayGetCount(subtypes
)),
827 SCPrint(TRUE
, stdout
, CFSTR("media type not valid\n"));
831 subtype_options
= SCNetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
832 if ((subtype_options
== NULL
) ||
833 !CFArrayContainsValue(subtype_options
,
834 CFRangeMake(0, CFArrayGetCount(subtype_options
)),
836 SCPrint(TRUE
, stdout
, CFSTR("media options not valid for \"%@\"\n"), subtype
);
840 if (options
== NULL
) {
841 CFDictionarySetValue(newConfiguration
, kSCPropNetEthernetMediaOptions
, config_options
);
848 if (available
!= NULL
) CFRelease(available
);
849 if (subtypes
!= NULL
) CFRelease(subtypes
);
850 if (subtype_options
!= NULL
) CFRelease(subtype_options
);
851 if (options
== NULL
) CFRelease(config_options
);
853 if (options
!= NULL
) {
854 SCPrint(TRUE
, stdout
, CFSTR("media type and options must both be specified\n"));
863 /* -------------------- */
868 show_interfaces(int argc
, char **argv
)
873 if (interfaces
!= NULL
) CFRelease(interfaces
);
874 interfaces
= _copy_interfaces();
875 if (interfaces
== NULL
) {
879 n
= CFArrayGetCount(interfaces
);
880 for (i
= 0; i
< n
; i
++) {
881 CFIndex childIndex
= 0;
882 SCNetworkInterfaceRef interface
;
884 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
886 CFStringRef interfaceName
;
889 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
890 if (interfaceName
== NULL
) {
891 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
893 if (interfaceName
== NULL
) {
894 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
898 if ((net_interface
!= NULL
) && CFEqual(interface
, net_interface
)) {
902 if (childIndex
== 0) {
903 SCPrint(TRUE
, stdout
, CFSTR("%c%2d: %@\n"),
908 SCPrint(TRUE
, stdout
, CFSTR("%c%2d.%d: %@\n"),
915 interface
= SCNetworkInterfaceGetInterface(interface
);
917 } while (interface
!= NULL
);
924 /* -------------------- */
928 _replaceOne(const void *key
, const void *value
, void *context
)
930 CFMutableDictionaryRef newConfiguration
= (CFMutableDictionaryRef
)context
;
932 CFDictionarySetValue(newConfiguration
, key
, value
);
938 updateInterfaceConfiguration(CFMutableDictionaryRef newConfiguration
)
940 CFDictionaryRef configuration
;
942 CFDictionaryRemoveAllValues(newConfiguration
);
944 configuration
= SCNetworkInterfaceGetConfiguration(net_interface
);
945 if (configuration
!= NULL
) {
946 CFDictionaryApplyFunction(configuration
, _replaceOne
, (void *)newConfiguration
);
954 #pragma mark Bond options
957 static options bondOptions
[] = {
958 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
959 // xxx { "+device" , ... },
960 // xxx { "-device" , ... },
962 { "?" , NULL
, isHelp
, NULL
, NULL
,
963 "\nBond configuration commands\n\n"
964 " set interface [mtu n] [media type] [mediaopts opts]\n"
967 #define N_BOND_OPTIONS (sizeof(bondOptions) / sizeof(bondOptions[0]))
971 set_interface_bond(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
973 CFStringRef interfaceName
;
976 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
977 if (interfaceName
== NULL
) {
978 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
982 ok
= _process_options(bondOptions
, N_BOND_OPTIONS
, argc
, argv
, newConfiguration
);
984 // validate configuration
985 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
995 #pragma mark Bridge options
998 static options bridgeOptions
[] = {
999 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1000 // xxx { "+device" , ... },
1001 // xxx { "-device" , ... },
1003 { "?" , NULL
, isHelp
, NULL
, NULL
,
1004 "\nBridge configuration commands\n\n"
1005 " set interface [mtu n] [media type] [mediaopts opts]\n"
1008 #define N_BRIDGE_OPTIONS (sizeof(bridgeOptions) / sizeof(bridgeOptions[0]))
1012 set_interface_bridge(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1014 CFStringRef interfaceName
;
1017 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1018 if (interfaceName
== NULL
) {
1019 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1023 ok
= _process_options(bridgeOptions
, N_BRIDGE_OPTIONS
, argc
, argv
, newConfiguration
);
1025 // validate configuration
1026 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1036 #pragma mark AirPort options
1039 static options airportOptions
[] = {
1040 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1041 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
1042 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
1044 { "?" , NULL
, isHelp
, NULL
, NULL
,
1045 "\nAirPort configuration commands\n\n"
1046 " set interface [mtu n] [media type] [mediaopts opts]\n"
1049 #define N_AIRPORT_OPTIONS (sizeof(airportOptions) / sizeof(airportOptions[0]))
1053 set_interface_airport(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1055 CFStringRef interfaceName
;
1058 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1059 if (interfaceName
== NULL
) {
1060 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1064 ok
= _process_options(airportOptions
, N_AIRPORT_OPTIONS
, argc
, argv
, newConfiguration
);
1066 // validate configuration
1067 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1077 #pragma mark Ethernet options
1081 __doCapability(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1086 SCPrint(TRUE
, stdout
,
1087 CFSTR("%s not specified\n"),
1088 description
!= NULL
? description
: "enable/disable");
1092 if (strlen(argv
[0]) == 0) {
1093 ok
= SCNetworkInterfaceSetCapability(net_interface
, key
, NULL
);
1094 } else if ((strcasecmp(argv
[0], "disable") == 0) ||
1095 (strcasecmp(argv
[0], "no" ) == 0) ||
1096 (strcasecmp(argv
[0], "off" ) == 0) ||
1097 (strcasecmp(argv
[0], "0" ) == 0)) {
1098 ok
= SCNetworkInterfaceSetCapability(net_interface
, key
, CFNumberRef_0
);
1099 } else if ((strcasecmp(argv
[0], "enable") == 0) ||
1100 (strcasecmp(argv
[0], "yes" ) == 0) ||
1101 (strcasecmp(argv
[0], "on" ) == 0) ||
1102 (strcasecmp(argv
[0], "1" ) == 0)) {
1103 ok
= SCNetworkInterfaceSetCapability(net_interface
, key
, CFNumberRef_1
);
1105 SCPrint(TRUE
, stdout
, CFSTR("invalid value\n"));
1110 updateInterfaceConfiguration(newConfiguration
);
1112 SCPrint(TRUE
, stdout
,
1113 CFSTR("%@ not updated: %s\n"),
1115 SCErrorString(SCError()));
1123 static options ethernetOptions
[] = {
1124 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1125 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
1126 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
1128 { "av" , NULL
, isOther
, &kSCPropNetEthernetCapabilityAV
, __doCapability
, NULL
},
1129 { "lro" , NULL
, isOther
, &kSCPropNetEthernetCapabilityLRO
, __doCapability
, NULL
},
1130 { "rxcsum" , NULL
, isOther
, &kSCPropNetEthernetCapabilityRXCSUM
, __doCapability
, NULL
},
1131 { "tso" , NULL
, isOther
, &kSCPropNetEthernetCapabilityTSO
, __doCapability
, NULL
},
1132 { "txcsum" , NULL
, isOther
, &kSCPropNetEthernetCapabilityTXCSUM
, __doCapability
, NULL
},
1134 { "?" , NULL
, isHelp
, NULL
, NULL
,
1135 "\nEthernet configuration commands\n\n"
1136 " set interface [mtu n] [media type] [mediaopts opts]\n"
1139 #define N_ETHERNET_OPTIONS (sizeof(ethernetOptions) / sizeof(ethernetOptions[0]))
1143 set_interface_ethernet(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1145 CFStringRef interfaceName
;
1148 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1149 if (interfaceName
== NULL
) {
1150 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1154 ok
= _process_options(ethernetOptions
, N_ETHERNET_OPTIONS
, argc
, argv
, newConfiguration
);
1156 // validate configuration
1157 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1167 #pragma mark IPSec options
1171 __doIPSecSharedSecret(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1173 CFStringRef encryptionType
;
1176 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret not specified\n"));
1180 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetIPSecSharedSecretEncryption
);
1181 if (strlen(argv
[0]) > 0) {
1182 if (encryptionType
== NULL
) {
1184 CFMutableDataRef pw
;
1187 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1188 n
= CFStringGetLength(str
);
1189 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
1190 CFDataSetLength(pw
, n
* sizeof(UniChar
));
1191 CFStringGetCharacters(str
,
1193 (UniChar
*)CFDataGetMutableBytePtr(pw
));
1196 CFDictionarySetValue(newConfiguration
, key
, pw
);
1198 } else if (CFEqual(encryptionType
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1203 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1204 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
1205 ok
= SCNetworkInterfaceSetPassword(net_interface
,
1206 kSCNetworkInterfacePasswordTypeIPSecSharedSecret
,
1212 updateInterfaceConfiguration(newConfiguration
);
1217 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret type \"%@\" not supported\n"), encryptionType
);
1221 if (encryptionType
== NULL
) {
1222 CFDictionaryRemoveValue(newConfiguration
, key
);
1223 } else if (CFEqual(encryptionType
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1225 ok
= SCNetworkInterfaceRemovePassword(net_interface
, kSCNetworkInterfacePasswordTypeIPSecSharedSecret
);
1227 updateInterfaceConfiguration(newConfiguration
);
1232 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret type \"%@\" not supported\n"), encryptionType
);
1242 __doIPSecSharedSecretType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1245 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret type mode not specified\n"));
1249 if (strlen(argv
[0]) > 0) {
1250 if (strcasecmp(argv
[0], "keychain") == 0) {
1251 CFDictionarySetValue(newConfiguration
, key
, kSCValNetIPSecSharedSecretEncryptionKeychain
);
1253 SCPrint(TRUE
, stdout
, CFSTR("invalid shared secret type\n"));
1257 CFDictionaryRemoveValue(newConfiguration
, key
);
1260 // encryption type changed, reset shared secret
1261 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPSecSharedSecret
);
1268 __doIPSecXAuthPassword(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1270 CFStringRef encryptionType
;
1273 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuth password not specified\n"));
1277 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetIPSecXAuthPasswordEncryption
);
1278 if (strlen(argv
[0]) > 0) {
1279 if (encryptionType
== NULL
) {
1281 CFMutableDataRef pw
;
1284 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1285 n
= CFStringGetLength(str
);
1286 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
1287 CFDataSetLength(pw
, n
* sizeof(UniChar
));
1288 CFStringGetCharacters(str
,
1290 (UniChar
*)CFDataGetMutableBytePtr(pw
));
1293 CFDictionarySetValue(newConfiguration
, key
, pw
);
1295 } else if (CFEqual(encryptionType
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
1300 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1301 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
1302 ok
= SCNetworkInterfaceSetPassword(net_interface
,
1303 kSCNetworkInterfacePasswordTypeIPSecXAuth
,
1309 updateInterfaceConfiguration(newConfiguration
);
1314 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuthPassword type \"%@\" not supported\n"), encryptionType
);
1318 if (encryptionType
== NULL
) {
1319 CFDictionaryRemoveValue(newConfiguration
, key
);
1320 } else if (CFEqual(encryptionType
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
1323 ok
= SCNetworkInterfaceRemovePassword(net_interface
, kSCNetworkInterfacePasswordTypeIPSecXAuth
);
1325 updateInterfaceConfiguration(newConfiguration
);
1330 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuthPassword type \"%@\" not supported\n"), encryptionType
);
1340 __doIPSecXAuthPasswordType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1343 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuth password type mode not specified\n"));
1347 if (strlen(argv
[0]) > 0) {
1348 if (strcasecmp(argv
[0], "keychain") == 0) {
1349 CFDictionarySetValue(newConfiguration
, key
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
1351 SCPrint(TRUE
, stdout
, CFSTR("invalid XAuth password type\n"));
1355 CFDictionaryRemoveValue(newConfiguration
, key
);
1358 // encryption type changed, reset XAuthPassword
1359 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPSecXAuthPassword
);
1366 __cleanupDomainName(CFStringRef domain
)
1368 CFMutableStringRef newDomain
;
1370 newDomain
= CFStringCreateMutableCopy(NULL
, 0, domain
);
1371 CFStringTrimWhitespace(newDomain
);
1372 CFStringTrim(newDomain
, CFSTR("."));
1373 if (CFStringGetLength(newDomain
) == 0) {
1374 CFRelease(newDomain
);
1383 __doOnDemandDomains(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1385 CFMutableArrayRef domains
;
1388 SCPrint(TRUE
, stdout
, CFSTR("OnDemand domain name(s) not specified\n"));
1392 domains
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1394 if (strlen(argv
[0]) > 0) {
1398 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1399 array
= CFStringCreateArrayBySeparatingStrings(NULL
, str
, CFSTR(","));
1402 if (array
!= NULL
) {
1404 CFIndex n
= CFArrayGetCount(array
);
1406 for (i
= 0; i
< n
; i
++) {
1409 domain
= __cleanupDomainName(CFArrayGetValueAtIndex(array
, i
));
1410 if (domain
!= NULL
) {
1411 CFArrayAppendValue(domains
, domain
);
1416 SCPrint(TRUE
, stdout
, CFSTR("invalid OnDemand domain name\n"));
1424 if (CFArrayGetCount(domains
) > 0) {
1425 CFDictionarySetValue(newConfiguration
, key
, domains
);
1427 CFDictionaryRemoveValue(newConfiguration
, key
);
1435 static options ipsecOnDemandOptions
[] = {
1436 { "OnDemandMatchDomainsAlways" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1437 { "always" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1438 { "OnDemandMatchDomainsOnRetry", "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1439 { "retry" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1440 { "OnDemandMatchDomainsNever" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1441 { "never" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1443 { "?" , NULL
, isHelp
, NULL
, NULL
,
1444 "\nOnDemandMatch configuration commands\n\n"
1445 " set interface OnDemandMatch always domain-name[,domain-name]\n"
1446 " set interface OnDemandMatch retry domain-name[,domain-name]\n"
1447 " set interface OnDemandMatch never domain-name[,domain-name]\n"
1450 #define N_IPSEC_ONDEMAND_OPTIONS (sizeof(ipsecOnDemandOptions) / sizeof(ipsecOnDemandOptions[0]))
1454 __doIPSecOnDemandMatch(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1459 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1463 ok
= _process_options(ipsecOnDemandOptions
, N_IPSEC_ONDEMAND_OPTIONS
, argc
, argv
, newConfiguration
);
1474 static selections ipsecAuthenticationMethodSelections
[] = {
1475 { CFSTR("SharedSecret"), &kSCValNetIPSecAuthenticationMethodSharedSecret
, 0 },
1476 { CFSTR("Certificate") , &kSCValNetIPSecAuthenticationMethodCertificate
, 0 },
1477 { CFSTR("Hybrid") , &kSCValNetIPSecAuthenticationMethodHybrid
, 0 },
1482 static selections ipsecLocalIdentifierTypeSelections
[] = {
1483 { CFSTR("KeyID") , &kSCValNetIPSecLocalIdentifierTypeKeyID
, 0 },
1488 static options ipsecOptions
[] = {
1489 { "AuthenticationMethod" , NULL
, isChooseOne
, &kSCPropNetIPSecAuthenticationMethod
, NULL
, (void *)ipsecAuthenticationMethodSelections
},
1490 { "LocalIdentifier" , NULL
, isString
, &kSCPropNetIPSecLocalIdentifier
, NULL
, NULL
},
1491 { "group" , NULL
, isString
, &kSCPropNetIPSecLocalIdentifier
, NULL
, NULL
},
1492 { "LocalIdentifierType" , NULL
, isChooseOne
, &kSCPropNetIPSecLocalIdentifierType
, NULL
, (void *)ipsecLocalIdentifierTypeSelections
},
1493 { "RemoteAddress" , NULL
, isString
, &kSCPropNetIPSecRemoteAddress
, NULL
, NULL
},
1494 { "SharedSecret" , NULL
, isOther
, &kSCPropNetIPSecSharedSecret
, __doIPSecSharedSecret
, NULL
},
1495 { "SharedSecretEncryption" , NULL
, isOther
, &kSCPropNetIPSecSharedSecretEncryption
, __doIPSecSharedSecretType
, NULL
},
1498 { "XAuthEnabled" , NULL
, isBoolean
, &kSCPropNetIPSecXAuthEnabled
, NULL
, NULL
},
1499 { "XAuthName" , NULL
, isString
, &kSCPropNetIPSecXAuthName
, NULL
, NULL
},
1500 { "XAuthPassword" , NULL
, isOther
, &kSCPropNetIPSecXAuthPassword
, __doIPSecXAuthPassword
, NULL
},
1501 { "XAuthPasswordEncryption", NULL
, isOther
, &kSCPropNetIPSecXAuthPasswordEncryption
, __doIPSecXAuthPasswordType
, NULL
},
1503 // --- OnDemand: ---
1504 { "OnDemandEnabled" , NULL
, isBoolean
, &kSCPropNetIPSecOnDemandEnabled
, NULL
, NULL
},
1505 { "OnDemandMatch" , NULL
, isOther
, NULL
, __doIPSecOnDemandMatch
, NULL
},
1507 { "?" , NULL
, isHelp
, NULL
, NULL
,
1508 "\nIPSec configuration commands\n\n"
1509 " set interface [AuthenticationMethod {SharedSecret|Certificate|Hybrid}]\n"
1510 " set interface [LocalIdentifier group]\n"
1511 " set interface [LocalIdentifierType {KeyID}]\n"
1512 " set interface [RemoteAddress name-or-address]\n"
1513 " set interface [SharedSecret secret]\n"
1514 " set interface [SharedSecretEncryption {Keychain}]\n"
1515 " set interface [XAuthEnabled {enable|disable}]\n"
1516 " set interface [XAuthPassword password]\n"
1517 " set interface [XAuthPasswordEncryption {Keychain}]\n"
1518 " set interface [OnDemandEnabled {enable|disable}]\n"
1519 " set interface [OnDemandMatch <match-options>]\n"
1522 #define N_IPSEC_OPTIONS (sizeof(ipsecOptions) / sizeof(ipsecOptions[0]))
1526 set_interface_ipsec(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1530 ok
= _process_options(ipsecOptions
, N_IPSEC_OPTIONS
, argc
, argv
, newConfiguration
);
1536 #pragma mark FireWire options
1539 static options firewireOptions
[] = {
1540 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1541 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
1542 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
1544 { "?" , NULL
, isHelp
, NULL
, NULL
,
1545 "\nFireWire configuration commands\n\n"
1546 " set interface [mtu n] [media type] [mediaopts opts]\n"
1549 #define N_FIREWIRE_OPTIONS (sizeof(firewireOptions) / sizeof(firewireOptions[0]))
1553 set_interface_firewire(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1555 CFStringRef interfaceName
;
1558 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1559 if (interfaceName
== NULL
) {
1560 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1564 ok
= _process_options(firewireOptions
, N_FIREWIRE_OPTIONS
, argc
, argv
, newConfiguration
);
1566 // validate configuration
1567 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1577 #pragma mark Modem options
1580 static selections modemDialSelections
[] = {
1581 { CFSTR("ignore"), &kSCValNetModemDialModeIgnoreDialTone
, 0 },
1582 { CFSTR("manual"), &kSCValNetModemDialModeManual
, 0 },
1583 { CFSTR("wait") , &kSCValNetModemDialModeWaitForDialTone
, 0 },
1587 static options modemOptions
[] = {
1588 { "ConnectionScript" , "script", isString
, &kSCPropNetModemConnectionScript
, NULL
, NULL
},
1589 { "DialMode" , "mode" , isChooseOne
, &kSCPropNetModemDialMode
, NULL
, (void *)modemDialSelections
},
1590 { "CallWaiting" , NULL
, isBoolean
, &kSCPropNetModemHoldEnabled
, NULL
, NULL
},
1591 { "CallWaitingAlert" , NULL
, isBoolean
, &kSCPropNetModemHoldCallWaitingAudibleAlert
, NULL
, NULL
},
1592 { "CallWaitingDisconnectOnAnswer", NULL
, isBoolean
, &kSCPropNetModemHoldDisconnectOnAnswer
, NULL
, NULL
},
1593 { "DataCompression" , NULL
, isBoolean
, &kSCPropNetModemDataCompression
, NULL
, NULL
},
1594 { "ErrorCorrection" , NULL
, isBoolean
, &kSCPropNetModemErrorCorrection
, NULL
, NULL
},
1595 { "HoldReminder" , NULL
, isBoolean
, &kSCPropNetModemHoldReminder
, NULL
, NULL
},
1596 { "HoldReminderTime" , "time" , isNumber
, &kSCPropNetModemHoldReminderTime
, NULL
, NULL
},
1597 { "PulseDial" , NULL
, isBoolean
, &kSCPropNetModemPulseDial
, NULL
, NULL
},
1598 { "Speaker" , NULL
, isBoolean
, &kSCPropNetModemSpeaker
, NULL
, NULL
},
1600 { "?" , NULL
, isHelp
, NULL
, NULL
,
1601 "\nModem configuration commands\n\n"
1602 " set interface [ConnectionScript connection-script]\n"
1603 " set interface [CallWaiting {enable|disable}]\n"
1604 " set interface [CallWaitingAlert {enable|disable}]\n"
1605 " set interface [CallWaitingDisconnectOnAnswer {enable|disable}]\n"
1606 " set interface [DialMode {ignore|wait}]\n"
1607 " set interface [DataCompression {enable|disable}]\n"
1608 " set interface [ErrorCorrection {enable|disable}]\n"
1609 " set interface [HoldReminder {enable|disable}]\n"
1610 " set interface [HoldReminderTime n]\n"
1611 " set interface [PulseDial {enable|disable}]\n"
1612 " set interface [Speaker {enable|disable}]\n"
1615 #define N_MODEM_OPTIONS (sizeof(modemOptions) / sizeof(modemOptions[0]))
1619 set_interface_modem(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1623 ok
= _process_options(modemOptions
, N_MODEM_OPTIONS
, argc
, argv
, newConfiguration
);
1629 #pragma mark PPP options
1633 __doPPPAuthPW(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1635 CFStringRef encryptionType
;
1638 SCPrint(TRUE
, stdout
, CFSTR("PPP password not specified\n"));
1642 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetPPPAuthPasswordEncryption
);
1643 if (strlen(argv
[0]) > 0) {
1644 if (encryptionType
== NULL
) {
1646 CFMutableDataRef pw
;
1649 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1650 n
= CFStringGetLength(str
);
1651 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
1652 CFDataSetLength(pw
, n
* sizeof(UniChar
));
1653 CFStringGetCharacters(str
,
1655 (UniChar
*)CFDataGetMutableBytePtr(pw
));
1658 CFDictionarySetValue(newConfiguration
, key
, pw
);
1660 } else if (CFEqual(encryptionType
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1665 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1666 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
1667 ok
= SCNetworkInterfaceSetPassword(net_interface
,
1668 kSCNetworkInterfacePasswordTypePPP
,
1674 updateInterfaceConfiguration(newConfiguration
);
1679 SCPrint(TRUE
, stdout
, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType
);
1683 if (encryptionType
== NULL
) {
1684 CFDictionaryRemoveValue(newConfiguration
, key
);
1685 } else if (CFEqual(encryptionType
, kSCValNetPPPAuthPasswordEncryptionKeychain
)) {
1688 ok
= SCNetworkInterfaceRemovePassword(net_interface
, kSCNetworkInterfacePasswordTypePPP
);
1690 updateInterfaceConfiguration(newConfiguration
);
1695 SCPrint(TRUE
, stdout
, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType
);
1705 __doPPPAuthPWType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1708 SCPrint(TRUE
, stdout
, CFSTR("PPP password type mode not specified\n"));
1712 if (strlen(argv
[0]) > 0) {
1713 if (strcasecmp(argv
[0], "keychain") == 0) {
1714 CFDictionarySetValue(newConfiguration
, key
, kSCValNetPPPAuthPasswordEncryptionKeychain
);
1716 SCPrint(TRUE
, stdout
, CFSTR("invalid password type\n"));
1720 CFDictionaryRemoveValue(newConfiguration
, key
);
1723 // encryption type changed, reset password
1724 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetPPPAuthPassword
);
1730 static options l2tp_ipsecOptions
[] = {
1731 { "SharedSecret" , NULL
, isOther
, &kSCPropNetIPSecSharedSecret
, __doIPSecSharedSecret
, NULL
},
1732 { "SharedSecretEncryption", NULL
, isOther
, &kSCPropNetIPSecSharedSecretEncryption
, __doIPSecSharedSecretType
, NULL
},
1734 { "?" , NULL
, isHelp
, NULL
, NULL
,
1735 "\nIPSec configuration commands\n\n"
1736 " set interface ipsec [SharedSecret secret]\n"
1737 " set interface ipsec [SharedSecretEncryption {Keychain}]\n"
1740 #define N_L2TP_IPSEC_OPTIONS (sizeof(l2tp_ipsecOptions) / sizeof(l2tp_ipsecOptions[0]))
1744 __doPPPIPSec(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newPPPConfiguration
)
1746 SCNetworkInterfaceRef childInterface
;
1747 CFStringRef childInterfaceType
;
1748 CFDictionaryRef configuration
;
1749 CFMutableDictionaryRef newConfiguration
;
1753 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1757 childInterface
= SCNetworkInterfaceGetInterface(net_interface
);
1758 if (childInterface
== NULL
) {
1759 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
1763 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
1764 if (!CFEqual(childInterfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
1765 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
1769 configuration
= SCNetworkInterfaceGetExtendedConfiguration(net_interface
, kSCEntNetIPSec
);
1770 if (configuration
== NULL
) {
1771 newConfiguration
= CFDictionaryCreateMutable(NULL
,
1773 &kCFTypeDictionaryKeyCallBacks
,
1774 &kCFTypeDictionaryValueCallBacks
);
1776 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
1777 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
1780 ok
= _process_options(l2tp_ipsecOptions
, N_L2TP_IPSEC_OPTIONS
, argc
, argv
, newConfiguration
);
1785 if (((configuration
== NULL
) && (CFDictionaryGetCount(newConfiguration
) > 0)) ||
1786 ((configuration
!= NULL
) && !CFEqual(configuration
, newConfiguration
))) {
1787 if (!SCNetworkInterfaceSetExtendedConfiguration(net_interface
, kSCEntNetIPSec
, newConfiguration
)) {
1788 if (SCError() == kSCStatusNoKey
) {
1789 SCPrint(TRUE
, stdout
, CFSTR("could not update per-service interface configuration\n"));
1791 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
1796 _prefs_changed
= TRUE
;
1801 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
1807 static options pppOnDemandOptions
[] = {
1808 { "OnDemandMatchDomainsAlways" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1809 { "always" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1810 { "OnDemandMatchDomainsOnRetry", "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1811 { "retry" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1812 { "OnDemandMatchDomainsNever" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1813 { "never" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1815 { "?" , NULL
, isHelp
, NULL
, NULL
,
1816 "\nOnDemandMatch configuration commands\n\n"
1817 " set interface OnDemand always domain-name[,domain-name]\n"
1818 " set interface OnDemand retry domain-name[,domain-name]\n"
1819 " set interface OnDemand never domain-name[,domain-name]\n"
1822 #define N_PPP_ONDEMAND_OPTIONS (sizeof(pppOnDemandOptions) / sizeof(pppOnDemandOptions[0]))
1826 __doPPPOnDemandMatch(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1831 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1835 ok
= _process_options(pppOnDemandOptions
, N_PPP_ONDEMAND_OPTIONS
, argc
, argv
, newConfiguration
);
1847 static selections authPromptSelections
[] = {
1848 { CFSTR("before"), &kSCValNetPPPAuthPromptBefore
, 0 },
1849 { CFSTR("after") , &kSCValNetPPPAuthPromptAfter
, 0 },
1854 static selections authProtocolSelections
[] = {
1855 { CFSTR("CHAP") , &kSCValNetPPPAuthProtocolCHAP
, 0 },
1856 { CFSTR("EAP") , &kSCValNetPPPAuthProtocolEAP
, 0 },
1857 { CFSTR("MSCHAP1"), &kSCValNetPPPAuthProtocolMSCHAP1
, 0 },
1858 { CFSTR("MSCHAP2"), &kSCValNetPPPAuthProtocolMSCHAP2
, 0 },
1859 { CFSTR("PAP") , &kSCValNetPPPAuthProtocolPAP
, 0 },
1864 static options pppOptions
[] = {
1865 { "ACSP" , NULL
, isBoolean
, &kSCPropNetPPPACSPEnabled
, NULL
, NULL
},
1866 { "ConnectTime" , "?time" , isNumber
, &kSCPropNetPPPConnectTime
, NULL
, NULL
},
1867 { "DialOnDemand" , NULL
, isBoolean
, &kSCPropNetPPPDialOnDemand
, NULL
, NULL
},
1868 { "DisconnectOnFastUserSwitch", NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnFastUserSwitch
, NULL
, NULL
},
1869 { "DisconnectOnIdle" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnIdle
, NULL
, NULL
},
1870 { "DisconnectOnIdleTimer" , "timeout" , isNumber
, &kSCPropNetPPPDisconnectOnIdleTimer
, NULL
, NULL
},
1871 { "DisconnectOnLogout" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnLogout
, NULL
, NULL
},
1872 { "DisconnectOnSleep" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnSleep
, NULL
, NULL
},
1873 { "DisconnectTime" , "?time" , isNumber
, &kSCPropNetPPPDisconnectTime
, NULL
, NULL
},
1874 { "IdleReminder" , NULL
, isBoolean
, &kSCPropNetPPPIdleReminder
, NULL
, NULL
},
1875 { "IdleReminderTimer" , "time" , isNumber
, &kSCPropNetPPPIdleReminderTimer
, NULL
, NULL
},
1876 { "Logfile" , "path" , isString
, &kSCPropNetPPPLogfile
, NULL
, NULL
},
1877 { "Plugins" , "plugin" , isStringArray
, &kSCPropNetPPPPlugins
, NULL
, NULL
},
1878 { "RetryConnectTime" , "time" , isNumber
, &kSCPropNetPPPRetryConnectTime
, NULL
, NULL
},
1879 { "SessionTimer" , "time" , isNumber
, &kSCPropNetPPPSessionTimer
, NULL
, NULL
},
1880 { "UseSessionTimer" , NULL
, isBoolean
, &kSCPropNetPPPUseSessionTimer
, NULL
, NULL
},
1881 { "VerboseLogging" , NULL
, isBoolean
, &kSCPropNetPPPVerboseLogging
, NULL
, NULL
},
1884 { "AuthEAPPlugins" , "plugin" , isStringArray
, &kSCPropNetPPPAuthEAPPlugins
, NULL
, NULL
},
1885 { "AuthName" , "account" , isString
, &kSCPropNetPPPAuthName
, NULL
, NULL
},
1886 { "Account" , "account" , isString
, &kSCPropNetPPPAuthName
, NULL
, NULL
},
1887 { "AuthPassword" , "password" , isOther
, &kSCPropNetPPPAuthPassword
, __doPPPAuthPW
, NULL
},
1888 { "Password" , "password" , isOther
, &kSCPropNetPPPAuthPassword
, __doPPPAuthPW
, NULL
},
1889 { "AuthPasswordEncryption" , "type" , isOther
, &kSCPropNetPPPAuthPasswordEncryption
, __doPPPAuthPWType
, NULL
},
1890 { "AuthPrompt" , "before/after", isChooseOne
, &kSCPropNetPPPAuthPrompt
, NULL
, (void *)authPromptSelections
},
1891 { "AuthProtocol" , "protocol" , isChooseMultiple
, &kSCPropNetPPPAuthProtocol
, NULL
, (void *)authProtocolSelections
},
1894 { "CommRemoteAddress" , "phone#" , isString
, &kSCPropNetPPPCommRemoteAddress
, NULL
, NULL
},
1895 { "CommAlternateRemoteAddress", "phone#" , isString
, &kSCPropNetPPPCommAlternateRemoteAddress
, NULL
, NULL
},
1896 { "CommConnectDelay" , "time" , isNumber
, &kSCPropNetPPPCommConnectDelay
, NULL
, NULL
},
1897 { "CommDisplayTerminalWindow" , NULL
, isBoolean
, &kSCPropNetPPPCommDisplayTerminalWindow
, NULL
, NULL
},
1898 { "CommRedialCount" , "retry count" , isNumber
, &kSCPropNetPPPCommRedialCount
, NULL
, NULL
},
1899 { "CommRedialEnabled" , NULL
, isBoolean
, &kSCPropNetPPPCommRedialEnabled
, NULL
, NULL
},
1900 { "CommRedialInterval" , "retry delay" , isNumber
, &kSCPropNetPPPCommRedialInterval
, NULL
, NULL
},
1901 { "CommTerminalScript" , "script" , isString
, &kSCPropNetPPPCommTerminalScript
, NULL
, NULL
},
1902 { "CommUseTerminalScript" , NULL
, isBoolean
, &kSCPropNetPPPCommUseTerminalScript
, NULL
, NULL
},
1905 { "CCPEnabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPEnabled
, NULL
, NULL
},
1906 { "CCPMPPE40Enabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPMPPE40Enabled
, NULL
, NULL
},
1907 { "CCPMPPE128Enabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPMPPE128Enabled
, NULL
, NULL
},
1910 { "IPCPCompressionVJ" , NULL
, isBoolean
, &kSCPropNetPPPIPCPCompressionVJ
, NULL
, NULL
},
1911 { "IPCPUsePeerDNS" , NULL
, isBoolean
, &kSCPropNetPPPIPCPUsePeerDNS
, NULL
, NULL
},
1914 { "LCPEchoEnabled" , NULL
, isBoolean
, &kSCPropNetPPPLCPEchoEnabled
, NULL
, NULL
},
1915 { "LCPEchoFailure" , NULL
, isNumber
, &kSCPropNetPPPLCPEchoFailure
, NULL
, NULL
},
1916 { "LCPEchoInterval" , NULL
, isNumber
, &kSCPropNetPPPLCPEchoInterval
, NULL
, NULL
},
1917 { "LCPCompressionACField" , NULL
, isBoolean
, &kSCPropNetPPPLCPCompressionACField
, NULL
, NULL
},
1918 { "LCPCompressionPField" , NULL
, isBoolean
, &kSCPropNetPPPLCPCompressionPField
, NULL
, NULL
},
1919 { "LCPMRU" , NULL
, isNumber
, &kSCPropNetPPPLCPMRU
, NULL
, NULL
},
1920 { "LCPMTU" , NULL
, isNumber
, &kSCPropNetPPPLCPMTU
, NULL
, NULL
},
1921 { "LCPReceiveACCM" , NULL
, isNumber
, &kSCPropNetPPPLCPReceiveACCM
, NULL
, NULL
},
1922 { "LCPTransmitACCM" , NULL
, isNumber
, &kSCPropNetPPPLCPTransmitACCM
, NULL
, NULL
},
1925 { "IPSec" , NULL
, isOther
, NULL
, __doPPPIPSec
, NULL
},
1928 // --- OnDemand: ---
1929 { "OnDemandEnabled" , NULL
, isBoolean
, &kSCPropNetPPPOnDemandEnabled
, NULL
, NULL
},
1930 { "OnDemandMatch" , NULL
, isOther
, NULL
, __doPPPOnDemandMatch
, NULL
},
1934 { "?" , NULL
, isHelp
, NULL
, NULL
,
1935 "\nPPP configuration commands\n\n"
1936 " set interface [Account account]\n"
1937 " set interface [Password password]\n"
1938 " set interface [Number telephone-number]\n"
1939 " set interface [AlternateNumber telephone-number]\n"
1940 " set interface [IdleReminder {enable|disable}]\n"
1941 " set interface [IdleReminderTimer time-in-seconds]\n"
1942 " set interface [DisconnectOnIdle {enable|disable}]\n"
1943 " set interface [DisconnectOnIdleTimer time-in-seconds]\n"
1944 " set interface [DisconnectOnLogout {enable|disable}]\n"
1945 " set interface [IPSec <ipsec-options>]\n"
1947 " set interface [OnDemandEnabled {enable|disable}]\n"
1948 " set interface [OnDemandMatch <match-options>]\n"
1952 #define N_PPP_OPTIONS (sizeof(pppOptions) / sizeof(pppOptions[0]))
1956 set_interface_ppp(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1960 ok
= _process_options(pppOptions
, N_PPP_OPTIONS
, argc
, argv
, newConfiguration
);
1966 #pragma mark VLAN options
1970 set_interface_vlan(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1972 // xxxxx ("device", "tag")
1973 SCPrint(TRUE
, stdout
, CFSTR("vlan interface management not yet supported\n"));
1979 #pragma mark VPN options
1983 __doVPNAuthPW(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1985 CFStringRef encryptionType
;
1988 SCPrint(TRUE
, stdout
, CFSTR("VPN password not specified\n"));
1992 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetVPNAuthPasswordEncryption
);
1993 if (strlen(argv
[0]) > 0) {
1994 if (encryptionType
== NULL
) {
1995 #ifdef USE_INLINE_CFDATA
1997 CFMutableDataRef pw
;
2000 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
2001 n
= CFStringGetLength(str
);
2002 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
2003 CFDataSetLength(pw
, n
* sizeof(UniChar
));
2004 CFStringGetCharacters(str
,
2006 (UniChar
*)CFDataGetMutableBytePtr(pw
));
2008 #else // USE_INLINE_CFDATA
2011 pw
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
2012 #endif // USE_INLINE_CFDATA
2014 CFDictionarySetValue(newConfiguration
, key
, pw
);
2016 } else if (CFEqual(encryptionType
, kSCValNetVPNAuthPasswordEncryptionKeychain
)) {
2021 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
2022 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
2023 ok
= SCNetworkInterfaceSetPassword(net_interface
,
2024 kSCNetworkInterfacePasswordTypeVPN
,
2030 updateInterfaceConfiguration(newConfiguration
);
2035 SCPrint(TRUE
, stdout
, CFSTR("VPN password type \"%@\" not supported\n"), encryptionType
);
2039 if (encryptionType
== NULL
) {
2040 CFDictionaryRemoveValue(newConfiguration
, key
);
2041 } else if (CFEqual(encryptionType
, kSCValNetVPNAuthPasswordEncryptionKeychain
)) {
2044 ok
= SCNetworkInterfaceRemovePassword(net_interface
, kSCNetworkInterfacePasswordTypeVPN
);
2046 updateInterfaceConfiguration(newConfiguration
);
2051 SCPrint(TRUE
, stdout
, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType
);
2061 __doVPNAuthPWType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2064 SCPrint(TRUE
, stdout
, CFSTR("VPN password type mode not specified\n"));
2068 if (strlen(argv
[0]) > 0) {
2069 if (strcasecmp(argv
[0], "keychain") == 0) {
2070 CFDictionarySetValue(newConfiguration
, key
, kSCValNetVPNAuthPasswordEncryptionKeychain
);
2071 } else if (strcasecmp(argv
[0], "prompt") == 0) {
2072 CFDictionarySetValue(newConfiguration
, key
, kSCValNetVPNAuthPasswordEncryptionPrompt
);
2074 SCPrint(TRUE
, stdout
, CFSTR("invalid password type\n"));
2078 CFDictionaryRemoveValue(newConfiguration
, key
);
2081 // encryption type changed, reset password
2082 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetVPNAuthPassword
);
2088 static selections vpnAuthenticationMethodSelections
[] = {
2089 { CFSTR("Password") , &kSCValNetVPNAuthenticationMethodPassword
, 0 },
2090 { CFSTR("Certificate") , &kSCValNetVPNAuthenticationMethodCertificate
, 0 },
2095 static options vpnOptions
[] = {
2096 { "AuthName" , "account" , isString
, &kSCPropNetVPNAuthName
, NULL
, NULL
},
2097 { "Account" , "account" , isString
, &kSCPropNetVPNAuthName
, NULL
, NULL
},
2098 { "AuthPassword" , "password" , isOther
, &kSCPropNetVPNAuthPassword
, __doVPNAuthPW
, NULL
},
2099 { "Password" , "password" , isOther
, &kSCPropNetVPNAuthPassword
, __doVPNAuthPW
, NULL
},
2100 { "AuthPasswordEncryption" , "type" , isOther
, &kSCPropNetVPNAuthPasswordEncryption
, __doVPNAuthPWType
, NULL
},
2101 { "AuthenticationMethod" , NULL
, isChooseOne
, &kSCPropNetVPNAuthenticationMethod
, NULL
, (void *)vpnAuthenticationMethodSelections
},
2102 { "ConnectTime" , "?time" , isNumber
, &kSCPropNetVPNConnectTime
, NULL
, NULL
},
2103 { "DisconnectOnFastUserSwitch", NULL
, isBoolean
, &kSCPropNetVPNDisconnectOnFastUserSwitch
, NULL
, NULL
},
2104 { "DisconnectOnIdle" , NULL
, isBoolean
, &kSCPropNetVPNDisconnectOnIdle
, NULL
, NULL
},
2105 { "DisconnectOnIdleTimer" , "timeout" , isNumber
, &kSCPropNetVPNDisconnectOnIdleTimer
, NULL
, NULL
},
2106 { "DisconnectOnLogout" , NULL
, isBoolean
, &kSCPropNetVPNDisconnectOnLogout
, NULL
, NULL
},
2107 { "DisconnectOnSleep" , NULL
, isBoolean
, &kSCPropNetVPNDisconnectOnSleep
, NULL
, NULL
},
2108 { "Logfile" , "path" , isString
, &kSCPropNetVPNLogfile
, NULL
, NULL
},
2109 { "MTU" , NULL
, isNumber
, &kSCPropNetVPNMTU
, NULL
, NULL
},
2110 { "RemoteAddress" , "server" , isString
, &kSCPropNetVPNRemoteAddress
, NULL
, NULL
},
2111 { "Server" , "server" , isString
, &kSCPropNetVPNRemoteAddress
, NULL
, NULL
},
2112 { "VerboseLogging" , NULL
, isBoolean
, &kSCPropNetVPNVerboseLogging
, NULL
, NULL
},
2115 { "?" , NULL
, isHelp
, NULL
, NULL
,
2116 "\nVPN configuration commands\n\n"
2117 " set interface [Server server]\n"
2118 " set interface [Account account]\n"
2119 " set interface [Password password]\n"
2122 #define N_VPN_OPTIONS (sizeof(vpnOptions) / sizeof(vpnOptions[0]))
2126 set_interface_vpn(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
2130 ok
= _process_options(vpnOptions
, N_VPN_OPTIONS
, argc
, argv
, newConfiguration
);
2136 #pragma mark [more] Interface management
2141 set_interface(int argc
, char **argv
)
2143 CFDictionaryRef configuration
;
2144 CFStringRef interfaceType
;
2145 CFMutableDictionaryRef newConfiguration
= NULL
;
2148 if (net_interface
== NULL
) {
2149 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
2154 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
2158 configuration
= SCNetworkInterfaceGetConfiguration(net_interface
);
2159 if (configuration
!= NULL
) {
2160 configuration
= CFDictionaryCreateCopy(NULL
, configuration
);
2161 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
2162 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
2164 newConfiguration
= CFDictionaryCreateMutable(NULL
,
2166 &kCFTypeDictionaryKeyCallBacks
,
2167 &kCFTypeDictionaryValueCallBacks
);
2170 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
2172 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeEthernet
)) {
2173 ok
= set_interface_ethernet(argc
, argv
, newConfiguration
);
2174 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeFireWire
)) {
2175 ok
= set_interface_firewire(argc
, argv
, newConfiguration
);
2176 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
2177 ok
= set_interface_ipsec(argc
, argv
, newConfiguration
);
2178 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeModem
)) {
2179 ok
= set_interface_modem(argc
, argv
, newConfiguration
);
2180 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIEEE80211
)) {
2181 ok
= set_interface_airport(argc
, argv
, newConfiguration
);
2182 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2183 ok
= set_interface_ppp(argc
, argv
, newConfiguration
);
2184 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
2185 ok
= set_interface_bond(argc
, argv
, newConfiguration
);
2186 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBridge
)) {
2187 ok
= set_interface_bridge(argc
, argv
, newConfiguration
);
2188 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
2189 ok
= set_interface_vlan(argc
, argv
, newConfiguration
);
2190 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
2191 ok
= set_interface_vpn(argc
, argv
, newConfiguration
);
2193 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
2200 if (((configuration
== NULL
) && (CFDictionaryGetCount(newConfiguration
) > 0)) ||
2201 ((configuration
!= NULL
) && !CFEqual(configuration
, newConfiguration
))) {
2202 if (!SCNetworkInterfaceSetConfiguration(net_interface
, newConfiguration
)) {
2203 if (SCError() == kSCStatusNoKey
) {
2204 SCPrint(TRUE
, stdout
, CFSTR("could not update per-service interface configuration\n"));
2206 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
2211 _prefs_changed
= TRUE
;
2216 if (configuration
!= NULL
) CFRelease(configuration
);
2217 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
2222 /* -------------------- */
2227 show_interface(int argc
, char **argv
)
2229 SCNetworkInterfaceRef interface
;
2232 interface
= _find_interface(argc
, argv
, NULL
);
2234 if (net_interface
!= NULL
) {
2235 interface
= net_interface
;
2237 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
2242 if (interface
!= NULL
) {
2243 _show_interface(interface
, CFSTR(""), TRUE
);
2250 /* -------------------- */
2255 _interface_description(SCNetworkInterfaceRef interface
)
2257 CFMutableStringRef description
;
2258 CFStringRef if_bsd_name
;
2259 CFStringRef if_type
;
2261 description
= CFStringCreateMutable(NULL
, 0);
2263 if_type
= SCNetworkInterfaceGetInterfaceType(interface
);
2264 CFStringAppend(description
, if_type
);
2266 if_bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
2267 if (if_bsd_name
!= NULL
) {
2268 CFStringAppendFormat(description
, NULL
, CFSTR(" (%@)"), if_bsd_name
);
2271 interface
= SCNetworkInterfaceGetInterface(interface
);
2272 while ((interface
!= NULL
) &&
2273 !CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
2274 CFStringRef childDescription
;
2276 childDescription
= _interface_description(interface
);
2277 CFStringAppendFormat(description
, NULL
, CFSTR(" / %@"), childDescription
);
2278 CFRelease(childDescription
);
2280 interface
= SCNetworkInterfaceGetInterface(interface
);