]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/tests.c
74a404931a63e659a55c1e95574ee0fe9908416f
[apple/configd.git] / scutil.tproj / tests.c
1 /*
2 * Copyright (c) 2000-2003 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
48 void
49 do_checkReachability(int argc, char **argv)
50 {
51 SCNetworkConnectionFlags flags = 0;
52 SCNetworkReachabilityRef target = NULL;
53
54 if (argc == 1) {
55 struct sockaddr_in sin;
56 struct sockaddr_in6 sin6;
57
58 bzero(&sin, sizeof(sin));
59 sin.sin_len = sizeof(sin);
60 sin.sin_family = AF_INET;
61
62 bzero(&sin6, sizeof(sin6));
63 sin6.sin6_len = sizeof(sin6);
64 sin6.sin6_family = AF_INET6;
65
66 if (inet_aton(argv[0], &sin.sin_addr) == 1) {
67 target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin);
68 } else if (inet_pton(AF_INET6, argv[0], &sin6.sin6_addr) == 1) {
69 char *p;
70
71 p = strchr(argv[0], '%');
72 if (p != NULL) {
73 sin6.sin6_scope_id = if_nametoindex(p+1);
74 }
75
76 target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin6);
77 } else {
78 target = SCNetworkReachabilityCreateWithName(NULL, argv[0]);
79 }
80 } else /* if (argc == 2) */ {
81 struct sockaddr_in l_sin;
82 struct sockaddr_in r_sin;
83
84 bzero(&l_sin, sizeof(l_sin));
85 l_sin.sin_len = sizeof(l_sin);
86 l_sin.sin_family = AF_INET;
87 if (inet_aton(argv[0], &l_sin.sin_addr) == 0) {
88 SCPrint(TRUE, stderr, CFSTR("Could not interpret address \"%s\"\n"), argv[0]);
89 exit(1);
90 }
91
92 bzero(&r_sin, sizeof(r_sin));
93 r_sin.sin_len = sizeof(r_sin);
94 r_sin.sin_family = AF_INET;
95 if (inet_aton(argv[1], &r_sin.sin_addr) == 0) {
96 SCPrint(TRUE, stderr, CFSTR("Could not interpret address \"%s\"\n"), argv[1]);
97 exit(1);
98 }
99
100 target = SCNetworkReachabilityCreateWithAddressPair(NULL,
101 (struct sockaddr *)&l_sin,
102 (struct sockaddr *)&r_sin);
103 }
104
105 if (!target) {
106 SCPrint(TRUE, stderr, CFSTR(" Could not determine status: %s\n"), SCErrorString(SCError()));
107 exit(1);
108 }
109
110 if (!SCNetworkReachabilityGetFlags(target, &flags)) {
111 SCPrint(TRUE, stderr, CFSTR(" Could not determine status: %s\n"), SCErrorString(SCError()));
112 exit(1);
113 }
114
115 SCPrint(_sc_debug, stdout, CFSTR("flags = 0x%x"), flags);
116 if (flags != 0) {
117 SCPrint(_sc_debug, stdout, CFSTR(" ("));
118 if (flags & kSCNetworkFlagsReachable) {
119 SCPrint(TRUE, stdout, CFSTR("Reachable"));
120 flags &= ~kSCNetworkFlagsReachable;
121 SCPrint(flags != 0, stdout, CFSTR(","));
122 }
123 if (flags & kSCNetworkFlagsTransientConnection) {
124 SCPrint(TRUE, stdout, CFSTR("Transient Connection"));
125 flags &= ~kSCNetworkFlagsTransientConnection;
126 SCPrint(flags != 0, stdout, CFSTR(","));
127 }
128 if (flags & kSCNetworkFlagsConnectionRequired) {
129 SCPrint(TRUE, stdout, CFSTR("Connection Required"));
130 flags &= ~kSCNetworkFlagsConnectionRequired;
131 SCPrint(flags != 0, stdout, CFSTR(","));
132 }
133 if (flags & kSCNetworkFlagsConnectionAutomatic) {
134 SCPrint(TRUE, stdout, CFSTR("Connection Automatic"));
135 flags &= ~kSCNetworkFlagsConnectionAutomatic;
136 SCPrint(flags != 0, stdout, CFSTR(","));
137 }
138 if (flags & kSCNetworkFlagsInterventionRequired) {
139 SCPrint(TRUE, stdout, CFSTR("Intervention Required"));
140 flags &= ~kSCNetworkFlagsInterventionRequired;
141 SCPrint(flags != 0, stdout, CFSTR(","));
142 }
143 if (flags & kSCNetworkFlagsIsLocalAddress) {
144 SCPrint(TRUE, stdout, CFSTR("Local Address"));
145 flags &= ~kSCNetworkFlagsIsLocalAddress;
146 SCPrint(flags != 0, stdout, CFSTR(","));
147 }
148 if (flags & kSCNetworkFlagsIsDirect) {
149 SCPrint(TRUE, stdout, CFSTR("Directly Reachable Address"));
150 flags &= ~kSCNetworkFlagsIsDirect;
151 SCPrint(flags != 0, stdout, CFSTR(","));
152 }
153 SCPrint(_sc_debug, stdout, CFSTR(")"));
154 } else {
155 SCPrint(_sc_debug, stdout, CFSTR(" ("));
156 SCPrint(TRUE, stdout, CFSTR("Not Reachable"));
157 SCPrint(_sc_debug, stdout, CFSTR(")"));
158 }
159 SCPrint(TRUE, stdout, CFSTR("\n"));
160 exit(0);
161 }
162
163
164 void
165 do_snapshot(int argc, char **argv)
166 {
167 if (!SCDynamicStoreSnapshot(store)) {
168 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
169 }
170 return;
171 }
172
173
174 static void
175 waitKeyFound()
176 {
177 exit(0);
178 }
179
180
181 static void
182 waitTimeout(int sigraised)
183 {
184 exit(1);
185 }
186
187
188 void
189 do_wait(char *waitKey, int timeout)
190 {
191 struct itimerval itv;
192 CFStringRef key;
193 CFMutableArrayRef keys;
194
195 store = SCDynamicStoreCreate(NULL, CFSTR("scutil (wait)"), waitKeyFound, NULL);
196 if (!store) {
197 SCPrint(TRUE, stderr,
198 CFSTR("SCDynamicStoreCreate() failed: %s\n"), SCErrorString(SCError()));
199 exit(1);
200 }
201
202 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
203 key = CFStringCreateWithCString(NULL, waitKey, kCFStringEncodingMacRoman);
204 CFArrayAppendValue(keys, key);
205
206 if (!SCDynamicStoreSetNotificationKeys(store, keys, NULL)) {
207 SCPrint(TRUE, stderr,
208 CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s\n"), SCErrorString(SCError()));
209 exit(1);
210 }
211
212 notifyRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
213 if (!notifyRls) {
214 SCPrint(TRUE, stderr,
215 CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s\n"), SCErrorString(SCError()));
216 exit(1);
217 }
218
219 CFRunLoopAddSource(CFRunLoopGetCurrent(), notifyRls, kCFRunLoopDefaultMode);
220
221 value = SCDynamicStoreCopyValue(store, key);
222 if (value) {
223 /* if the key is already present */
224 exit(0);
225 }
226 CFRelease(key);
227
228 if (waitTimeout > 0) {
229 signal(SIGALRM, waitTimeout);
230 bzero(&itv, sizeof(itv));
231 itv.it_value.tv_sec = timeout;
232 if (setitimer(ITIMER_REAL, &itv, NULL) < 0) {
233 SCPrint(TRUE, stderr,
234 CFSTR("setitimer() failed: %s\n"), strerror(errno));
235 exit(1);
236 }
237 }
238
239 CFRunLoopRun();
240 }