2 * Copyright (c) 2000-2012 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@
27 #include <sys/cdefs.h>
28 #include <sys/socket.h>
31 #include <sys/syslog.h>
32 #include <mach/message.h>
33 #include <sys/sysctl.h>
35 #include <CoreFoundation/CoreFoundation.h>
37 /* SCDynamicStore SPIs */
38 #include <SystemConfiguration/SCDynamicStorePrivate.h>
39 #include <SystemConfiguration/SCDynamicStoreCopySpecificPrivate.h>
40 #include <SystemConfiguration/SCDynamicStoreSetSpecificPrivate.h>
42 /* SCPreferences SPIs */
43 #include <SystemConfiguration/SCPreferencesPrivate.h>
44 #include <SystemConfiguration/SCPreferencesGetSpecificPrivate.h>
45 #include <SystemConfiguration/SCPreferencesSetSpecificPrivate.h>
47 /* [private] Schema Definitions (for SCDynamicStore and SCPreferences) */
48 #include <SystemConfiguration/SCSchemaDefinitionsPrivate.h>
50 /* SCNetworkConfiguration SPIs */
51 #include <SystemConfiguration/SCNetworkConfigurationPrivate.h>
53 /* SCNetworkConnection SPIs */
54 #include <SystemConfiguration/SCNetworkConnectionPrivate.h>
57 #include <SystemConfiguration/SCPreferencesKeychainPrivate.h>
64 /* atomic operations */
65 #define _SC_ATOMIC_CMPXCHG(p, o, n) __sync_bool_compare_and_swap((p), (o), (n))
66 #define _SC_ATOMIC_INC(p) __sync_fetch_and_add((p), 1) // return (n++);
67 #define _SC_ATOMIC_DEC(p) __sync_sub_and_fetch((p), 1) // return (--n);
68 #define _SC_ATOMIC_ZERO(p) __sync_fetch_and_and((p), 0) // old_n = n; n = 0; return(old_n);
71 /* framework variables */
72 extern int _sc_debug
; /* non-zero if debugging enabled */
73 extern int _sc_verbose
; /* non-zero if verbose logging enabled */
74 extern int _sc_log
; /* 0 if SC messages should be written to stdout/stderr,
75 1 if SC messages should be logged w/asl(3),
76 2 if SC messages should be written to stdout/stderr AND logged */
79 @group SCNetworkReachabilityCreateWithOptions #defines
80 @discussion The following defines the keys and values that can
81 be passed to the SCNetworkReachabilityCreateWithOptions
86 @constant kSCNetworkReachabilityOptionNodeName
87 @discussion A CFString that will be passed to getaddrinfo(3). An acceptable
88 value is either a valid host name or a numeric host address string
89 consisting of a dotted decimal IPv4 address or an IPv6 address.
91 #define kSCNetworkReachabilityOptionNodeName CFSTR("nodename")
94 @constant kSCNetworkReachabilityOptionLocalAddress
95 @discussion A CFData wrapping a "struct sockaddr" that represents
96 local address associated with a network connection.
98 #define kSCNetworkReachabilityOptionLocalAddress CFSTR("local-address")
101 @constant kSCNetworkReachabilityOptionRemoteAddress
102 @discussion A CFData wrapping a "struct sockaddr" that represents
103 remote address associated with a network connection.
105 #define kSCNetworkReachabilityOptionRemoteAddress CFSTR("remote-address")
108 @constant kSCNetworkReachabilityOptionServName
109 @discussion A CFString that will be passed to getaddrinfo(3). An acceptable
110 value is either a decimal port number or a service name listed in
113 #define kSCNetworkReachabilityOptionServName CFSTR("servname")
116 @constant kSCNetworkReachabilityOptionHints
117 @discussion A CFData wrapping a "struct addrinfo" that will be passed to
118 getaddrinfo(3). The caller can supply any of the ai_family,
119 ai_socktype, ai_protocol, and ai_flags structure elements. All
120 other elements must be 0 or the null pointer.
122 #define kSCNetworkReachabilityOptionHints CFSTR("hints")
125 @constant kSCNetworkReachabilityOptionInterface
126 @discussion A CFString specifying that the reachability query should be
127 limited to the provided network interface (e.g. "en0", "en1", ...).
129 #define kSCNetworkReachabilityOptionInterface CFSTR("interface")
132 @constant kSCNetworkReachabilityOptionConnectionOnDemandBypass
133 @discussion A CFBoolean that indicates if we should bypass the VPNOnDemand
134 checks for this target.
136 #define kSCNetworkReachabilityOptionConnectionOnDemandBypass CFSTR("ConnectionOnDemandBypass")
139 @constant kSCNetworkReachabilityOptionResolverBypass
140 @discussion A CFBoolean that indicates if we should bypass resolving any
141 node names. Instead, the status of the DNS server configuration
142 associated with the name will be returned. */
143 #define kSCNetworkReachabilityOptionResolverBypass CFSTR("ResolverBypass")
147 @constant kSCNetworkReachabilityOptionLongLivedQueryBypass
148 @discussion A CFBoolean that indicates if we should bypass usage of any
149 long-lived-queries (w/DNSServiceCreateConnection) when resolving
150 hostnames for this target.
152 #define kSCNetworkReachabilityOptionLongLivedQueryBypass CFSTR("LongLivedQueryBypass")
155 @constant kSCNetworkReachabilityOptionServerBypass
156 @discussion A CFBoolean that indicates if we should bypass usage of the
157 SCNetworkReachability "server" for this target.
159 #define kSCNetworkReachabilityOptionServerBypass CFSTR("ServerBypass")
169 #pragma mark SCError()
173 @function _SCErrorSet
174 @discussion Sets the last SystemConfiguration.framework API error code.
175 @param error The error encountered.
177 void _SCErrorSet (int error
);
181 #pragma mark Serialization/Unserialization
185 @function _SCSerialize
186 @discussion Serialize a CFPropertyList object for passing
188 @param obj CFPropertyList object to serialize
189 @param xml A pointer to a CFDataRef, NULL if data should be
191 @param dataRef A pointer to the newly allocated/serialized data
192 @param dataLen A pointer to the length in bytes of the newly
193 allocated/serialized data
195 Boolean
_SCSerialize (CFPropertyListRef obj
,
201 @function _SCUnserialize
202 @discussion Unserialize a stream of bytes passed from/to configd
203 into a CFPropertyList object.
204 @param obj A pointer to memory that will be filled with the CFPropertyList
205 associated with the stream of bytes.
206 @param xml CFDataRef with the serialized data
207 @param dataRef A pointer to the serialized data
208 @param dataLen A pointer to the length of the serialized data
210 Specify either "xml" or "data/dataLen".
212 Boolean
_SCUnserialize (CFPropertyListRef
*obj
,
218 @function _SCSerializeString
219 @discussion Serialize a CFString object for passing
221 @param str CFString key to serialize
222 @param data A pointer to a CFDataRef, NULL if storage should be
224 @param dataRef A pointer to the newly allocated/serialized data
225 @param dataLen A pointer to the length in bytes of the newly
226 allocated/serialized data
228 Boolean
_SCSerializeString (CFStringRef str
,
234 @function _SCUnserializeString
235 @discussion Unserialize a stream of bytes passed from/to configd
236 into a CFString object.
237 @param str A pointer to memory that will be filled with the CFString
238 associated with the stream of bytes.
239 @param utf8 CFDataRef with the serialized data
240 @param dataRef A pointer to the serialized data
241 @param dataLen A pointer to the length of the serialized data
243 Specify either "utf8" or "data/dataLen".
245 Boolean
_SCUnserializeString (CFStringRef
*str
,
251 @function _SCSerializeData
252 @discussion Serialize a CFData object for passing
254 @param data CFData key to serialize
255 @param dataRef A pointer to the newly allocated/serialized data
256 @param dataLen A pointer to the length in bytes of the newly
257 allocated/serialized data
259 Boolean
_SCSerializeData (CFDataRef data
,
264 @function _SCUnserializeData
265 @discussion Unserialize a stream of bytes passed from/to configd
266 into a CFData object.
267 @param data A pointer to memory that will be filled with the CFData
268 associated with the stream of bytes.
269 @param dataRef A pointer to the serialized data
270 @param dataLen A pointer to the length of the serialized data
272 Boolean
_SCUnserializeData (CFDataRef
*data
,
277 @function _SCSerializeMultiple
278 @discussion Convert a CFDictionary containing a set of CFPropertlyList
279 values into a CFDictionary containing a set of serialized CFData
281 @param dict The CFDictionary with CFPropertyList values.
282 @result The serialized CFDictionary with CFData values
285 CFDictionaryRef
_SCSerializeMultiple (CFDictionaryRef dict
);
288 @function _SCUnserializeMultiple
289 @discussion Convert a CFDictionary containing a set of CFData
290 values into a CFDictionary containing a set of serialized
291 CFPropertlyList values.
292 @param dict The CFDictionary with CFData values.
293 @result The serialized CFDictionary with CFPropertyList values
296 CFDictionaryRef
_SCUnserializeMultiple (CFDictionaryRef dict
);
300 #pragma mark String conversion
304 @function _SC_cfstring_to_cstring
305 @discussion Extracts a C-string from a CFString.
306 @param cfstr The CFString to extract the data from.
307 @param buf A user provided buffer of the specified length. If NULL,
308 a new buffer will be allocated to contain the C-string. It
309 is the responsiblity of the caller to free an allocated
311 @param bufLen The size of the user provided buffer.
312 @param encoding The string encoding
313 @result If the extraction (conversion) is successful then a pointer
314 to the user provided (or allocated) buffer is returned, NULL
315 if the string could not be extracted.
317 char * _SC_cfstring_to_cstring (CFStringRef cfstr
,
320 CFStringEncoding encoding
);
323 * @function _SC_sockaddr_to_string
324 * @discussion Formats a "struct sockaddr" for reporting
325 * @param address The address to format
326 * @param buf A user provided buffer of the specified length.
327 * @param bufLen The size of the user provided buffer.
329 void _SC_sockaddr_to_string (const struct sockaddr
*address
,
335 * @function _SC_string_to_sockaddr
336 * @discussion Parses a string into a "struct sockaddr"
337 * @param str The address string to parse
338 * @param af Allowed address families (AF_UNSPEC, AF_INET, AF_INET6)
339 * @param buf A user provided buffer of the specified length; NULL
340 * if a new buffer should be allocated (and deallocated by the
342 * @param bufLen The size of the user provided buffer.
343 * @result A pointer to the parsed "struct sockaddr"; NULL if
344 * the string could not be parsed as an IP[v6] address.
347 _SC_string_to_sockaddr (const char *str
,
353 * @function _SC_trimDomain
354 * @discussion Trims leading and trailing "."s from a domain or host name
355 * @param domain The domain name to trim
356 * @result The trimmed domain name.
359 CFStringRef
_SC_trimDomain (CFStringRef domain
);
363 #pragma mark Mach IPC
367 @function _SC_sendMachMessage
368 @discussion Sends a trivial mach message (one with just a
369 message ID) to the specified port.
370 @param port The mach port.
371 @param msg_id The message id.
373 void _SC_sendMachMessage (mach_port_t port
,
374 mach_msg_id_t msg_id
);
382 @function _SCCopyDescription
383 @discussion Returns a formatted textual description of a CF object.
384 @param cf The CFType object (a generic reference of type CFTypeRef) from
385 which to derive a description.
386 @param formatOptions A dictionary containing formatting options for the object.
387 @result A string that contains a formatted description of cf.
389 CFStringRef
_SCCopyDescription (CFTypeRef cf
,
390 CFDictionaryRef formatOptions
);
395 @discussion Conditionally issue a log message.
396 @param condition A boolean value indicating if the message should be logged
397 @param level A syslog(3) logging priority.
398 @param formatString The format string
399 @result The specified message will be written to the system message
400 logger (See syslogd(8)).
402 void SCLog (Boolean condition
,
404 CFStringRef formatString
,
410 @discussion Issue a log message.
411 @param asl An asl client handle to be used for logging. If NULL, a shared
413 @param msg An asl msg structure to be used for logging. If NULL, a default
414 asl msg will be used.
415 @param level A asl(3) logging priority. Passing the complement of a logging
416 priority (e.g. ~ASL_LEVEL_NOTICE) will result in log message lines
417 NOT being split by a "\n".
418 @param formatString The format string
419 @result The specified message will be written to the system message
420 logger (See syslogd(8)).
422 void SCLOG (aslclient asl
,
425 CFStringRef formatString
,
431 @discussion Conditionally issue a debug message.
432 @param condition A boolean value indicating if the message should be written
433 @param stream The output stream for the log message.
434 @param formatString The format string
435 @result The message will be written to the specified stream
438 void SCPrint (Boolean condition
,
440 CFStringRef formatString
,
445 @discussion Conditionally issue a debug message with a time stamp.
446 @param condition A boolean value indicating if the message should be written
447 @param stream The output stream for the log message.
448 @param formatString The format string
449 @result The message will be written to the specified stream
452 void SCTrace (Boolean condition
,
454 CFStringRef formatString
,
462 @function SCNetworkProxiesCopyMatching
464 @param globalConfiguration the proxy dictionary currently returned
465 by SCDynamicStoreCopyProxies().
466 @param server A CFString specying the hostname of interest; NULL if
467 no specific hostname should be used in selecting the proxy
469 @param interface A CFString specifying that the proxy configuration
470 for the provided network interface (e.g. "en0", "en1", ...)
471 should be returned; NULL if proxy usage will not be scoped
473 @result A CFArray containing the proxy configurations associated
474 with the requested server and/or network interface.
478 SCNetworkProxiesCopyMatching (CFDictionaryRef globalConfiguration
,
480 CFStringRef interface
) __OSX_AVAILABLE_STARTING(__MAC_10_7
,__IPHONE_5_0
/*SPI*/);
483 #pragma mark Reachability
487 @function SCNetworkReachabilityCopyOnDemandService
488 @discussion For target hosts that require an OnDemand connection, returns
489 the SCNetworkService associated with the connection and user
490 options to use with SCNetworkConnectionStart.
491 @result The SCNetworkService for the target; NULL if there is
492 no associated OnDemand service.
495 SCNetworkReachabilityCopyOnDemandService (SCNetworkReachabilityRef target
,
496 CFDictionaryRef
*userOptions
);
499 @function SCNetworkReachabilityCopyResolvedAddress
500 @discussion Return the resolved addresses associated with the
502 @result A CFArray[CFData], where each CFData is a (struct sockaddr)
505 SCNetworkReachabilityCopyResolvedAddress (SCNetworkReachabilityRef target
,
509 @function SCNetworkReachabilityCreateWithOptions
510 @discussion Creates a reference to a specified network host. The
511 options allow the caller to specify the node name and/or
512 the service name. This reference can be used later to
513 monitor the reachability of the target host.
514 @param allocator The CFAllocator that should be used to allocate
515 memory for the SCNetworkReachability object.
516 This parameter may be NULL in which case the current
517 default CFAllocator is used. If this reference is not
518 a valid CFAllocator, the behavior is undefined.
519 @param options A CFDictionary containing options specifying the
520 network host. The options reflect the arguments that would
521 be passed to getaddrinfo().
523 SCNetworkReachabilityRef
524 SCNetworkReachabilityCreateWithOptions (CFAllocatorRef allocator
,
525 CFDictionaryRef options
);
528 @function _SC_checkResolverReachabilityByAddress
529 @discussion Check the reachability of a reverse DNS query
532 _SC_checkResolverReachabilityByAddress (SCDynamicStoreRef
*storeP
,
533 SCNetworkReachabilityFlags
*flags
,
535 struct sockaddr
*sa
);
538 @function SCNetworkReachabilityGetInterfaceIndex
539 @discussion Returns the interface index associated with network interface that will
540 be used to interact with the target host.
541 @param target The SCNetworkReachability reference associated with the address or
542 name to be checked for reachability.
543 @result Returns the interface index associated with the target. Returning -1 means that
544 the target is not reachable.
547 SCNetworkReachabilityGetInterfaceIndex (SCNetworkReachabilityRef target
);
553 @function _SC_domainEndsWithDomain
554 @discussion Checks if one domain is a subset of another
555 @param compare_domain The domain to be compared.
556 @param match_domain The domain to be matched.
557 @return TRUE if the match_domain is contained in the compare_domain.
561 _SC_domainEndsWithDomain (CFStringRef compare_domain
,
562 CFStringRef match_domain
);
568 #if !TARGET_OS_IPHONE
570 * DOS encoding/codepage
573 _SC_dos_encoding_and_codepage (CFStringEncoding macEncoding
,
575 CFStringEncoding
*dosEncoding
,
576 UInt32
*dosCodepage
);
577 #endif // !TARGET_OS_IPHONE
580 #pragma mark ScheduleWithRunLoop/UnscheduleFromRunLoop
584 * object / CFRunLoop management
587 _SC_signalRunLoop (CFTypeRef obj
,
588 CFRunLoopSourceRef rls
,
592 _SC_isScheduled (CFTypeRef obj
,
593 CFRunLoopRef runLoop
,
594 CFStringRef runLoopMode
,
595 CFMutableArrayRef rlList
);
598 _SC_schedule (CFTypeRef obj
,
599 CFRunLoopRef runLoop
,
600 CFStringRef runLoopMode
,
601 CFMutableArrayRef rlList
);
604 _SC_unschedule (CFTypeRef obj
,
605 CFRunLoopRef runLoop
,
606 CFStringRef runLoopMode
,
607 CFMutableArrayRef rlList
,
618 _SC_CFBundleGet (void);
621 _SC_CFBundleCopyNonLocalizedString (CFBundleRef bundle
,
624 CFStringRef tableName
);
634 _SC_CFMachPortCreateWithPort (const char * portDescription
,
636 CFMachPortCallBack callout
,
637 CFMachPortContext
*context
);
642 static __inline__ Boolean
643 _SC_CFEqual(CFTypeRef val1
, CFTypeRef val2
)
648 if (val1
!= NULL
&& val2
!= NULL
) {
649 return CFEqual(val1
, val2
);
654 static __inline__ Boolean
655 _SC_isAppleInternal()
657 static int isInternal
= 0;
659 if (isInternal
== 0) {
663 ret
= stat("/AppleInternal", &statbuf
);
664 isInternal
= (ret
== 0) ? 1 : 2;
667 return (isInternal
== 1);
670 #define MODEL CFSTR("Model")
672 static __inline__ CFStringRef
677 * Hardware model for this network configuration.
679 static CFStringRef model
= NULL
;
683 int mib
[] = { CTL_HW
, HW_MODEL
};
684 size_t n
= sizeof(hwModel
);
688 bzero(&hwModel
, sizeof(hwModel
));
689 ret
= sysctl(mib
, sizeof(mib
) / sizeof(mib
[0]), &hwModel
, &n
, NULL
, 0);
691 SCLog(TRUE
, LOG_ERR
, CFSTR("sysctl() CTL_HW/HW_MODEL failed: %s"), strerror(errno
));
694 hwModel
[sizeof(hwModel
) - 1] = '\0';
696 model
= CFStringCreateWithCString(NULL
, hwModel
, kCFStringEncodingASCII
);
707 #ifdef DEBUG_MACH_PORT_ALLOCATIONS
708 #define __MACH_PORT_DEBUG(cond, str, port) \
710 if (cond) _SC_logMachPortReferences(str, port); \
712 #else // DEBUG_MACH_PORT_ALLOCATIONS
713 #define __MACH_PORT_DEBUG(cond, str, port)
714 #endif // DEBUG_MACH_PORT_ALLOCATIONS
717 _SC_logMachPortStatus (void);
720 _SC_logMachPortReferences (const char *str
,
724 _SC_copyBacktrace (void);
727 _SC_crash (const char *crash_info
,
728 CFStringRef notifyHeader
,
729 CFStringRef notifyMessage
);
733 #endif /* _SCPRIVATE_H */