]> git.saurik.com Git - apple/configd.git/blob - Plugins/KernelEventMonitor/ev_dlil.c
configd-136.2.tar.gz
[apple/configd.git] / Plugins / KernelEventMonitor / ev_dlil.c
1 /*
2 * Copyright (c) 2002-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 * August 5, 2002 Allan Nathanson <ajn@apple.com>
28 * - split code out from eventmon.c
29 */
30
31 #include "eventmon.h"
32 #include "cache.h"
33 #include "ev_dlil.h"
34
35 static CFStringRef
36 create_interface_key(const char * if_name)
37 {
38 CFStringRef interface;
39 CFStringRef key;
40
41 interface = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingMacRoman);
42 key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
43 kSCDynamicStoreDomainState,
44 interface,
45 kSCEntNetLink);
46 CFRelease(interface);
47 return (key);
48 }
49
50
51 static CFMutableDictionaryRef
52 copy_entity(CFStringRef key)
53 {
54 CFDictionaryRef dict;
55 CFMutableDictionaryRef newDict = NULL;
56
57 dict = cache_SCDynamicStoreCopyValue(store, key);
58 if (dict != NULL) {
59 if (isA_CFDictionary(dict) != NULL) {
60 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
61 }
62 CFRelease(dict);
63 }
64 if (newDict == NULL) {
65 newDict = CFDictionaryCreateMutable(NULL,
66 0,
67 &kCFTypeDictionaryKeyCallBacks,
68 &kCFTypeDictionaryValueCallBacks);
69 }
70 return (newDict);
71 }
72
73
74 static void
75 interface_update_status(const char *if_name, CFBooleanRef active,
76 boolean_t attach)
77 {
78 CFStringRef key = NULL;
79 CFMutableDictionaryRef newDict = NULL;
80 CFBooleanRef state = NULL;
81
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 */
87 if (active == NULL) {
88 CFDictionaryRemoveValue(newDict, kSCPropNetLinkActive);
89 } else {
90 CFDictionarySetValue(newDict, kSCPropNetLinkActive, active);
91 }
92 if (attach == TRUE) {
93 /* the interface was attached, remove stale state */
94 CFDictionaryRemoveValue(newDict, kSCPropNetLinkDetaching);
95 }
96
97 /* update status */
98 if (CFDictionaryGetCount(newDict) > 0) {
99 cache_SCDynamicStoreSetValue(store, key, newDict);
100 } else {
101 cache_SCDynamicStoreRemoveValue(store, key);
102 }
103
104 CFRelease(key);
105 CFRelease(newDict);
106 return;
107 }
108
109 __private_extern__
110 void
111 interface_detaching(const char *if_name)
112 {
113 CFStringRef key;
114 CFMutableDictionaryRef newDict;
115
116 key = create_interface_key(if_name);
117 newDict = copy_entity(key);
118 CFDictionarySetValue(newDict, kSCPropNetLinkDetaching,
119 kCFBooleanTrue);
120 cache_SCDynamicStoreSetValue(store, key, newDict);
121 CFRelease(newDict);
122 CFRelease(key);
123 return;
124 }
125
126 static void
127 interface_remove(const char *if_name)
128 {
129 CFStringRef key;
130
131 key = create_interface_key(if_name);
132 cache_SCDynamicStoreRemoveValue(store, key);
133 CFRelease(key);
134 return;
135 }
136
137
138 __private_extern__
139 void
140 link_update_status(const char *if_name, boolean_t attach)
141 {
142 CFBooleanRef active = NULL;
143 struct ifmediareq ifm;
144 int sock;
145
146 sock = dgram_socket(AF_INET);
147 if (sock < 0) {
148 SCLog(TRUE, LOG_NOTICE, CFSTR("link_update_status: socket open failed, %s"), strerror(errno));
149 goto done;
150 }
151 bzero((char *)&ifm, sizeof(ifm));
152 (void) strncpy(ifm.ifm_name, if_name, sizeof(ifm.ifm_name));
153
154 if (ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifm) == -1) {
155 /* if media status not available for this interface */
156 goto done;
157 }
158
159 if (ifm.ifm_count == 0) {
160 /* no media types */
161 goto done;
162 }
163
164 if (!(ifm.ifm_status & IFM_AVALID)) {
165 /* if active bit not valid */
166 goto done;
167 }
168
169 if (ifm.ifm_status & IFM_ACTIVE) {
170 active = kCFBooleanTrue;
171 } else {
172 active = kCFBooleanFalse;
173 }
174
175 done:
176 interface_update_status(if_name, active, attach);
177 if (sock >= 0)
178 close(sock);
179 return;
180 }
181
182
183 __private_extern__
184 void
185 link_add(const char *if_name)
186 {
187 CFStringRef interface;
188 CFStringRef cacheKey;
189 CFDictionaryRef dict;
190 CFMutableDictionaryRef newDict = NULL;
191 CFArrayRef ifList;
192 CFMutableArrayRef newIFList = NULL;
193
194 interface = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingMacRoman);
195 cacheKey = SCDynamicStoreKeyCreateNetworkInterface(NULL,
196 kSCDynamicStoreDomainState);
197
198 dict = cache_SCDynamicStoreCopyValue(store, cacheKey);
199 if (dict) {
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);
205 }
206 }
207 CFRelease(dict);
208 }
209
210 if (!newDict) {
211 newDict = CFDictionaryCreateMutable(NULL,
212 0,
213 &kCFTypeDictionaryKeyCallBacks,
214 &kCFTypeDictionaryValueCallBacks);
215 }
216
217 if (!newIFList) {
218 newIFList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
219 }
220
221 if (CFArrayContainsValue(newIFList,
222 CFRangeMake(0, CFArrayGetCount(newIFList)),
223 interface) == FALSE) {
224 CFArrayAppendValue(newIFList, interface);
225 CFDictionarySetValue(newDict,
226 kSCDynamicStorePropNetInterfaces,
227 newIFList);
228 }
229 cache_SCDynamicStoreSetValue(store, cacheKey, newDict);
230 link_update_status(if_name, TRUE);
231 CFRelease(cacheKey);
232 CFRelease(interface);
233 if (newDict) CFRelease(newDict);
234 if (newIFList) CFRelease(newIFList);
235
236 return;
237 }
238
239
240 __private_extern__
241 void
242 link_remove(const char *if_name)
243 {
244 CFStringRef interface;
245 CFStringRef cacheKey;
246 CFDictionaryRef dict;
247 CFMutableDictionaryRef newDict = NULL;
248 CFArrayRef ifList;
249 CFMutableArrayRef newIFList = NULL;
250 CFIndex i;
251
252 interface = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingMacRoman);
253 cacheKey = SCDynamicStoreKeyCreateNetworkInterface(NULL,
254 kSCDynamicStoreDomainState);
255
256 dict = cache_SCDynamicStoreCopyValue(store, cacheKey);
257 if (dict) {
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);
263 }
264 }
265 CFRelease(dict);
266 }
267
268 if (!newIFList ||
269 ((i = CFArrayGetFirstIndexOfValue(newIFList,
270 CFRangeMake(0, CFArrayGetCount(newIFList)),
271 interface)) == kCFNotFound)
272 ) {
273 /* we're not tracking this interface */
274 goto done;
275 }
276
277 CFArrayRemoveValueAtIndex(newIFList, i);
278 CFDictionarySetValue(newDict, kSCDynamicStorePropNetInterfaces, newIFList);
279 cache_SCDynamicStoreSetValue(store, cacheKey, newDict);
280
281 interface_remove(if_name);
282
283 done:
284
285 CFRelease(cacheKey);
286 CFRelease(interface);
287 if (newDict) CFRelease(newDict);
288 if (newIFList) CFRelease(newIFList);
289
290 return;
291 }