2 * Copyright (c) 2004 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>
34 #include "net_service.h"
35 #include "net_interface.h"
36 #include "net_protocol.h"
39 /* -------------------- */
44 _compare_services(const void *val1
, const void *val2
, void *context
)
48 CFArrayRef order
= (CFArrayRef
)context
;
49 SCNetworkServiceRef s1
= (SCNetworkServiceRef
)val1
;
50 SCNetworkServiceRef s2
= (SCNetworkServiceRef
)val2
;
52 id1
= SCNetworkServiceGetServiceID(s1
);
53 id2
= SCNetworkServiceGetServiceID(s2
);
60 range
= CFRangeMake(0, CFArrayGetCount(order
));
61 o1
= CFArrayGetFirstIndexOfValue(order
, range
, id1
);
62 o2
= CFArrayGetFirstIndexOfValue(order
, range
, id2
);
65 return (o2
!= kCFNotFound
) ? kCFCompareGreaterThan
: kCFCompareLessThan
;
67 return (o1
!= kCFNotFound
) ? kCFCompareLessThan
: kCFCompareGreaterThan
;
71 return CFStringCompare(id1
, id2
, 0);
75 static SCNetworkServiceRef
76 _find_service(char *match
)
78 Boolean allowIndex
= TRUE
;
81 CFStringRef select_name
= NULL
;
82 SCNetworkServiceRef selected
= NULL
;
84 if (services
== NULL
) {
85 if (net_set
== NULL
) {
86 SCPrint(TRUE
, stdout
, CFSTR("set not selected\n"));
90 services
= SCNetworkSetCopyServices(net_set
);
91 if (services
== NULL
) {
92 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
99 // try to select the service by its serviceID
101 select_name
= CFStringCreateWithCString(NULL
, match
, kCFStringEncodingUTF8
);
103 n
= CFArrayGetCount(services
);
104 for (i
= 0; i
< n
; i
++) {
105 SCNetworkServiceRef service
;
106 CFStringRef serviceID
;
108 service
= CFArrayGetValueAtIndex(services
, i
);
109 serviceID
= SCNetworkServiceGetServiceID(service
);
110 if (CFEqual(select_name
, serviceID
)) {
116 // try to select the service by its name
118 for (i
= 0; i
< n
; i
++) {
119 SCNetworkServiceRef service
;
120 CFStringRef serviceName
;
122 service
= CFArrayGetValueAtIndex(services
, i
);
123 serviceName
= SCNetworkServiceGetName(service
);
124 if ((serviceName
!= NULL
) && CFEqual(select_name
, serviceName
)) {
125 if (selected
== NULL
) {
128 // if multiple services match
130 SCPrint(TRUE
, stdout
, CFSTR("multiple services match\n"));
136 if (selected
!= NULL
) {
140 // try to select the service by its name (case insensitive)
142 for (i
= 0; i
< n
; i
++) {
143 SCNetworkServiceRef service
;
144 CFStringRef serviceName
;
146 service
= CFArrayGetValueAtIndex(services
, i
);
147 serviceName
= SCNetworkServiceGetName(service
);
148 if ((serviceName
!= NULL
) &&
149 CFStringCompare(select_name
,
151 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
152 if (selected
== NULL
) {
155 // if multiple services match
157 SCPrint(TRUE
, stdout
, CFSTR("multiple services match\n"));
163 if (selected
!= NULL
) {
167 // try to select the service by its [BSD] interface name
169 for (i
= 0; i
< n
; i
++) {
170 SCNetworkInterfaceRef interface
;
171 CFStringRef interfaceName
= NULL
;
172 SCNetworkServiceRef service
;
174 service
= CFArrayGetValueAtIndex(services
, i
);
176 interface
= SCNetworkServiceGetInterface(service
);
177 while ((interface
!= NULL
) && (interfaceName
== NULL
)) {
178 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
179 if (interfaceName
== NULL
) {
180 interface
= SCNetworkInterfaceGetInterface(interface
);
184 if (interfaceName
== NULL
) {
188 if (CFStringCompare(select_name
,
190 kCFCompareCaseInsensitive
) == kCFCompareEqualTo
) {
191 if (selected
== NULL
) {
194 // if multiple services match
196 SCPrint(TRUE
, stdout
, CFSTR("multiple services match\n"));
202 if (selected
!= NULL
) {
206 // try to select the service by its index
214 val
= strtol(str
, &end
, 10);
215 if ((*str
!= '\0') && (*end
== '\0') && (errno
== 0)) {
216 if ((val
> 0) && (val
<= n
)) {
217 selected
= CFArrayGetValueAtIndex(services
, val
- 1);
222 if (selected
!= NULL
) {
226 SCPrint(TRUE
, stdout
, CFSTR("no match, which service?\n"));
230 if (select_name
!= NULL
) CFRelease(select_name
);
235 /* -------------------- */
240 create_service(int argc
, char **argv
)
242 SCNetworkInterfaceRef interface
;
243 CFStringRef interfaceName
;
246 CFMutableArrayRef newOrder
;
247 SCNetworkServiceRef service
= NULL
;
248 CFStringRef serviceName
;
250 CFArrayRef supported
;
253 SCPrint(TRUE
, stdout
, CFSTR("network configuration not open\n"));
257 if (net_set
== NULL
) {
258 SCPrint(TRUE
, stdout
, CFSTR("set not selected\n"));
263 if (net_interface
== NULL
) {
264 SCPrint(TRUE
, stdout
, CFSTR("no network interface selected\n"));
268 interface
= net_interface
;
270 interface
= _find_interface(argv
[0]);
275 if (interface
== NULL
) {
279 supported
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
);
280 if (supported
== NULL
) {
281 SCPrint(TRUE
, stdout
, CFSTR("no network protocols are supported over this interface\n"));
285 service
= SCNetworkServiceCreate(prefs
, interface
);
286 if (service
== NULL
) {
287 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
291 if ((argc
> 0) && (strlen(argv
[0]) > 0)) {
294 serviceName
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
298 ok
= SCNetworkServiceSetName(service
, serviceName
);
299 CFRelease(serviceName
);
301 SCPrint(TRUE
, stdout
, CFSTR("service not created: %s\n"), SCErrorString(SCError()));
307 ok
= SCNetworkSetAddService(net_set
, service
);
309 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
310 (void)SCNetworkServiceRemove(service
);
316 order
= SCNetworkSetGetServiceOrder(net_set
);
318 newOrder
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
320 newOrder
= CFArrayCreateMutableCopy(NULL
, 0, order
);
322 CFArrayAppendValue(newOrder
, SCNetworkServiceGetServiceID(service
));
323 ok
= SCNetworkSetSetServiceOrder(net_set
, newOrder
);
326 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
327 (void)SCNetworkServiceRemove(service
);
331 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
332 if (interfaceName
== NULL
) {
333 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
335 if (interfaceName
!= NULL
) {
336 if (!SCNetworkServiceSetName(service
, interfaceName
)) {
339 for (i
= 2; i
< 100; i
++) {
340 serviceName
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@ %d"), interfaceName
, i
);
341 ok
= SCNetworkServiceSetName(service
, serviceName
);
342 CFRelease(serviceName
);
350 if (net_service
!= NULL
) CFRelease(net_service
);
351 net_service
= CFRetain(service
);
353 serviceName
= SCNetworkServiceGetName(service
);
354 if (serviceName
!= NULL
) {
355 SCPrint(TRUE
, stdout
,
356 CFSTR("service \"%@\" (%@) created and selected\n"),
358 SCNetworkServiceGetServiceID(service
));
360 SCPrint(TRUE
, stdout
,
361 CFSTR("service ID \"%@\" created and selected\n"),
362 SCNetworkServiceGetServiceID(service
));
365 setName
= SCNetworkSetGetName(net_set
);
366 if (setName
!= NULL
) {
367 SCPrint(TRUE
, stdout
, CFSTR("& added to set \"%@\"\n"), setName
);
369 SCPrint(TRUE
, stdout
, CFSTR("& added to set ID \"%@\"\n"),
370 SCNetworkSetGetSetID(net_set
));
373 if (net_interface
!= NULL
) CFRelease(net_interface
);
374 net_interface
= CFRetain(interface
);
376 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
377 if (interfaceName
== NULL
) {
378 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
380 if (interfaceName
== NULL
) {
381 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
384 SCPrint(TRUE
, stdout
,
385 CFSTR("& interface \"%@\" selected\n"),
388 if (protocols
!= NULL
) {
389 CFRelease(protocols
);
393 if (net_protocol
!= NULL
) {
394 CFRelease(net_protocol
);
396 SCPrint(TRUE
, stdout
, CFSTR("& no protocol selected\n"));
399 if (services
!= NULL
) {
406 if (service
!= NULL
) CFRelease(service
);
413 disable_service(int argc
, char **argv
)
415 SCNetworkServiceRef service
;
418 service
= _find_service(argv
[0]);
420 if (net_service
!= NULL
) {
421 service
= net_service
;
423 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
428 if (service
== NULL
) {
432 if (!SCNetworkServiceSetEnabled(service
, FALSE
)) {
433 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
445 enable_service(int argc
, char **argv
)
447 SCNetworkServiceRef service
;
450 service
= _find_service(argv
[0]);
452 if (net_service
!= NULL
) {
453 service
= net_service
;
455 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
460 if (service
== NULL
) {
464 if (!SCNetworkServiceSetEnabled(service
, TRUE
)) {
465 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
477 remove_service(int argc
, char **argv
)
479 SCNetworkServiceRef service
= NULL
;
480 CFStringRef serviceName
;
483 service
= _find_service(argv
[0]);
485 if (net_service
!= NULL
) {
486 service
= net_service
;
490 if (service
== NULL
) {
496 if (!SCNetworkServiceRemove(service
)) {
497 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
503 serviceName
= SCNetworkServiceGetName(service
);
504 if (serviceName
!= NULL
) {
505 SCPrint(TRUE
, stdout
, CFSTR("service \"%@\" removed\n"), serviceName
);
507 SCPrint(TRUE
, stdout
,
508 CFSTR("service ID \"%@\" removed\n"),
509 SCNetworkServiceGetServiceID(service
));
512 if ((net_service
!= NULL
) && CFEqual(service
, net_service
)) {
513 CFRelease(net_service
);
515 SCPrint(TRUE
, stdout
, CFSTR("& no service selected\n"));
517 if (protocols
!= NULL
) {
518 CFRelease(protocols
);
522 if (net_protocol
!= NULL
) {
523 CFRelease(net_protocol
);
525 SCPrint(TRUE
, stdout
, CFSTR("& no protocol selected\n"));
528 if (net_interface
!= NULL
) {
529 CFRelease(net_interface
);
530 net_interface
= NULL
;
531 SCPrint(TRUE
, stdout
, CFSTR("& no interface selected\n"));
535 if (services
!= NULL
) {
549 select_service(int argc
, char **argv
)
551 SCNetworkInterfaceRef interface
;
552 SCNetworkServiceRef service
;
553 CFStringRef serviceName
;
555 service
= _find_service(argv
[0]);
557 if (service
== NULL
) {
561 if (net_service
!= NULL
) CFRelease(net_service
);
562 net_service
= CFRetain(service
);
564 serviceName
= SCNetworkServiceGetName(service
);
565 if (serviceName
!= NULL
) {
566 SCPrint(TRUE
, stdout
, CFSTR("service \"%@\" selected\n"), serviceName
);
568 SCPrint(TRUE
, stdout
,
569 CFSTR("service ID \"%@\" selected\n"),
570 SCNetworkServiceGetServiceID(service
));
573 interface
= SCNetworkServiceGetInterface(service
);
574 if (interface
!= NULL
) {
575 CFStringRef interfaceName
;
577 if (net_interface
!= NULL
) CFRelease(net_interface
);
578 net_interface
= CFRetain(interface
);
580 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
581 if (interfaceName
== NULL
) {
582 interfaceName
= SCNetworkInterfaceGetBSDName(interface
);
584 if (interfaceName
== NULL
) {
585 interfaceName
= SCNetworkInterfaceGetInterfaceType(interface
);
588 SCPrint(TRUE
, stdout
,
589 CFSTR("& interface \"%@\" selected\n"),
592 if (net_interface
!= NULL
) {
593 CFRelease(net_interface
);
594 net_interface
= NULL
;
595 SCPrint(TRUE
, stdout
, CFSTR("& no interface selected\n"));
599 if (protocols
!= NULL
) {
600 CFRelease(protocols
);
604 if (net_protocol
!= NULL
) {
605 CFRelease(net_protocol
);
607 SCPrint(TRUE
, stdout
, CFSTR("& no protocol selected\n"));
616 set_service(int argc
, char **argv
)
620 if (net_service
== NULL
) {
621 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
626 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
637 if (strcmp(command
, "name") == 0) {
638 CFStringRef serviceName
;
641 SCPrint(TRUE
, stdout
, CFSTR("name not specified\n"));
645 serviceName
= (strlen(argv
[0]) > 0)
646 ? CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
)
651 ok
= SCNetworkServiceSetName(net_service
, serviceName
);
652 if (serviceName
!= NULL
) CFRelease(serviceName
);
654 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
659 } else if (strcmp(command
, "order") == 0) {
667 services
= SCNetworkSetCopyServices(net_set
);
668 nServices
= CFArrayGetCount(services
);
672 SCPrint(TRUE
, stdout
, CFSTR("order not specified\n"));
676 if (net_set
== NULL
) {
677 SCPrint(TRUE
, stdout
, CFSTR("set not selected\n"));
686 newIndex
= strtol(str
, &end
, 10);
687 if ((*str
!= '\0') && (*end
== '\0') && (errno
== 0)) {
688 if ((newIndex
> 0) && (newIndex
<= nServices
)) {
690 CFMutableArrayRef newOrder
;
692 CFStringRef serviceID
= SCNetworkServiceGetServiceID(net_service
);
694 order
= SCNetworkSetGetServiceOrder(net_set
);
696 newOrder
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
698 newOrder
= CFArrayCreateMutableCopy(NULL
, 0, order
);
701 curIndex
= CFArrayGetFirstIndexOfValue(newOrder
,
702 CFRangeMake(0, CFArrayGetCount(newOrder
)),
704 if (curIndex
!= kCFNotFound
) {
705 CFArrayRemoveValueAtIndex(newOrder
, curIndex
);
708 if (newIndex
<= CFArrayGetCount(newOrder
)) {
709 CFArrayInsertValueAtIndex(newOrder
, newIndex
- 1, serviceID
);
711 CFArrayAppendValue(newOrder
, serviceID
);
714 ok
= SCNetworkSetSetServiceOrder(net_set
, newOrder
);
717 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
723 SCPrint(TRUE
, stdout
, CFSTR("set order to what?\n"));
727 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
731 SCPrint(TRUE
, stdout
, CFSTR("set what?\n"));
740 __show_service_interface(SCNetworkServiceRef service
, const char *prefix
)
742 CFStringRef description
;
743 SCNetworkInterfaceRef interface
;
745 interface
= SCNetworkServiceGetInterface(service
);
746 if (interface
== NULL
) {
750 description
= _interface_description(interface
);
751 SCPrint(TRUE
, stdout
, CFSTR("%s%@\n"), prefix
, description
);
752 CFRelease(description
);
758 __show_service_protocols(SCNetworkServiceRef service
, const char *prefix
, Boolean skipEmpty
)
762 CFArrayRef protocols
;
764 protocols
= SCNetworkServiceCopyProtocols(service
);
765 if (protocols
== NULL
) {
769 n
= CFArrayGetCount(protocols
);
771 CFMutableArrayRef sorted
;
773 sorted
= CFArrayCreateMutableCopy(NULL
, 0, protocols
);
774 CFArraySortValues(sorted
,
778 CFRelease(protocols
);
782 for (i
= 0; i
< n
; i
++) {
783 CFStringRef description
;
784 SCNetworkProtocolRef protocol
;
786 protocol
= CFArrayGetValueAtIndex(protocols
, i
);
787 description
= _protocol_description(protocol
, skipEmpty
);
788 if (description
!= NULL
) {
789 CFStringRef protocolType
;
791 protocolType
= SCNetworkProtocolGetProtocolType(protocol
);
792 SCPrint(TRUE
, stdout
,
793 CFSTR("%s%@%*s : %@\n"),
796 sizeof("Interface") - CFStringGetLength(protocolType
) - 1,
799 CFRelease(description
);
803 CFRelease(protocols
);
810 show_service(int argc
, char **argv
)
812 SCNetworkInterfaceRef interface
;
813 CFArrayRef protocols
;
814 SCNetworkServiceRef service
;
815 CFStringRef serviceName
;
818 service
= _find_service(argv
[0]);
820 if (net_service
!= NULL
) {
821 service
= net_service
;
823 SCPrint(TRUE
, stdout
, CFSTR("service not selected\n"));
828 if (service
== NULL
) {
832 SCPrint(TRUE
, stdout
, CFSTR("service id = %@\n"), SCNetworkServiceGetServiceID(service
));
834 serviceName
= SCNetworkServiceGetName(service
);
835 SCPrint(TRUE
, stdout
, CFSTR("name = %@\n"),
836 (serviceName
!= NULL
) ? serviceName
: CFSTR(""));
838 interface
= SCNetworkServiceGetInterface(service
);
839 if (interface
!= NULL
) {
840 CFStringRef interfaceName
;
842 interfaceName
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
843 if (interfaceName
!= NULL
) {
844 CFRetain(interfaceName
);
846 interfaceName
= _interface_description(interface
);
848 if (interfaceName
!= NULL
) {
849 SCPrint(TRUE
, stdout
, CFSTR("interface = %@\n"), interfaceName
);
850 CFRelease(interfaceName
);
853 SCPrint(TRUE
, stdout
, CFSTR("\n No interface!\n\n"));
856 protocols
= SCNetworkServiceCopyProtocols(service
);
857 if (protocols
!= NULL
) {
860 n
= CFArrayGetCount(protocols
);
862 CFMutableArrayRef sorted
;
864 sorted
= CFArrayCreateMutableCopy(NULL
, 0, protocols
);
865 CFArraySortValues(sorted
,
869 CFRelease(protocols
);
876 SCPrint(TRUE
, stdout
, CFSTR("configured protocols = "));
877 for (i
= 0; i
< n
; i
++) {
878 SCNetworkProtocolRef protocol
;
880 protocol
= CFArrayGetValueAtIndex(protocols
, i
);
881 SCPrint(TRUE
, stdout
, CFSTR("%s%@"),
882 (i
== 0) ? "" : ", ",
883 SCNetworkProtocolGetProtocolType(protocol
));
885 SCPrint(TRUE
, stdout
, CFSTR("\n"));
887 __show_service_protocols(service
, " ", FALSE
);
889 SCPrint(TRUE
, stdout
, CFSTR("no configured protocols\n"));
892 CFRelease(protocols
);
896 SCPrint(TRUE
, stdout
, CFSTR("\n%@\n"), service
);
905 show_services(int argc
, char **argv
)
911 SCPrint(TRUE
, stdout
, CFSTR("network configuration not open\n"));
916 if (services
!= NULL
) CFRelease(services
);
917 services
= SCNetworkServiceCopyAll(prefs
);
919 if (net_set
== NULL
) {
920 SCPrint(TRUE
, stdout
, CFSTR("set not selected\n"));
924 if (services
!= NULL
) CFRelease(services
);
925 services
= SCNetworkSetCopyServices(net_set
);
926 n
= (services
!= NULL
) ? CFArrayGetCount(services
) : 0;
929 CFMutableArrayRef sorted
;
931 order
= SCNetworkSetGetServiceOrder(net_set
);
932 sorted
= CFArrayCreateMutableCopy(NULL
, 0, services
);
933 CFArraySortValues(sorted
,
934 CFRangeMake(0, CFArrayGetCount(sorted
)),
942 if (services
== NULL
) {
943 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
947 n
= CFArrayGetCount(services
);
948 for (i
= 0; i
< n
; i
++) {
949 SCNetworkServiceRef service
;
950 CFStringRef serviceName
;
951 CFStringRef serviceID
;
953 service
= CFArrayGetValueAtIndex(services
, i
);
954 serviceID
= SCNetworkServiceGetServiceID(service
);
955 serviceName
= SCNetworkServiceGetName(service
);
956 if (serviceName
== NULL
) serviceName
= CFSTR("");
958 SCPrint(TRUE
, stdout
, CFSTR("%c%2d: %@%-*s (%@)%s\n"),
959 ((net_service
!= NULL
) && CFEqual(service
, net_service
)) ? '>' : ' ',
962 30 - CFStringGetLength(serviceName
),
965 SCNetworkServiceGetEnabled(service
) ? "" : " *DISABLED*");
967 __show_service_interface(service
, " Interface : ");
968 __show_service_protocols(service
, " ", TRUE
);