]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/tests.c
configd-130.tar.gz
[apple/configd.git] / scutil.tproj / tests.c
1 /*
2 * Copyright (c) 2000-2004 Apple Computer, 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 * July 9, 2001 Allan Nathanson <ajn@apple.com>
28 * - added "-r" option for checking network reachability
29 * - added "-w" option to check/wait for the presence of a
30 * dynamic store key.
31 *
32 * June 1, 2001 Allan Nathanson <ajn@apple.com>
33 * - public API conversion
34 *
35 * November 9, 2000 Allan Nathanson <ajn@apple.com>
36 * - initial revision
37 */
38
39 #include "scutil.h"
40 #include "tests.h"
41
42 #include <sys/time.h>
43 #include <net/if.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
46
47 #include <dnsinfo.h>
48
49 __private_extern__
50 void
51 do_checkReachability(int argc, char **argv)
52 {
53 SCNetworkConnectionFlags flags = 0;
54 SCNetworkReachabilityRef target = NULL;
55
56 if (argc == 1) {
57 struct sockaddr_in sin;
58 struct sockaddr_in6 sin6;
59
60 bzero(&sin, sizeof(sin));
61 sin.sin_len = sizeof(sin);
62 sin.sin_family = AF_INET;
63
64 bzero(&sin6, sizeof(sin6));
65 sin6.sin6_len = sizeof(sin6);
66 sin6.sin6_family = AF_INET6;
67
68 if (inet_aton(argv[0], &sin.sin_addr) == 1) {
69 target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin);
70 } else if (inet_pton(AF_INET6, argv[0], &sin6.sin6_addr) == 1) {
71 char *p;
72
73 p = strchr(argv[0], '%');
74 if (p != NULL) {
75 sin6.sin6_scope_id = if_nametoindex(p+1);
76 }
77
78 target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin6);
79 } else {
80 target = SCNetworkReachabilityCreateWithName(NULL, argv[0]);
81 }
82 } else /* if (argc == 2) */ {
83 struct sockaddr_in l_sin;
84 struct sockaddr_in r_sin;
85
86 bzero(&l_sin, sizeof(l_sin));
87 l_sin.sin_len = sizeof(l_sin);
88 l_sin.sin_family = AF_INET;
89 if (inet_aton(argv[0], &l_sin.sin_addr) == 0) {
90 SCPrint(TRUE, stderr, CFSTR("Could not interpret address \"%s\"\n"), argv[0]);
91 exit(1);
92 }
93
94 bzero(&r_sin, sizeof(r_sin));
95 r_sin.sin_len = sizeof(r_sin);
96 r_sin.sin_family = AF_INET;
97 if (inet_aton(argv[1], &r_sin.sin_addr) == 0) {
98 SCPrint(TRUE, stderr, CFSTR("Could not interpret address \"%s\"\n"), argv[1]);
99 exit(1);
100 }
101
102 target = SCNetworkReachabilityCreateWithAddressPair(NULL,
103 (struct sockaddr *)&l_sin,
104 (struct sockaddr *)&r_sin);
105 }
106
107 if (!target) {
108 SCPrint(TRUE, stderr, CFSTR(" Could not determine status: %s\n"), SCErrorString(SCError()));
109 exit(1);
110 }
111
112 if (!SCNetworkReachabilityGetFlags(target, &flags)) {
113 SCPrint(TRUE, stderr, CFSTR(" Could not determine status: %s\n"), SCErrorString(SCError()));
114 exit(1);
115 }
116
117 SCPrint(_sc_debug, stdout, CFSTR("flags = 0x%x"), flags);
118 if (flags != 0) {
119 SCPrint(_sc_debug, stdout, CFSTR(" ("));
120 if (flags & kSCNetworkFlagsReachable) {
121 SCPrint(TRUE, stdout, CFSTR("Reachable"));
122 flags &= ~kSCNetworkFlagsReachable;
123 SCPrint(flags != 0, stdout, CFSTR(","));
124 }
125 if (flags & kSCNetworkFlagsTransientConnection) {
126 SCPrint(TRUE, stdout, CFSTR("Transient Connection"));
127 flags &= ~kSCNetworkFlagsTransientConnection;
128 SCPrint(flags != 0, stdout, CFSTR(","));
129 }
130 if (flags & kSCNetworkFlagsConnectionRequired) {
131 SCPrint(TRUE, stdout, CFSTR("Connection Required"));
132 flags &= ~kSCNetworkFlagsConnectionRequired;
133 SCPrint(flags != 0, stdout, CFSTR(","));
134 }
135 if (flags & kSCNetworkFlagsConnectionAutomatic) {
136 SCPrint(TRUE, stdout, CFSTR("Connection Automatic"));
137 flags &= ~kSCNetworkFlagsConnectionAutomatic;
138 SCPrint(flags != 0, stdout, CFSTR(","));
139 }
140 if (flags & kSCNetworkFlagsInterventionRequired) {
141 SCPrint(TRUE, stdout, CFSTR("Intervention Required"));
142 flags &= ~kSCNetworkFlagsInterventionRequired;
143 SCPrint(flags != 0, stdout, CFSTR(","));
144 }
145 if (flags & kSCNetworkFlagsIsLocalAddress) {
146 SCPrint(TRUE, stdout, CFSTR("Local Address"));
147 flags &= ~kSCNetworkFlagsIsLocalAddress;
148 SCPrint(flags != 0, stdout, CFSTR(","));
149 }
150 if (flags & kSCNetworkFlagsIsDirect) {
151 SCPrint(TRUE, stdout, CFSTR("Directly Reachable Address"));
152 flags &= ~kSCNetworkFlagsIsDirect;
153 SCPrint(flags != 0, stdout, CFSTR(","));
154 }
155 SCPrint(_sc_debug, stdout, CFSTR(")"));
156 } else {
157 SCPrint(_sc_debug, stdout, CFSTR(" ("));
158 SCPrint(TRUE, stdout, CFSTR("Not Reachable"));
159 SCPrint(_sc_debug, stdout, CFSTR(")"));
160 }
161 SCPrint(TRUE, stdout, CFSTR("\n"));
162 exit(0);
163 }
164
165
166 __private_extern__
167 void
168 do_showDNSConfiguration(int argc, char **argv)
169 {
170 dns_config_t *dns_config;
171
172 dns_config = dns_configuration_copy();
173 if (dns_config) {
174 int n;
175
176 SCPrint(TRUE, stdout, CFSTR("DNS configuration\n"));
177
178 for (n = 0; n < dns_config->n_resolver; n++) {
179 int i;
180 dns_resolver_t *resolver = dns_config->resolver[n];
181
182 SCPrint(TRUE, stdout, CFSTR("\nresolver #%d\n"), n + 1);
183
184 if (resolver->domain != NULL) {
185 SCPrint(TRUE, stdout, CFSTR(" domain : %s\n"), resolver->domain);
186 }
187
188 for (i = 0; i < resolver->n_search; i++) {
189 SCPrint(TRUE, stdout, CFSTR(" search domain[%d] : %s\n"), i, resolver->search[i]);
190 }
191
192 for (i = 0; i < resolver->n_nameserver; i++) {
193 char buf[128];
194
195 _SC_sockaddr_to_string(resolver->nameserver[i], buf, sizeof(buf));
196 SCPrint(TRUE, stdout, CFSTR(" nameserver[%d] : %s\n"), i, buf);
197 }
198
199 for (i = 0; i < resolver->n_sortaddr; i++) {
200 SCPrint(TRUE, stdout, CFSTR(" sortaddr[%d] : %s/%s\n"),
201 i,
202 inet_ntoa(resolver->sortaddr[i]->address),
203 inet_ntoa(resolver->sortaddr[i]->mask));
204 }
205
206 if (resolver->options != NULL) {
207 SCPrint(TRUE, stdout, CFSTR(" options : %s\n"), resolver->options);
208 }
209
210 if (resolver->port != 0) {
211 SCPrint(TRUE, stdout, CFSTR(" port : %hd\n"), ntohs(resolver->port));
212 }
213
214 if (resolver->timeout != 0) {
215 SCPrint(TRUE, stdout, CFSTR(" timeout : %d\n"), resolver->timeout);
216 }
217
218 if (resolver->search_order != 0) {
219 SCPrint(TRUE, stdout, CFSTR(" order : %d\n"), resolver->search_order);
220 }
221 }
222
223 dns_configuration_free(dns_config);
224 } else {
225 SCPrint(TRUE, stdout, CFSTR("No DNS configuration available\n"));
226 }
227
228 exit(0);
229 }
230
231
232 __private_extern__
233 void
234 do_showProxyConfiguration(int argc, char **argv)
235 {
236 CFDictionaryRef proxies;
237
238 proxies = SCDynamicStoreCopyProxies(NULL);
239 if (proxies != NULL) {
240 SCPrint(TRUE, stdout, CFSTR("%@\n"), proxies);
241 } else {
242 SCPrint(TRUE, stdout, CFSTR("No proxy configuration available\n"));
243 }
244
245 exit(0);
246 }
247
248
249 __private_extern__
250 void
251 do_snapshot(int argc, char **argv)
252 {
253 if (!SCDynamicStoreSnapshot(store)) {
254 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
255 }
256 return;
257 }
258
259
260 static void
261 waitKeyFound()
262 {
263 exit(0);
264 }
265
266
267 static void
268 waitTimeout(int sigraised)
269 {
270 exit(1);
271 }
272
273
274 __private_extern__
275 void
276 do_wait(char *waitKey, int timeout)
277 {
278 struct itimerval itv;
279 CFStringRef key;
280 CFMutableArrayRef keys;
281
282 store = SCDynamicStoreCreate(NULL, CFSTR("scutil (wait)"), waitKeyFound, NULL);
283 if (store == NULL) {
284 SCPrint(TRUE, stderr,
285 CFSTR("SCDynamicStoreCreate() failed: %s\n"), SCErrorString(SCError()));
286 exit(1);
287 }
288
289 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
290 key = CFStringCreateWithCString(NULL, waitKey, kCFStringEncodingUTF8);
291 CFArrayAppendValue(keys, key);
292
293 if (!SCDynamicStoreSetNotificationKeys(store, keys, NULL)) {
294 SCPrint(TRUE, stderr,
295 CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s\n"), SCErrorString(SCError()));
296 exit(1);
297 }
298
299 notifyRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
300 if (!notifyRls) {
301 SCPrint(TRUE, stderr,
302 CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s\n"), SCErrorString(SCError()));
303 exit(1);
304 }
305
306 CFRunLoopAddSource(CFRunLoopGetCurrent(), notifyRls, kCFRunLoopDefaultMode);
307
308 value = SCDynamicStoreCopyValue(store, key);
309 if (value) {
310 /* if the key is already present */
311 exit(0);
312 }
313 CFRelease(key);
314
315 if (timeout > 0) {
316 signal(SIGALRM, waitTimeout);
317 bzero(&itv, sizeof(itv));
318 itv.it_value.tv_sec = timeout;
319 if (setitimer(ITIMER_REAL, &itv, NULL) < 0) {
320 SCPrint(TRUE, stderr,
321 CFSTR("setitimer() failed: %s\n"), strerror(errno));
322 exit(1);
323 }
324 }
325
326 CFRunLoopRun();
327 }