2 * Copyright (c) 2004-2006 Apple Computer, 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>
39 /* -------------------- */
45 CFMutableArrayRef interfaces
;
46 CFArrayRef real_interfaces
;
48 real_interfaces
= SCNetworkInterfaceCopyAll();
49 if (real_interfaces
== NULL
) {
50 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
54 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
56 // include real interfaces
57 CFArrayAppendArray(interfaces
,
59 CFRangeMake(0, CFArrayGetCount(real_interfaces
)));
60 CFRelease(real_interfaces
);
62 // include pseudo interfaces
63 CFArrayAppendValue(interfaces
, kSCNetworkInterfaceIPv4
);
65 // include interfaces that we have created
66 if (new_interfaces
!= NULL
) {
67 CFArrayAppendArray(interfaces
,
69 CFRangeMake(0, CFArrayGetCount(new_interfaces
)));
72 return (CFArrayRef
)interfaces
;
78 _find_interface(char *match
)
80 Boolean allowIndex
= TRUE
;
83 CFStringRef select_name
= NULL
;
84 SCNetworkInterfaceRef selected
= NULL
;
86 if (strcasecmp(match
, "$child") == 0) {
87 if (net_interface
== NULL
) {
88 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
92 selected
= SCNetworkInterfaceGetInterface(net_interface
);
93 if(selected
== NULL
) {
94 SCPrint(TRUE
, stdout
, CFSTR("no child interface\n"));
98 } else if (strcasecmp(match
, "$service") == 0) {
99 if (net_service
== NULL
) {
100 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
104 selected
= SCNetworkServiceGetInterface(net_service
);
105 if(selected
== NULL
) {
106 SCPrint(TRUE
, stdout
, CFSTR("no interface for service\n"));
112 if (interfaces
== NULL
) {
113 interfaces
= _copy_interfaces();
114 if (interfaces
== NULL
) {
120 // try to select the interface by its display name
122 select_name
= CFStringCreateWithCString(NULL
, match
, kCFStringEncodingUTF8
);
124 n
= CFArrayGetCount(interfaces
);
125 for (i
= 0; i
< n
; i
++) {
126 SCNetworkInterfaceRef interface
;
127 CFStringRef interfaceName
;
129 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
130 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
131 if ((interfaceName
!= NULL
) && CFEqual(select_name
, interfaceName
)) {
132 if (selected
== NULL
) {
133 selected
= interface
;
135 // if multiple interfaces match
137 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
143 if (selected
!= NULL
) {
147 // try to select the interface by its BSD name
149 for (i
= 0; i
< n
; i
++) {
150 SCNetworkInterfaceRef interface
;
151 CFStringRef bsd_name
= NULL
;
153 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
154 while ((interface
!= NULL
) && (bsd_name
== NULL
)) {
155 bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
156 if (bsd_name
== NULL
) {
157 interface
= SCNetworkInterfaceGetInterface(interface
);
161 if ((bsd_name
!= NULL
) && CFEqual(select_name
, bsd_name
)) {
162 if (selected
== NULL
) {
163 selected
= interface
;
165 // if multiple interfaces match
167 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
173 if (selected
!= NULL
) {
177 // try to select the interface by its interface type
179 for (i
= 0; i
< n
; i
++) {
180 SCNetworkInterfaceRef interface
;
181 CFStringRef interfaceType
;
183 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
184 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
185 if (CFEqual(select_name
, interfaceType
)) {
186 if (selected
== NULL
) {
187 selected
= interface
;
189 // if multiple interfaces match
191 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
197 if (selected
!= NULL
) {
206 // try to select the interface by its index
209 val
= strtol(str
, &end
, 10);
210 if ((*str
!= '\0') &&
211 ((*end
== '\0') || (*end
== '.')) &&
213 if ((val
> 0) && (val
<= n
)) {
214 selected
= CFArrayGetValueAtIndex(interfaces
, val
- 1);
218 val
= strtol(str
, &end
, 10);
219 if ((*str
!= '\0') && (*end
== '\0') && (errno
== 0)) {
221 selected
= SCNetworkInterfaceGetInterface(selected
);
222 if (selected
== NULL
) {
232 if (selected
!= NULL
) {
236 SCPrint(TRUE
, stdout
, CFSTR("no match\n"));
240 if (select_name
!= NULL
) CFRelease(select_name
);
245 /* -------------------- */
250 create_interface(int argc
, char **argv
)
252 SCNetworkInterfaceRef interface
;
253 CFStringRef interfaceName
;
254 CFStringRef interfaceType
;
255 SCNetworkInterfaceRef new_interface
;
258 SCPrint(TRUE
, stdout
, CFSTR("what interface type?\n"));
262 interfaceType
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
264 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
266 SCPrint(TRUE
, stdout
, CFSTR("vlan creation not yet supported\n"));
268 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
270 SCPrint(TRUE
, stdout
, CFSTR("bond creation not yet supported\n"));
274 if (net_interface
== NULL
) {
275 SCPrint(TRUE
, stdout
, CFSTR("no network interface selected\n"));
279 interface
= net_interface
;
281 interface
= _find_interface(argv
[1]);
284 if (interface
== NULL
) {
288 new_interface
= SCNetworkInterfaceCreateWithInterface(interface
, interfaceType
);
289 if (new_interface
== NULL
) {
290 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
295 if (new_interfaces
== NULL
) {
296 new_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
298 CFArrayAppendValue(new_interfaces
, new_interface
);
300 if (net_interface
!= NULL
) CFRelease(net_interface
);
301 net_interface
= new_interface
;
303 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(net_interface
);
304 if (interfaceName
== NULL
) {
305 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
307 if (interfaceName
== NULL
) {
308 interfaceName
= SCNetworkInterfaceGetInterfaceType(net_interface
);
310 SCPrint(TRUE
, stdout
, CFSTR("interface \"%@\" created and selected\n"), interfaceName
);
314 CFRelease(interfaceType
);
319 /* -------------------- */
324 select_interface(int argc
, char **argv
)
326 SCNetworkInterfaceRef interface
;
328 interface
= _find_interface(argv
[0]);
330 if (interface
!= NULL
) {
331 CFStringRef interfaceName
;
333 if (net_interface
!= NULL
) CFRelease(net_interface
);
334 net_interface
= CFRetain(interface
);
336 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
337 if (interfaceName
== NULL
) {
338 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
340 if (interfaceName
== NULL
) {
341 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
344 SCPrint(TRUE
, stdout
, CFSTR("interface \"%@\" selected\n"), interfaceName
);
351 /* -------------------- */
356 _show_interface(SCNetworkInterfaceRef interface
, CFStringRef prefix
, Boolean showChild
)
358 CFDictionaryRef configuration
;
359 CFStringRef if_bsd_name
;
360 CFStringRef if_localized_name
;
361 CFStringRef if_mac_address
;
363 CFArrayRef supported
;
365 if_localized_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
366 if (if_localized_name
!= NULL
) {
367 SCPrint(TRUE
, stdout
, CFSTR("%@ name = %@\n"), prefix
, if_localized_name
);
370 if_bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
371 if (if_bsd_name
!= NULL
) {
372 SCPrint(TRUE
, stdout
, CFSTR("%@ interface name = %@\n"), prefix
, if_bsd_name
);
375 if_type
= SCNetworkInterfaceGetInterfaceType(interface
);
376 SCPrint(TRUE
, stdout
, CFSTR("%@ type = %@\n"), prefix
, if_type
);
378 if_mac_address
= SCNetworkInterfaceGetHardwareAddressString(interface
);
379 if (if_mac_address
!= NULL
) {
380 SCPrint(TRUE
, stdout
, CFSTR("%@ address = %@\n"), prefix
, if_mac_address
);
383 configuration
= SCNetworkInterfaceGetConfiguration(interface
);
384 if ((configuration
!= NULL
) &&
385 CFDictionaryContainsKey(configuration
, kSCResvInactive
)) {
386 configuration
= NULL
;
389 if (if_bsd_name
!= NULL
) {
390 CFArrayRef available
;
391 CFDictionaryRef active
;
396 if (SCNetworkInterfaceCopyMTU(interface
, &mtu_cur
, &mtu_min
, &mtu_max
)) {
397 char isCurrent
= '*';
399 if (configuration
!= NULL
) {
403 num
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMTU
);
404 if (isA_CFNumber(num
)) {
405 CFNumberGetValue(num
, kCFNumberIntType
, &mtu_req
);
406 if (mtu_cur
!= mtu_req
) {
413 SCPrint(TRUE
, stdout
, CFSTR("%@ mtu %c = %ld (%ld < n < %ld)\n"),
421 if (SCNetworkInterfaceCopyMediaOptions(interface
, NULL
, &active
, &available
, TRUE
)) {
422 char isCurrent
= ' ';
423 CFArrayRef options
= NULL
;
424 CFArrayRef options_req
= NULL
;
425 CFStringRef subtype
= NULL
;
426 CFStringRef subtype_req
= NULL
;
428 if (configuration
!= NULL
) {
429 subtype_req
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMediaSubType
);
430 options_req
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMediaOptions
);
433 if (subtype_req
== NULL
) {
434 subtype_req
= CFSTR("autoselect");
437 if (active
!= NULL
) {
438 subtype
= CFDictionaryGetValue(active
, kSCPropNetEthernetMediaSubType
);
439 options
= CFDictionaryGetValue(active
, kSCPropNetEthernetMediaOptions
);
442 if (subtype
!= NULL
) {
443 if (((subtype_req
!= NULL
) &&
444 CFEqual(subtype
, subtype_req
)) &&
445 ((options
== options_req
) ||
446 ((options
!= NULL
) &&
447 (options_req
!= NULL
) &&
448 CFEqual(options
, options_req
)))
451 } else if ((subtype_req
== NULL
) ||
452 ((subtype_req
!= NULL
) &&
453 CFEqual(subtype_req
, CFSTR("autoselect")))) {
454 // if requested subtype not specified or "autoselect"
459 if (subtype_req
!= NULL
) {
460 SCPrint(TRUE
, stdout
, CFSTR("%@ media %c = %@"),
465 if ((options_req
!= NULL
) &&
466 (CFArrayGetCount(options_req
) > 0)) {
467 CFStringRef options_str
;
469 options_str
= CFStringCreateByCombiningStrings(NULL
, options_req
, CFSTR(","));
470 SCPrint(TRUE
, stdout
, CFSTR(" <%@>"), options_str
);
471 CFRelease(options_str
);
474 SCPrint(TRUE
, stdout
, CFSTR("\n"));
477 SCPrint(TRUE
, stdout
, CFSTR("\n"));
479 if (available
!= NULL
) {
484 subtypes
= SCNetworkInterfaceCopyMediaSubTypes(available
);
485 n_subtypes
= (subtypes
!= NULL
) ? CFArrayGetCount(subtypes
) : 0;
486 for (i
= 0; i
< n_subtypes
; i
++) {
488 CFIndex n_subtype_options
;
490 CFArrayRef subtype_options
;
492 subtype
= CFArrayGetValueAtIndex(subtypes
, i
);
493 subtype_options
= SCNetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
494 n_subtype_options
= (subtype_options
!= NULL
) ? CFArrayGetCount(subtype_options
) : 0;
495 for (j
= 0; j
< n_subtype_options
; j
++) {
496 char isCurrent
= ' ';
499 options
= CFArrayGetValueAtIndex(subtype_options
, j
);
501 if (((subtype_req
!= NULL
) &&
502 CFEqual(subtype
, subtype_req
)) &&
503 ((options
== options_req
) ||
504 ((options
!= NULL
) &&
505 (options_req
!= NULL
) &&
506 CFEqual(options
, options_req
)))
511 SCPrint(TRUE
, stdout
, CFSTR("%@ %s %c = %@"),
513 ((i
== 0) && (j
== 0)) ? "supported media" : " ",
517 if ((options
!= NULL
) &&
518 (CFArrayGetCount(options
) > 0)) {
519 CFStringRef options_str
;
521 options_str
= CFStringCreateByCombiningStrings(NULL
, options
, CFSTR(","));
522 SCPrint(TRUE
, stdout
, CFSTR(" <%@>"), options_str
);
523 CFRelease(options_str
);
526 SCPrint(TRUE
, stdout
, CFSTR("\n"));
528 CFRelease(subtype_options
);
532 SCPrint(TRUE
, stdout
, CFSTR("\n"));
536 supported
= SCNetworkInterfaceGetSupportedInterfaceTypes(interface
);
537 SCPrint(TRUE
, stdout
, CFSTR("%@ supported interfaces = "), prefix
);
538 if (supported
!= NULL
) {
540 CFIndex n
= CFArrayGetCount(supported
);
542 for (i
= 0; i
< n
; i
++) {
543 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
544 (i
== 0) ? "" : ", ",
545 CFArrayGetValueAtIndex(supported
, i
));
548 SCPrint(TRUE
, stdout
, CFSTR("\n"));
550 supported
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
);
551 SCPrint(TRUE
, stdout
, CFSTR("%@ supported protocols = "), prefix
);
552 if (supported
!= NULL
) {
554 CFIndex n
= CFArrayGetCount(supported
);
556 for (i
= 0; i
< n
; i
++) {
557 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
558 (i
== 0) ? "" : ", ",
559 CFArrayGetValueAtIndex(supported
, i
));
562 SCPrint(TRUE
, stdout
, CFSTR("\n"));
564 if (configuration
!= NULL
) {
565 CFMutableDictionaryRef effective
;
567 effective
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
569 // remove known (and already reported) interface configuration keys
570 if (CFDictionaryContainsKey(effective
, kSCResvInactive
)) {
571 CFDictionaryRemoveAllValues(effective
);
573 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMTU
);
574 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMediaSubType
);
575 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMediaOptions
);
577 if (CFDictionaryGetCount(effective
) > 0) {
578 SCPrint(TRUE
, stdout
, CFSTR("\n%@ per-interface configuration\n"), prefix
);
579 _show_entity(effective
, prefix
);
582 CFRelease(effective
);
586 SCPrint(TRUE
, stdout
, CFSTR("\n%@\n"), interface
);
589 interface
= SCNetworkInterfaceGetInterface(interface
);
590 if (interface
!= NULL
) {
591 CFStringRef newPrefix
;
593 newPrefix
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@ "), prefix
);
594 SCPrint(TRUE
, stdout
, CFSTR("\n%@child interface\n"), newPrefix
);
595 _show_interface(interface
, newPrefix
, showChild
);
596 CFRelease(newPrefix
);
603 /* -------------------- */
607 validateMediaOptions(SCNetworkInterfaceRef interface
, CFMutableDictionaryRef newConfiguration
)
614 mtu
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMTU
);
615 if (isA_CFNumber(mtu
)) {
620 if (!SCNetworkInterfaceCopyMTU(interface
, NULL
, &mtu_min
, &mtu_max
)) {
621 SCPrint(TRUE
, stdout
, CFSTR("cannot set MTU\n"));
625 if (!CFNumberGetValue(mtu
, kCFNumberIntType
, &mtu_val
) ||
626 (mtu_val
< mtu_min
) ||
627 (mtu_val
> mtu_max
)) {
628 SCPrint(TRUE
, stdout
, CFSTR("mtu out of range\n"));
633 subtype
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMediaSubType
);
634 options
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMediaOptions
);
636 if (subtype
!= NULL
) {
637 CFArrayRef available
= NULL
;
638 CFArrayRef config_options
= options
;
639 CFArrayRef subtypes
= NULL
;
640 CFArrayRef subtype_options
= NULL
;
644 if (options
== NULL
) {
645 config_options
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
648 if (!SCNetworkInterfaceCopyMediaOptions(interface
, NULL
, NULL
, &available
, FALSE
)) {
649 SCPrint(TRUE
, stdout
, CFSTR("media type / options not available\n"));
653 if (available
== NULL
) {
657 subtypes
= SCNetworkInterfaceCopyMediaSubTypes(available
);
658 if ((subtypes
== NULL
) ||
659 !CFArrayContainsValue(subtypes
,
660 CFRangeMake(0, CFArrayGetCount(subtypes
)),
662 SCPrint(TRUE
, stdout
, CFSTR("media type not valid\n"));
666 subtype_options
= SCNetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
667 if ((subtype_options
== NULL
) ||
668 !CFArrayContainsValue(subtype_options
,
669 CFRangeMake(0, CFArrayGetCount(subtype_options
)),
671 SCPrint(TRUE
, stdout
, CFSTR("media options not valid for \"%@\"\n"), subtype
);
675 if (options
== NULL
) {
676 CFDictionarySetValue(newConfiguration
, kSCPropNetEthernetMediaOptions
, config_options
);
683 if (available
!= NULL
) CFRelease(available
);
684 if (subtypes
!= NULL
) CFRelease(subtypes
);
685 if (subtype_options
!= NULL
) CFRelease(subtype_options
);
686 if (options
== NULL
) CFRelease(config_options
);
688 if (options
!= NULL
) {
689 SCPrint(TRUE
, stdout
, CFSTR("media type and options must both be specified\n"));
698 /* -------------------- */
703 show_interfaces(int argc
, char **argv
)
708 if (interfaces
!= NULL
) CFRelease(interfaces
);
709 interfaces
= _copy_interfaces();
710 if (interfaces
== NULL
) {
714 n
= CFArrayGetCount(interfaces
);
715 for (i
= 0; i
< n
; i
++) {
716 CFIndex childIndex
= 0;
717 SCNetworkInterfaceRef interface
;
719 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
721 CFStringRef interfaceName
;
724 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
725 if (interfaceName
== NULL
) {
726 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
728 if (interfaceName
== NULL
) {
729 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
733 if ((net_interface
!= NULL
) && CFEqual(interface
, net_interface
)) {
737 if (childIndex
== 0) {
738 SCPrint(TRUE
, stdout
, CFSTR("%c%2d: %@\n"),
743 SCPrint(TRUE
, stdout
, CFSTR("%c%2d.%d: %@\n"),
750 interface
= SCNetworkInterfaceGetInterface(interface
);
752 } while (interface
!= NULL
);
759 /* -------------------- */
762 static options bondOptions
[] = {
763 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
764 // xxx { "+device" , ... },
765 // xxx { "-device" , ... },
767 { "?" , NULL
, isHelp
, NULL
, NULL
,
768 "\nBond configuration commands\n\n"
769 " set interface [mtu n] [media type] [mediaopts opts]\n"
772 #define N_BOND_OPTIONS (sizeof(bondOptions) / sizeof(bondOptions[0]))
776 set_interface_bond(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
778 CFStringRef interfaceName
;
781 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
782 if (interfaceName
== NULL
) {
783 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
787 ok
= _process_options(bondOptions
, N_BOND_OPTIONS
, argc
, argv
, newConfiguration
);
789 // validate configuration
790 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
799 /* -------------------- */
802 static options airportOptions
[] = {
803 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
804 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
805 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
807 { "?" , NULL
, isHelp
, NULL
, NULL
,
808 "\nAirPort configuration commands\n\n"
809 " set interface [mtu n] [media type] [mediaopts opts]\n"
812 #define N_AIRPORT_OPTIONS (sizeof(airportOptions) / sizeof(airportOptions[0]))
816 set_interface_airport(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
818 CFStringRef interfaceName
;
821 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
822 if (interfaceName
== NULL
) {
823 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
827 ok
= _process_options(airportOptions
, N_AIRPORT_OPTIONS
, argc
, argv
, newConfiguration
);
829 // validate configuration
830 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
839 /* -------------------- */
842 static options ethernetOptions
[] = {
843 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
844 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
845 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
847 { "?" , NULL
, isHelp
, NULL
, NULL
,
848 "\nEthernet configuration commands\n\n"
849 " set interface [mtu n] [media type] [mediaopts opts]\n"
852 #define N_ETHERNET_OPTIONS (sizeof(ethernetOptions) / sizeof(ethernetOptions[0]))
856 set_interface_ethernet(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
858 CFStringRef interfaceName
;
861 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
862 if (interfaceName
== NULL
) {
863 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
867 ok
= _process_options(ethernetOptions
, N_ETHERNET_OPTIONS
, argc
, argv
, newConfiguration
);
869 // validate configuration
870 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
879 /* -------------------- */
882 static options firewireOptions
[] = {
883 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
884 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
885 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
887 { "?" , NULL
, isHelp
, NULL
, NULL
,
888 "\nFireWire configuration commands\n\n"
889 " set interface [mtu n] [media type] [mediaopts opts]\n"
892 #define N_FIREWIRE_OPTIONS (sizeof(firewireOptions) / sizeof(firewireOptions[0]))
896 set_interface_firewire(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
898 CFStringRef interfaceName
;
901 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
902 if (interfaceName
== NULL
) {
903 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
907 ok
= _process_options(firewireOptions
, N_FIREWIRE_OPTIONS
, argc
, argv
, newConfiguration
);
909 // validate configuration
910 if (!validateMediaOptions(net_interface
, newConfiguration
)) {
919 /* -------------------- */
922 static selections modemDialSelections
[] = {
923 { CFSTR("ignore"), &kSCValNetModemDialModeIgnoreDialTone
, 0 },
924 { CFSTR("manual"), &kSCValNetModemDialModeManual
, 0 },
925 { CFSTR("wait") , &kSCValNetModemDialModeWaitForDialTone
, 0 },
929 static options modemOptions
[] = {
930 { "ConnectionScript" , "script", isString
, &kSCPropNetModemConnectionScript
, NULL
, NULL
},
931 { "DialMode" , "mode" , isChooseOne
, &kSCPropNetModemDialMode
, NULL
, (void *)modemDialSelections
},
932 { "CallWaiting" , NULL
, isBoolean
, &kSCPropNetModemHoldEnabled
, NULL
, NULL
},
933 { "CallWaitingAlert" , NULL
, isBoolean
, &kSCPropNetModemHoldCallWaitingAudibleAlert
, NULL
, NULL
},
934 { "CallWaitingDisconnectOnAnswer", NULL
, isBoolean
, &kSCPropNetModemHoldDisconnectOnAnswer
, NULL
, NULL
},
935 { "DataCompression" , NULL
, isBoolean
, &kSCPropNetModemDataCompression
, NULL
, NULL
},
936 { "ErrorCorrection" , NULL
, isBoolean
, &kSCPropNetModemErrorCorrection
, NULL
, NULL
},
937 { "HoldReminder" , NULL
, isBoolean
, &kSCPropNetModemHoldReminder
, NULL
, NULL
},
938 { "HoldReminderTime" , "time" , isNumber
, &kSCPropNetModemHoldReminderTime
, NULL
, NULL
},
939 { "PulseDial" , NULL
, isBoolean
, &kSCPropNetModemPulseDial
, NULL
, NULL
},
940 { "Speaker" , NULL
, isBoolean
, &kSCPropNetModemSpeaker
, NULL
, NULL
},
942 { "?" , NULL
, isHelp
, NULL
, NULL
,
943 "\nModem configuration commands\n\n"
944 " set interface [ConnectionScript connection-script]\n"
945 " set interface [CallWaiting {enable|disable}]\n"
946 " set interface [CallWaitingAlert {enable|disable}]\n"
947 " set interface [CallWaitingDisconnectOnAnswer {enable|disable}]\n"
948 " set interface [DialMode {ignore|wait}]\n"
949 " set interface [DataCompression {enable|disable}]\n"
950 " set interface [ErrorCorrection {enable|disable}]\n"
951 " set interface [HoldReminder {enable|disable}]\n"
952 " set interface [HoldReminderTime n]\n"
953 " set interface [PulseDial {enable|disable}]\n"
954 " set interface [Speaker {enable|disable}]"
957 #define N_MODEM_OPTIONS (sizeof(modemOptions) / sizeof(modemOptions[0]))
961 set_interface_modem(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
965 ok
= _process_options(modemOptions
, N_MODEM_OPTIONS
, argc
, argv
, newConfiguration
);
970 /* -------------------- */
974 __doPPPAuthPW(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
977 SCPrint(TRUE
, stdout
, CFSTR("PPP password not specified\n"));
981 if (strlen(argv
[0]) > 0) {
982 CFStringRef encryptionType
;
984 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetPPPAuthPasswordEncryption
);
985 if (encryptionType
== NULL
) {
990 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
991 n
= CFStringGetLength(str
);
992 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
993 CFDataSetLength(pw
, n
* sizeof(UniChar
));
994 CFStringGetCharacters(str
,
996 (UniChar
*)CFDataGetMutableBytePtr(pw
));
999 CFDictionarySetValue(newConfiguration
, key
, pw
);
1002 SCPrint(TRUE
, stdout
, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType
);
1006 CFDictionaryRemoveValue(newConfiguration
, key
);
1014 __doPPPAuthPWType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1017 SCPrint(TRUE
, stdout
, CFSTR("PPP password type mode not specified\n"));
1021 if (strlen(argv
[0]) > 0) {
1022 if (strcasecmp(argv
[0], "keychain") == 0) {
1023 CFDictionarySetValue(newConfiguration
, key
, kSCValNetPPPAuthPasswordEncryptionKeychain
);
1025 SCPrint(TRUE
, stdout
, CFSTR("invalid password type\n"));
1029 CFDictionaryRemoveValue(newConfiguration
, key
);
1032 // encryption type changed, reset password
1033 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetPPPAuthPassword
);
1039 static selections authPromptSelections
[] = {
1040 { CFSTR("before"), &kSCValNetPPPAuthPromptBefore
, 0 },
1041 { CFSTR("after") , &kSCValNetPPPAuthPromptAfter
, 0 },
1046 static selections authProtocolSelections
[] = {
1047 { CFSTR("CHAP") , &kSCValNetPPPAuthProtocolCHAP
, 0 },
1048 { CFSTR("EAP") , &kSCValNetPPPAuthProtocolEAP
, 0 },
1049 { CFSTR("MSCHAP1"), &kSCValNetPPPAuthProtocolMSCHAP1
, 0 },
1050 { CFSTR("MSCHAP2"), &kSCValNetPPPAuthProtocolMSCHAP2
, 0 },
1051 { CFSTR("PAP") , &kSCValNetPPPAuthProtocolPAP
, 0 },
1056 static options pppOptions
[] = {
1057 { "ACSP" , NULL
, isBoolean
, &kSCPropNetPPPACSPEnabled
, NULL
, NULL
},
1058 { "ConnectTime" , "?time" , isNumber
, &kSCPropNetPPPConnectTime
, NULL
, NULL
},
1059 { "DialOnDemand" , NULL
, isBoolean
, &kSCPropNetPPPDialOnDemand
, NULL
, NULL
},
1060 { "DisconnectOnFastUserSwitch", NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnFastUserSwitch
, NULL
, NULL
},
1061 { "DisconnectOnIdle" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnIdle
, NULL
, NULL
},
1062 { "DisconnectOnIdleTimer" , "timeout" , isNumber
, &kSCPropNetPPPDisconnectOnIdleTimer
, NULL
, NULL
},
1063 { "DisconnectOnLogout" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnLogout
, NULL
, NULL
},
1064 { "DisconnectOnSleep" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnSleep
, NULL
, NULL
},
1065 { "DisconnectTime" , "?time" , isNumber
, &kSCPropNetPPPDisconnectTime
, NULL
, NULL
},
1066 { "IdleReminder" , NULL
, isBoolean
, &kSCPropNetPPPIdleReminder
, NULL
, NULL
},
1067 { "IdleReminderTimer" , "time" , isNumber
, &kSCPropNetPPPIdleReminderTimer
, NULL
, NULL
},
1068 { "Logfile" , "path" , isString
, &kSCPropNetPPPLogfile
, NULL
, NULL
},
1069 { "Plugins" , "plugin" , isStringArray
, &kSCPropNetPPPPlugins
, NULL
, NULL
},
1070 { "RetryConnectTime" , "time" , isNumber
, &kSCPropNetPPPRetryConnectTime
, NULL
, NULL
},
1071 { "SessionTimer" , "time" , isNumber
, &kSCPropNetPPPSessionTimer
, NULL
, NULL
},
1072 { "UseSessionTimer" , NULL
, isBoolean
, &kSCPropNetPPPUseSessionTimer
, NULL
, NULL
},
1073 { "VerboseLogging" , NULL
, isBoolean
, &kSCPropNetPPPVerboseLogging
, NULL
, NULL
},
1076 { "AuthEAPPlugins" , "plugin" , isStringArray
, &kSCPropNetPPPAuthEAPPlugins
, NULL
, NULL
},
1077 { "AuthName" , "account" , isString
, &kSCPropNetPPPAuthName
, NULL
, NULL
},
1078 { "Account" , "account" , isString
, &kSCPropNetPPPAuthName
, NULL
, NULL
},
1079 { "AuthPassword" , "password" , isOther
, &kSCPropNetPPPAuthPassword
, __doPPPAuthPW
, NULL
},
1080 { "Password" , "password" , isOther
, &kSCPropNetPPPAuthPassword
, __doPPPAuthPW
, NULL
},
1081 { "AuthPasswordEncryption" , "type" , isOther
, &kSCPropNetPPPAuthPasswordEncryption
, __doPPPAuthPWType
, NULL
},
1082 { "AuthPrompt" , "before/after", isChooseOne
, &kSCPropNetPPPAuthPrompt
, NULL
, (void *)authPromptSelections
},
1083 { "AuthProtocol" , "protocol" , isChooseMultiple
, &kSCPropNetPPPAuthProtocol
, NULL
, (void *)authProtocolSelections
},
1086 { "CommRemoteAddress" , "phone#" , isString
, &kSCPropNetPPPCommRemoteAddress
, NULL
, NULL
},
1087 { "CommAlternateRemoteAddress", "phone#" , isString
, &kSCPropNetPPPCommAlternateRemoteAddress
, NULL
, NULL
},
1088 { "CommConnectDelay" , "time" , isNumber
, &kSCPropNetPPPCommConnectDelay
, NULL
, NULL
},
1089 { "CommDisplayTerminalWindow" , NULL
, isBoolean
, &kSCPropNetPPPCommDisplayTerminalWindow
, NULL
, NULL
},
1090 { "CommRedialCount" , "retry count" , isNumber
, &kSCPropNetPPPCommRedialCount
, NULL
, NULL
},
1091 { "CommRedialEnabled" , NULL
, isBoolean
, &kSCPropNetPPPCommRedialEnabled
, NULL
, NULL
},
1092 { "CommRedialInterval" , "retry delay" , isNumber
, &kSCPropNetPPPCommRedialInterval
, NULL
, NULL
},
1093 { "CommTerminalScript" , "script" , isString
, &kSCPropNetPPPCommTerminalScript
, NULL
, NULL
},
1094 { "CommUseTerminalScript" , NULL
, isBoolean
, &kSCPropNetPPPCommUseTerminalScript
, NULL
, NULL
},
1097 { "CCPEnabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPEnabled
, NULL
, NULL
},
1098 { "CCPMPPE40Enabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPMPPE40Enabled
, NULL
, NULL
},
1099 { "CCPMPPE128Enabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPMPPE128Enabled
, NULL
, NULL
},
1102 { "IPCPCompressionVJ" , NULL
, isBoolean
, &kSCPropNetPPPIPCPCompressionVJ
, NULL
, NULL
},
1103 { "IPCPUsePeerDNS" , NULL
, isBoolean
, &kSCPropNetPPPIPCPUsePeerDNS
, NULL
, NULL
},
1106 { "LCPEchoEnabled" , NULL
, isBoolean
, &kSCPropNetPPPLCPEchoEnabled
, NULL
, NULL
},
1107 { "LCPEchoFailure" , NULL
, isNumber
, &kSCPropNetPPPLCPEchoFailure
, NULL
, NULL
},
1108 { "LCPEchoInterval" , NULL
, isNumber
, &kSCPropNetPPPLCPEchoInterval
, NULL
, NULL
},
1109 { "LCPCompressionACField" , NULL
, isBoolean
, &kSCPropNetPPPLCPCompressionACField
, NULL
, NULL
},
1110 { "LCPCompressionPField" , NULL
, isBoolean
, &kSCPropNetPPPLCPCompressionPField
, NULL
, NULL
},
1111 { "LCPMRU" , NULL
, isNumber
, &kSCPropNetPPPLCPMRU
, NULL
, NULL
},
1112 { "LCPMTU" , NULL
, isNumber
, &kSCPropNetPPPLCPMTU
, NULL
, NULL
},
1113 { "LCPReceiveACCM" , NULL
, isNumber
, &kSCPropNetPPPLCPReceiveACCM
, NULL
, NULL
},
1114 { "LCPTransmitACCM" , NULL
, isNumber
, &kSCPropNetPPPLCPTransmitACCM
, NULL
, NULL
},
1117 { "?" , NULL
, isHelp
, NULL
, NULL
,
1118 "\nPPP configuration commands\n\n"
1119 " set interface [Account account]\n"
1120 " set interface [Password password]\n"
1121 " set interface [Number telephone-number]\n"
1122 " set interface [AlternateNumber telephone-number]\n"
1123 " set interface [IdleReminder {enable|disable}]\n"
1124 " set interface [IdleReminderTimer time-in-seconds]\n"
1125 " set interface [DisconnectOnIdle {enable|disable}]\n"
1126 " set interface [DisconnectOnIdleTimer time-in-seconds]\n"
1127 " set interface [DisconnectOnLogout {enable|disable}]"
1130 #define N_PPP_OPTIONS (sizeof(pppOptions) / sizeof(pppOptions[0]))
1134 set_interface_ppp(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1138 ok
= _process_options(pppOptions
, N_PPP_OPTIONS
, argc
, argv
, newConfiguration
);
1143 /* -------------------- */
1147 set_interface_vlan(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1149 // xxxxx ("device", "tag")
1150 SCPrint(TRUE
, stdout
, CFSTR("vlan interface management not yet supported\n"));
1155 /* -------------------- */
1160 set_interface(int argc
, char **argv
)
1162 CFDictionaryRef configuration
;
1163 CFStringRef interfaceType
;
1164 CFMutableDictionaryRef newConfiguration
= NULL
;
1167 if (net_interface
== NULL
) {
1168 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
1173 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1177 configuration
= SCNetworkInterfaceGetConfiguration(net_interface
);
1178 if (configuration
== NULL
) {
1179 newConfiguration
= CFDictionaryCreateMutable(NULL
,
1181 &kCFTypeDictionaryKeyCallBacks
,
1182 &kCFTypeDictionaryValueCallBacks
);
1184 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
1185 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
1188 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
1190 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
1191 ok
= set_interface_bond(argc
, argv
, newConfiguration
);
1192 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeEthernet
)) {
1193 ok
= set_interface_ethernet(argc
, argv
, newConfiguration
);
1194 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeFireWire
)) {
1195 ok
= set_interface_firewire(argc
, argv
, newConfiguration
);
1196 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeModem
)) {
1197 ok
= set_interface_modem(argc
, argv
, newConfiguration
);
1198 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIEEE80211
)) {
1199 ok
= set_interface_airport(argc
, argv
, newConfiguration
);
1200 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
1201 ok
= set_interface_ppp(argc
, argv
, newConfiguration
);
1202 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
1203 ok
= set_interface_vlan(argc
, argv
, newConfiguration
);
1205 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
1212 if (((configuration
== NULL
) && (CFDictionaryGetCount(newConfiguration
) > 0)) ||
1213 ((configuration
!= NULL
) && !CFEqual(configuration
, newConfiguration
))) {
1214 if (!SCNetworkInterfaceSetConfiguration(net_interface
, newConfiguration
)) {
1215 if (SCError() == kSCStatusNoKey
) {
1216 SCPrint(TRUE
, stdout
, CFSTR("could not update per-service interface configuration\n"));
1218 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
1223 _prefs_changed
= TRUE
;
1228 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
1233 /* -------------------- */
1238 show_interface(int argc
, char **argv
)
1240 SCNetworkInterfaceRef interface
;
1243 interface
= _find_interface(argv
[0]);
1245 if (net_interface
!= NULL
) {
1246 interface
= net_interface
;
1248 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
1253 if (interface
!= NULL
) {
1254 _show_interface(interface
, CFSTR(""), TRUE
);
1261 /* -------------------- */
1266 _interface_description(SCNetworkInterfaceRef interface
)
1268 CFMutableStringRef description
;
1269 CFStringRef if_bsd_name
;
1270 CFStringRef if_type
;
1272 description
= CFStringCreateMutable(NULL
, 0);
1274 if_type
= SCNetworkInterfaceGetInterfaceType(interface
);
1275 CFStringAppend(description
, if_type
);
1277 if_bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
1278 if (if_bsd_name
!= NULL
) {
1279 CFStringAppendFormat(description
, NULL
, CFSTR(" (%@)"), if_bsd_name
);
1282 interface
= SCNetworkInterfaceGetInterface(interface
);
1283 while ((interface
!= NULL
) &&
1284 !CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
1285 CFStringRef childDescription
;
1287 childDescription
= _interface_description(interface
);
1288 CFStringAppendFormat(description
, NULL
, CFSTR(" / %@"), childDescription
);
1289 CFRelease(childDescription
);
1291 interface
= SCNetworkInterfaceGetInterface(interface
);