2 * Copyright (c) 2004, 2005 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>
35 #include <SystemConfiguration/LinkConfiguration.h>
38 /* -------------------- */
44 CFMutableArrayRef interfaces
;
45 CFArrayRef real_interfaces
;
47 real_interfaces
= SCNetworkInterfaceCopyAll();
48 if (real_interfaces
== NULL
) {
49 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
53 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
55 // include real interfaces
56 CFArrayAppendArray(interfaces
,
58 CFRangeMake(0, CFArrayGetCount(real_interfaces
)));
59 CFRelease(real_interfaces
);
61 // include pseudo interfaces
62 CFArrayAppendValue(interfaces
, kSCNetworkInterfaceIPv4
);
64 // include interfaces that we have created
65 if (new_interfaces
!= NULL
) {
66 CFArrayAppendArray(interfaces
,
68 CFRangeMake(0, CFArrayGetCount(new_interfaces
)));
71 return (CFArrayRef
)interfaces
;
77 _find_interface(char *match
)
79 Boolean allowIndex
= TRUE
;
82 CFStringRef select_name
= NULL
;
83 SCNetworkInterfaceRef selected
= NULL
;
85 if (strcasecmp(match
, "$child") == 0) {
86 if (net_interface
== NULL
) {
87 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
91 selected
= SCNetworkInterfaceGetInterface(net_interface
);
92 if(selected
== NULL
) {
93 SCPrint(TRUE
, stdout
, CFSTR("no child interface\n"));
97 } else if (strcasecmp(match
, "$service") == 0) {
98 if (net_service
== NULL
) {
99 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
103 selected
= SCNetworkServiceGetInterface(net_service
);
104 if(selected
== NULL
) {
105 SCPrint(TRUE
, stdout
, CFSTR("no interface for service\n"));
111 if (interfaces
== NULL
) {
112 interfaces
= _copy_interfaces();
113 if (interfaces
== NULL
) {
119 // try to select the interface by its display name
121 select_name
= CFStringCreateWithCString(NULL
, match
, kCFStringEncodingUTF8
);
123 n
= CFArrayGetCount(interfaces
);
124 for (i
= 0; i
< n
; i
++) {
125 SCNetworkInterfaceRef interface
;
126 CFStringRef interfaceName
;
128 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
129 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
130 if ((interfaceName
!= NULL
) && CFEqual(select_name
, interfaceName
)) {
131 if (selected
== NULL
) {
132 selected
= interface
;
134 // if multiple interfaces match
136 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
142 if (selected
!= NULL
) {
146 // try to select the interface by its BSD name
148 for (i
= 0; i
< n
; i
++) {
149 SCNetworkInterfaceRef interface
;
150 CFStringRef bsd_name
= NULL
;
152 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
153 while ((interface
!= NULL
) && (bsd_name
== NULL
)) {
154 bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
155 if (bsd_name
== NULL
) {
156 interface
= SCNetworkInterfaceGetInterface(interface
);
160 if ((bsd_name
!= NULL
) && CFEqual(select_name
, bsd_name
)) {
161 if (selected
== NULL
) {
162 selected
= interface
;
164 // if multiple interfaces match
166 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
172 if (selected
!= NULL
) {
176 // try to select the interface by its interface type
178 for (i
= 0; i
< n
; i
++) {
179 SCNetworkInterfaceRef interface
;
180 CFStringRef interfaceType
;
182 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
183 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
184 if (CFEqual(select_name
, interfaceType
)) {
185 if (selected
== NULL
) {
186 selected
= interface
;
188 // if multiple interfaces match
190 SCPrint(TRUE
, stdout
, CFSTR("multiple interfaces match\n"));
196 if (selected
!= NULL
) {
205 // try to select the interface by its index
208 val
= strtol(str
, &end
, 10);
209 if ((*str
!= '\0') &&
210 ((*end
== '\0') || (*end
== '.')) &&
212 if ((val
> 0) && (val
<= n
)) {
213 selected
= CFArrayGetValueAtIndex(interfaces
, val
- 1);
217 val
= strtol(str
, &end
, 10);
218 if ((*str
!= '\0') && (*end
== '\0') && (errno
== 0)) {
220 selected
= SCNetworkInterfaceGetInterface(selected
);
221 if (selected
== NULL
) {
231 if (selected
!= NULL
) {
235 SCPrint(TRUE
, stdout
, CFSTR("no match\n"));
239 if (select_name
!= NULL
) CFRelease(select_name
);
244 /* -------------------- */
249 create_interface(int argc
, char **argv
)
251 SCNetworkInterfaceRef interface
;
252 CFStringRef interfaceName
;
253 CFStringRef interfaceType
;
254 SCNetworkInterfaceRef new_interface
;
257 SCPrint(TRUE
, stdout
, CFSTR("what interface type?\n"));
261 interfaceType
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
263 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
265 SCPrint(TRUE
, stdout
, CFSTR("vlan creation not yet supported\n"));
267 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
269 SCPrint(TRUE
, stdout
, CFSTR("bond creation not yet supported\n"));
273 if (net_interface
== NULL
) {
274 SCPrint(TRUE
, stdout
, CFSTR("no network interface selected\n"));
278 interface
= net_interface
;
280 interface
= _find_interface(argv
[1]);
283 if (interface
== NULL
) {
287 new_interface
= SCNetworkInterfaceCreateWithInterface(interface
, interfaceType
);
288 if (new_interface
== NULL
) {
289 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
294 if (new_interfaces
== NULL
) {
295 new_interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
297 CFArrayAppendValue(new_interfaces
, new_interface
);
299 if (net_interface
!= NULL
) CFRelease(net_interface
);
300 net_interface
= new_interface
;
302 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(net_interface
);
303 if (interfaceName
== NULL
) {
304 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
306 if (interfaceName
== NULL
) {
307 interfaceName
= SCNetworkInterfaceGetInterfaceType(net_interface
);
309 SCPrint(TRUE
, stdout
, CFSTR("interface \"%@\" created and selected\n"), interfaceName
);
313 CFRelease(interfaceType
);
318 /* -------------------- */
323 select_interface(int argc
, char **argv
)
325 SCNetworkInterfaceRef interface
;
327 interface
= _find_interface(argv
[0]);
329 if (interface
!= NULL
) {
330 CFStringRef interfaceName
;
332 if (net_interface
!= NULL
) CFRelease(net_interface
);
333 net_interface
= CFRetain(interface
);
335 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
336 if (interfaceName
== NULL
) {
337 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
339 if (interfaceName
== NULL
) {
340 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
343 SCPrint(TRUE
, stdout
, CFSTR("interface \"%@\" selected\n"), interfaceName
);
350 /* -------------------- */
355 _show_interface(SCNetworkInterfaceRef interface
, CFStringRef prefix
, Boolean showChild
)
357 CFDictionaryRef configuration
;
358 CFStringRef if_bsd_name
;
359 CFStringRef if_localized_name
;
360 CFStringRef if_mac_address
;
362 CFArrayRef supported
;
364 if_localized_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
365 if (if_localized_name
!= NULL
) {
366 SCPrint(TRUE
, stdout
, CFSTR("%@ name = %@\n"), prefix
, if_localized_name
);
369 if_bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
370 if (if_bsd_name
!= NULL
) {
371 SCPrint(TRUE
, stdout
, CFSTR("%@ interface name = %@\n"), prefix
, if_bsd_name
);
374 if_type
= SCNetworkInterfaceGetInterfaceType(interface
);
375 SCPrint(TRUE
, stdout
, CFSTR("%@ type = %@\n"), prefix
, if_type
);
377 if_mac_address
= SCNetworkInterfaceGetHardwareAddressString(interface
);
378 if (if_mac_address
!= NULL
) {
379 SCPrint(TRUE
, stdout
, CFSTR("%@ address = %@\n"), prefix
, if_mac_address
);
382 configuration
= SCNetworkInterfaceGetConfiguration(interface
);
383 if ((configuration
!= NULL
) &&
384 CFDictionaryContainsKey(configuration
, kSCResvInactive
)) {
385 configuration
= NULL
;
388 if (if_bsd_name
!= NULL
) {
389 CFArrayRef available
;
390 CFDictionaryRef active
;
395 if (NetworkInterfaceCopyMTU(if_bsd_name
, &mtu_cur
, &mtu_min
, &mtu_max
)) {
396 char isCurrent
= '*';
398 if (configuration
!= NULL
) {
402 num
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMTU
);
403 if (isA_CFNumber(num
)) {
404 CFNumberGetValue(num
, kCFNumberIntType
, &mtu_req
);
405 if (mtu_cur
!= mtu_req
) {
412 SCPrint(TRUE
, stdout
, CFSTR("%@ mtu %c = %ld (%ld < n < %ld)\n"),
420 if (NetworkInterfaceCopyMediaOptions(if_bsd_name
, NULL
, &active
, &available
, TRUE
)) {
421 char isCurrent
= ' ';
422 CFArrayRef options
= NULL
;
423 CFArrayRef options_req
= NULL
;
424 CFStringRef subtype
= NULL
;
425 CFStringRef subtype_req
= NULL
;
427 if (configuration
!= NULL
) {
428 subtype_req
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMediaSubType
);
429 options_req
= CFDictionaryGetValue(configuration
, kSCPropNetEthernetMediaOptions
);
432 if (subtype_req
== NULL
) {
433 subtype_req
= CFSTR("autoselect");
436 if (active
!= NULL
) {
437 subtype
= CFDictionaryGetValue(active
, kSCPropNetEthernetMediaSubType
);
438 options
= CFDictionaryGetValue(active
, kSCPropNetEthernetMediaOptions
);
441 if (subtype
!= NULL
) {
442 if (((subtype_req
!= NULL
) &&
443 CFEqual(subtype
, subtype_req
)) &&
444 ((options
== options_req
) ||
445 ((options
!= NULL
) &&
446 (options_req
!= NULL
) &&
447 CFEqual(options
, options_req
)))
450 } else if ((subtype_req
== NULL
) ||
451 ((subtype_req
!= NULL
) &&
452 CFEqual(subtype_req
, CFSTR("autoselect")))) {
453 // if requested subtype not specified or "autoselect"
458 if (subtype_req
!= NULL
) {
459 SCPrint(TRUE
, stdout
, CFSTR("%@ media %c = %@"),
464 if ((options_req
!= NULL
) &&
465 (CFArrayGetCount(options_req
) > 0)) {
466 CFStringRef options_str
;
468 options_str
= CFStringCreateByCombiningStrings(NULL
, options_req
, CFSTR(","));
469 SCPrint(TRUE
, stdout
, CFSTR(" <%@>"), options_str
);
470 CFRelease(options_str
);
473 SCPrint(TRUE
, stdout
, CFSTR("\n"));
476 SCPrint(TRUE
, stdout
, CFSTR("\n"));
478 if (available
!= NULL
) {
483 subtypes
= NetworkInterfaceCopyMediaSubTypes(available
);
484 n_subtypes
= (subtypes
!= NULL
) ? CFArrayGetCount(subtypes
) : 0;
485 for (i
= 0; i
< n_subtypes
; i
++) {
487 CFIndex n_subtype_options
;
489 CFArrayRef subtype_options
;
491 subtype
= CFArrayGetValueAtIndex(subtypes
, i
);
492 subtype_options
= NetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
493 n_subtype_options
= (subtype_options
!= NULL
) ? CFArrayGetCount(subtype_options
) : 0;
494 for (j
= 0; j
< n_subtype_options
; j
++) {
495 char isCurrent
= ' ';
498 options
= CFArrayGetValueAtIndex(subtype_options
, j
);
500 if (((subtype_req
!= NULL
) &&
501 CFEqual(subtype
, subtype_req
)) &&
502 ((options
== options_req
) ||
503 ((options
!= NULL
) &&
504 (options_req
!= NULL
) &&
505 CFEqual(options
, options_req
)))
510 SCPrint(TRUE
, stdout
, CFSTR("%@ %s %c = %@"),
512 ((i
== 0) && (j
== 0)) ? "supported media" : " ",
516 if ((options
!= NULL
) &&
517 (CFArrayGetCount(options
) > 0)) {
518 CFStringRef options_str
;
520 options_str
= CFStringCreateByCombiningStrings(NULL
, options
, CFSTR(","));
521 SCPrint(TRUE
, stdout
, CFSTR(" <%@>"), options_str
);
522 CFRelease(options_str
);
525 SCPrint(TRUE
, stdout
, CFSTR("\n"));
527 CFRelease(subtype_options
);
531 SCPrint(TRUE
, stdout
, CFSTR("\n"));
535 supported
= SCNetworkInterfaceGetSupportedInterfaceTypes(interface
);
536 SCPrint(TRUE
, stdout
, CFSTR("%@ supported interfaces = "), prefix
);
537 if (supported
!= NULL
) {
539 CFIndex n
= CFArrayGetCount(supported
);
541 for (i
= 0; i
< n
; i
++) {
542 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
543 (i
== 0) ? "" : ", ",
544 CFArrayGetValueAtIndex(supported
, i
));
547 SCPrint(TRUE
, stdout
, CFSTR("\n"));
549 supported
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
);
550 SCPrint(TRUE
, stdout
, CFSTR("%@ supported protocols = "), prefix
);
551 if (supported
!= NULL
) {
553 CFIndex n
= CFArrayGetCount(supported
);
555 for (i
= 0; i
< n
; i
++) {
556 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
557 (i
== 0) ? "" : ", ",
558 CFArrayGetValueAtIndex(supported
, i
));
561 SCPrint(TRUE
, stdout
, CFSTR("\n"));
563 if (configuration
!= NULL
) {
564 CFMutableDictionaryRef effective
;
566 effective
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
568 // remove known (and already reported) interface configuration keys
569 if (CFDictionaryContainsKey(effective
, kSCResvInactive
)) {
570 CFDictionaryRemoveAllValues(effective
);
572 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMTU
);
573 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMediaSubType
);
574 CFDictionaryRemoveValue(effective
, kSCPropNetEthernetMediaOptions
);
576 if (CFDictionaryGetCount(effective
) > 0) {
577 SCPrint(TRUE
, stdout
, CFSTR("\n%@ per-interface configuration\n"), prefix
);
578 _show_entity(configuration
, prefix
);
581 CFRelease(effective
);
585 SCPrint(TRUE
, stdout
, CFSTR("\n%@\n"), interface
);
588 interface
= SCNetworkInterfaceGetInterface(interface
);
589 if (interface
!= NULL
) {
590 CFStringRef newPrefix
;
592 newPrefix
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@ "), prefix
);
593 SCPrint(TRUE
, stdout
, CFSTR("\n%@child interface\n"), newPrefix
);
594 _show_interface(interface
, newPrefix
, showChild
);
595 CFRelease(newPrefix
);
602 /* -------------------- */
606 validateMediaOptions(CFStringRef interfaceName
, CFMutableDictionaryRef newConfiguration
)
613 mtu
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMTU
);
614 if (isA_CFNumber(mtu
)) {
619 if (!NetworkInterfaceCopyMTU(interfaceName
, NULL
, &mtu_min
, &mtu_max
)) {
620 SCPrint(TRUE
, stdout
, CFSTR("cannot set MTU\n"));
624 if (!CFNumberGetValue(mtu
, kCFNumberIntType
, &mtu_val
) ||
625 (mtu_val
< mtu_min
) ||
626 (mtu_val
> mtu_max
)) {
627 SCPrint(TRUE
, stdout
, CFSTR("mtu out of range\n"));
632 subtype
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMediaSubType
);
633 options
= CFDictionaryGetValue(newConfiguration
, kSCPropNetEthernetMediaOptions
);
635 if (subtype
!= NULL
) {
636 CFArrayRef available
= NULL
;
637 CFArrayRef config_options
= options
;
638 CFArrayRef subtypes
= NULL
;
639 CFArrayRef subtype_options
= NULL
;
643 if (options
== NULL
) {
644 config_options
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
);
647 if (interfaceName
== NULL
) {
648 SCPrint(TRUE
, stdout
, CFSTR("media type / options not available\n"));
652 if (!NetworkInterfaceCopyMediaOptions(interfaceName
, NULL
, NULL
, &available
, FALSE
)) {
653 SCPrint(TRUE
, stdout
, CFSTR("media type / options not available\n"));
657 if (available
== NULL
) {
661 subtypes
= NetworkInterfaceCopyMediaSubTypes(available
);
662 if ((subtypes
== NULL
) ||
663 !CFArrayContainsValue(subtypes
,
664 CFRangeMake(0, CFArrayGetCount(subtypes
)),
666 SCPrint(TRUE
, stdout
, CFSTR("media type not valid\n"));
670 subtype_options
= NetworkInterfaceCopyMediaSubTypeOptions(available
, subtype
);
671 if ((subtype_options
== NULL
) ||
672 !CFArrayContainsValue(subtype_options
,
673 CFRangeMake(0, CFArrayGetCount(subtype_options
)),
675 SCPrint(TRUE
, stdout
, CFSTR("media options not valid for \"%@\"\n"), subtype
);
679 if (options
== NULL
) {
680 CFDictionarySetValue(newConfiguration
, kSCPropNetEthernetMediaOptions
, config_options
);
687 if (available
!= NULL
) CFRelease(available
);
688 if (subtypes
!= NULL
) CFRelease(subtypes
);
689 if (subtype_options
!= NULL
) CFRelease(subtype_options
);
690 if (options
== NULL
) CFRelease(config_options
);
692 if (options
!= NULL
) {
693 SCPrint(TRUE
, stdout
, CFSTR("media type and options must both be specified\n"));
702 /* -------------------- */
707 show_interfaces(int argc
, char **argv
)
712 if (interfaces
!= NULL
) CFRelease(interfaces
);
713 interfaces
= _copy_interfaces();
714 if (interfaces
== NULL
) {
718 n
= CFArrayGetCount(interfaces
);
719 for (i
= 0; i
< n
; i
++) {
720 CFIndex childIndex
= 0;
721 SCNetworkInterfaceRef interface
;
723 interface
= CFArrayGetValueAtIndex(interfaces
, i
);
725 CFStringRef interfaceName
;
728 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
729 if (interfaceName
== NULL
) {
730 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
732 if (interfaceName
== NULL
) {
733 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
737 if ((net_interface
!= NULL
) && CFEqual(interface
, net_interface
)) {
741 if (childIndex
== 0) {
742 SCPrint(TRUE
, stdout
, CFSTR("%c%2d: %@\n"),
747 SCPrint(TRUE
, stdout
, CFSTR("%c%2d.%d: %@\n"),
754 interface
= SCNetworkInterfaceGetInterface(interface
);
756 } while (interface
!= NULL
);
763 /* -------------------- */
767 set_interface_bond(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
769 // xxxxx ("+device", "-device")
770 SCPrint(TRUE
, stdout
, CFSTR("bond interface management not yet supported\n"));
775 /* -------------------- */
778 static options airportOptions
[] = {
779 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
780 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
781 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
783 { "?" , NULL
, isHelp
, NULL
, NULL
,
784 "\nAirPort configuration commands\n\n"
785 " set interface [mtu n] [media type] [mediaopts opts]\n"
788 #define N_AIRPORT_OPTIONS (sizeof(airportOptions) / sizeof(airportOptions[0]))
792 set_interface_airport(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
794 CFStringRef interfaceName
;
797 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
798 if (interfaceName
== NULL
) {
799 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
803 ok
= _process_options(airportOptions
, N_AIRPORT_OPTIONS
, argc
, argv
, newConfiguration
);
805 // validate configuration
806 if (!validateMediaOptions(interfaceName
, newConfiguration
)) {
815 /* -------------------- */
818 static options ethernetOptions
[] = {
819 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
820 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
821 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
823 { "?" , NULL
, isHelp
, NULL
, NULL
,
824 "\nEthernet configuration commands\n\n"
825 " set interface [mtu n] [media type] [mediaopts opts]\n"
828 #define N_ETHERNET_OPTIONS (sizeof(ethernetOptions) / sizeof(ethernetOptions[0]))
832 set_interface_ethernet(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
834 CFStringRef interfaceName
;
837 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
838 if (interfaceName
== NULL
) {
839 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
843 ok
= _process_options(ethernetOptions
, N_ETHERNET_OPTIONS
, argc
, argv
, newConfiguration
);
845 // validate configuration
846 if (!validateMediaOptions(interfaceName
, newConfiguration
)) {
855 /* -------------------- */
858 static options firewireOptions
[] = {
859 { "mtu" , NULL
, isNumber
, &kSCPropNetEthernetMTU
, NULL
, NULL
},
860 { "media" , NULL
, isString
, &kSCPropNetEthernetMediaSubType
, NULL
, NULL
},
861 { "mediaopt" , NULL
, isStringArray
, &kSCPropNetEthernetMediaOptions
, NULL
, NULL
},
863 { "?" , NULL
, isHelp
, NULL
, NULL
,
864 "\nFireWire configuration commands\n\n"
865 " set interface [mtu n] [media type] [mediaopts opts]\n"
868 #define N_FIREWIRE_OPTIONS (sizeof(firewireOptions) / sizeof(firewireOptions[0]))
872 set_interface_firewire(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
874 CFStringRef interfaceName
;
877 interfaceName
= SCNetworkInterfaceGetBSDName(net_interface
);
878 if (interfaceName
== NULL
) {
879 SCPrint(TRUE
, stdout
, CFSTR("no BSD interface\n"));
883 ok
= _process_options(firewireOptions
, N_FIREWIRE_OPTIONS
, argc
, argv
, newConfiguration
);
885 // validate configuration
886 if (!validateMediaOptions(interfaceName
, newConfiguration
)) {
895 /* -------------------- */
898 static selections modemDialSelections
[] = {
899 { CFSTR("ignore"), &kSCValNetModemDialModeIgnoreDialTone
, 0 },
900 { CFSTR("manual"), &kSCValNetModemDialModeManual
, 0 },
901 { CFSTR("wait") , &kSCValNetModemDialModeWaitForDialTone
, 0 },
905 static options modemOptions
[] = {
906 { "ConnectionScript" , "script", isString
, &kSCPropNetModemConnectionScript
, NULL
, NULL
},
907 { "DialMode" , "mode" , isChooseOne
, &kSCPropNetModemDialMode
, NULL
, (void *)modemDialSelections
},
908 { "CallWaiting" , NULL
, isBoolean
, &kSCPropNetModemHoldEnabled
, NULL
, NULL
},
909 { "CallWaitingAlert" , NULL
, isBoolean
, &kSCPropNetModemHoldCallWaitingAudibleAlert
, NULL
, NULL
},
910 { "CallWaitingDisconnectOnAnswer", NULL
, isBoolean
, &kSCPropNetModemHoldDisconnectOnAnswer
, NULL
, NULL
},
911 { "DataCompression" , NULL
, isBoolean
, &kSCPropNetModemDataCompression
, NULL
, NULL
},
912 { "ErrorCorrection" , NULL
, isBoolean
, &kSCPropNetModemErrorCorrection
, NULL
, NULL
},
913 { "HoldReminder" , NULL
, isBoolean
, &kSCPropNetModemHoldReminder
, NULL
, NULL
},
914 { "HoldReminderTime" , "time" , isNumber
, &kSCPropNetModemHoldReminderTime
, NULL
, NULL
},
915 { "PulseDial" , NULL
, isBoolean
, &kSCPropNetModemPulseDial
, NULL
, NULL
},
916 { "Speaker" , NULL
, isBoolean
, &kSCPropNetModemSpeaker
, NULL
, NULL
},
918 { "?" , NULL
, isHelp
, NULL
, NULL
,
919 "\nModem configuration commands\n\n"
920 " set interface [ConnectionScript connection-script]\n"
921 " set interface [CallWaiting {enable|disable}]\n"
922 " set interface [CallWaitingAlert {enable|disable}]\n"
923 " set interface [CallWaitingDisconnectOnAnswer {enable|disable}]\n"
924 " set interface [DialMode {ignore|wait}]\n"
925 " set interface [DataCompression {enable|disable}]\n"
926 " set interface [ErrorCorrection {enable|disable}]\n"
927 " set interface [HoldReminder {enable|disable}]\n"
928 " set interface [HoldReminderTime n]\n"
929 " set interface [PulseDial {enable|disable}]\n"
930 " set interface [Speaker {enable|disable}]"
933 #define N_MODEM_OPTIONS (sizeof(modemOptions) / sizeof(modemOptions[0]))
937 set_interface_modem(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
941 ok
= _process_options(modemOptions
, N_MODEM_OPTIONS
, argc
, argv
, newConfiguration
);
946 /* -------------------- */
950 __doPPPAuthPW(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
953 SCPrint(TRUE
, stdout
, CFSTR("PPP password not specified\n"));
957 if (strlen(argv
[0]) > 0) {
958 CFStringRef encryptionType
;
960 encryptionType
= CFDictionaryGetValue(newConfiguration
, kSCPropNetPPPAuthPasswordEncryption
);
961 if (encryptionType
== NULL
) {
966 str
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
967 n
= CFStringGetLength(str
);
968 pw
= CFDataCreateMutable(NULL
, n
* sizeof(UniChar
));
969 CFDataSetLength(pw
, n
* sizeof(UniChar
));
970 CFStringGetCharacters(str
,
972 (UniChar
*)CFDataGetMutableBytePtr(pw
));
975 CFDictionarySetValue(newConfiguration
, key
, pw
);
978 SCPrint(TRUE
, stdout
, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType
);
982 CFDictionaryRemoveValue(newConfiguration
, key
);
990 __doPPPAuthPWType(CFStringRef key
, const char *description
, void *info
, int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
993 SCPrint(TRUE
, stdout
, CFSTR("PPP password type mode not specified\n"));
997 if (strlen(argv
[0]) > 0) {
998 if (strcasecmp(argv
[0], "keychain") == 0) {
999 CFDictionarySetValue(newConfiguration
, key
, kSCValNetPPPAuthPasswordEncryptionKeychain
);
1001 SCPrint(TRUE
, stdout
, CFSTR("invalid password type\n"));
1005 CFDictionaryRemoveValue(newConfiguration
, key
);
1008 // encryption type changed, reset password
1009 CFDictionaryRemoveValue(newConfiguration
, kSCPropNetPPPAuthPassword
);
1015 static selections authPromptSelections
[] = {
1016 { CFSTR("before"), &kSCValNetPPPAuthPromptBefore
, 0 },
1017 { CFSTR("after") , &kSCValNetPPPAuthPromptAfter
, 0 },
1022 static selections authProtocolSelections
[] = {
1023 { CFSTR("CHAP") , &kSCValNetPPPAuthProtocolCHAP
, 0 },
1024 { CFSTR("EAP") , &kSCValNetPPPAuthProtocolEAP
, 0 },
1025 { CFSTR("MSCHAP1"), &kSCValNetPPPAuthProtocolMSCHAP1
, 0 },
1026 { CFSTR("MSCHAP2"), &kSCValNetPPPAuthProtocolMSCHAP2
, 0 },
1027 { CFSTR("PAP") , &kSCValNetPPPAuthProtocolPAP
, 0 },
1032 static options pppOptions
[] = {
1033 { "ACSP" , NULL
, isBoolean
, &kSCPropNetPPPACSPEnabled
, NULL
, NULL
},
1034 { "ConnectTime" , "?time" , isNumber
, &kSCPropNetPPPConnectTime
, NULL
, NULL
},
1035 { "DialOnDemand" , NULL
, isBoolean
, &kSCPropNetPPPDialOnDemand
, NULL
, NULL
},
1036 { "DisconnectOnFastUserSwitch", NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnFastUserSwitch
, NULL
, NULL
},
1037 { "DisconnectOnIdle" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnIdle
, NULL
, NULL
},
1038 { "DisconnectOnIdleTimer" , "timeout" , isNumber
, &kSCPropNetPPPDisconnectOnIdleTimer
, NULL
, NULL
},
1039 { "DisconnectOnLogout" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnLogout
, NULL
, NULL
},
1040 { "DisconnectOnSleep" , NULL
, isBoolean
, &kSCPropNetPPPDisconnectOnSleep
, NULL
, NULL
},
1041 { "DisconnectTime" , "?time" , isNumber
, &kSCPropNetPPPDisconnectTime
, NULL
, NULL
},
1042 { "IdleReminder" , NULL
, isBoolean
, &kSCPropNetPPPIdleReminder
, NULL
, NULL
},
1043 { "IdleReminderTimer" , "time" , isNumber
, &kSCPropNetPPPIdleReminderTimer
, NULL
, NULL
},
1044 { "Logfile" , "path" , isString
, &kSCPropNetPPPLogfile
, NULL
, NULL
},
1045 { "Plugins" , "plugin" , isStringArray
, &kSCPropNetPPPPlugins
, NULL
, NULL
},
1046 { "RetryConnectTime" , "time" , isNumber
, &kSCPropNetPPPRetryConnectTime
, NULL
, NULL
},
1047 { "SessionTimer" , "time" , isNumber
, &kSCPropNetPPPSessionTimer
, NULL
, NULL
},
1048 { "UseSessionTimer" , NULL
, isBoolean
, &kSCPropNetPPPUseSessionTimer
, NULL
, NULL
},
1049 { "VerboseLogging" , NULL
, isBoolean
, &kSCPropNetPPPVerboseLogging
, NULL
, NULL
},
1052 { "AuthEAPPlugins" , "plugin" , isStringArray
, &kSCPropNetPPPAuthEAPPlugins
, NULL
, NULL
},
1053 { "AuthName" , "account" , isString
, &kSCPropNetPPPAuthName
, NULL
, NULL
},
1054 { "Account" , "account" , isString
, &kSCPropNetPPPAuthName
, NULL
, NULL
},
1055 { "AuthPassword" , "password" , isOther
, &kSCPropNetPPPAuthPassword
, __doPPPAuthPW
, NULL
},
1056 { "Password" , "password" , isOther
, &kSCPropNetPPPAuthPassword
, __doPPPAuthPW
, NULL
},
1057 { "AuthPasswordEncryption" , "type" , isOther
, &kSCPropNetPPPAuthPasswordEncryption
, __doPPPAuthPWType
, NULL
},
1058 { "AuthPrompt" , "before/after", isChooseOne
, &kSCPropNetPPPAuthPrompt
, NULL
, (void *)authPromptSelections
},
1059 { "AuthProtocol" , "protocol" , isChooseMultiple
, &kSCPropNetPPPAuthProtocol
, NULL
, (void *)authProtocolSelections
},
1062 { "CommRemoteAddress" , "phone#" , isString
, &kSCPropNetPPPCommRemoteAddress
, NULL
, NULL
},
1063 { "CommAlternateRemoteAddress", "phone#" , isString
, &kSCPropNetPPPCommAlternateRemoteAddress
, NULL
, NULL
},
1064 { "CommConnectDelay" , "time" , isNumber
, &kSCPropNetPPPCommConnectDelay
, NULL
, NULL
},
1065 { "CommDisplayTerminalWindow" , NULL
, isBoolean
, &kSCPropNetPPPCommDisplayTerminalWindow
, NULL
, NULL
},
1066 { "CommRedialCount" , "retry count" , isNumber
, &kSCPropNetPPPCommRedialCount
, NULL
, NULL
},
1067 { "CommRedialEnabled" , NULL
, isBoolean
, &kSCPropNetPPPCommRedialEnabled
, NULL
, NULL
},
1068 { "CommRedialInterval" , "retry delay" , isNumber
, &kSCPropNetPPPCommRedialInterval
, NULL
, NULL
},
1069 { "CommTerminalScript" , "script" , isString
, &kSCPropNetPPPCommTerminalScript
, NULL
, NULL
},
1070 { "CommUseTerminalScript" , NULL
, isBoolean
, &kSCPropNetPPPCommUseTerminalScript
, NULL
, NULL
},
1073 { "CCPEnabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPEnabled
, NULL
, NULL
},
1074 { "CCPMPPE40Enabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPMPPE40Enabled
, NULL
, NULL
},
1075 { "CCPMPPE128Enabled" , NULL
, isBoolean
, &kSCPropNetPPPCCPMPPE128Enabled
, NULL
, NULL
},
1078 { "IPCPCompressionVJ" , NULL
, isBoolean
, &kSCPropNetPPPIPCPCompressionVJ
, NULL
, NULL
},
1079 { "IPCPUsePeerDNS" , NULL
, isBoolean
, &kSCPropNetPPPIPCPUsePeerDNS
, NULL
, NULL
},
1082 { "LCPEchoEnabled" , NULL
, isBoolean
, &kSCPropNetPPPLCPEchoEnabled
, NULL
, NULL
},
1083 { "LCPEchoFailure" , NULL
, isNumber
, &kSCPropNetPPPLCPEchoFailure
, NULL
, NULL
},
1084 { "LCPEchoInterval" , NULL
, isNumber
, &kSCPropNetPPPLCPEchoInterval
, NULL
, NULL
},
1085 { "LCPCompressionACField" , NULL
, isBoolean
, &kSCPropNetPPPLCPCompressionACField
, NULL
, NULL
},
1086 { "LCPCompressionPField" , NULL
, isBoolean
, &kSCPropNetPPPLCPCompressionPField
, NULL
, NULL
},
1087 { "LCPMRU" , NULL
, isNumber
, &kSCPropNetPPPLCPMRU
, NULL
, NULL
},
1088 { "LCPMTU" , NULL
, isNumber
, &kSCPropNetPPPLCPMTU
, NULL
, NULL
},
1089 { "LCPReceiveACCM" , NULL
, isNumber
, &kSCPropNetPPPLCPReceiveACCM
, NULL
, NULL
},
1090 { "LCPTransmitACCM" , NULL
, isNumber
, &kSCPropNetPPPLCPTransmitACCM
, NULL
, NULL
},
1093 { "?" , NULL
, isHelp
, NULL
, NULL
,
1094 "\nPPP configuration commands\n\n"
1095 " set interface [Account account]\n"
1096 " set interface [Password password]\n"
1097 " set interface [Number telephone-number]\n"
1098 " set interface [AlternateNumber telephone-number]\n"
1099 " set interface [IdleReminder {enable|disable}]\n"
1100 " set interface [IdleReminderTimer time-in-seconds]\n"
1101 " set interface [DisconnectOnIdle {enable|disable}]\n"
1102 " set interface [DisconnectOnIdleTimer time-in-seconds]\n"
1103 " set interface [DisconnectOnLogout {enable|disable}]"
1106 #define N_PPP_OPTIONS (sizeof(pppOptions) / sizeof(pppOptions[0]))
1110 set_interface_ppp(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1114 ok
= _process_options(pppOptions
, N_PPP_OPTIONS
, argc
, argv
, newConfiguration
);
1119 /* -------------------- */
1123 set_interface_vlan(int argc
, char **argv
, CFMutableDictionaryRef newConfiguration
)
1125 // xxxxx ("device", "tag")
1126 SCPrint(TRUE
, stdout
, CFSTR("vlan interface management not yet supported\n"));
1131 /* -------------------- */
1136 set_interface(int argc
, char **argv
)
1138 CFDictionaryRef configuration
;
1139 CFStringRef interfaceType
;
1140 CFMutableDictionaryRef newConfiguration
= NULL
;
1143 if (net_interface
== NULL
) {
1144 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
1149 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
1153 configuration
= SCNetworkInterfaceGetConfiguration(net_interface
);
1154 if (configuration
== NULL
) {
1155 newConfiguration
= CFDictionaryCreateMutable(NULL
,
1157 &kCFTypeDictionaryKeyCallBacks
,
1158 &kCFTypeDictionaryValueCallBacks
);
1160 newConfiguration
= CFDictionaryCreateMutableCopy(NULL
, 0, configuration
);
1161 CFDictionaryRemoveValue(newConfiguration
, kSCResvInactive
);
1164 interfaceType
= SCNetworkInterfaceGetInterfaceType(net_interface
);
1166 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBond
)) {
1167 ok
= set_interface_bond(argc
, argv
, newConfiguration
);
1168 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeEthernet
)) {
1169 ok
= set_interface_ethernet(argc
, argv
, newConfiguration
);
1170 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeFireWire
)) {
1171 ok
= set_interface_firewire(argc
, argv
, newConfiguration
);
1172 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeModem
)) {
1173 ok
= set_interface_modem(argc
, argv
, newConfiguration
);
1174 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIEEE80211
)) {
1175 ok
= set_interface_airport(argc
, argv
, newConfiguration
);
1176 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
1177 ok
= set_interface_ppp(argc
, argv
, newConfiguration
);
1178 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVLAN
)) {
1179 ok
= set_interface_vlan(argc
, argv
, newConfiguration
);
1181 SCPrint(TRUE
, stdout
, CFSTR("this interfaces configuration cannot be changed\n"));
1188 if (((configuration
== NULL
) && (CFDictionaryGetCount(newConfiguration
) > 0)) ||
1189 ((configuration
!= NULL
) && !CFEqual(configuration
, newConfiguration
))) {
1190 if (!SCNetworkInterfaceSetConfiguration(net_interface
, newConfiguration
)) {
1191 if (SCError() == kSCStatusNoKey
) {
1192 SCPrint(TRUE
, stdout
, CFSTR("could not update per-service interface configuration\n"));
1194 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
1204 if (newConfiguration
!= NULL
) CFRelease(newConfiguration
);
1209 /* -------------------- */
1214 show_interface(int argc
, char **argv
)
1216 SCNetworkInterfaceRef interface
;
1219 interface
= _find_interface(argv
[0]);
1221 if (net_interface
!= NULL
) {
1222 interface
= net_interface
;
1224 SCPrint(TRUE
, stdout
, CFSTR("interface not selected\n"));
1229 if (interface
!= NULL
) {
1230 _show_interface(interface
, CFSTR(""), TRUE
);
1237 /* -------------------- */
1242 _interface_description(SCNetworkInterfaceRef interface
)
1244 CFMutableStringRef description
;
1245 CFStringRef if_bsd_name
;
1246 CFStringRef if_type
;
1248 description
= CFStringCreateMutable(NULL
, 0);
1250 if_type
= SCNetworkInterfaceGetInterfaceType(interface
);
1251 CFStringAppend(description
, if_type
);
1253 if_bsd_name
= SCNetworkInterfaceGetBSDName(interface
);
1254 if (if_bsd_name
!= NULL
) {
1255 CFStringAppendFormat(description
, NULL
, CFSTR(" (%@)"), if_bsd_name
);
1258 interface
= SCNetworkInterfaceGetInterface(interface
);
1259 while ((interface
!= NULL
) &&
1260 !CFEqual(interface
, kSCNetworkInterfaceIPv4
)) {
1261 CFStringRef childDescription
;
1263 childDescription
= _interface_description(interface
);
1264 CFStringAppendFormat(description
, NULL
, CFSTR(" / %@"), childDescription
);
1265 CFRelease(childDescription
);
1267 interface
= SCNetworkInterfaceGetInterface(interface
);