2 * Copyright (c) 2004-2009 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * August 5, 2004 Allan Nathanson <ajn@apple.com>
36 #include <SystemConfiguration/LinkConfiguration.h>
40 #pragma mark Interface management
46 CFMutableArrayRef interfaces
;
47 CFArrayRef real_interfaces
;
49 real_interfaces
= SCNetworkInterfaceCopyAll();
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
, kSCNetworkInterfaceIPv4
);
66 // include interfaces that we have created
67 if (new_interfaces
!= NULL
) {
68 CFArrayAppendArray(interfaces
,
70 CFRangeMake(0, CFArrayGetCount(new_interfaces
)));
73 return (CFArrayRef
)interfaces
;
79 _find_interface(int argc
, char **argv
, int *nArgs
)
81 Boolean allowIndex
= TRUE
;
83 CFArrayRef myInterfaces
= interfaces
;
85 CFStringRef select_name
= NULL
;
86 SCNetworkInterfaceRef selected
= NULL
;
89 SCPrint(TRUE
, stdout
, CFSTR("no interface specified\n"));
93 if (nArgs
!= NULL
) *nArgs
= 1;
95 if (strcasecmp(argv
[0], "$child") == 0) {
96 if (net_interface
== NULL
) {
97 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
101 selected
= SCNetworkInterfaceGetInterface(net_interface
);
102 if(selected
== NULL
) {
103 SCPrint(TRUE
, stdout
, CFSTR("no child interface\n"));
107 } else if (strcasecmp(argv
[0], "$service") == 0) {
108 if (net_service
== NULL
) {
109 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
113 selected
= SCNetworkServiceGetInterface(net_service
);
114 if(selected
== NULL
) {
115 SCPrint(TRUE
, stdout
, CFSTR("no interface for service\n"));
119 #if !TARGET_OS_IPHONE
120 } else if (strcasecmp(argv
[0], "$bond") == 0) {
121 CFStringRef interfaceType
;
123 if (net_interface
== NULL
) {
124 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
128 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
129 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
130 SCPrint(TRUE
, stdout
, CFSTR("interface not Bond\n"));
135 SCPrint(TRUE
, stdout
, CFSTR("no member interface specified\n"));
140 if (nArgs
!= NULL
) *nArgs
+= 1;
142 myInterfaces
= SCBondInterfaceGetMemberInterfaces(net_interface
);
143 if (myInterfaces
== NULL
) {
144 SCPrint(TRUE
, stdout
, CFSTR("no member interfaces\n"));
148 } else if (strcasecmp(argv
[0], "$vlan") == 0) {
149 CFStringRef interfaceType
;
151 if (net_interface
== NULL
) {
152 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
156 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
157 if (!CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
158 SCPrint(TRUE
, stdout
, CFSTR("interface not VLAN\n"));
162 selected
= SCVLANInterfaceGetPhysicalInterface(net_interface
);
163 if(selected
== NULL
) {
164 SCPrint(TRUE
, stdout
, CFSTR("no physical interface\n"));
168 #endif // !TARGET_OS_IPHONE
171 if ((myInterfaces
== NULL
) && (interfaces
== NULL
)) {
172 interfaces
= _copy_interfaces();
173 if (interfaces
== NULL
) {
176 myInterfaces
= interfaces
;
180 // try to select the interface by its display name
182 select_name
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
184 n
= (myInterfaces
!= NULL
) ? CFArrayGetCount(myInterfaces
) : 0;
185 for (i
= 0; i
< n
; i
++) {
186 SCNetworkInterfaceRef interface
;
187 CFStringRef interfaceName
;
189 interface
= CFArrayGetValueAtIndex(myInterfaces
, i
);
190 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
191 if ((interfaceName
!= NULL
) && CFEqual(select_name
, interfaceName
)) {
192 if (selected
== NULL
) {
193 selected
= interface
;
195 // if multiple interfaces match
197 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
203 if (selected
!= NULL
) {
207 // try to select the interface by its BSD name
209 for (i
= 0; i
< n
; i
++) {
210 SCNetworkInterfaceRef interface
;
211 CFStringRef bsd_name
= NULL
;
213 interface
= CFArrayGetValueAtIndex(myInterfaces
, i
);
214 while ((interface
!= NULL
) && (bsd_name
== NULL
)) {
215 bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
216 if (bsd_name
== NULL
) {
217 interface
= SCNetworkInterfaceGetInterface(interface
);
221 if ((bsd_name
!= NULL
) && CFEqual(select_name
, bsd_name
)) {
222 if (selected
== NULL
) {
223 selected
= interface
;
225 // if multiple interfaces match
227 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
233 if (selected
!= NULL
) {
237 // try to select the interface by its interface type
239 for (i
= 0; i
< n
; i
++) {
240 SCNetworkInterfaceRef interface
;
241 CFStringRef interfaceType
;
243 interface
= CFArrayGetValueAtIndex(myInterfaces
, i
);
244 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
245 if (CFEqual(select_name
, interfaceType
)) {
246 if (selected
== NULL
) {
247 selected
= interface
;
249 // if multiple interfaces match
251 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
257 if (selected
!= NULL
) {
266 // try to select the interface by its index
269 val
= strtol(str
, &end
, 10);
270 if ((*str
!= '\0') &&
271 ((*end
== '\0') || (*end
== '.')) &&
273 if ((val
> 0) && (val
<= n
)) {
274 selected
= CFArrayGetValueAtIndex(myInterfaces
, val
- 1);
278 val
= strtol(str
, &end
, 10);
279 if ((*str
!= '\0') && (*end
== '\0') && (errno
== 0)) {
281 selected
= SCNetworkInterfaceGetInterface(selected
);
282 if (selected
== NULL
) {
292 if (selected
!= NULL
) {
296 SCPrint(TRUE
, stdout
, CFSTR("no match\n"));
300 if (select_name
!= NULL
) CFRelease(select_name
);
305 /* -------------------- */
310 create_interface(int argc
, char **argv
)
312 SCNetworkInterfaceRef interface
;
313 CFStringRef interfaceName
;
314 CFStringRef interfaceType
;
315 SCNetworkInterfaceRef new_interface
;
318 SCPrint(TRUE
, stdout
, CFSTR("what interface type?\n"));
322 interfaceType
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
326 #if !TARGET_OS_IPHONE
327 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
328 SCPrint(TRUE
, stdout
, CFSTR("bond creation not yet supported\n"));
331 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
332 SCPrint(TRUE
, stdout
, CFSTR("vlan creation not yet supported\n"));
335 #endif // !TARGET_OS_IPHONE
338 if (net_interface
== NULL
) {
339 SCPrint(TRUE
, stdout
, CFSTR("no network interface selected\n"));
343 interface
= net_interface
;
345 interface
= _find_interface(argc
, argv
, NULL
);
348 if (interface
== NULL
) {
352 new_interface
= SCNetworkInterfaceCreateWithInterface(interface
, interfaceType
);
353 if (new_interface
== NULL
) {
354 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
358 if (new_interfaces
== NULL
) {
359 new_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
361 CFArrayAppendValue(new_interfaces
, new_interface
);
363 if (net_interface
!= NULL
) CFRelease(net_interface
);
364 net_interface
= new_interface
;
366 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(net_interface
);
367 if (interfaceName
== NULL
) {
368 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
370 if (interfaceName
== NULL
) {
371 interfaceName
= SCNetworkInterfaceGetInterfaceType(net_interface
);
373 SCPrint(TRUE
, stdout
, CFSTR("interface \"%@\" created and selected\n"), interfaceName
);
377 CFRelease(interfaceType
);
382 /* -------------------- */
387 select_interface(int argc
, char **argv
)
389 SCNetworkInterfaceRef interface
;
391 interface
= _find_interface(argc
, argv
, NULL
);
392 if (interface
!= NULL
) {
393 CFStringRef interfaceName
;
395 if (net_interface
!= NULL
) CFRelease(net_interface
);
396 net_interface
= CFRetain(interface
);
398 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
399 if (interfaceName
== NULL
) {
400 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
402 if (interfaceName
== NULL
) {
403 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
406 SCPrint(TRUE
, stdout
, CFSTR("interface \"%@\" selected\n"), interfaceName
);
413 /* -------------------- */
418 _show_interface(SCNetworkInterfaceRef interface
, CFStringRef prefix
, Boolean showChild
)
420 CFDictionaryRef configuration
;
421 CFStringRef if_bsd_name
;
422 CFStringRef if_localized_name
;
423 CFStringRef if_mac_address
;
425 CFArrayRef supported
;
427 if_localized_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
428 if (if_localized_name
!= NULL
) {
429 SCPrint(TRUE
, stdout
, CFSTR("%@ name = %@\n"), prefix
, if_localized_name
);
432 if_bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
433 if (if_bsd_name
!= NULL
) {
434 SCPrint(TRUE
, stdout
, CFSTR("%@ interface name = %@\n"), prefix
, if_bsd_name
);
437 if_type
= SCNetworkInterfaceGetInterfaceType(interface
);
438 SCPrint(TRUE
, stdout
, CFSTR("%@ type = %@\n"), prefix
, if_type
);
440 if_mac_address
= SCNetworkInterfaceGetHardwareAddressString(interface
);
441 if (if_mac_address
!= NULL
) {
442 SCPrint(TRUE
, stdout
, CFSTR("%@ address = %@\n"), prefix
, if_mac_address
);
445 configuration
= SCNetworkInterfaceGetConfiguration(interface
);
446 if ((configuration
!= NULL
) &&
447 CFDictionaryContainsKey(configuration
, kSCResvInactive
)) {
448 configuration
= NULL
;
451 if (if_bsd_name
!= NULL
) {
452 CFArrayRef available
;
453 CFDictionaryRef active
;
458 if (SCNetworkInterfaceCopyMTU(interface
, &mtu_cur
, &mtu_min
, &mtu_max
)) {
459 char isCurrent
= '*';
461 if (configuration
!= NULL
) {
465 num
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMTU
);
466 if (isA_CFNumber(num
)) {
467 CFNumberGetValue(num
, kCFNumberIntType
, &mtu_req
);
468 if (mtu_cur
!= mtu_req
) {
475 SCPrint(TRUE
, stdout
, CFSTR("%@ mtu %c = %d (%d < n < %d)\n"),
483 if (SCNetworkInterfaceCopyMediaOptions(interface
, NULL
, &active
, &available
, TRUE
)) {
484 char isCurrent
= ' ';
485 CFArrayRef options
= NULL
;
486 CFArrayRef options_req
= NULL
;
487 CFStringRef subtype
= NULL
;
488 CFStringRef subtype_req
= NULL
;
490 if (configuration
!= NULL
) {
491 subtype_req
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMediaSubType
);
492 options_req
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMediaOptions
);
495 if (subtype_req
== NULL
) {
496 subtype_req
= CFSTR("autoselect");
499 if (active
!= NULL
) {
500 subtype
= CFDictionaryGetValue(active
, kSCPropNetEthernetMediaSubType
);
501 options
= CFDictionaryGetValue(active
, kSCPropNetEthernetMediaOptions
);
504 if (subtype
!= NULL
) {
505 if (((subtype_req
!= NULL
) &&
506 CFEqual(subtype
, subtype_req
)) &&
507 ((options
== options_req
) ||
508 ((options
!= NULL
) &&
509 (options_req
!= NULL
) &&
510 CFEqual(options
, options_req
)))
513 } else if ((subtype_req
== NULL
) ||
514 ((subtype_req
!= NULL
) &&
515 CFEqual(subtype_req
, CFSTR("autoselect")))) {
516 // if requested subtype not specified or "autoselect"
521 if (subtype_req
!= NULL
) {
522 SCPrint(TRUE
, stdout
, CFSTR("%@ media %c = %@"),
527 if ((options_req
!= NULL
) &&
528 (CFArrayGetCount(options_req
) > 0)) {
529 CFStringRef options_str
;
531 options_str
= CFStringCreateByCombiningStrings(NULL
, options_req
, CFSTR(","));
532 SCPrint(TRUE
, stdout
, CFSTR(" <%@>"), options_str
);
533 CFRelease(options_str
);
536 SCPrint(TRUE
, stdout
, CFSTR("\n"));
539 SCPrint(TRUE
, stdout
, CFSTR("\n"));
541 if (available
!= NULL
) {
546 subtypes
= SCNetworkInterfaceCopyMediaSubTypes(available
);
547 n_subtypes
= (subtypes
!= NULL
) ? CFArrayGetCount(subtypes
) : 0;
548 for (i
= 0; i
< n_subtypes
; i
++) {
550 CFIndex n_subtype_options
;
552 CFArrayRef subtype_options
;
554 subtype
= CFArrayGetValueAtIndex(subtypes
, i
);
555 subtype_options
= SCNetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
556 n_subtype_options
= (subtype_options
!= NULL
) ? CFArrayGetCount(subtype_options
) : 0;
557 for (j
= 0; j
< n_subtype_options
; j
++) {
558 char isCurrent
= ' ';
561 options
= CFArrayGetValueAtIndex(subtype_options
, j
);
563 if (((subtype_req
!= NULL
) &&
564 CFEqual(subtype
, subtype_req
)) &&
565 ((options
== options_req
) ||
566 ((options
!= NULL
) &&
567 (options_req
!= NULL
) &&
568 CFEqual(options
, options_req
)))
573 SCPrint(TRUE
, stdout
, CFSTR("%@ %s %c = %@"),
575 ((i
== 0) && (j
== 0)) ? "supported media" : " ",
579 if ((options
!= NULL
) &&
580 (CFArrayGetCount(options
) > 0)) {
581 CFStringRef options_str
;
583 options_str
= CFStringCreateByCombiningStrings(NULL
, options
, CFSTR(","));
584 SCPrint(TRUE
, stdout
, CFSTR(" <%@>"), options_str
);
585 CFRelease(options_str
);
588 SCPrint(TRUE
, stdout
, CFSTR("\n"));
590 CFRelease(subtype_options
);
592 if (subtypes
!= NULL
) CFRelease(subtypes
);
595 SCPrint(TRUE
, stdout
, CFSTR("\n"));
599 supported
= SCNetworkInterfaceGetSupportedInterfaceTypes(interface
);
600 SCPrint(TRUE
, stdout
, CFSTR("%@ supported interfaces = "), prefix
);
601 if (supported
!= NULL
) {
603 CFIndex n
= CFArrayGetCount(supported
);
605 for (i
= 0; i
< n
; i
++) {
606 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
607 (i
== 0) ? "" : ", ",
608 CFArrayGetValueAtIndex(supported
, i
));
611 SCPrint(TRUE
, stdout
, CFSTR("\n"));
613 supported
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
);
614 SCPrint(TRUE
, stdout
, CFSTR("%@ supported protocols = "), prefix
);
615 if (supported
!= NULL
) {
617 CFIndex n
= CFArrayGetCount(supported
);
619 for (i
= 0; i
< n
; i
++) {
620 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
621 (i
== 0) ? "" : ", ",
622 CFArrayGetValueAtIndex(supported
, i
));
625 SCPrint(TRUE
, stdout
, CFSTR("\n"));
627 if (configuration
!= NULL
) {
628 CFMutableDictionaryRef effective
;
630 effective
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
632 // remove known (and already reported) interface configuration keys
633 if (CFDictionaryContainsKey(effective
, kSCResvInactive
)) {
634 CFDictionaryRemoveAllValues(effective
);
636 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMTU
);
637 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMediaSubType
);
638 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMediaOptions
);
640 if (CFDictionaryGetCount(effective
) > 0) {
641 SCPrint(TRUE
, stdout
, CFSTR("\n%@ per-interface configuration\n"), prefix
);
642 _show_entity(effective
, prefix
);
645 CFRelease(effective
);
648 if (CFEqual(if_type
, kSCNetworkInterfaceTypePPP
)) {
649 SCNetworkInterfaceRef childInterface
;
651 childInterface
= SCNetworkInterfaceGetInterface(interface
);
652 if (childInterface
!= NULL
) {
653 CFStringRef childInterfaceType
;
655 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
656 if (CFEqual(childInterfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
657 CFDictionaryRef ipsec_configuration
;
659 ipsec_configuration
= SCNetworkInterfaceGetExtendedConfiguration(interface
, kSCEntNetIPSec
);
660 if (isA_CFDictionary(ipsec_configuration
) &&
661 (CFDictionaryGetCount(ipsec_configuration
) > 0)) {
662 SCPrint(TRUE
, stdout
, CFSTR("\n%@ per-interface IPSec configuration\n"), prefix
);
663 _show_entity(ipsec_configuration
, prefix
);
670 SCPrint(TRUE
, stdout
, CFSTR("\n%@\n"), interface
);
673 interface
= SCNetworkInterfaceGetInterface(interface
);
674 if (interface
!= NULL
) {
675 CFStringRef newPrefix
;
677 newPrefix
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@ "), prefix
);
678 SCPrint(TRUE
, stdout
, CFSTR("\n%@child interface\n"), newPrefix
);
679 _show_interface(interface
, newPrefix
, showChild
);
680 CFRelease(newPrefix
);
687 /* -------------------- */
691 validateMediaOptions(SCNetworkInterfaceRef interface
, CFMutableDictionaryRef newConfiguration
)
698 mtu
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMTU
);
699 if (isA_CFNumber(mtu
)) {
704 if (!SCNetworkInterfaceCopyMTU(interface
, NULL
, &mtu_min
, &mtu_max
)) {
705 SCPrint(TRUE
, stdout
, CFSTR("cannot set MTU\n"));
709 if (!CFNumberGetValue(mtu
, kCFNumberIntType
, &mtu_val
) ||
710 (mtu_val
< mtu_min
) ||
711 (mtu_val
> mtu_max
)) {
712 SCPrint(TRUE
, stdout
, CFSTR("mtu out of range\n"));
717 subtype
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMediaSubType
);
718 options
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMediaOptions
);
720 if (subtype
!= NULL
) {
721 CFArrayRef available
= NULL
;
722 CFArrayRef config_options
= options
;
723 CFArrayRef subtypes
= NULL
;
724 CFArrayRef subtype_options
= NULL
;
728 if (options
== NULL
) {
729 config_options
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
732 if (!SCNetworkInterfaceCopyMediaOptions(interface
, NULL
, NULL
, &available
, FALSE
)) {
733 SCPrint(TRUE
, stdout
, CFSTR("media type / options not available\n"));
737 if (available
== NULL
) {
741 subtypes
= SCNetworkInterfaceCopyMediaSubTypes(available
);
742 if ((subtypes
== NULL
) ||
743 !CFArrayContainsValue(subtypes
,
744 CFRangeMake(0, CFArrayGetCount(subtypes
)),
746 SCPrint(TRUE
, stdout
, CFSTR("media type not valid\n"));
750 subtype_options
= SCNetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
751 if ((subtype_options
== NULL
) ||
752 !CFArrayContainsValue(subtype_options
,
753 CFRangeMake(0, CFArrayGetCount(subtype_options
)),
755 SCPrint(TRUE
, stdout
, CFSTR("media options not valid for \"%@\"\n"), subtype
);
759 if (options
== NULL
) {
760 CFDictionarySetValue(newConfiguration
, kSCPropNetEthernetMediaOptions
, config_options
);
767 if (available
!= NULL
) CFRelease(available
);
768 if (subtypes
!= NULL
) CFRelease(subtypes
);
769 if (subtype_options
!= NULL
) CFRelease(subtype_options
);
770 if (options
== NULL
) CFRelease(config_options
);
772 if (options
!= NULL
) {
773 SCPrint(TRUE
, stdout
, CFSTR("media type and options must both be specified\n"));
782 /* -------------------- */
787 show_interfaces(int argc
, char **argv
)
792 if (interfaces
!= NULL
) CFRelease(interfaces
);
793 interfaces
= _copy_interfaces();
794 if (interfaces
== NULL
) {
798 n
= CFArrayGetCount(interfaces
);
799 for (i
= 0; i
< n
; i
++) {
800 CFIndex childIndex
= 0;
801 SCNetworkInterfaceRef interface
;
803 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
805 CFStringRef interfaceName
;
808 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
809 if (interfaceName
== NULL
) {
810 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
812 if (interfaceName
== NULL
) {
813 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
817 if ((net_interface
!= NULL
) && CFEqual(interface
, net_interface
)) {
821 if (childIndex
== 0) {
822 SCPrint(TRUE
, stdout
, CFSTR("%c%2d: %@\n"),
827 SCPrint(TRUE
, stdout
, CFSTR("%c%2d.%d: %@\n"),
834 interface
= SCNetworkInterfaceGetInterface(interface
);
836 } while (interface
!= NULL
);
844 #pragma mark Bond options
847 #if !TARGET_OS_IPHONE
850 static options bondOptions
[] = {
851 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
852 // xxx { "+device" , ... },
853 // xxx { "-device" , ... },
855 { "?" , NULL
, isHelp
, NULL
, NULL
,
856 "\nBond configuration commands\n\n"
857 " set interface [mtu n] [media type] [mediaopts opts]\n"
860 #define N_BOND_OPTIONS (sizeof(bondOptions) / sizeof(bondOptions[0]))
864 set_interface_bond(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
866 CFStringRef interfaceName
;
869 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
870 if (interfaceName
== NULL
) {
871 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
875 ok
= _process_options(bondOptions
, N_BOND_OPTIONS
, argc
, argv
, newConfiguration
);
877 // validate configuration
878 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
887 #endif // !TARGET_OS_IPHONE
891 #pragma mark AirPort options
894 static options airportOptions
[] = {
895 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
896 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
897 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
899 { "?" , NULL
, isHelp
, NULL
, NULL
,
900 "\nAirPort configuration commands\n\n"
901 " set interface [mtu n] [media type] [mediaopts opts]\n"
904 #define N_AIRPORT_OPTIONS (sizeof(airportOptions) / sizeof(airportOptions[0]))
908 set_interface_airport(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
910 CFStringRef interfaceName
;
913 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
914 if (interfaceName
== NULL
) {
915 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
919 ok
= _process_options(airportOptions
, N_AIRPORT_OPTIONS
, argc
, argv
, newConfiguration
);
921 // validate configuration
922 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
932 #pragma mark Ethernet options
935 static options ethernetOptions
[] = {
936 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
937 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
938 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
940 { "?" , NULL
, isHelp
, NULL
, NULL
,
941 "\nEthernet configuration commands\n\n"
942 " set interface [mtu n] [media type] [mediaopts opts]\n"
945 #define N_ETHERNET_OPTIONS (sizeof(ethernetOptions) / sizeof(ethernetOptions[0]))
949 set_interface_ethernet(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
951 CFStringRef interfaceName
;
954 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
955 if (interfaceName
== NULL
) {
956 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
960 ok
= _process_options(ethernetOptions
, N_ETHERNET_OPTIONS
, argc
, argv
, newConfiguration
);
962 // validate configuration
963 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
973 #pragma mark IPSec options
977 replaceOne(const void *key
, const void *value
, void *context
)
979 CFMutableDictionaryRef newConfiguration
= (CFMutableDictionaryRef
)context
;
981 CFDictionarySetValue(newConfiguration
, key
, value
);
987 updateInterfaceConfiguration(CFMutableDictionaryRef newConfiguration
)
989 CFDictionaryRef configuration
;
991 CFDictionaryRemoveAllValues(newConfiguration
);
993 configuration
= SCNetworkInterfaceGetConfiguration(net_interface
);
994 if (configuration
!= NULL
) {
995 CFDictionaryApplyFunction(configuration
, replaceOne
, (void *)newConfiguration
);
1003 __doIPSecSharedSecret(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1006 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret not specified\n"));
1010 if (strlen(argv
[0]) > 0) {
1011 CFStringRef encryptionType
;
1013 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetIPSecSharedSecretEncryption
);
1014 if (encryptionType
== NULL
) {
1016 CFMutableDataRef pw
;
1019 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1020 n
= CFStringGetLength(str
);
1021 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
1022 CFDataSetLength(pw
, n
* sizeof(UniChar
));
1023 CFStringGetCharacters(str
,
1025 (UniChar
*)CFDataGetMutableBytePtr(pw
));
1028 CFDictionarySetValue(newConfiguration
, key
, pw
);
1030 } else if (CFEqual(encryptionType
, kSCValNetIPSecSharedSecretEncryptionKeychain
)) {
1035 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1036 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
1037 ok
= SCNetworkInterfaceSetPassword(net_interface
,
1038 kSCNetworkInterfacePasswordTypeIPSecSharedSecret
,
1044 updateInterfaceConfiguration(newConfiguration
);
1049 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret type \"%@\" not supported\n"), encryptionType
);
1053 CFDictionaryRemoveValue(newConfiguration
, key
);
1061 __doIPSecSharedSecretType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1064 SCPrint(TRUE
, stdout
, CFSTR("IPSec shared secret type mode not specified\n"));
1068 if (strlen(argv
[0]) > 0) {
1069 if (strcasecmp(argv
[0], "keychain") == 0) {
1070 CFDictionarySetValue(newConfiguration
, key
, kSCValNetIPSecSharedSecretEncryptionKeychain
);
1072 SCPrint(TRUE
, stdout
, CFSTR("invalid shared secret type\n"));
1076 CFDictionaryRemoveValue(newConfiguration
, key
);
1079 // encryption type changed, reset shared secret
1080 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPSecSharedSecret
);
1087 __doIPSecXAuthPassword(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1090 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuth password not specified\n"));
1094 if (strlen(argv
[0]) > 0) {
1095 CFStringRef encryptionType
;
1097 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetIPSecXAuthPasswordEncryption
);
1098 if (encryptionType
== NULL
) {
1100 CFMutableDataRef pw
;
1103 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1104 n
= CFStringGetLength(str
);
1105 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
1106 CFDataSetLength(pw
, n
* sizeof(UniChar
));
1107 CFStringGetCharacters(str
,
1109 (UniChar
*)CFDataGetMutableBytePtr(pw
));
1112 CFDictionarySetValue(newConfiguration
, key
, pw
);
1114 } else if (CFEqual(encryptionType
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
)) {
1119 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1120 pw
= CFStringCreateExternalRepresentation(NULL
, str
, kCFStringEncodingUTF8
, 0);
1121 ok
= SCNetworkInterfaceSetPassword(net_interface
,
1122 kSCNetworkInterfacePasswordTypeIPSecXAuth
,
1128 updateInterfaceConfiguration(newConfiguration
);
1133 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuthPassword type \"%@\" not supported\n"), encryptionType
);
1137 CFDictionaryRemoveValue(newConfiguration
, key
);
1145 __doIPSecXAuthPasswordType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1148 SCPrint(TRUE
, stdout
, CFSTR("IPSec XAuth password type mode not specified\n"));
1152 if (strlen(argv
[0]) > 0) {
1153 if (strcasecmp(argv
[0], "keychain") == 0) {
1154 CFDictionarySetValue(newConfiguration
, key
, kSCValNetIPSecXAuthPasswordEncryptionKeychain
);
1156 SCPrint(TRUE
, stdout
, CFSTR("invalid XAuth password type\n"));
1160 CFDictionaryRemoveValue(newConfiguration
, key
);
1163 // encryption type changed, reset XAuthPassword
1164 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetIPSecXAuthPassword
);
1171 __cleanupDomainName(CFStringRef domain
)
1173 CFMutableStringRef newDomain
;
1175 newDomain
= CFStringCreateMutableCopy(NULL
, 0, domain
);
1176 CFStringTrimWhitespace(newDomain
);
1177 CFStringTrim(newDomain
, CFSTR("."));
1178 if (CFStringGetLength(newDomain
) == 0) {
1179 CFRelease(newDomain
);
1188 __doOnDemandDomains(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1190 CFMutableArrayRef domains
;
1193 SCPrint(TRUE
, stdout
, CFSTR("OnDemand domain name(s) not specified\n"));
1197 domains
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1199 if (strlen(argv
[0]) > 0) {
1203 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1204 array
= CFStringCreateArrayBySeparatingStrings(NULL
, str
, CFSTR(","));
1207 if (array
!= NULL
) {
1209 CFIndex n
= CFArrayGetCount(array
);
1211 for (i
= 0; i
< n
; i
++) {
1214 domain
= __cleanupDomainName(CFArrayGetValueAtIndex(array
, i
));
1215 if (domain
!= NULL
) {
1216 CFArrayAppendValue(domains
, domain
);
1221 SCPrint(TRUE
, stdout
, CFSTR("invalid OnDemand domain name\n"));
1229 if (CFArrayGetCount(domains
) > 0) {
1230 CFDictionarySetValue(newConfiguration
, key
, domains
);
1232 CFDictionaryRemoveValue(newConfiguration
, key
);
1240 static options ipsecOnDemandOptions
[] = {
1241 { "OnDemandMatchDomainsAlways" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1242 { "always" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1243 { "OnDemandMatchDomainsOnRetry", "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1244 { "retry" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1245 { "OnDemandMatchDomainsNever" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1246 { "never" , "domain", isOther
, &kSCPropNetIPSecOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1248 { "?" , NULL
, isHelp
, NULL
, NULL
,
1249 "\nOnDemandMatch configuration commands\n\n"
1250 " set interface OnDemandMatch always domain-name[,domain-name]\n"
1251 " set interface OnDemandMatch retry domain-name[,domain-name]\n"
1252 " set interface OnDemandMatch never domain-name[,domain-name]\n"
1255 #define N_IPSEC_ONDEMAND_OPTIONS (sizeof(ipsecOnDemandOptions) / sizeof(ipsecOnDemandOptions[0]))
1259 __doIPSecOnDemandMatch(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1264 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1268 ok
= _process_options(ipsecOnDemandOptions
, N_IPSEC_ONDEMAND_OPTIONS
, argc
, argv
, newConfiguration
);
1279 static selections ipsecAuthenticationMethodSelections
[] = {
1280 { CFSTR("SharedSecret"), &kSCValNetIPSecAuthenticationMethodSharedSecret
, 0 },
1281 { CFSTR("Certificate") , &kSCValNetIPSecAuthenticationMethodCertificate
, 0 },
1282 { CFSTR("Hybrid") , &kSCValNetIPSecAuthenticationMethodHybrid
, 0 },
1287 static selections ipsecLocalIdentifierTypeSelections
[] = {
1288 { CFSTR("KeyID") , &kSCValNetIPSecLocalIdentifierTypeKeyID
, 0 },
1293 static options ipsecOptions
[] = {
1294 { "AuthenticationMethod" , NULL
, isChooseOne
, &kSCPropNetIPSecAuthenticationMethod
, NULL
, (void *)ipsecAuthenticationMethodSelections
},
1295 { "LocalIdentifier" , NULL
, isString
, &kSCPropNetIPSecLocalIdentifier
, NULL
, NULL
},
1296 { "group" , NULL
, isString
, &kSCPropNetIPSecLocalIdentifier
, NULL
, NULL
},
1297 { "LocalIdentifierType" , NULL
, isChooseOne
, &kSCPropNetIPSecLocalIdentifierType
, NULL
, (void *)ipsecLocalIdentifierTypeSelections
},
1298 { "RemoteAddress" , NULL
, isString
, &kSCPropNetIPSecRemoteAddress
, NULL
, NULL
},
1299 { "SharedSecret" , NULL
, isOther
, &kSCPropNetIPSecSharedSecret
, __doIPSecSharedSecret
, NULL
},
1300 { "SharedSecretEncryption" , NULL
, isOther
, &kSCPropNetIPSecSharedSecretEncryption
, __doIPSecSharedSecretType
, NULL
},
1303 { "XAuthEnabled" , NULL
, isBoolean
, &kSCPropNetIPSecXAuthEnabled
, NULL
, NULL
},
1304 { "XAuthName" , NULL
, isString
, &kSCPropNetIPSecXAuthName
, NULL
, NULL
},
1305 { "XAuthPassword" , NULL
, isOther
, &kSCPropNetIPSecXAuthPassword
, __doIPSecXAuthPassword
, NULL
},
1306 { "XAuthPasswordEncryption", NULL
, isOther
, &kSCPropNetIPSecXAuthPasswordEncryption
, __doIPSecXAuthPasswordType
, NULL
},
1308 // --- OnDemand: ---
1309 { "OnDemandEnabled" , NULL
, isBoolean
, &kSCPropNetIPSecOnDemandEnabled
, NULL
, NULL
},
1310 { "OnDemandMatch" , NULL
, isOther
, NULL
, __doIPSecOnDemandMatch
, NULL
},
1312 { "?" , NULL
, isHelp
, NULL
, NULL
,
1313 "\nIPSec configuration commands\n\n"
1314 " set interface [AuthenticationMethod {SharedSecret|Certificate|Hybrid}]\n"
1315 " set interface [LocalIdentifier group]\n"
1316 " set interface [LocalIdentifierType {KeyID}]\n"
1317 " set interface [RemoteAddress name-or-address]\n"
1318 " set interface [SharedSecret secret]\n"
1319 " set interface [SharedSecretEncryption {Keychain}]\n"
1320 " set interface [XAuthEnabled {enable|disable}]\n"
1321 " set interface [XAuthPassword password]\n"
1322 " set interface [XAuthPasswordEncryption {Keychain}]\n"
1323 " set interface [OnDemandEnabled {enable|disable}]\n"
1324 " set interface [OnDemandMatch <match-options>]\n"
1327 #define N_IPSEC_OPTIONS (sizeof(ipsecOptions) / sizeof(ipsecOptions[0]))
1331 set_interface_ipsec(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1335 ok
= _process_options(ipsecOptions
, N_IPSEC_OPTIONS
, argc
, argv
, newConfiguration
);
1341 #pragma mark FireWire options
1344 static options firewireOptions
[] = {
1345 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
1346 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
1347 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
1349 { "?" , NULL
, isHelp
, NULL
, NULL
,
1350 "\nFireWire configuration commands\n\n"
1351 " set interface [mtu n] [media type] [mediaopts opts]\n"
1354 #define N_FIREWIRE_OPTIONS (sizeof(firewireOptions) / sizeof(firewireOptions[0]))
1358 set_interface_firewire(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1360 CFStringRef interfaceName
;
1363 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
1364 if (interfaceName
== NULL
) {
1365 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
1369 ok
= _process_options(firewireOptions
, N_FIREWIRE_OPTIONS
, argc
, argv
, newConfiguration
);
1371 // validate configuration
1372 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
1382 #pragma mark Modem options
1385 static selections modemDialSelections
[] = {
1386 { CFSTR("ignore"), &kSCValNetModemDialModeIgnoreDialTone
, 0 },
1387 { CFSTR("manual"), &kSCValNetModemDialModeManual
, 0 },
1388 { CFSTR("wait") , &kSCValNetModemDialModeWaitForDialTone
, 0 },
1392 static options modemOptions
[] = {
1393 { "ConnectionScript" , "script", isString
, &kSCPropNetModemConnectionScript
, NULL
, NULL
},
1394 { "DialMode" , "mode" , isChooseOne
, &kSCPropNetModemDialMode
, NULL
, (void *)modemDialSelections
},
1395 { "CallWaiting" , NULL
, isBoolean
, &kSCPropNetModemHoldEnabled
, NULL
, NULL
},
1396 { "CallWaitingAlert" , NULL
, isBoolean
, &kSCPropNetModemHoldCallWaitingAudibleAlert
, NULL
, NULL
},
1397 { "CallWaitingDisconnectOnAnswer", NULL
, isBoolean
, &kSCPropNetModemHoldDisconnectOnAnswer
, NULL
, NULL
},
1398 { "DataCompression" , NULL
, isBoolean
, &kSCPropNetModemDataCompression
, NULL
, NULL
},
1399 { "ErrorCorrection" , NULL
, isBoolean
, &kSCPropNetModemErrorCorrection
, NULL
, NULL
},
1400 { "HoldReminder" , NULL
, isBoolean
, &kSCPropNetModemHoldReminder
, NULL
, NULL
},
1401 { "HoldReminderTime" , "time" , isNumber
, &kSCPropNetModemHoldReminderTime
, NULL
, NULL
},
1402 { "PulseDial" , NULL
, isBoolean
, &kSCPropNetModemPulseDial
, NULL
, NULL
},
1403 { "Speaker" , NULL
, isBoolean
, &kSCPropNetModemSpeaker
, NULL
, NULL
},
1405 { "?" , NULL
, isHelp
, NULL
, NULL
,
1406 "\nModem configuration commands\n\n"
1407 " set interface [ConnectionScript connection-script]\n"
1408 " set interface [CallWaiting {enable|disable}]\n"
1409 " set interface [CallWaitingAlert {enable|disable}]\n"
1410 " set interface [CallWaitingDisconnectOnAnswer {enable|disable}]\n"
1411 " set interface [DialMode {ignore|wait}]\n"
1412 " set interface [DataCompression {enable|disable}]\n"
1413 " set interface [ErrorCorrection {enable|disable}]\n"
1414 " set interface [HoldReminder {enable|disable}]\n"
1415 " set interface [HoldReminderTime n]\n"
1416 " set interface [PulseDial {enable|disable}]\n"
1417 " set interface [Speaker {enable|disable}]\n"
1420 #define N_MODEM_OPTIONS (sizeof(modemOptions) / sizeof(modemOptions[0]))
1424 set_interface_modem(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1428 ok
= _process_options(modemOptions
, N_MODEM_OPTIONS
, argc
, argv
, newConfiguration
);
1434 #pragma mark PPP options
1438 __doPPPAuthPW(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1441 SCPrint(TRUE
, stdout
, CFSTR("PPP password not specified\n"));
1445 if (strlen(argv
[0]) > 0) {
1446 CFStringRef encryptionType
;
1448 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetPPPAuthPasswordEncryption
);
1449 if (encryptionType
== NULL
) {
1451 CFMutableDataRef pw
;
1454 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1455 n
= CFStringGetLength(str
);
1456 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
1457 CFDataSetLength(pw
, n
* sizeof(UniChar
));
1458 CFStringGetCharacters(str
,
1460 (UniChar
*)CFDataGetMutableBytePtr(pw
));
1463 CFDictionarySetValue(newConfiguration
, key
, pw
);
1466 SCPrint(TRUE
, stdout
, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType
);
1470 CFDictionaryRemoveValue(newConfiguration
, key
);
1478 __doPPPAuthPWType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1481 SCPrint(TRUE
, stdout
, CFSTR("PPP password type mode not specified\n"));
1485 if (strlen(argv
[0]) > 0) {
1486 if (strcasecmp(argv
[0], "keychain") == 0) {
1487 CFDictionarySetValue(newConfiguration
, key
, kSCValNetPPPAuthPasswordEncryptionKeychain
);
1489 SCPrint(TRUE
, stdout
, CFSTR("invalid password type\n"));
1493 CFDictionaryRemoveValue(newConfiguration
, key
);
1496 // encryption type changed, reset password
1497 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetPPPAuthPassword
);
1503 static options l2tp_ipsecOptions
[] = {
1504 { "SharedSecret" , NULL
, isOther
, &kSCPropNetIPSecSharedSecret
, __doIPSecSharedSecret
, NULL
},
1505 { "SharedSecretEncryption", NULL
, isOther
, &kSCPropNetIPSecSharedSecretEncryption
, __doIPSecSharedSecretType
, NULL
},
1507 { "?" , NULL
, isHelp
, NULL
, NULL
,
1508 "\nIPSec configuration commands\n\n"
1509 " set interface ipsec [SharedSecret secret]\n"
1510 " set interface ipsec [SharedSecretEncryption {Keychain}]\n"
1513 #define N_L2TP_IPSEC_OPTIONS (sizeof(l2tp_ipsecOptions) / sizeof(l2tp_ipsecOptions[0]))
1517 __doPPPIPSec(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newPPPConfiguration
)
1519 SCNetworkInterfaceRef childInterface
;
1520 CFStringRef childInterfaceType
;
1521 CFDictionaryRef configuration
;
1522 CFMutableDictionaryRef newConfiguration
;
1526 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1530 childInterface
= SCNetworkInterfaceGetInterface(net_interface
);
1531 if (childInterface
== NULL
) {
1532 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
1536 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
1537 if (!CFEqual(childInterfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
1538 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
1542 configuration
= SCNetworkInterfaceGetExtendedConfiguration(net_interface
, kSCEntNetIPSec
);
1543 if (configuration
== NULL
) {
1544 newConfiguration
= CFDictionaryCreateMutable(NULL
,
1546 &kCFTypeDictionaryKeyCallBacks
,
1547 &kCFTypeDictionaryValueCallBacks
);
1549 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
1550 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
1553 ok
= _process_options(l2tp_ipsecOptions
, N_L2TP_IPSEC_OPTIONS
, argc
, argv
, newConfiguration
);
1558 if (((configuration
== NULL
) && (CFDictionaryGetCount(newConfiguration
) > 0)) ||
1559 ((configuration
!= NULL
) && !CFEqual(configuration
, newConfiguration
))) {
1560 if (!SCNetworkInterfaceSetExtendedConfiguration(net_interface
, kSCEntNetIPSec
, newConfiguration
)) {
1561 if (SCError() == kSCStatusNoKey
) {
1562 SCPrint(TRUE
, stdout
, CFSTR("could not update per-service interface configuration\n"));
1564 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
1569 _prefs_changed
= TRUE
;
1574 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
1580 static options pppOnDemandOptions
[] = {
1581 { "OnDemandMatchDomainsAlways" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1582 { "always" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsAlways
, __doOnDemandDomains
, NULL
},
1583 { "OnDemandMatchDomainsOnRetry", "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1584 { "retry" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsOnRetry
, __doOnDemandDomains
, NULL
},
1585 { "OnDemandMatchDomainsNever" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1586 { "never" , "domain", isOther
, &kSCPropNetPPPOnDemandMatchDomainsNever
, __doOnDemandDomains
, NULL
},
1588 { "?" , NULL
, isHelp
, NULL
, NULL
,
1589 "\nOnDemandMatch configuration commands\n\n"
1590 " set interface OnDemand always domain-name[,domain-name]\n"
1591 " set interface OnDemand retry domain-name[,domain-name]\n"
1592 " set interface OnDemand never domain-name[,domain-name]\n"
1595 #define N_PPP_ONDEMAND_OPTIONS (sizeof(pppOnDemandOptions) / sizeof(pppOnDemandOptions[0]))
1599 __doPPPOnDemandMatch(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1604 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1608 ok
= _process_options(pppOnDemandOptions
, N_PPP_ONDEMAND_OPTIONS
, argc
, argv
, newConfiguration
);
1620 static selections authPromptSelections
[] = {
1621 { CFSTR("before"), &kSCValNetPPPAuthPromptBefore
, 0 },
1622 { CFSTR("after") , &kSCValNetPPPAuthPromptAfter
, 0 },
1627 static selections authProtocolSelections
[] = {
1628 { CFSTR("CHAP") , &kSCValNetPPPAuthProtocolCHAP
, 0 },
1629 { CFSTR("EAP") , &kSCValNetPPPAuthProtocolEAP
, 0 },
1630 { CFSTR("MSCHAP1"), &kSCValNetPPPAuthProtocolMSCHAP1
, 0 },
1631 { CFSTR("MSCHAP2"), &kSCValNetPPPAuthProtocolMSCHAP2
, 0 },
1632 { CFSTR("PAP") , &kSCValNetPPPAuthProtocolPAP
, 0 },
1637 static options pppOptions
[] = {
1638 { "ACSP" , NULL
, isBoolean
, &kSCPropNetPPPACSPEnabled
, NULL
, NULL
},
1639 { "ConnectTime" , "?time" , isNumber
, &kSCPropNetPPPConnectTime
, NULL
, NULL
},
1640 { "DialOnDemand" , NULL
, isBoolean
, &kSCPropNetPPPDialOnDemand
, NULL
, NULL
},
1641 { "DisconnectOnFastUserSwitch", NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnFastUserSwitch
, NULL
, NULL
},
1642 { "DisconnectOnIdle" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnIdle
, NULL
, NULL
},
1643 { "DisconnectOnIdleTimer" , "timeout" , isNumber
, &kSCPropNetPPPDisconnectOnIdleTimer
, NULL
, NULL
},
1644 { "DisconnectOnLogout" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnLogout
, NULL
, NULL
},
1645 { "DisconnectOnSleep" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnSleep
, NULL
, NULL
},
1646 { "DisconnectTime" , "?time" , isNumber
, &kSCPropNetPPPDisconnectTime
, NULL
, NULL
},
1647 { "IdleReminder" , NULL
, isBoolean
, &kSCPropNetPPPIdleReminder
, NULL
, NULL
},
1648 { "IdleReminderTimer" , "time" , isNumber
, &kSCPropNetPPPIdleReminderTimer
, NULL
, NULL
},
1649 { "Logfile" , "path" , isString
, &kSCPropNetPPPLogfile
, NULL
, NULL
},
1650 { "Plugins" , "plugin" , isStringArray
, &kSCPropNetPPPPlugins
, NULL
, NULL
},
1651 { "RetryConnectTime" , "time" , isNumber
, &kSCPropNetPPPRetryConnectTime
, NULL
, NULL
},
1652 { "SessionTimer" , "time" , isNumber
, &kSCPropNetPPPSessionTimer
, NULL
, NULL
},
1653 { "UseSessionTimer" , NULL
, isBoolean
, &kSCPropNetPPPUseSessionTimer
, NULL
, NULL
},
1654 { "VerboseLogging" , NULL
, isBoolean
, &kSCPropNetPPPVerboseLogging
, NULL
, NULL
},
1657 { "AuthEAPPlugins" , "plugin" , isStringArray
, &kSCPropNetPPPAuthEAPPlugins
, NULL
, NULL
},
1658 { "AuthName" , "account" , isString
, &kSCPropNetPPPAuthName
, NULL
, NULL
},
1659 { "Account" , "account" , isString
, &kSCPropNetPPPAuthName
, NULL
, NULL
},
1660 { "AuthPassword" , "password" , isOther
, &kSCPropNetPPPAuthPassword
, __doPPPAuthPW
, NULL
},
1661 { "Password" , "password" , isOther
, &kSCPropNetPPPAuthPassword
, __doPPPAuthPW
, NULL
},
1662 { "AuthPasswordEncryption" , "type" , isOther
, &kSCPropNetPPPAuthPasswordEncryption
, __doPPPAuthPWType
, NULL
},
1663 { "AuthPrompt" , "before/after", isChooseOne
, &kSCPropNetPPPAuthPrompt
, NULL
, (void *)authPromptSelections
},
1664 { "AuthProtocol" , "protocol" , isChooseMultiple
, &kSCPropNetPPPAuthProtocol
, NULL
, (void *)authProtocolSelections
},
1667 { "CommRemoteAddress" , "phone#" , isString
, &kSCPropNetPPPCommRemoteAddress
, NULL
, NULL
},
1668 { "CommAlternateRemoteAddress", "phone#" , isString
, &kSCPropNetPPPCommAlternateRemoteAddress
, NULL
, NULL
},
1669 { "CommConnectDelay" , "time" , isNumber
, &kSCPropNetPPPCommConnectDelay
, NULL
, NULL
},
1670 { "CommDisplayTerminalWindow" , NULL
, isBoolean
, &kSCPropNetPPPCommDisplayTerminalWindow
, NULL
, NULL
},
1671 { "CommRedialCount" , "retry count" , isNumber
, &kSCPropNetPPPCommRedialCount
, NULL
, NULL
},
1672 { "CommRedialEnabled" , NULL
, isBoolean
, &kSCPropNetPPPCommRedialEnabled
, NULL
, NULL
},
1673 { "CommRedialInterval" , "retry delay" , isNumber
, &kSCPropNetPPPCommRedialInterval
, NULL
, NULL
},
1674 { "CommTerminalScript" , "script" , isString
, &kSCPropNetPPPCommTerminalScript
, NULL
, NULL
},
1675 { "CommUseTerminalScript" , NULL
, isBoolean
, &kSCPropNetPPPCommUseTerminalScript
, NULL
, NULL
},
1678 { "CCPEnabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPEnabled
, NULL
, NULL
},
1679 { "CCPMPPE40Enabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPMPPE40Enabled
, NULL
, NULL
},
1680 { "CCPMPPE128Enabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPMPPE128Enabled
, NULL
, NULL
},
1683 { "IPCPCompressionVJ" , NULL
, isBoolean
, &kSCPropNetPPPIPCPCompressionVJ
, NULL
, NULL
},
1684 { "IPCPUsePeerDNS" , NULL
, isBoolean
, &kSCPropNetPPPIPCPUsePeerDNS
, NULL
, NULL
},
1687 { "LCPEchoEnabled" , NULL
, isBoolean
, &kSCPropNetPPPLCPEchoEnabled
, NULL
, NULL
},
1688 { "LCPEchoFailure" , NULL
, isNumber
, &kSCPropNetPPPLCPEchoFailure
, NULL
, NULL
},
1689 { "LCPEchoInterval" , NULL
, isNumber
, &kSCPropNetPPPLCPEchoInterval
, NULL
, NULL
},
1690 { "LCPCompressionACField" , NULL
, isBoolean
, &kSCPropNetPPPLCPCompressionACField
, NULL
, NULL
},
1691 { "LCPCompressionPField" , NULL
, isBoolean
, &kSCPropNetPPPLCPCompressionPField
, NULL
, NULL
},
1692 { "LCPMRU" , NULL
, isNumber
, &kSCPropNetPPPLCPMRU
, NULL
, NULL
},
1693 { "LCPMTU" , NULL
, isNumber
, &kSCPropNetPPPLCPMTU
, NULL
, NULL
},
1694 { "LCPReceiveACCM" , NULL
, isNumber
, &kSCPropNetPPPLCPReceiveACCM
, NULL
, NULL
},
1695 { "LCPTransmitACCM" , NULL
, isNumber
, &kSCPropNetPPPLCPTransmitACCM
, NULL
, NULL
},
1698 { "IPSec" , NULL
, isOther
, NULL
, __doPPPIPSec
, NULL
},
1701 // --- OnDemand: ---
1702 { "OnDemandEnabled" , NULL
, isBoolean
, &kSCPropNetPPPOnDemandEnabled
, NULL
, NULL
},
1703 { "OnDemandMatch" , NULL
, isOther
, NULL
, __doPPPOnDemandMatch
, NULL
},
1707 { "?" , NULL
, isHelp
, NULL
, NULL
,
1708 "\nPPP configuration commands\n\n"
1709 " set interface [Account account]\n"
1710 " set interface [Password password]\n"
1711 " set interface [Number telephone-number]\n"
1712 " set interface [AlternateNumber telephone-number]\n"
1713 " set interface [IdleReminder {enable|disable}]\n"
1714 " set interface [IdleReminderTimer time-in-seconds]\n"
1715 " set interface [DisconnectOnIdle {enable|disable}]\n"
1716 " set interface [DisconnectOnIdleTimer time-in-seconds]\n"
1717 " set interface [DisconnectOnLogout {enable|disable}]\n"
1718 " set interface [IPSec <ipsec-options>]\n"
1720 " set interface [OnDemandEnabled {enable|disable}]\n"
1721 " set interface [OnDemandMatch <match-options>]\n"
1725 #define N_PPP_OPTIONS (sizeof(pppOptions) / sizeof(pppOptions[0]))
1729 set_interface_ppp(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1733 ok
= _process_options(pppOptions
, N_PPP_OPTIONS
, argc
, argv
, newConfiguration
);
1739 #pragma mark VLAN options
1742 #if !TARGET_OS_IPHONE
1746 set_interface_vlan(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1748 // xxxxx ("device", "tag")
1749 SCPrint(TRUE
, stdout
, CFSTR("vlan interface management not yet supported\n"));
1754 #endif // !TARGET_OS_IPHONE
1758 #pragma mark [more] Interface management
1763 set_interface(int argc
, char **argv
)
1765 CFDictionaryRef configuration
;
1766 CFStringRef interfaceType
;
1767 CFMutableDictionaryRef newConfiguration
= NULL
;
1770 if (net_interface
== NULL
) {
1771 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
1776 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1780 configuration
= SCNetworkInterfaceGetConfiguration(net_interface
);
1781 if (configuration
!= NULL
) {
1782 configuration
= CFDictionaryCreateCopy(NULL
, configuration
);
1783 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
1784 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
1786 newConfiguration
= CFDictionaryCreateMutable(NULL
,
1788 &kCFTypeDictionaryKeyCallBacks
,
1789 &kCFTypeDictionaryValueCallBacks
);
1792 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
1794 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeEthernet
)) {
1795 ok
= set_interface_ethernet(argc
, argv
, newConfiguration
);
1796 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeFireWire
)) {
1797 ok
= set_interface_firewire(argc
, argv
, newConfiguration
);
1798 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
1799 ok
= set_interface_ipsec(argc
, argv
, newConfiguration
);
1800 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeModem
)) {
1801 ok
= set_interface_modem(argc
, argv
, newConfiguration
);
1802 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIEEE80211
)) {
1803 ok
= set_interface_airport(argc
, argv
, newConfiguration
);
1804 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
1805 ok
= set_interface_ppp(argc
, argv
, newConfiguration
);
1806 #if !TARGET_OS_IPHONE
1807 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
1808 ok
= set_interface_bond(argc
, argv
, newConfiguration
);
1809 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
1810 ok
= set_interface_vlan(argc
, argv
, newConfiguration
);
1811 #endif // !TARGET_OS_IPHONE
1813 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
1820 if (((configuration
== NULL
) && (CFDictionaryGetCount(newConfiguration
) > 0)) ||
1821 ((configuration
!= NULL
) && !CFEqual(configuration
, newConfiguration
))) {
1822 if (!SCNetworkInterfaceSetConfiguration(net_interface
, newConfiguration
)) {
1823 if (SCError() == kSCStatusNoKey
) {
1824 SCPrint(TRUE
, stdout
, CFSTR("could not update per-service interface configuration\n"));
1826 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
1831 _prefs_changed
= TRUE
;
1836 if (configuration
!= NULL
) CFRelease(configuration
);
1837 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
1842 /* -------------------- */
1847 show_interface(int argc
, char **argv
)
1849 SCNetworkInterfaceRef interface
;
1852 interface
= _find_interface(argc
, argv
, NULL
);
1854 if (net_interface
!= NULL
) {
1855 interface
= net_interface
;
1857 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
1862 if (interface
!= NULL
) {
1863 _show_interface(interface
, CFSTR(""), TRUE
);
1870 /* -------------------- */
1875 _interface_description(SCNetworkInterfaceRef interface
)
1877 CFMutableStringRef description
;
1878 CFStringRef if_bsd_name
;
1879 CFStringRef if_type
;
1881 description
= CFStringCreateMutable(NULL
, 0);
1883 if_type
= SCNetworkInterfaceGetInterfaceType(interface
);
1884 CFStringAppend(description
, if_type
);
1886 if_bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
1887 if (if_bsd_name
!= NULL
) {
1888 CFStringAppendFormat(description
, NULL
, CFSTR(" (%@)"), if_bsd_name
);
1891 interface
= SCNetworkInterfaceGetInterface(interface
);
1892 while ((interface
!= NULL
) &&
1893 !CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
1894 CFStringRef childDescription
;
1896 childDescription
= _interface_description(interface
);
1897 CFStringAppendFormat(description
, NULL
, CFSTR(" / %@"), childDescription
);
1898 CFRelease(childDescription
);
1900 interface
= SCNetworkInterfaceGetInterface(interface
);