]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/net_service.c
configd-395.11.tar.gz
[apple/configd.git] / scutil.tproj / net_service.c
1 /*
2 * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * Modification History
26 *
27 * August 5, 2004 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31
32 #include "scutil.h"
33 #include "net.h"
34 #include "net_service.h"
35 #include "net_interface.h"
36 #include "net_protocol.h"
37 #include "prefs.h"
38
39
40 /* -------------------- */
41
42
43 static SCNetworkServiceRef
44 _find_service(char *match)
45 {
46 Boolean allowIndex = TRUE;
47 CFIndex i;
48 CFIndex n;
49 CFStringRef select_name = NULL;
50 SCNetworkServiceRef selected = NULL;
51
52 if (services == NULL) {
53 if (net_set == NULL) {
54 SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
55 return NULL;
56 }
57
58 services = SCNetworkSetCopyServices(net_set);
59 if (services == NULL) {
60 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
61 return NULL;
62 }
63
64 allowIndex = FALSE;
65 }
66
67 // try to select the service by its serviceID
68
69 select_name = CFStringCreateWithCString(NULL, match, kCFStringEncodingUTF8);
70
71 n = CFArrayGetCount(services);
72 for (i = 0; i < n; i++) {
73 SCNetworkServiceRef service;
74 CFStringRef serviceID;
75
76 service = CFArrayGetValueAtIndex(services, i);
77 serviceID = SCNetworkServiceGetServiceID(service);
78 if (CFEqual(select_name, serviceID)) {
79 selected = service;
80 goto done;
81 }
82 }
83
84 // try to select the service by its name
85
86 for (i = 0; i < n; i++) {
87 SCNetworkServiceRef service;
88 CFStringRef serviceName;
89
90 service = CFArrayGetValueAtIndex(services, i);
91 serviceName = SCNetworkServiceGetName(service);
92 if ((serviceName != NULL) && CFEqual(select_name, serviceName)) {
93 if (selected == NULL) {
94 selected = service;
95 } else {
96 // if multiple services match
97 selected = NULL;
98 SCPrint(TRUE, stdout, CFSTR("multiple services match\n"));
99 goto done;
100 }
101 }
102 }
103
104 if (selected != NULL) {
105 goto done;
106 }
107
108 // try to select the service by its name (case insensitive)
109
110 for (i = 0; i < n; i++) {
111 SCNetworkServiceRef service;
112 CFStringRef serviceName;
113
114 service = CFArrayGetValueAtIndex(services, i);
115 serviceName = SCNetworkServiceGetName(service);
116 if ((serviceName != NULL) &&
117 CFStringCompare(select_name,
118 serviceName,
119 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
120 if (selected == NULL) {
121 selected = service;
122 } else {
123 // if multiple services match
124 selected = NULL;
125 SCPrint(TRUE, stdout, CFSTR("multiple services match\n"));
126 goto done;
127 }
128 }
129 }
130
131 if (selected != NULL) {
132 goto done;
133 }
134
135 // try to select the service by its [BSD] interface name
136
137 for (i = 0; i < n; i++) {
138 SCNetworkInterfaceRef interface;
139 CFStringRef interfaceName = NULL;
140 SCNetworkServiceRef service;
141
142 service = CFArrayGetValueAtIndex(services, i);
143
144 interface = SCNetworkServiceGetInterface(service);
145 while ((interface != NULL) && (interfaceName == NULL)) {
146 interfaceName = SCNetworkInterfaceGetBSDName(interface);
147 if (interfaceName == NULL) {
148 interface = SCNetworkInterfaceGetInterface(interface);
149 }
150 }
151
152 if (interfaceName == NULL) {
153 continue;
154 }
155
156 if (CFStringCompare(select_name,
157 interfaceName,
158 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
159 if (selected == NULL) {
160 selected = service;
161 } else {
162 // if multiple services match
163 selected = NULL;
164 SCPrint(TRUE, stdout, CFSTR("multiple services match\n"));
165 goto done;
166 }
167 }
168 }
169
170 if (selected != NULL) {
171 goto done;
172 }
173
174 // try to select the service by its index
175
176 if (allowIndex) {
177 char *end;
178 char *str = match;
179 long val;
180
181 errno = 0;
182 val = strtol(str, &end, 10);
183 if ((*str != '\0') && (*end == '\0') && (errno == 0)) {
184 if ((val > 0) && (val <= n)) {
185 selected = CFArrayGetValueAtIndex(services, val - 1);
186 }
187 }
188 }
189
190 if (selected != NULL) {
191 goto done;
192 }
193
194 SCPrint(TRUE, stdout, CFSTR("no match, which service?\n"));
195
196 done :
197
198 if (select_name != NULL) CFRelease(select_name);
199 return selected;
200 }
201
202
203 /* -------------------- */
204
205
206 __private_extern__
207 void
208 create_service(int argc, char **argv)
209 {
210 SCNetworkInterfaceRef interface;
211 CFStringRef interfaceName;
212 Boolean ok;
213 SCNetworkServiceRef service = NULL;
214 CFStringRef serviceName;
215 CFStringRef setName;
216 CFArrayRef supported;
217
218 if (prefs == NULL) {
219 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
220 return;
221 }
222
223 if (net_set == NULL) {
224 SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
225 return;
226 }
227
228 if (argc < 1) {
229 if (net_interface == NULL) {
230 SCPrint(TRUE, stdout, CFSTR("no network interface selected\n"));
231 return;
232 }
233
234 interface = net_interface;
235 } else {
236 int nArgs;
237
238 interface = _find_interface(argc, argv, &nArgs);
239 argv += nArgs;
240 argc -= nArgs;
241 }
242
243 if (interface == NULL) {
244 return;
245 }
246
247 supported = SCNetworkInterfaceGetSupportedProtocolTypes(interface);
248 if (supported == NULL) {
249 SCPrint(TRUE, stdout, CFSTR("no network protocols are supported over this interface\n"));
250 return;
251 }
252
253 service = SCNetworkServiceCreate(prefs, interface);
254 if (service == NULL) {
255 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
256 goto done;
257 }
258
259 if ((argc > 0) && (strlen(argv[0]) > 0)) {
260 Boolean ok;
261
262 serviceName = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
263 // argv++;
264 // argc--;
265
266 ok = SCNetworkServiceSetName(service, serviceName);
267 CFRelease(serviceName);
268 if (!ok) {
269 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
270 (void)SCNetworkServiceRemove(service);
271 goto done;
272 }
273 }
274
275 ok = SCNetworkServiceEstablishDefaultConfiguration(service);
276 if (!ok) {
277 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
278 (void)SCNetworkServiceRemove(service);
279 goto done;
280 }
281
282 ok = SCNetworkSetAddService(net_set, service);
283 if (!ok) {
284 SCPrint(TRUE, stdout, CFSTR("service not created: %s\n"), SCErrorString(SCError()));
285 (void)SCNetworkServiceRemove(service);
286 goto done;
287 }
288
289 _prefs_changed = TRUE;
290
291 if (net_service != NULL) CFRelease(net_service);
292 net_service = CFRetain(service);
293
294 serviceName = SCNetworkServiceGetName(service);
295 if (serviceName != NULL) {
296 SCPrint(TRUE, stdout,
297 CFSTR("service \"%@\" (%@) created and selected\n"),
298 serviceName,
299 SCNetworkServiceGetServiceID(service));
300 } else {
301 SCPrint(TRUE, stdout,
302 CFSTR("service ID \"%@\" created and selected\n"),
303 SCNetworkServiceGetServiceID(service));
304 }
305
306 setName = SCNetworkSetGetName(net_set);
307 if (setName != NULL) {
308 SCPrint(TRUE, stdout, CFSTR("& added to set \"%@\"\n"), setName);
309 } else {
310 SCPrint(TRUE, stdout, CFSTR("& added to set ID \"%@\"\n"),
311 SCNetworkSetGetSetID(net_set));
312 }
313
314 if (net_interface != NULL) CFRelease(net_interface);
315 net_interface = SCNetworkServiceGetInterface(net_service);
316 if (net_interface != NULL) {
317 CFRetain(net_interface);
318 }
319
320 interfaceName = SCNetworkInterfaceGetLocalizedDisplayName(interface);
321 if (interfaceName == NULL) {
322 interfaceName = SCNetworkInterfaceGetBSDName(interface);
323 }
324 if (interfaceName == NULL) {
325 interfaceName = SCNetworkInterfaceGetInterfaceType(interface);
326 }
327
328 SCPrint(TRUE, stdout,
329 CFSTR("& interface \"%@\" selected\n"),
330 interfaceName);
331
332 if (protocols != NULL) {
333 CFRelease(protocols);
334 protocols = NULL;
335 }
336
337 if (net_protocol != NULL) {
338 CFRelease(net_protocol);
339 net_protocol = NULL;
340 SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n"));
341 }
342
343 if (services != NULL) {
344 CFRelease(services);
345 services = NULL;
346 }
347
348 done :
349
350 if (service != NULL) CFRelease(service);
351 return;
352 }
353
354
355 __private_extern__
356 void
357 disable_service(int argc, char **argv)
358 {
359 SCNetworkServiceRef service;
360
361 if (argc == 1) {
362 service = _find_service(argv[0]);
363 } else {
364 if (net_service != NULL) {
365 service = net_service;
366 } else {
367 SCPrint(TRUE, stdout, CFSTR("service not selected\n"));
368 return;
369 }
370 }
371
372 if (service == NULL) {
373 return;
374 }
375
376 if (!SCNetworkServiceSetEnabled(service, FALSE)) {
377 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
378 return;
379 }
380
381 _prefs_changed = TRUE;
382 return;
383 }
384
385
386 __private_extern__
387 void
388 enable_service(int argc, char **argv)
389 {
390 SCNetworkServiceRef service;
391
392 if (argc == 1) {
393 service = _find_service(argv[0]);
394 } else {
395 if (net_service != NULL) {
396 service = net_service;
397 } else {
398 SCPrint(TRUE, stdout, CFSTR("service not selected\n"));
399 return;
400 }
401 }
402
403 if (service == NULL) {
404 return;
405 }
406
407 if (!SCNetworkServiceSetEnabled(service, TRUE)) {
408 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
409 return;
410 }
411
412 _prefs_changed = TRUE;
413 return;
414 }
415
416
417 __private_extern__
418 void
419 remove_service(int argc, char **argv)
420 {
421 SCNetworkServiceRef service = NULL;
422 CFStringRef serviceName;
423
424 if (argc == 1) {
425 service = _find_service(argv[0]);
426 } else {
427 if (net_service != NULL) {
428 service = net_service;
429 }
430 }
431
432 if (service == NULL) {
433 return;
434 }
435
436 CFRetain(service);
437
438 if (!SCNetworkServiceRemove(service)) {
439 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
440 goto done;
441 }
442
443 _prefs_changed = TRUE;
444
445 serviceName = SCNetworkServiceGetName(service);
446 if (serviceName != NULL) {
447 SCPrint(TRUE, stdout, CFSTR("service \"%@\" removed\n"), serviceName);
448 } else {
449 SCPrint(TRUE, stdout,
450 CFSTR("service ID \"%@\" removed\n"),
451 SCNetworkServiceGetServiceID(service));
452 }
453
454 if ((net_service != NULL) && CFEqual(service, net_service)) {
455 CFRelease(net_service);
456 net_service = NULL;
457 SCPrint(TRUE, stdout, CFSTR("& no service selected\n"));
458
459 if (protocols != NULL) {
460 CFRelease(protocols);
461 protocols = NULL;
462 }
463
464 if (net_protocol != NULL) {
465 CFRelease(net_protocol);
466 net_protocol = NULL;
467 SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n"));
468 }
469
470 if (net_interface != NULL) {
471 CFRelease(net_interface);
472 net_interface = NULL;
473 SCPrint(TRUE, stdout, CFSTR("& no interface selected\n"));
474 }
475 }
476
477 if (services != NULL) {
478 CFRelease(services);
479 services = NULL;
480 }
481
482 done :
483
484 CFRelease(service);
485 return;
486 }
487
488
489 __private_extern__
490 void
491 select_service(int argc, char **argv)
492 {
493 SCNetworkInterfaceRef interface;
494 SCNetworkServiceRef service;
495 CFStringRef serviceName;
496
497 service = _find_service(argv[0]);
498
499 if (service == NULL) {
500 return;
501 }
502
503 if (net_service != NULL) CFRelease(net_service);
504 net_service = CFRetain(service);
505
506 serviceName = SCNetworkServiceGetName(service);
507 if (serviceName != NULL) {
508 SCPrint(TRUE, stdout, CFSTR("service \"%@\" selected\n"), serviceName);
509 } else {
510 SCPrint(TRUE, stdout,
511 CFSTR("service ID \"%@\" selected\n"),
512 SCNetworkServiceGetServiceID(service));
513 }
514
515 interface = SCNetworkServiceGetInterface(service);
516 if (interface != NULL) {
517 CFStringRef interfaceName;
518
519 if (net_interface != NULL) CFRelease(net_interface);
520 net_interface = CFRetain(interface);
521
522 interfaceName = SCNetworkInterfaceGetLocalizedDisplayName(interface);
523 if (interfaceName == NULL) {
524 interfaceName = SCNetworkInterfaceGetBSDName(interface);
525 }
526 if (interfaceName == NULL) {
527 interfaceName = SCNetworkInterfaceGetInterfaceType(interface);
528 }
529
530 SCPrint(TRUE, stdout,
531 CFSTR("& interface \"%@\" selected\n"),
532 interfaceName);
533 } else {
534 if (net_interface != NULL) {
535 CFRelease(net_interface);
536 net_interface = NULL;
537 SCPrint(TRUE, stdout, CFSTR("& no interface selected\n"));
538 }
539 }
540
541 if (protocols != NULL) {
542 CFRelease(protocols);
543 protocols = NULL;
544 }
545
546 if (net_protocol != NULL) {
547 CFRelease(net_protocol);
548 net_protocol = NULL;
549 SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n"));
550 }
551
552 return;
553 }
554
555
556 __private_extern__
557 void
558 set_service(int argc, char **argv)
559 {
560 Boolean ok;
561
562 if (net_service == NULL) {
563 SCPrint(TRUE, stdout, CFSTR("service not selected\n"));
564 return;
565 }
566
567 if (argc < 1) {
568 SCPrint(TRUE, stdout, CFSTR("set what?\n"));
569 return;
570 }
571
572 while (argc > 0) {
573 char *command;
574
575 command = argv[0];
576 argv++;
577 argc--;
578
579 if (strcmp(command, "name") == 0) {
580 CFStringRef serviceName;
581
582 if (argc < 1) {
583 SCPrint(TRUE, stdout, CFSTR("name not specified\n"));
584 return;
585 }
586
587 serviceName = (strlen(argv[0]) > 0)
588 ? CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8)
589 : NULL;
590 argv++;
591 argc--;
592
593 ok = SCNetworkServiceSetName(net_service, serviceName);
594 if (serviceName != NULL) CFRelease(serviceName);
595 if (!ok) {
596 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
597 return;
598 }
599
600 _prefs_changed = TRUE;
601 } else if (strcmp(command, "order") == 0) {
602
603 char *end;
604 long newIndex;
605 CFIndex nServices;
606 char *str;
607 CFArrayRef services;
608
609 services = SCNetworkSetCopyServices(net_set);
610 nServices = CFArrayGetCount(services);
611 CFRelease(services);
612
613 if (argc < 1) {
614 SCPrint(TRUE, stdout, CFSTR("order not specified\n"));
615 return;
616 }
617
618 if (net_set == NULL) {
619 SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
620 return;
621 }
622
623 str = argv[0];
624 argv++;
625 argc--;
626
627 errno = 0;
628 newIndex = strtol(str, &end, 10);
629 if ((*str != '\0') && (*end == '\0') && (errno == 0)) {
630 if ((newIndex > 0) && (newIndex <= nServices)) {
631 CFIndex curIndex;
632 CFMutableArrayRef newOrder;
633 CFArrayRef order;
634 CFStringRef serviceID = SCNetworkServiceGetServiceID(net_service);
635
636 order = SCNetworkSetGetServiceOrder(net_set);
637 if (order == NULL) {
638 newOrder = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
639 } else {
640 newOrder = CFArrayCreateMutableCopy(NULL, 0, order);
641 }
642
643 curIndex = CFArrayGetFirstIndexOfValue(newOrder,
644 CFRangeMake(0, CFArrayGetCount(newOrder)),
645 serviceID);
646 if (curIndex != kCFNotFound) {
647 CFArrayRemoveValueAtIndex(newOrder, curIndex);
648 }
649
650 if (newIndex <= CFArrayGetCount(newOrder)) {
651 CFArrayInsertValueAtIndex(newOrder, newIndex - 1, serviceID);
652 } else {
653 CFArrayAppendValue(newOrder, serviceID);
654 }
655
656 ok = SCNetworkSetSetServiceOrder(net_set, newOrder);
657 CFRelease(newOrder);
658 if (!ok) {
659 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
660 return;
661 }
662
663 _prefs_changed = TRUE;
664 } else {
665 SCPrint(TRUE, stdout, CFSTR("set order to what?\n"));
666 return;
667 }
668 } else {
669 SCPrint(TRUE, stdout, CFSTR("set what?\n"));
670 return;
671 }
672 } else if (strcmp(command, "rank") == 0) {
673 SCNetworkServicePrimaryRank rank = kSCNetworkServicePrimaryRankDefault;
674 SCNetworkServiceRef service = (argc < 2) ? net_service : NULL;
675
676 if (argc < 1) {
677 SCPrint(TRUE, stdout, CFSTR("rank not specified\n"));
678 return;
679 }
680
681 if (strlen(argv[0]) > 0) {
682 if (strcasecmp(argv[0], "Never") == 0) {
683 rank = kSCNetworkServicePrimaryRankNever;
684 } else if ((service != net_service) && (strcasecmp(argv[0], "First") == 0)) {
685 rank = kSCNetworkServicePrimaryRankFirst;
686 } else if ((service != net_service) && (strcasecmp(argv[0], "Last") == 0)) {
687 rank = kSCNetworkServicePrimaryRankLast;
688 } else {
689 SCPrint(TRUE, stdout, CFSTR("rank not valid\n"));
690 return;
691 }
692 }
693 argv++;
694 argc--;
695
696 if (service == NULL) {
697 CFStringRef serviceID;
698 SCDynamicStoreRef store;
699
700 store = SCDynamicStoreCreate(NULL,
701 CFSTR("scutil (set primary rank)"),
702 NULL,
703 NULL);
704 serviceID = SCNetworkServiceGetServiceID(net_service);
705 service = _SCNetworkServiceCopyActive(store, serviceID);
706 CFRelease(store);
707
708 argv++;
709 argc--;
710 }
711
712 ok = SCNetworkServiceSetPrimaryRank(service, rank);
713 if (service != net_service) CFRelease(service);
714 if (ok) {
715 if (service == net_service) _prefs_changed = TRUE;
716 } else {
717 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
718 return;
719 }
720 } else {
721 SCPrint(TRUE, stdout, CFSTR("set what?\n"));
722 }
723 }
724
725 return;
726 }
727
728
729 static void
730 __show_service_interface(SCNetworkServiceRef service, const char *prefix)
731 {
732 CFStringRef description;
733 SCNetworkInterfaceRef interface;
734
735 interface = SCNetworkServiceGetInterface(service);
736 if (interface == NULL) {
737 return;
738 }
739
740 description = _interface_description(interface);
741 SCPrint(TRUE, stdout, CFSTR("%s%@\n"), prefix, description);
742 CFRelease(description);
743
744 return;
745 }
746
747 static void
748 __show_service_protocols(SCNetworkServiceRef service, const char *prefix, Boolean skipEmpty)
749 {
750 CFIndex i;
751 CFIndex n;
752 CFArrayRef protocols;
753
754 protocols = SCNetworkServiceCopyProtocols(service);
755 if (protocols == NULL) {
756 return;
757 }
758
759 n = CFArrayGetCount(protocols);
760 if (n > 1) {
761 CFMutableArrayRef sorted;
762
763 sorted = CFArrayCreateMutableCopy(NULL, 0, protocols);
764 CFArraySortValues(sorted,
765 CFRangeMake(0, n),
766 _compare_protocols,
767 NULL);
768 CFRelease(protocols);
769 protocols = sorted;
770 }
771
772 for (i = 0; i < n; i++) {
773 CFStringRef description;
774 SCNetworkProtocolRef protocol;
775
776 protocol = CFArrayGetValueAtIndex(protocols, i);
777 description = _protocol_description(protocol, skipEmpty);
778 if (description != NULL) {
779 CFStringRef protocolType;
780
781 protocolType = SCNetworkProtocolGetProtocolType(protocol);
782 SCPrint(TRUE, stdout,
783 CFSTR("%s%@%*s : %@\n"),
784 prefix,
785 protocolType,
786 sizeof("Interface") - CFStringGetLength(protocolType) - 1,
787 "",
788 description);
789 CFRelease(description);
790 }
791 }
792
793 CFRelease(protocols);
794 return;
795 }
796
797
798 __private_extern__
799 void
800 show_service(int argc, char **argv)
801 {
802 SCNetworkInterfaceRef interface;
803 CFArrayRef protocols;
804 SCNetworkServiceRef service;
805 CFStringRef serviceName;
806 SCNetworkServicePrimaryRank serviceRank;
807
808 if (argc == 1) {
809 service = _find_service(argv[0]);
810 } else {
811 if (net_service != NULL) {
812 service = net_service;
813 } else {
814 SCPrint(TRUE, stdout, CFSTR("service not selected\n"));
815 return;
816 }
817 }
818
819 if (service == NULL) {
820 return;
821 }
822
823 SCPrint(TRUE, stdout, CFSTR("service id = %@\n"), SCNetworkServiceGetServiceID(service));
824
825 serviceName = SCNetworkServiceGetName(service);
826 SCPrint(TRUE, stdout, CFSTR("name = %@\n"),
827 (serviceName != NULL) ? serviceName : CFSTR(""));
828
829 serviceRank = SCNetworkServiceGetPrimaryRank(service);
830 switch (serviceRank) {
831 case kSCNetworkServicePrimaryRankDefault :
832 // nothing to report
833 break;
834 case kSCNetworkServicePrimaryRankFirst :
835 SCPrint(TRUE, stdout, CFSTR("primary rank = FIRST\n"));
836 break;
837 case kSCNetworkServicePrimaryRankLast :
838 SCPrint(TRUE, stdout, CFSTR("primary rank = LAST\n"));
839 break;
840 case kSCNetworkServicePrimaryRankNever :
841 SCPrint(TRUE, stdout, CFSTR("primary rank = NEVER\n"));
842 break;
843 default :
844 SCPrint(TRUE, stdout, CFSTR("primary rank = %d\n"), serviceRank);
845 break;
846 }
847
848 interface = SCNetworkServiceGetInterface(service);
849 if (interface != NULL) {
850 CFStringRef interfaceName;
851
852 interfaceName = SCNetworkInterfaceGetLocalizedDisplayName(interface);
853 if (interfaceName != NULL) {
854 CFRetain(interfaceName);
855 } else {
856 interfaceName = _interface_description(interface);
857 }
858 if (interfaceName != NULL) {
859 SCPrint(TRUE, stdout, CFSTR("interface = %@\n"), interfaceName);
860 CFRelease(interfaceName);
861 }
862 } else {
863 SCPrint(TRUE, stdout, CFSTR("\n No interface!\n\n"));
864 }
865
866 protocols = SCNetworkServiceCopyProtocols(service);
867 if (protocols != NULL) {
868 CFIndex n;
869
870 n = CFArrayGetCount(protocols);
871 if (n > 1) {
872 CFMutableArrayRef sorted;
873
874 sorted = CFArrayCreateMutableCopy(NULL, 0, protocols);
875 CFArraySortValues(sorted,
876 CFRangeMake(0, n),
877 _compare_protocols,
878 NULL);
879 CFRelease(protocols);
880 protocols = sorted;
881 }
882
883 if (n > 0) {
884 CFIndex i;
885
886 SCPrint(TRUE, stdout, CFSTR("configured protocols = "));
887 for (i = 0; i < n; i++) {
888 SCNetworkProtocolRef protocol;
889
890 protocol = CFArrayGetValueAtIndex(protocols, i);
891 SCPrint(TRUE, stdout, CFSTR("%s%@"),
892 (i == 0) ? "" : ", ",
893 SCNetworkProtocolGetProtocolType(protocol));
894 }
895 SCPrint(TRUE, stdout, CFSTR("\n"));
896
897 __show_service_protocols(service, " ", FALSE);
898 } else {
899 SCPrint(TRUE, stdout, CFSTR("no configured protocols\n"));
900 }
901
902 CFRelease(protocols);
903 }
904
905 if (_sc_debug) {
906 SCPrint(TRUE, stdout, CFSTR("\n%@\n"), service);
907 }
908
909 return;
910 }
911
912
913 __private_extern__
914 void
915 show_services(int argc, char **argv)
916 {
917 CFIndex i;
918 CFIndex n;
919
920 if (prefs == NULL) {
921 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
922 return;
923 }
924
925 if (argc == 1) {
926 if (services != NULL) CFRelease(services);
927 services = SCNetworkServiceCopyAll(prefs);
928 } else {
929 if (net_set == NULL) {
930 SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
931 return;
932 }
933
934 if (services != NULL) CFRelease(services);
935 services = SCNetworkSetCopyServices(net_set);
936 n = (services != NULL) ? CFArrayGetCount(services) : 0;
937 if (n > 1) {
938 CFArrayRef order;
939 CFMutableArrayRef sorted;
940
941 order = SCNetworkSetGetServiceOrder(net_set);
942 sorted = CFArrayCreateMutableCopy(NULL, 0, services);
943 CFArraySortValues(sorted,
944 CFRangeMake(0, CFArrayGetCount(sorted)),
945 _SCNetworkServiceCompare,
946 (void *)order);
947 CFRelease(services);
948 services = sorted;
949 }
950 }
951
952 if (services == NULL) {
953 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
954 return;
955 }
956
957 n = CFArrayGetCount(services);
958 for (i = 0; i < n; i++) {
959 SCNetworkServiceRef service;
960 CFStringRef serviceName;
961 CFStringRef serviceID;
962
963 service = CFArrayGetValueAtIndex(services, i);
964 serviceID = SCNetworkServiceGetServiceID(service);
965 serviceName = SCNetworkServiceGetName(service);
966 if (serviceName == NULL) serviceName = CFSTR("");
967
968 SCPrint(TRUE, stdout, CFSTR("%c%2d: %@%-*s (%@)%s\n"),
969 ((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ',
970 i + 1,
971 serviceName,
972 30 - CFStringGetLength(serviceName),
973 " ",
974 serviceID,
975 SCNetworkServiceGetEnabled(service) ? "" : " *DISABLED*");
976
977 __show_service_interface(service, " Interface : ");
978 __show_service_protocols(service, " ", TRUE);
979 }
980
981 return;
982 }