2 * Copyright (c) 2003-2014 Apple 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@
24 #ifndef _SCNETWORKREACHABILITYINTERNAL_H
25 #define _SCNETWORKREACHABILITYINTERNAL_H
27 #include <Availability.h>
28 #include <TargetConditionals.h>
29 #include <sys/cdefs.h>
30 #include <CoreFoundation/CoreFoundation.h>
31 #include <CoreFoundation/CFRuntime.h>
32 #include <SystemConfiguration/SystemConfiguration.h>
33 #include <SystemConfiguration/SCPrivate.h>
34 #include <dispatch/dispatch.h>
38 #include <sys/socket.h>
46 #pragma mark SCNetworkReachability
49 #define kSCNetworkReachabilityFlagsFirstResolvePending (1<<31)
53 #define kSCNetworkReachabilityFlagsMask 0x00ffffff // top 8-bits reserved for implementation
64 // by-address SCNetworkReachability targets
65 reachabilityTypeAddress
,
66 reachabilityTypeAddressPair
,
67 // by-name SCNetworkReachability targets
70 } ReachabilityAddressType
;
72 #define isReachabilityTypeAddress(type) (type < reachabilityTypeName)
73 #define isReachabilityTypeName(type) (type >= reachabilityTypeName)
78 SCNetworkReachabilityFlags flags
;
79 unsigned int if_index
;
80 char if_name
[IFNAMSIZ
];
87 /* base CFType information */
97 ReachabilityAddressType type
;
99 /* target host name */
102 CFArrayRef resolvedAddresses
; /* CFArray[CFData] or CFArray[CFString] */
104 SCNetworkReachabilityFlags resolverFlags
;
106 /* [scoped routing] interface constraints */
107 unsigned int if_index
;
108 char if_name
[IFNAMSIZ
];
110 /* local & remote addresses */
111 struct sockaddr
*localAddress
;
112 struct sockaddr
*remoteAddress
;
114 /* current reachability flags */
116 ReachabilityInfo info
;
117 ReachabilityInfo last_notify
;
119 /* run loop source, callout, context, rl scheduling info */
121 CFRunLoopSourceRef rls
;
122 SCNetworkReachabilityCallBack rlsFunction
;
123 SCNetworkReachabilityContext rlsContext
;
124 CFMutableArrayRef rlList
;
125 unsigned int pending
; // 0 == no notifications queued, else # to be delivered
127 dispatch_group_t dispatchGroup
;
128 dispatch_queue_t dispatchQueue
; // SCNetworkReachabilitySetDispatchQueue
130 /* [async] DNS query info */
132 struct timeval dnsQueryStart
;
133 struct timeval dnsQueryEnd
;
135 /* [async] processing info */
136 struct timeval last_dns
;
137 struct timeval last_network
;
138 #if !TARGET_OS_IPHONE
139 struct timeval last_power
;
140 #endif // !TARGET_OS_IPHONE
141 struct timeval last_push
;
144 Boolean onDemandBypass
;
145 CFStringRef onDemandName
;
146 CFStringRef onDemandRemoteAddress
;
147 SCNetworkReachabilityRef onDemandServer
;
148 CFStringRef onDemandServiceID
;
154 Boolean dnsActive
:1; // if DNSServiceGetAddrInfo active
156 Boolean dnsHaveError
:1; // error during query
157 Boolean dnsHaveV4
:1; // have IPv4 (A) reply
158 Boolean dnsHaveV6
:1; // have IPv6 (AAAA) reply
159 Boolean dnsHavePTR
:1; // have PTR reply
160 Boolean dnsHaveTimeout
:1; // no replies (A, AAAA, or PTR)
163 CFArrayRef dnsAddresses
; // CFArray[CFData]
164 Boolean dnsBlocked
; // if DNS query blocked
166 int dnsFailures
; // # of unexpected DNSServiceXXX errors
168 DNSServiceRef dnsTarget
;
169 Boolean dnsNoAddressesSinceLastTimeout
;
171 /* SCNetworkReachability server "client" info */
172 Boolean serverActive
;
173 Boolean serverBypass
;
174 Boolean serverScheduled
;
175 ReachabilityInfo serverInfo
;
177 /* SCNetworkReachability server "server" info */
178 CFDataRef serverDigest
;
179 dispatch_group_t serverGroup
;
180 Boolean serverInfoValid
;
181 unsigned int serverSyncQueryActive
; // 0 == no [sync] query active, else # waiting on group
182 dispatch_queue_t serverQueue
;
183 unsigned int serverReferences
; // how many [client] targets
184 CFMutableDictionaryRef serverWatchers
; // [client_id/target_id] watchers
188 void *nePolicyResult
;
189 Boolean serverBypassForVPN
; // if serverBypassForVPN, only use client mode
191 Boolean resolverBypass
; // set this flag to bypass resolving the name
198 } SCNetworkReachabilityPrivate
, *SCNetworkReachabilityPrivateRef
;
202 // ------------------------------------------------------------
205 #pragma mark [XPC] Reachability Server
208 #define REACH_SERVER_VERSION 20110323
210 #if !TARGET_IPHONE_SIMULATOR
211 #define REACH_SERVICE_NAME "com.apple.SystemConfiguration.SCNetworkReachability"
212 #else // !TARGET_IPHONE_SIMULATOR
213 #define REACH_SERVICE_NAME "com.apple.SystemConfiguration.SCNetworkReachability_sim"
214 #endif // !TARGET_IPHONE_SIMULATOR
216 // ------------------------------------------------------------
220 #pragma mark [XPC] Reachability Server (client->server request)
223 #define REACH_CLIENT_PROC_NAME "proc_name" // string
224 #define REACH_CLIENT_TARGET_ID "target_id" // uint64
226 #define REACH_REQUEST "request_op" // int64
229 REACH_REQUEST_CREATE
= 0x0001,
230 REACH_REQUEST_REMOVE
,
231 REACH_REQUEST_SCHEDULE
,
232 REACH_REQUEST_STATUS
,
233 REACH_REQUEST_UNSCHEDULE
,
234 REACH_REQUEST_SNAPSHOT
= 0x0101,
237 #define REACH_TARGET_NAME "name" // string
239 #define REACH_TARGET_LOCAL_ADDR "local_address" // data (struct sockaddr)
240 #define REACH_TARGET_REMOTE_ADDR "remote_address" // data (struct sockaddr)
242 #define REACH_TARGET_PTR_ADDR "ptr_address" // data (struct sockaddr)
244 #define REACH_TARGET_IF_INDEX "if_index" // int64
245 #define REACH_TARGET_IF_NAME "if_name" // string
246 #define REACH_TARGET_ONDEMAND_BYPASS "ondemand_bypass" // bool
247 #define REACH_TARGET_RESOLVER_BYPASS "resolver_bypass" // bool
250 #define REACH_REQUEST_REPLY "reply" // int64
251 #define REACH_REQUEST_REPLY_DETAIL "reply_detail" // string
254 REACH_REQUEST_REPLY_OK
= 0x0000,
255 REACH_REQUEST_REPLY_FAILED
,
256 REACH_REQUEST_REPLY_UNKNOWN
,
260 // ------------------------------------------------------------
264 #pragma mark [XPC] Reachability Server (server->client request)
267 #define MESSAGE_NOTIFY "notify_op" // int64
270 MESSAGE_REACHABILITY_STATUS
= 0x1001,
273 #define REACH_STATUS_CYCLE "cycle" // uint64
274 #define REACH_STATUS_DNS_FLAGS "dns_flags" // uint64
275 #define REACH_STATUS_FLAGS "flags" // uint64
276 #define REACH_STATUS_IF_INDEX "if_index" // uint64
277 #define REACH_STATUS_IF_NAME "if_name" // data (char if_name[IFNAMSIZ])
278 #define REACH_STATUS_RESOLVED_ADDRESSES "resolved_addresses" // array[data]
279 #define REACH_STATUS_RESOLVED_ERROR "resolved_error" // int64
280 #define REACH_STATUS_SLEEPING "sleeping" // bool
283 // ------------------------------------------------------------
289 _SCNetworkReachabilityCopyTargetDescription (SCNetworkReachabilityRef target
);
292 _SCNetworkReachabilityCopyTargetFlags (SCNetworkReachabilityRef target
);
295 __SCNetworkReachabilityUpdate (SCNetworkReachabilityRef target
);
298 __SCNetworkReachabilityUpdateConcurrent (SCNetworkReachabilityRef target
);
301 __SCNetworkReachability_concurrent_queue (void);
304 #pragma mark [XPC] Reachability Server (client APIs)
307 _SCNetworkReachabilityServer_snapshot (void);
310 __SCNetworkReachabilityServer_targetAdd (SCNetworkReachabilityRef target
);
313 __SCNetworkReachabilityServer_targetRemove (SCNetworkReachabilityRef target
);
316 __SCNetworkReachabilityServer_targetSchedule (SCNetworkReachabilityRef target
);
319 __SCNetworkReachabilityServer_targetStatus (SCNetworkReachabilityRef target
);
322 __SCNetworkReachabilityServer_targetUnschedule (SCNetworkReachabilityRef target
);
326 __SC_checkResolverReachabilityInternal (SCDynamicStoreRef
*storeP
,
327 SCNetworkReachabilityFlags
*flags
,
329 const char *nodename
,
330 uint32_t *resolver_if_index
,
331 int *dns_config_index
);
333 static __inline__
void
334 __SCNetworkReachabilityPrintFlags(SCNetworkReachabilityFlags flags
)
337 if (flags
& kSCNetworkReachabilityFlagsReachable
) {
338 SCPrint(TRUE
, stdout
, CFSTR("Reachable"));
339 flags
&= ~kSCNetworkReachabilityFlagsReachable
;
340 SCPrint(flags
!= 0, stdout
, CFSTR(","));
342 if (flags
& kSCNetworkReachabilityFlagsTransientConnection
) {
343 SCPrint(TRUE
, stdout
, CFSTR("Transient Connection"));
344 flags
&= ~kSCNetworkReachabilityFlagsTransientConnection
;
345 SCPrint(flags
!= 0, stdout
, CFSTR(","));
347 if (flags
& kSCNetworkReachabilityFlagsConnectionRequired
) {
348 SCPrint(TRUE
, stdout
, CFSTR("Connection Required"));
349 flags
&= ~kSCNetworkReachabilityFlagsConnectionRequired
;
350 SCPrint(flags
!= 0, stdout
, CFSTR(","));
352 if (flags
& kSCNetworkReachabilityFlagsConnectionOnTraffic
) {
353 SCPrint(TRUE
, stdout
, CFSTR("Automatic Connection On Traffic"));
354 flags
&= ~kSCNetworkReachabilityFlagsConnectionOnTraffic
;
355 SCPrint(flags
!= 0, stdout
, CFSTR(","));
357 if (flags
& kSCNetworkReachabilityFlagsConnectionOnDemand
) {
358 SCPrint(TRUE
, stdout
, CFSTR("Automatic Connection On Demand"));
359 flags
&= ~kSCNetworkReachabilityFlagsConnectionOnDemand
;
360 SCPrint(flags
!= 0, stdout
, CFSTR(","));
362 if (flags
& kSCNetworkReachabilityFlagsInterventionRequired
) {
363 SCPrint(TRUE
, stdout
, CFSTR("Intervention Required"));
364 flags
&= ~kSCNetworkReachabilityFlagsInterventionRequired
;
365 SCPrint(flags
!= 0, stdout
, CFSTR(","));
367 if (flags
& kSCNetworkReachabilityFlagsIsLocalAddress
) {
368 SCPrint(TRUE
, stdout
, CFSTR("Local Address"));
369 flags
&= ~kSCNetworkReachabilityFlagsIsLocalAddress
;
370 SCPrint(flags
!= 0, stdout
, CFSTR(","));
372 if (flags
& kSCNetworkReachabilityFlagsIsDirect
) {
373 SCPrint(TRUE
, stdout
, CFSTR("Directly Reachable Address"));
374 flags
&= ~kSCNetworkReachabilityFlagsIsDirect
;
375 SCPrint(flags
!= 0, stdout
, CFSTR(","));
378 if (flags
& kSCNetworkReachabilityFlagsIsWWAN
) {
379 SCPrint(TRUE
, stdout
, CFSTR("WWAN"));
380 flags
&= ~kSCNetworkReachabilityFlagsIsWWAN
;
381 SCPrint(flags
!= 0, stdout
, CFSTR(","));
383 #endif // TARGET_OS_IPHONE
385 SCPrint(TRUE
, stdout
, CFSTR("0x%08x"), flags
);
388 SCPrint(TRUE
, stdout
, CFSTR("Not Reachable"));
397 #endif // _SCNETWORKREACHABILITYINTERNAL_H