]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/net_set.c
configd-1109.40.9.tar.gz
[apple/configd.git] / scutil.tproj / net_set.c
1 /*
2 * Copyright (c) 2004, 2005, 2009-2011, 2013-2015, 2017 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_set.h"
35 #include "net_service.h"
36 #include "prefs.h"
37
38
39 /* -------------------- */
40
41
42 static CFArrayRef
43 _copy_sets()
44 {
45 CFArrayRef sets;
46 CFMutableArrayRef sorted;
47
48 sets = SCNetworkSetCopyAll(prefs);
49 if (sets == NULL) {
50 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
51 return NULL;
52 }
53
54 sorted = CFArrayCreateMutableCopy(NULL, 0, sets);
55 CFArraySortValues(sorted,
56 CFRangeMake(0, CFArrayGetCount(sorted)),
57 _SCNetworkSetCompare,
58 NULL);
59
60 CFRelease(sets);
61 sets = CFArrayCreateCopy(NULL, sorted);
62 CFRelease(sorted);
63 return sets;
64 }
65
66
67 static SCNetworkSetRef
68 _find_set(char *match)
69 {
70 Boolean allowIndex = TRUE;
71 CFIndex i;
72 CFIndex n;
73 CFStringRef select_name = NULL;
74 SCNetworkSetRef selected = NULL;
75
76 if (sets == NULL) {
77 if (prefs == NULL) {
78 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
79 return NULL;
80 }
81
82 sets = _copy_sets();
83 if (sets == NULL) {
84 return NULL;
85 }
86
87 allowIndex = FALSE;
88 }
89
90 // try to select the set by its setID
91
92 select_name = CFStringCreateWithCString(NULL, match, kCFStringEncodingUTF8);
93
94 n = CFArrayGetCount(sets);
95 for (i = 0; i < n; i++) {
96 SCNetworkSetRef set;
97 CFStringRef setID;
98
99 set = CFArrayGetValueAtIndex(sets, i);
100 setID = SCNetworkSetGetSetID(set);
101 if (CFEqual(select_name, setID)) {
102 selected = set;
103 goto done;
104
105 }
106 }
107
108 // try to select the set by its name
109
110 for (i = 0; i < n; i++) {
111 SCNetworkSetRef set;
112 CFStringRef setName;
113
114 set = CFArrayGetValueAtIndex(sets, i);
115 setName = SCNetworkSetGetName(set);
116 if ((setName != NULL) &&
117 CFEqual(select_name, setName)) {
118 if (selected == NULL) {
119 selected = set;
120 } else {
121 // if multiple sets match
122 selected = NULL;
123 SCPrint(TRUE, stdout, CFSTR("multiple sets match\n"));
124 goto done;
125 }
126 }
127 }
128
129 if (selected != NULL) {
130 goto done;
131 }
132
133 // try to select the set by its name (case insensitive)
134
135 for (i = 0; i < n; i++) {
136 SCNetworkSetRef set;
137 CFStringRef setName;
138
139 set = CFArrayGetValueAtIndex(sets, i);
140 setName = SCNetworkSetGetName(set);
141 if ((setName != NULL) &&
142 CFStringCompare(select_name,
143 setName,
144 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
145 if (selected == NULL) {
146 selected = set;
147 } else {
148 // if multiple sets match
149 selected = NULL;
150 SCPrint(TRUE, stdout, CFSTR("multiple sets match\n"));
151 goto done;
152 }
153 }
154 }
155
156 if (selected != NULL) {
157 goto done;
158 }
159
160 // try to select the set by its index
161
162 if (allowIndex) {
163 char *end;
164 char *str = match;
165 long val;
166
167 errno = 0;
168 val = strtol(str, &end, 10);
169 if ((*str != '\0') && (*end == '\0') && (errno == 0)) {
170 if ((val > 0) && (val <= n)) {
171 selected = CFArrayGetValueAtIndex(sets, val - 1);
172 }
173 }
174 }
175
176 if (selected != NULL) {
177 goto done;
178 }
179
180 SCPrint(TRUE, stdout, CFSTR("no match, which set?\n"));
181
182 done :
183
184 if (select_name != NULL) CFRelease(select_name);
185 return selected;
186 }
187
188
189 /* -------------------- */
190
191
192 __private_extern__
193 void
194 create_set(int argc, char **argv)
195 {
196 SCNetworkSetRef set;
197 CFStringRef setName;
198
199 if (prefs == NULL) {
200 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
201 return;
202 }
203
204 set = SCNetworkSetCreate(prefs);
205 if (set == NULL) {
206 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
207 return;
208 }
209
210 if ((argc > 0) && (strlen(argv[0]) > 0)) {
211 Boolean ok;
212
213 setName = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
214 // argv++;
215 // argc--;
216
217 ok = SCNetworkSetSetName(set, setName);
218 CFRelease(setName);
219 if (!ok) {
220 SCPrint(TRUE, stdout, CFSTR("set not created: %s\n"), SCErrorString(SCError()));
221 (void) SCNetworkSetRemove(set);
222 CFRelease(set);
223 return;
224 }
225 }
226
227 _prefs_changed = TRUE;
228
229 if (net_set != NULL) CFRelease(net_set);
230 net_set = set;
231
232 setName = SCNetworkSetGetName(set);
233 if (setName != NULL) {
234 SCPrint(TRUE, stdout,
235 CFSTR("set \"%@\" (%@) created and selected\n"),
236 setName,
237 SCNetworkSetGetSetID(set));
238 } else {
239 SCPrint(TRUE, stdout,
240 CFSTR("set ID \"%@\" created and selected\n"),
241 SCNetworkSetGetSetID(set));
242 }
243
244 if (net_service != NULL) {
245 CFRelease(net_service);
246 net_service = NULL;
247 SCPrint(TRUE, stdout, CFSTR("& no service selected\n"));
248 }
249
250 if (net_protocol != NULL) {
251 CFRelease(net_protocol);
252 net_protocol = NULL;
253 SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n"));
254 }
255
256 if (net_interface != NULL) {
257 CFRelease(net_interface);
258 net_interface = NULL;
259 SCPrint(TRUE, stdout, CFSTR("& no interface selected\n"));
260 }
261
262 if (sets != NULL) {
263 CFRelease(sets);
264 sets = NULL;
265 }
266
267 return;
268 }
269
270
271 __private_extern__
272 void
273 remove_set(int argc, char **argv)
274 {
275 SCNetworkSetRef set = NULL;
276 CFStringRef setName;
277
278 if (argc == 1) {
279 set = _find_set(argv[0]);
280 } else {
281 if (net_set != NULL) {
282 set = net_set;
283 }
284 }
285
286 if (set == NULL) {
287 return;
288 }
289
290 CFRetain(set);
291
292 if (!SCNetworkSetRemove(set)) {
293 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
294 goto done;
295 }
296
297 _prefs_changed = TRUE;
298
299 setName = SCNetworkSetGetName(set);
300 if (setName != NULL) {
301 SCPrint(TRUE, stdout, CFSTR("set \"%@\" removed\n"), setName);
302 } else {
303 SCPrint(TRUE, stdout,
304 CFSTR("set ID \"%@\" removed\n"),
305 SCNetworkSetGetSetID(set));
306 }
307
308 if (CFEqual(set, net_set)) {
309 if (net_service != NULL) {
310 CFRelease(net_service);
311 net_service = NULL;
312 SCPrint(TRUE, stdout, CFSTR("& no service selected\n"));
313 }
314
315 if (net_protocol != NULL) {
316 CFRelease(net_protocol);
317 net_protocol = NULL;
318 SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n"));
319 }
320
321 if (net_interface != NULL) {
322 CFRelease(net_interface);
323 net_interface = NULL;
324 SCPrint(TRUE, stdout, CFSTR("& no interface selected\n"));
325 }
326 }
327
328 if (sets != NULL) {
329 CFRelease(sets);
330 sets = NULL;
331 }
332
333 done :
334
335 CFRelease(set);
336 return;
337 }
338
339
340 __private_extern__
341 void
342 select_set(int argc, char **argv)
343 {
344 #pragma unused(argc)
345 SCNetworkSetRef set;
346 CFStringRef setName;
347
348 set = _find_set(argv[0]);
349
350 if (set == NULL) {
351 return;
352 }
353
354 if (net_set != NULL) CFRelease(net_set);
355 net_set = CFRetain(set);
356
357 setName = SCNetworkSetGetName(set);
358 if (setName != NULL) {
359 SCPrint(TRUE, stdout, CFSTR("set \"%@\" selected\n"), setName);
360 } else {
361 SCPrint(TRUE, stdout,
362 CFSTR("set ID \"%@\" selected\n"),
363 SCNetworkSetGetSetID(set));
364 }
365
366 if (net_service != NULL) {
367 CFRelease(net_service);
368 net_service = NULL;
369 SCPrint(TRUE, stdout, CFSTR("& no service selected\n"));
370 }
371
372 if (net_protocol != NULL) {
373 CFRelease(net_protocol);
374 net_protocol = NULL;
375 SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n"));
376 }
377
378 if (net_interface != NULL) {
379 CFRelease(net_interface);
380 net_interface = NULL;
381 SCPrint(TRUE, stdout, CFSTR("& no interface selected\n"));
382 }
383
384 return;
385 }
386
387
388 __private_extern__
389 void
390 set_set(int argc, char **argv)
391 {
392 Boolean ok;
393
394 if (net_set == NULL) {
395 SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
396 return;
397 }
398
399 if (argc < 1) {
400 SCPrint(TRUE, stdout, CFSTR("set what?\n"));
401 return;
402 }
403
404 while (argc > 0) {
405 char *command;
406
407 command = argv[0];
408 argv++;
409 argc--;
410
411 if (strcmp(command, "name") == 0) {
412 CFStringRef setName;
413
414 if (argc < 1) {
415 SCPrint(TRUE, stdout, CFSTR("name not specified\n"));
416 return;
417 }
418
419 setName = (strlen(argv[0]) > 0)
420 ? CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8)
421 : NULL;
422 argv++;
423 argc--;
424
425 ok = SCNetworkSetSetName(net_set, setName);
426 if (setName != NULL) CFRelease(setName);
427 if (!ok) {
428 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
429 return;
430 }
431
432 _prefs_changed = TRUE;
433
434 if (sets != NULL) {
435 /*
436 * since the (displayed) ordering may have changed, refresh sets
437 */
438 char *setID;
439
440 setID = _SC_cfstring_to_cstring(SCNetworkSetGetSetID(net_set),
441 NULL,
442 0,
443 kCFStringEncodingUTF8);
444
445 CFRelease(net_set);
446 net_set = NULL;
447
448 CFRelease(sets);
449 sets = NULL;
450
451 net_set = _find_set(setID);
452 if (net_set != NULL) {
453 CFRetain(net_set);
454 }
455
456 CFAllocatorDeallocate(NULL, setID);
457 }
458 } else if (strcmp(command, "current") == 0) {
459 ok = SCNetworkSetSetCurrent(net_set);
460 if (!ok) {
461 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
462 return;
463 }
464
465 _prefs_changed = TRUE;
466 } else if (strcmp(command, "id") == 0) {
467 char *newID;
468 CFStringRef setID;
469
470 if ((argc < 1) || (strlen(argv[0]) == 0)) {
471 SCPrint(TRUE, stdout, CFSTR("set id not specified\n"));
472 return;
473 }
474
475 newID = argv[0];
476 setID = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
477 argv++;
478 argc--;
479
480 ok = _SCNetworkSetSetSetID(net_set, setID);
481 CFRelease(setID);
482 if (!ok) {
483 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
484 return;
485 }
486
487 _prefs_changed = TRUE;
488
489 if (sets != NULL) {
490 /*
491 * since the (displayed) ordering may have changed, refresh sets
492 */
493 CFRelease(net_set);
494 net_set = NULL;
495
496 CFRelease(sets);
497 sets = NULL;
498
499 net_set = _find_set(newID);
500 if (net_set != NULL) {
501 CFRetain(net_set);
502 }
503 }
504 } else {
505 SCPrint(TRUE, stdout, CFSTR("set what?\n"));
506 }
507
508 if (net_set == NULL) {
509 break;
510 }
511 }
512
513 return;
514 }
515
516
517 __private_extern__
518 void
519 show_set(int argc, char **argv)
520 {
521 CFArrayRef interfaces;
522 CFArrayRef services;
523 SCNetworkSetRef set = NULL;
524 CFStringRef setName;
525
526 if (argc == 1) {
527 set = _find_set(argv[0]);
528 } else {
529 if (net_set != NULL) {
530 set = net_set;
531 } else {
532 SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
533 return;
534 }
535 }
536
537 if (set == NULL) {
538 return;
539 }
540
541 SCPrint(TRUE, stdout, CFSTR("set id = %@\n"), SCNetworkSetGetSetID(set));
542
543 setName = SCNetworkSetGetName(set);
544 SCPrint(TRUE, stdout, CFSTR("name = %@\n"),
545 (setName != NULL) ? setName : CFSTR(""));
546
547 services = SCNetworkSetCopyServices(set);
548 if (services != NULL) {
549 CFIndex i;
550 CFIndex n;
551 CFIndex nOrder = 0;
552 CFArrayRef order;
553
554 order = SCNetworkSetGetServiceOrder(set);
555 if (order != NULL) {
556 nOrder = CFArrayGetCount(order);
557 }
558
559 n = CFArrayGetCount(services);
560 if (n > 1) {
561 CFMutableArrayRef sorted;
562
563 sorted = CFArrayCreateMutableCopy(NULL, 0, services);
564 CFArraySortValues(sorted,
565 CFRangeMake(0, CFArrayGetCount(sorted)),
566 _SCNetworkServiceCompare,
567 (void *)order);
568 CFRelease(services);
569 services = sorted;
570 }
571
572 SCPrint(TRUE, stdout, CFSTR("services =\n"));
573
574 for (i = 0; i < n; i++) {
575 CFIndex orderIndex = kCFNotFound;
576 SCNetworkServiceRef service;
577 CFStringRef serviceName;
578 CFStringRef serviceID;
579
580 service = CFArrayGetValueAtIndex(services, i);
581 serviceID = SCNetworkServiceGetServiceID(service);
582 serviceName = SCNetworkServiceGetName(service);
583 if (serviceName == NULL) serviceName = CFSTR("");
584
585 if (order != NULL) {
586 orderIndex = CFArrayGetFirstIndexOfValue(order,
587 CFRangeMake(0, nOrder),
588 serviceID);
589 }
590 if (orderIndex != kCFNotFound) {
591 SCPrint(TRUE, stdout, CFSTR("%c%2ld: %@%-*s (%@)\n"),
592 ((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ',
593 orderIndex + 1,
594 serviceName,
595 (int)(30 - CFStringGetLength(serviceName)),
596 " ",
597 serviceID);
598 } else {
599 SCPrint(TRUE, stdout, CFSTR("%c : %@%-*s (%@)\n"),
600 ((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ',
601 serviceName,
602 (int)(30 - CFStringGetLength(serviceName)),
603 " ",
604 serviceID);
605 }
606 }
607
608 CFRelease(services);
609 }
610
611 interfaces = SCNetworkSetCopyAvailableInterfaces(set);
612 if (interfaces != NULL) {
613 CFIndex i;
614 SCNetworkInterfaceRef interface;
615 CFIndex n;
616
617 SCPrint(TRUE, stdout, CFSTR("available interfaces =\n"));
618
619 n = CFArrayGetCount(interfaces);
620 for (i = 0; i < n; i++) {
621 interface = CFArrayGetValueAtIndex(interfaces, i);
622 SCPrint(TRUE, stdout, CFSTR(" %2ld: %@\n"),
623 i + 1,
624 SCNetworkInterfaceGetLocalizedDisplayName(interface));
625 }
626
627 CFRelease(interfaces);
628 }
629
630 if (_sc_debug) {
631 SCPrint(TRUE, stdout, CFSTR("\n%@\n"), set);
632 }
633
634 return;
635 }
636
637
638 __private_extern__
639 void
640 show_sets(int argc, char **argv)
641 {
642 #pragma unused(argc)
643 #pragma unused(argv)
644 SCNetworkSetRef current;
645 CFIndex i;
646 CFIndex n;
647
648 if (prefs == NULL) {
649 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
650 return;
651 }
652
653 if (sets == NULL) {
654 sets = _copy_sets();
655 if (sets == NULL) {
656 return;
657 }
658 }
659
660 current = SCNetworkSetCopyCurrent(prefs);
661
662 n = CFArrayGetCount(sets);
663 for (i = 0; i < n; i++) {
664 SCNetworkSetRef set;
665 CFStringRef setID;
666 CFStringRef setName;
667
668 set = CFArrayGetValueAtIndex(sets, i);
669 setID = SCNetworkSetGetSetID(set);
670 setName = SCNetworkSetGetName(set);
671 if (setName == NULL) setName = CFSTR("");
672
673 SCPrint(TRUE, stdout, CFSTR(" %c%c%2ld: %@%-*s (%@)\n"),
674 ((current != NULL) && CFEqual(set, current)) ? '*' : ' ',
675 ((net_set != NULL) && CFEqual(set, net_set)) ? '>' : ' ',
676 i + 1,
677 setName,
678 (int)(30 - CFStringGetLength(setName)),
679 " ",
680 setID);
681 }
682
683 if (current != NULL) CFRelease(current);
684
685 return;
686 }