2 * Copyright (c) 2002-2003 Apple Computer, 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
;
80 CFBooleanRef state
= NULL
;
82 key
= create_interface_key(if_name
);
83 newDict
= copy_entity(key
);
84 state
= isA_CFBoolean(CFDictionaryGetValue(newDict
,
85 kSCPropNetLinkActive
));
86 /* if new status available, update cache */
88 CFDictionaryRemoveValue(newDict
, kSCPropNetLinkActive
);
90 CFDictionarySetValue(newDict
, kSCPropNetLinkActive
, active
);
93 /* the interface was attached, remove stale state */
94 CFDictionaryRemoveValue(newDict
, kSCPropNetLinkDetaching
);
98 if (CFDictionaryGetCount(newDict
) > 0) {
99 cache_SCDynamicStoreSetValue(store
, key
, newDict
);
101 cache_SCDynamicStoreRemoveValue(store
, key
);
111 interface_detaching(const char *if_name
)
114 CFMutableDictionaryRef newDict
;
116 key
= create_interface_key(if_name
);
117 newDict
= copy_entity(key
);
118 CFDictionarySetValue(newDict
, kSCPropNetLinkDetaching
,
120 cache_SCDynamicStoreSetValue(store
, key
, newDict
);
127 interface_remove(const char *if_name
)
131 key
= create_interface_key(if_name
);
132 cache_SCDynamicStoreRemoveValue(store
, key
);
140 link_update_status(const char *if_name
, boolean_t attach
)
142 CFBooleanRef active
= NULL
;
143 struct ifmediareq ifm
;
146 sock
= dgram_socket(AF_INET
);
148 SCLog(TRUE
, LOG_NOTICE
, CFSTR("link_update_status: socket open failed, %s"), strerror(errno
));
151 bzero((char *)&ifm
, sizeof(ifm
));
152 (void) strncpy(ifm
.ifm_name
, if_name
, sizeof(ifm
.ifm_name
));
154 if (ioctl(sock
, SIOCGIFMEDIA
, (caddr_t
)&ifm
) == -1) {
155 /* if media status not available for this interface */
159 if (ifm
.ifm_count
== 0) {
164 if (!(ifm
.ifm_status
& IFM_AVALID
)) {
165 /* if active bit not valid */
169 if (ifm
.ifm_status
& IFM_ACTIVE
) {
170 active
= kCFBooleanTrue
;
172 active
= kCFBooleanFalse
;
176 interface_update_status(if_name
, active
, attach
);
185 link_add(const char *if_name
)
187 CFStringRef interface
;
188 CFStringRef cacheKey
;
189 CFDictionaryRef dict
;
190 CFMutableDictionaryRef newDict
= NULL
;
192 CFMutableArrayRef newIFList
= NULL
;
194 interface
= CFStringCreateWithCString(NULL
, if_name
, kCFStringEncodingMacRoman
);
195 cacheKey
= SCDynamicStoreKeyCreateNetworkInterface(NULL
,
196 kSCDynamicStoreDomainState
);
198 dict
= cache_SCDynamicStoreCopyValue(store
, cacheKey
);
200 if (isA_CFDictionary(dict
)) {
201 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
202 ifList
= CFDictionaryGetValue(newDict
, kSCDynamicStorePropNetInterfaces
);
203 if (isA_CFArray(ifList
)) {
204 newIFList
= CFArrayCreateMutableCopy(NULL
, 0, ifList
);
211 newDict
= CFDictionaryCreateMutable(NULL
,
213 &kCFTypeDictionaryKeyCallBacks
,
214 &kCFTypeDictionaryValueCallBacks
);
218 newIFList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
221 if (CFArrayContainsValue(newIFList
,
222 CFRangeMake(0, CFArrayGetCount(newIFList
)),
223 interface
) == FALSE
) {
224 CFArrayAppendValue(newIFList
, interface
);
225 CFDictionarySetValue(newDict
,
226 kSCDynamicStorePropNetInterfaces
,
229 cache_SCDynamicStoreSetValue(store
, cacheKey
, newDict
);
230 link_update_status(if_name
, TRUE
);
232 CFRelease(interface
);
233 if (newDict
) CFRelease(newDict
);
234 if (newIFList
) CFRelease(newIFList
);
242 link_remove(const char *if_name
)
244 CFStringRef interface
;
245 CFStringRef cacheKey
;
246 CFDictionaryRef dict
;
247 CFMutableDictionaryRef newDict
= NULL
;
249 CFMutableArrayRef newIFList
= NULL
;
252 interface
= CFStringCreateWithCString(NULL
, if_name
, kCFStringEncodingMacRoman
);
253 cacheKey
= SCDynamicStoreKeyCreateNetworkInterface(NULL
,
254 kSCDynamicStoreDomainState
);
256 dict
= cache_SCDynamicStoreCopyValue(store
, cacheKey
);
258 if (isA_CFDictionary(dict
)) {
259 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
260 ifList
= CFDictionaryGetValue(newDict
, kSCDynamicStorePropNetInterfaces
);
261 if (isA_CFArray(ifList
)) {
262 newIFList
= CFArrayCreateMutableCopy(NULL
, 0, ifList
);
269 ((i
= CFArrayGetFirstIndexOfValue(newIFList
,
270 CFRangeMake(0, CFArrayGetCount(newIFList
)),
271 interface
)) == kCFNotFound
)
273 /* we're not tracking this interface */
277 CFArrayRemoveValueAtIndex(newIFList
, i
);
278 CFDictionarySetValue(newDict
, kSCDynamicStorePropNetInterfaces
, newIFList
);
279 cache_SCDynamicStoreSetValue(store
, cacheKey
, newDict
);
281 interface_remove(if_name
);
286 CFRelease(interface
);
287 if (newDict
) CFRelease(newDict
);
288 if (newIFList
) CFRelease(newIFList
);