2 * Copyright (c) 2002-2006, 2009 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@
25 * Modification History
27 * August 5, 2002 Allan Nathanson <ajn@apple.com>
28 * - split code out from eventmon.c
36 create_interface_key(const char * if_name
)
38 CFStringRef interface
;
41 interface
= CFStringCreateWithCString(NULL
, if_name
, kCFStringEncodingMacRoman
);
42 key
= SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL
,
43 kSCDynamicStoreDomainState
,
51 static CFMutableDictionaryRef
52 copy_entity(CFStringRef key
)
55 CFMutableDictionaryRef newDict
= NULL
;
57 dict
= cache_SCDynamicStoreCopyValue(store
, key
);
59 if (isA_CFDictionary(dict
) != NULL
) {
60 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
64 if (newDict
== NULL
) {
65 newDict
= CFDictionaryCreateMutable(NULL
,
67 &kCFTypeDictionaryKeyCallBacks
,
68 &kCFTypeDictionaryValueCallBacks
);
75 interface_update_status(const char *if_name
, CFBooleanRef active
,
78 CFStringRef key
= NULL
;
79 CFMutableDictionaryRef newDict
= NULL
;
81 key
= create_interface_key(if_name
);
82 newDict
= copy_entity(key
);
83 /* if new status available, update cache */
85 CFDictionaryRemoveValue(newDict
, kSCPropNetLinkActive
);
87 CFDictionarySetValue(newDict
, kSCPropNetLinkActive
, active
);
90 /* the interface was attached, remove stale state */
91 CFDictionaryRemoveValue(newDict
, kSCPropNetLinkDetaching
);
95 if (CFDictionaryGetCount(newDict
) > 0) {
96 cache_SCDynamicStoreSetValue(store
, key
, newDict
);
98 cache_SCDynamicStoreRemoveValue(store
, key
);
108 interface_detaching(const char *if_name
)
111 CFMutableDictionaryRef newDict
;
113 key
= create_interface_key(if_name
);
114 newDict
= copy_entity(key
);
115 CFDictionarySetValue(newDict
, kSCPropNetLinkDetaching
,
117 cache_SCDynamicStoreSetValue(store
, key
, newDict
);
124 interface_remove(const char *if_name
)
128 key
= create_interface_key(if_name
);
129 cache_SCDynamicStoreRemoveValue(store
, key
);
137 link_update_status(const char *if_name
, boolean_t attach
)
139 CFBooleanRef active
= NULL
;
140 struct ifmediareq ifm
;
143 sock
= dgram_socket(AF_INET
);
145 SCLog(TRUE
, LOG_NOTICE
, CFSTR("link_update_status: socket open failed, %s"), strerror(errno
));
148 bzero((char *)&ifm
, sizeof(ifm
));
149 (void) strncpy(ifm
.ifm_name
, if_name
, sizeof(ifm
.ifm_name
));
151 if (ioctl(sock
, SIOCGIFMEDIA
, (caddr_t
)&ifm
) == -1) {
152 /* if media status not available for this interface */
156 if (ifm
.ifm_count
== 0) {
161 if (!(ifm
.ifm_status
& IFM_AVALID
)) {
162 /* if active bit not valid */
166 if (ifm
.ifm_status
& IFM_ACTIVE
) {
167 active
= kCFBooleanTrue
;
169 active
= kCFBooleanFalse
;
173 interface_update_status(if_name
, active
, attach
);
182 link_add(const char *if_name
)
184 CFStringRef interface
;
185 CFStringRef cacheKey
;
186 CFDictionaryRef dict
;
187 CFMutableDictionaryRef newDict
= NULL
;
189 CFMutableArrayRef newIFList
= NULL
;
191 interface
= CFStringCreateWithCString(NULL
, if_name
, kCFStringEncodingMacRoman
);
192 cacheKey
= SCDynamicStoreKeyCreateNetworkInterface(NULL
,
193 kSCDynamicStoreDomainState
);
195 dict
= cache_SCDynamicStoreCopyValue(store
, cacheKey
);
197 if (isA_CFDictionary(dict
)) {
198 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
199 ifList
= CFDictionaryGetValue(newDict
, kSCPropNetInterfaces
);
200 if (isA_CFArray(ifList
)) {
201 newIFList
= CFArrayCreateMutableCopy(NULL
, 0, ifList
);
208 newDict
= CFDictionaryCreateMutable(NULL
,
210 &kCFTypeDictionaryKeyCallBacks
,
211 &kCFTypeDictionaryValueCallBacks
);
215 newIFList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
218 if (CFArrayContainsValue(newIFList
,
219 CFRangeMake(0, CFArrayGetCount(newIFList
)),
220 interface
) == FALSE
) {
221 CFArrayAppendValue(newIFList
, interface
);
222 CFDictionarySetValue(newDict
, kSCPropNetInterfaces
, newIFList
);
224 cache_SCDynamicStoreSetValue(store
, cacheKey
, newDict
);
225 link_update_status(if_name
, TRUE
);
227 CFRelease(interface
);
228 if (newDict
) CFRelease(newDict
);
229 if (newIFList
) CFRelease(newIFList
);
237 link_remove(const char *if_name
)
239 CFStringRef interface
;
240 CFStringRef cacheKey
;
241 CFDictionaryRef dict
;
242 CFMutableDictionaryRef newDict
= NULL
;
244 CFMutableArrayRef newIFList
= NULL
;
247 interface
= CFStringCreateWithCString(NULL
, if_name
, kCFStringEncodingMacRoman
);
248 cacheKey
= SCDynamicStoreKeyCreateNetworkInterface(NULL
,
249 kSCDynamicStoreDomainState
);
251 dict
= cache_SCDynamicStoreCopyValue(store
, cacheKey
);
253 if (isA_CFDictionary(dict
)) {
254 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
255 ifList
= CFDictionaryGetValue(newDict
, kSCPropNetInterfaces
);
256 if (isA_CFArray(ifList
)) {
257 newIFList
= CFArrayCreateMutableCopy(NULL
, 0, ifList
);
264 ((i
= CFArrayGetFirstIndexOfValue(newIFList
,
265 CFRangeMake(0, CFArrayGetCount(newIFList
)),
266 interface
)) == kCFNotFound
)
268 /* we're not tracking this interface */
272 CFArrayRemoveValueAtIndex(newIFList
, i
);
273 CFDictionarySetValue(newDict
, kSCPropNetInterfaces
, newIFList
);
274 cache_SCDynamicStoreSetValue(store
, cacheKey
, newDict
);
276 interface_remove(if_name
);
281 CFRelease(interface
);
282 if (newDict
) CFRelease(newDict
);
283 if (newIFList
) CFRelease(newIFList
);