2 * Copyright (c) 2004-2007 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>
34 #include "net_service.h"
35 #include "net_interface.h"
36 #include "net_protocol.h"
40 /* -------------------- */
45 _compare_services(const void *val1
, const void *val2
, void *context
)
49 CFArrayRef order
= (CFArrayRef
)context
;
50 SCNetworkServiceRef s1
= (SCNetworkServiceRef
)val1
;
51 SCNetworkServiceRef s2
= (SCNetworkServiceRef
)val2
;
53 id1
= SCNetworkServiceGetServiceID(s1
);
54 id2
= SCNetworkServiceGetServiceID(s2
);
61 range
= CFRangeMake(0, CFArrayGetCount(order
));
62 o1
= CFArrayGetFirstIndexOfValue(order
, range
, id1
);
63 o2
= CFArrayGetFirstIndexOfValue(order
, range
, id2
);
66 return (o2
!= kCFNotFound
) ? kCFCompareGreaterThan
: kCFCompareLessThan
;
68 return (o1
!= kCFNotFound
) ? kCFCompareLessThan
: kCFCompareGreaterThan
;
72 return CFStringCompare(id1
, id2
, 0);
76 static SCNetworkServiceRef
77 _find_service(char *match
)
79 Boolean allowIndex
= TRUE
;
82 CFStringRef select_name
= NULL
;
83 SCNetworkServiceRef selected
= NULL
;
85 if (services
== NULL
) {
86 if (net_set
== NULL
) {
87 SCPrint(TRUE
, stdout
, CFSTR("set not selected\n"));
91 services
= SCNetworkSetCopyServices(net_set
);
92 if (services
== NULL
) {
93 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
100 // try to select the service by its serviceID
102 select_name
= CFStringCreateWithCString(NULL
, match
, kCFStringEncodingUTF8
);
104 n
= CFArrayGetCount(services
);
105 for (i
= 0; i
< n
; i
++) {
106 SCNetworkServiceRef service
;
107 CFStringRef serviceID
;
109 service
= CFArrayGetValueAtIndex(services
, i
);
110 serviceID
= SCNetworkServiceGetServiceID(service
);
111 if (CFEqual(select_name
, serviceID
)) {
117 // try to select the service by its name
119 for (i
= 0; i
< n
; i
++) {
120 SCNetworkServiceRef service
;
121 CFStringRef serviceName
;
123 service
= CFArrayGetValueAtIndex(services
, i
);
124 serviceName
= SCNetworkServiceGetName(service
);
125 if ((serviceName
!= NULL
) && CFEqual(select_name
, serviceName
)) {
126 if (selected
== NULL
) {
129 // if multiple services match
131 SCPrint(TRUE
, stdout
, CFSTR("multiple services match\n"));
137 if (selected
!= NULL
) {
141 // try to select the service by its name (case insensitive)
143 for (i
= 0; i
< n
; i
++) {
144 SCNetworkServiceRef service
;
145 CFStringRef serviceName
;
147 service
= CFArrayGetValueAtIndex(services
, i
);
148 serviceName
= SCNetworkServiceGetName(service
);
149 if ((serviceName
!= NULL
) &&
150 CFStringCompare(select_name
,
152 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
153 if (selected
== NULL
) {
156 // if multiple services match
158 SCPrint(TRUE
, stdout
, CFSTR("multiple services match\n"));
164 if (selected
!= NULL
) {
168 // try to select the service by its [BSD] interface name
170 for (i
= 0; i
< n
; i
++) {
171 SCNetworkInterfaceRef interface
;
172 CFStringRef interfaceName
= NULL
;
173 SCNetworkServiceRef service
;
175 service
= CFArrayGetValueAtIndex(services
, i
);
177 interface
= SCNetworkServiceGetInterface(service
);
178 while ((interface
!= NULL
) && (interfaceName
== NULL
)) {
179 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
180 if (interfaceName
== NULL
) {
181 interface
= SCNetworkInterfaceGetInterface(interface
);
185 if (interfaceName
== NULL
) {
189 if (CFStringCompare(select_name
,
191 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
192 if (selected
== NULL
) {
195 // if multiple services match
197 SCPrint(TRUE
, stdout
, CFSTR("multiple services match\n"));
203 if (selected
!= NULL
) {
207 // try to select the service by its index
215 val
= strtol(str
, &end
, 10);
216 if ((*str
!= '\0') && (*end
== '\0') && (errno
== 0)) {
217 if ((val
> 0) && (val
<= n
)) {
218 selected
= CFArrayGetValueAtIndex(services
, val
- 1);
223 if (selected
!= NULL
) {
227 SCPrint(TRUE
, stdout
, CFSTR("no match, which service?\n"));
231 if (select_name
!= NULL
) CFRelease(select_name
);
236 /* -------------------- */
241 create_service(int argc
, char **argv
)
243 SCNetworkInterfaceRef interface
;
244 CFStringRef interfaceName
;
246 SCNetworkServiceRef service
= NULL
;
247 CFStringRef serviceName
;
249 CFArrayRef supported
;
252 SCPrint(TRUE
, stdout
, CFSTR("network configuration not open\n"));
256 if (net_set
== NULL
) {
257 SCPrint(TRUE
, stdout
, CFSTR("set not selected\n"));
262 if (net_interface
== NULL
) {
263 SCPrint(TRUE
, stdout
, CFSTR("no network interface selected\n"));
267 interface
= net_interface
;
269 interface
= _find_interface(argv
[0]);
274 if (interface
== NULL
) {
278 supported
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
);
279 if (supported
== NULL
) {
280 SCPrint(TRUE
, stdout
, CFSTR("no network protocols are supported over this interface\n"));
284 service
= SCNetworkServiceCreate(prefs
, interface
);
285 if (service
== NULL
) {
286 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
290 if ((argc
> 0) && (strlen(argv
[0]) > 0)) {
293 serviceName
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
297 ok
= SCNetworkServiceSetName(service
, serviceName
);
298 CFRelease(serviceName
);
300 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
301 (void)SCNetworkServiceRemove(service
);
306 ok
= SCNetworkSetAddService(net_set
, service
);
308 SCPrint(TRUE
, stdout
, CFSTR("service not created: %s\n"), SCErrorString(SCError()));
309 (void)SCNetworkServiceRemove(service
);
313 _prefs_changed
= TRUE
;
315 if (net_service
!= NULL
) CFRelease(net_service
);
316 net_service
= CFRetain(service
);
318 serviceName
= SCNetworkServiceGetName(service
);
319 if (serviceName
!= NULL
) {
320 SCPrint(TRUE
, stdout
,
321 CFSTR("service \"%@\" (%@) created and selected\n"),
323 SCNetworkServiceGetServiceID(service
));
325 SCPrint(TRUE
, stdout
,
326 CFSTR("service ID \"%@\" created and selected\n"),
327 SCNetworkServiceGetServiceID(service
));
330 setName
= SCNetworkSetGetName(net_set
);
331 if (setName
!= NULL
) {
332 SCPrint(TRUE
, stdout
, CFSTR("& added to set \"%@\"\n"), setName
);
334 SCPrint(TRUE
, stdout
, CFSTR("& added to set ID \"%@\"\n"),
335 SCNetworkSetGetSetID(net_set
));
338 if (net_interface
!= NULL
) CFRelease(net_interface
);
339 net_interface
= CFRetain(interface
);
341 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
342 if (interfaceName
== NULL
) {
343 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
345 if (interfaceName
== NULL
) {
346 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
349 SCPrint(TRUE
, stdout
,
350 CFSTR("& interface \"%@\" selected\n"),
353 if (protocols
!= NULL
) {
354 CFRelease(protocols
);
358 if (net_protocol
!= NULL
) {
359 CFRelease(net_protocol
);
361 SCPrint(TRUE
, stdout
, CFSTR("& no protocol selected\n"));
364 if (services
!= NULL
) {
371 if (service
!= NULL
) CFRelease(service
);
378 disable_service(int argc
, char **argv
)
380 SCNetworkServiceRef service
;
383 service
= _find_service(argv
[0]);
385 if (net_service
!= NULL
) {
386 service
= net_service
;
388 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
393 if (service
== NULL
) {
397 if (!SCNetworkServiceSetEnabled(service
, FALSE
)) {
398 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
402 _prefs_changed
= TRUE
;
409 enable_service(int argc
, char **argv
)
411 SCNetworkServiceRef service
;
414 service
= _find_service(argv
[0]);
416 if (net_service
!= NULL
) {
417 service
= net_service
;
419 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
424 if (service
== NULL
) {
428 if (!SCNetworkServiceSetEnabled(service
, TRUE
)) {
429 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
433 _prefs_changed
= TRUE
;
440 remove_service(int argc
, char **argv
)
442 SCNetworkServiceRef service
= NULL
;
443 CFStringRef serviceName
;
446 service
= _find_service(argv
[0]);
448 if (net_service
!= NULL
) {
449 service
= net_service
;
453 if (service
== NULL
) {
459 if (!SCNetworkServiceRemove(service
)) {
460 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
464 _prefs_changed
= TRUE
;
466 serviceName
= SCNetworkServiceGetName(service
);
467 if (serviceName
!= NULL
) {
468 SCPrint(TRUE
, stdout
, CFSTR("service \"%@\" removed\n"), serviceName
);
470 SCPrint(TRUE
, stdout
,
471 CFSTR("service ID \"%@\" removed\n"),
472 SCNetworkServiceGetServiceID(service
));
475 if ((net_service
!= NULL
) && CFEqual(service
, net_service
)) {
476 CFRelease(net_service
);
478 SCPrint(TRUE
, stdout
, CFSTR("& no service selected\n"));
480 if (protocols
!= NULL
) {
481 CFRelease(protocols
);
485 if (net_protocol
!= NULL
) {
486 CFRelease(net_protocol
);
488 SCPrint(TRUE
, stdout
, CFSTR("& no protocol selected\n"));
491 if (net_interface
!= NULL
) {
492 CFRelease(net_interface
);
493 net_interface
= NULL
;
494 SCPrint(TRUE
, stdout
, CFSTR("& no interface selected\n"));
498 if (services
!= NULL
) {
512 select_service(int argc
, char **argv
)
514 SCNetworkInterfaceRef interface
;
515 SCNetworkServiceRef service
;
516 CFStringRef serviceName
;
518 service
= _find_service(argv
[0]);
520 if (service
== NULL
) {
524 if (net_service
!= NULL
) CFRelease(net_service
);
525 net_service
= CFRetain(service
);
527 serviceName
= SCNetworkServiceGetName(service
);
528 if (serviceName
!= NULL
) {
529 SCPrint(TRUE
, stdout
, CFSTR("service \"%@\" selected\n"), serviceName
);
531 SCPrint(TRUE
, stdout
,
532 CFSTR("service ID \"%@\" selected\n"),
533 SCNetworkServiceGetServiceID(service
));
536 interface
= SCNetworkServiceGetInterface(service
);
537 if (interface
!= NULL
) {
538 CFStringRef interfaceName
;
540 if (net_interface
!= NULL
) CFRelease(net_interface
);
541 net_interface
= CFRetain(interface
);
543 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
544 if (interfaceName
== NULL
) {
545 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
547 if (interfaceName
== NULL
) {
548 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
551 SCPrint(TRUE
, stdout
,
552 CFSTR("& interface \"%@\" selected\n"),
555 if (net_interface
!= NULL
) {
556 CFRelease(net_interface
);
557 net_interface
= NULL
;
558 SCPrint(TRUE
, stdout
, CFSTR("& no interface selected\n"));
562 if (protocols
!= NULL
) {
563 CFRelease(protocols
);
567 if (net_protocol
!= NULL
) {
568 CFRelease(net_protocol
);
570 SCPrint(TRUE
, stdout
, CFSTR("& no protocol selected\n"));
579 set_service(int argc
, char **argv
)
583 if (net_service
== NULL
) {
584 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
589 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
600 if (strcmp(command
, "name") == 0) {
601 CFStringRef serviceName
;
604 SCPrint(TRUE
, stdout
, CFSTR("name not specified\n"));
608 serviceName
= (strlen(argv
[0]) > 0)
609 ? CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
)
614 ok
= SCNetworkServiceSetName(net_service
, serviceName
);
615 if (serviceName
!= NULL
) CFRelease(serviceName
);
617 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
621 _prefs_changed
= TRUE
;
622 } else if (strcmp(command
, "order") == 0) {
630 services
= SCNetworkSetCopyServices(net_set
);
631 nServices
= CFArrayGetCount(services
);
635 SCPrint(TRUE
, stdout
, CFSTR("order not specified\n"));
639 if (net_set
== NULL
) {
640 SCPrint(TRUE
, stdout
, CFSTR("set not selected\n"));
649 newIndex
= strtol(str
, &end
, 10);
650 if ((*str
!= '\0') && (*end
== '\0') && (errno
== 0)) {
651 if ((newIndex
> 0) && (newIndex
<= nServices
)) {
653 CFMutableArrayRef newOrder
;
655 CFStringRef serviceID
= SCNetworkServiceGetServiceID(net_service
);
657 order
= SCNetworkSetGetServiceOrder(net_set
);
659 newOrder
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
661 newOrder
= CFArrayCreateMutableCopy(NULL
, 0, order
);
664 curIndex
= CFArrayGetFirstIndexOfValue(newOrder
,
665 CFRangeMake(0, CFArrayGetCount(newOrder
)),
667 if (curIndex
!= kCFNotFound
) {
668 CFArrayRemoveValueAtIndex(newOrder
, curIndex
);
671 if (newIndex
<= CFArrayGetCount(newOrder
)) {
672 CFArrayInsertValueAtIndex(newOrder
, newIndex
- 1, serviceID
);
674 CFArrayAppendValue(newOrder
, serviceID
);
677 ok
= SCNetworkSetSetServiceOrder(net_set
, newOrder
);
680 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
684 _prefs_changed
= TRUE
;
686 SCPrint(TRUE
, stdout
, CFSTR("set order to what?\n"));
690 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
694 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
703 __show_service_interface(SCNetworkServiceRef service
, const char *prefix
)
705 CFStringRef description
;
706 SCNetworkInterfaceRef interface
;
708 interface
= SCNetworkServiceGetInterface(service
);
709 if (interface
== NULL
) {
713 description
= _interface_description(interface
);
714 SCPrint(TRUE
, stdout
, CFSTR("%s%@\n"), prefix
, description
);
715 CFRelease(description
);
721 __show_service_protocols(SCNetworkServiceRef service
, const char *prefix
, Boolean skipEmpty
)
725 CFArrayRef protocols
;
727 protocols
= SCNetworkServiceCopyProtocols(service
);
728 if (protocols
== NULL
) {
732 n
= CFArrayGetCount(protocols
);
734 CFMutableArrayRef sorted
;
736 sorted
= CFArrayCreateMutableCopy(NULL
, 0, protocols
);
737 CFArraySortValues(sorted
,
741 CFRelease(protocols
);
745 for (i
= 0; i
< n
; i
++) {
746 CFStringRef description
;
747 SCNetworkProtocolRef protocol
;
749 protocol
= CFArrayGetValueAtIndex(protocols
, i
);
750 description
= _protocol_description(protocol
, skipEmpty
);
751 if (description
!= NULL
) {
752 CFStringRef protocolType
;
754 protocolType
= SCNetworkProtocolGetProtocolType(protocol
);
755 SCPrint(TRUE
, stdout
,
756 CFSTR("%s%@%*s : %@\n"),
759 sizeof("Interface") - CFStringGetLength(protocolType
) - 1,
762 CFRelease(description
);
766 CFRelease(protocols
);
773 show_service(int argc
, char **argv
)
775 SCNetworkInterfaceRef interface
;
776 CFArrayRef protocols
;
777 SCNetworkServiceRef service
;
778 CFStringRef serviceName
;
781 service
= _find_service(argv
[0]);
783 if (net_service
!= NULL
) {
784 service
= net_service
;
786 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
791 if (service
== NULL
) {
795 SCPrint(TRUE
, stdout
, CFSTR("service id = %@\n"), SCNetworkServiceGetServiceID(service
));
797 serviceName
= SCNetworkServiceGetName(service
);
798 SCPrint(TRUE
, stdout
, CFSTR("name = %@\n"),
799 (serviceName
!= NULL
) ? serviceName
: CFSTR(""));
801 interface
= SCNetworkServiceGetInterface(service
);
802 if (interface
!= NULL
) {
803 CFStringRef interfaceName
;
805 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
806 if (interfaceName
!= NULL
) {
807 CFRetain(interfaceName
);
809 interfaceName
= _interface_description(interface
);
811 if (interfaceName
!= NULL
) {
812 SCPrint(TRUE
, stdout
, CFSTR("interface = %@\n"), interfaceName
);
813 CFRelease(interfaceName
);
816 SCPrint(TRUE
, stdout
, CFSTR("\n No interface!\n\n"));
819 protocols
= SCNetworkServiceCopyProtocols(service
);
820 if (protocols
!= NULL
) {
823 n
= CFArrayGetCount(protocols
);
825 CFMutableArrayRef sorted
;
827 sorted
= CFArrayCreateMutableCopy(NULL
, 0, protocols
);
828 CFArraySortValues(sorted
,
832 CFRelease(protocols
);
839 SCPrint(TRUE
, stdout
, CFSTR("configured protocols = "));
840 for (i
= 0; i
< n
; i
++) {
841 SCNetworkProtocolRef protocol
;
843 protocol
= CFArrayGetValueAtIndex(protocols
, i
);
844 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
845 (i
== 0) ? "" : ", ",
846 SCNetworkProtocolGetProtocolType(protocol
));
848 SCPrint(TRUE
, stdout
, CFSTR("\n"));
850 __show_service_protocols(service
, " ", FALSE
);
852 SCPrint(TRUE
, stdout
, CFSTR("no configured protocols\n"));
855 CFRelease(protocols
);
859 SCPrint(TRUE
, stdout
, CFSTR("\n%@\n"), service
);
868 show_services(int argc
, char **argv
)
874 SCPrint(TRUE
, stdout
, CFSTR("network configuration not open\n"));
879 if (services
!= NULL
) CFRelease(services
);
880 services
= SCNetworkServiceCopyAll(prefs
);
882 if (net_set
== NULL
) {
883 SCPrint(TRUE
, stdout
, CFSTR("set not selected\n"));
887 if (services
!= NULL
) CFRelease(services
);
888 services
= SCNetworkSetCopyServices(net_set
);
889 n
= (services
!= NULL
) ? CFArrayGetCount(services
) : 0;
892 CFMutableArrayRef sorted
;
894 order
= SCNetworkSetGetServiceOrder(net_set
);
895 sorted
= CFArrayCreateMutableCopy(NULL
, 0, services
);
896 CFArraySortValues(sorted
,
897 CFRangeMake(0, CFArrayGetCount(sorted
)),
905 if (services
== NULL
) {
906 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
910 n
= CFArrayGetCount(services
);
911 for (i
= 0; i
< n
; i
++) {
912 SCNetworkServiceRef service
;
913 CFStringRef serviceName
;
914 CFStringRef serviceID
;
916 service
= CFArrayGetValueAtIndex(services
, i
);
917 serviceID
= SCNetworkServiceGetServiceID(service
);
918 serviceName
= SCNetworkServiceGetName(service
);
919 if (serviceName
== NULL
) serviceName
= CFSTR("");
921 SCPrint(TRUE
, stdout
, CFSTR("%c%2d: %@%-*s (%@)%s\n"),
922 ((net_service
!= NULL
) && CFEqual(service
, net_service
)) ? '>' : ' ',
925 30 - CFStringGetLength(serviceName
),
928 SCNetworkServiceGetEnabled(service
) ? "" : " *DISABLED*");
930 __show_service_interface(service
, " Interface : ");
931 __show_service_protocols(service
, " ", TRUE
);