]> git.saurik.com Git - apple/configd.git/blob - Plugins/Logger/logger.c
configd-596.13.tar.gz
[apple/configd.git] / Plugins / Logger / logger.c
1 /*
2 * Copyright (c) 2005-2013 Apple 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 * January 15, 2005 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <sys/filio.h>
34 #include <sys/ioctl.h>
35 #include <sys/socket.h>
36 #include <sys/time.h>
37 #include <sys/types.h>
38 #include <net/ethernet.h>
39 #include <net/if.h>
40 #include <net/if_dl.h>
41 #include <net/if_media.h>
42 #include <net/if_types.h>
43 #include <net/if_var.h>
44 #include <sys/kern_event.h>
45 #include <netinet/in.h>
46 #include <netinet/in_var.h>
47 #include <netinet6/in6_var.h>
48 #include <ifaddrs.h>
49 #include <arpa/inet.h>
50
51 #include <TargetConditionals.h>
52 #include <CoreFoundation/CoreFoundation.h>
53 #include <SystemConfiguration/SystemConfiguration.h>
54 #include <SystemConfiguration/SCPrivate.h>
55 #include <IOKit/IOKitLib.h>
56 #include <IOKit/IOMessage.h>
57 #include <IOKit/pwr_mgt/IOPM.h>
58 #include <IOKit/pwr_mgt/IOPMLib.h>
59 #include <IOKit/pwr_mgt/IOPMLibPrivate.h>
60
61 #include <dnsinfo.h>
62 #include <network_information.h>
63 #include <notify.h>
64 #if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) && !TARGET_OS_EMBEDDED
65 #include <utmpx.h>
66 #include <utmpx_thread.h>
67 #endif // !(__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) && !TARGET_OS_EMBEDDED
68
69
70 /* generic MessageTracer keys */
71 #define MSGTRACER_KEY_DOMAIN "com.apple.message.domain"
72 #define MSGTRACER_KEY_SIG "com.apple.message.signature"
73 #define MSGTRACER_KEY_UUID "com.apple.message.uuid"
74 #define MSGTRACER_KEY_VALUE1 "com.apple.message.value"
75
76
77 #define MY_ASL_FACILITY "com.apple.SystemConfiguration.Logger"
78 #define MY_MSGTRACER_DOMAIN "com.apple.network.log"
79
80
81 static aslmsg log_msg = NULL;
82 static io_connect_t power = MACH_PORT_NULL;
83 static Boolean verbose = FALSE;
84
85
86 static char *
87 elapsed()
88 {
89 static char str[128];
90 struct tm tm_diff;
91 struct tm tm_now;
92 struct timeval tv_diff;
93 struct timeval tv_now;
94 static struct timeval tv_then = { 0, 0 };
95
96 (void)gettimeofday(&tv_now, NULL);
97
98 (void)localtime_r(&tv_now.tv_sec, &tm_now);
99
100 timersub(&tv_now, &tv_then, &tv_diff);
101 (void)localtime_r(&tv_diff.tv_sec, &tm_diff);
102 #ifdef MAIN
103 sprintf(str, "%2d:%02d:%02d.%03d (+%ld.%03d)",
104 tm_now.tm_hour,
105 tm_now.tm_min,
106 tm_now.tm_sec,
107 tv_now.tv_usec / 1000,
108 tv_diff.tv_sec,
109 tv_diff.tv_usec / 1000);
110 #else
111 sprintf(str, ".%03d (+%ld.%03d)",
112 tv_now.tv_usec / 1000,
113 tv_diff.tv_sec,
114 tv_diff.tv_usec / 1000);
115 #endif
116
117 tv_then = tv_now;
118 return str;
119 }
120
121
122 #pragma mark -
123 #pragma mark [Network] Kernel Events
124
125
126 static CFStringRef
127 copyInterfaceFlags(const char *if_name)
128 {
129 const char * iff_up = "? ";
130 struct ifreq ifr;
131 const char *ifm_active = "? ";
132 int sock;
133 CFStringRef str = NULL;
134
135 sock = socket(AF_INET, SOCK_DGRAM, 0);
136 if (sock == -1) {
137 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("socket() failed"));
138 return NULL;
139 }
140
141 bzero((char *)&ifr, sizeof(ifr));
142 (void) strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
143 if (ioctl(sock, SIOCGIFFLAGS, (caddr_t)&ifr) == 0) {
144 struct ifmediareq ifm;
145
146 iff_up = (ifr.ifr_flags & IFF_UP) ? "yes" : "no ";
147
148 bzero((char *)&ifm, sizeof(ifm));
149 (void) strncpy(ifm.ifm_name, if_name, sizeof(ifm.ifm_name));
150 if ((ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifm) == 0) &&
151 (ifm.ifm_count > 0) &&
152 (ifm.ifm_status & IFM_AVALID)) {
153 ifm_active = (ifm.ifm_status & IFM_ACTIVE) ? "yes" : "no ";
154 }
155
156 str = CFStringCreateWithFormat(NULL,
157 NULL,
158 CFSTR("\n%-5s: IFF_UP = %s IFM_ACTIVE = %s"),
159 if_name,
160 iff_up,
161 ifm_active);
162 }
163
164 (void)close(sock);
165
166 return str;
167 }
168
169
170 static int
171 prefixLength(struct sockaddr_in6 *sin6)
172 {
173 register u_int8_t *name = &sin6->sin6_addr.s6_addr[0];
174 register int byte;
175 register int bit;
176 int plen = 0;
177
178 for (byte = 0; byte < sizeof(struct in6_addr); byte++, plen += 8) {
179 if (name[byte] != 0xff) {
180 break;
181 }
182 }
183
184 if (byte == sizeof(struct in6_addr)) {
185 return plen;
186 }
187
188 for (bit = 7; bit != 0; bit--, plen++) {
189 if (!(name[byte] & (1 << bit))) {
190 break;
191 }
192 }
193
194 for (; bit != 0; bit--) {
195 if (name[byte] & (1 << bit)) {
196 return 0;
197 }
198 }
199
200 byte++;
201 for (; byte < sizeof(struct in6_addr); byte++) {
202 if (name[byte]) {
203 return 0;
204 }
205 }
206
207 return plen;
208 }
209
210
211 static void
212 KernelEvent_notification(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
213 {
214 int so = CFSocketGetNative(s);
215 int status;
216 union {
217 char bytes[1024];
218 struct kern_event_msg ev_msg1; // first kernel event
219 } buf;
220 struct kern_event_msg *ev_msg = &buf.ev_msg1;
221 int offset = 0;
222
223 status = recv(so, &buf, sizeof(buf), 0);
224 if (status == -1) {
225 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("recv() failed: %s"), strerror(errno));
226 CFSocketInvalidate(s);
227 return;
228 }
229
230 while (offset < status) {
231 if ((offset + ev_msg->total_size) > status) {
232 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("missed SYSPROTO_EVENT event, buffer not big enough"));
233 break;
234 }
235
236 switch (ev_msg->vendor_code) {
237 case KEV_VENDOR_APPLE :
238 switch (ev_msg->kev_class) {
239 case KEV_NETWORK_CLASS : {
240 void *event_data = &ev_msg->event_data[0];
241
242 switch (ev_msg->kev_subclass) {
243 case KEV_DL_SUBCLASS : {
244 struct net_event_data *ev;
245 char if_name[IFNAMSIZ];
246
247 ev = (struct net_event_data *)event_data;
248
249 snprintf(if_name, IFNAMSIZ, "%s%d",
250 ev->if_name,
251 ev->if_unit);
252
253 switch (ev_msg->event_code) {
254 case KEV_DL_IF_ATTACHED : {
255 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
256 CFSTR("%s kernel event: %s: attached"),
257 elapsed(),
258 if_name);
259 break;
260 }
261 case KEV_DL_IF_DETACHING : {
262 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
263 CFSTR("%s kernel event: %s: detaching"),
264 elapsed(),
265 if_name);
266 break;
267 }
268 case KEV_DL_IF_DETACHED : {
269 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
270 CFSTR("%s kernel event: %s: detached"),
271 elapsed(),
272 if_name);
273 break;
274 }
275 case KEV_DL_LINK_OFF : {
276 CFStringRef str;
277
278 str = verbose ? copyInterfaceFlags(if_name) : NULL;
279 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
280 CFSTR("%s kernel event: %s: link down%@"),
281 elapsed(),
282 if_name,
283 str != NULL ? str : CFSTR(""));
284 if (str != NULL) CFRelease(str);
285 break;
286 }
287 case KEV_DL_LINK_ON : {
288 CFStringRef str;
289
290 str = verbose ? copyInterfaceFlags(if_name) : NULL;
291 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
292 CFSTR("%s kernel event: %s: link up%@"),
293 elapsed(),
294 if_name,
295 str != NULL ? str : CFSTR(""));
296 if (str != NULL) CFRelease(str);
297 break;
298 }
299 default :
300 break;
301 }
302 break;
303 }
304 case KEV_INET_SUBCLASS : {
305 char addr[128];
306 struct kev_in_data *ev;
307 char if_name[IFNAMSIZ];
308 char mask[128];
309
310 ev = (struct kev_in_data *)event_data;
311
312 snprintf(if_name, IFNAMSIZ, "%s%d",
313 ev->link_data.if_name,
314 ev->link_data.if_unit);
315
316 switch (ev_msg->event_code) {
317 case KEV_INET_NEW_ADDR :
318 case KEV_INET_CHANGED_ADDR :
319 case KEV_INET_ADDR_DELETED : {
320 struct sockaddr_in sin;
321
322 bzero(&sin, sizeof(sin));
323 sin.sin_len = sizeof(sin);
324 sin.sin_family = AF_INET;
325 sin.sin_addr = ev->ia_addr;
326 _SC_sockaddr_to_string((struct sockaddr *)&sin, addr, sizeof(addr));
327
328 bzero(&sin, sizeof(sin));
329 sin.sin_len = sizeof(sin);
330 sin.sin_family = AF_INET;
331 sin.sin_addr.s_addr = ntohl(ev->ia_subnetmask);
332 _SC_sockaddr_to_string((struct sockaddr *)&sin, mask, sizeof(mask));
333 break;
334 }
335 default :
336 break;
337 }
338
339 switch (ev_msg->event_code) {
340 case KEV_INET_NEW_ADDR : {
341 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
342 CFSTR("%s kernel event: %s: IPv4 address added (%s/%s)"),
343 elapsed(),
344 if_name,
345 addr,
346 mask);
347 break;
348 }
349 case KEV_INET_CHANGED_ADDR : {
350 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
351 CFSTR("%s kernel event: %s: IPv4 address changed (%s/%s)"),
352 elapsed(),
353 if_name,
354 addr,
355 mask);
356 break;
357 }
358 case KEV_INET_ADDR_DELETED : {
359 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
360 CFSTR("%s kernel event: %s: IPv4 address removed (%s/%s)"),
361 elapsed(),
362 if_name,
363 addr,
364 mask);
365 break;
366 }
367 default :
368 break;
369 }
370 break;
371 }
372 case KEV_INET6_SUBCLASS : {
373 char addr[128];
374 struct kev_in6_data *ev;
375 char if_name[IFNAMSIZ];
376 int plen = 0;
377
378 ev = (struct kev_in6_data *)event_data;
379
380 snprintf(if_name, IFNAMSIZ, "%s%d",
381 ev->link_data.if_name,
382 ev->link_data.if_unit);
383
384 switch (ev_msg->event_code) {
385 case KEV_INET6_NEW_USER_ADDR :
386 case KEV_INET6_NEW_LL_ADDR :
387 case KEV_INET6_CHANGED_ADDR :
388 case KEV_INET6_ADDR_DELETED : {
389 _SC_sockaddr_to_string((struct sockaddr *)&ev->ia_addr, addr, sizeof(addr));
390 plen = prefixLength(&ev->ia_prefixmask);
391 break;
392 }
393 default :
394 break;
395 }
396
397 switch (ev_msg->event_code) {
398 case KEV_INET6_NEW_USER_ADDR :
399 case KEV_INET6_NEW_LL_ADDR : {
400 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
401 CFSTR("%s kernel event: %s: IPv6 address added (%s/%d)"),
402 elapsed(),
403 if_name,
404 addr,
405 plen);
406 break;
407 }
408 case KEV_INET6_CHANGED_ADDR : {
409 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
410 CFSTR("%s kernel event: %s: IPv6 address changed (%s/%d)"),
411 elapsed(),
412 if_name,
413 addr,
414 plen);
415 break;
416 }
417 case KEV_INET6_ADDR_DELETED : {
418 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
419 CFSTR("%s kernel event: %s: IPv6 address removed"),
420 elapsed(),
421 if_name);
422 break;
423 }
424 default :
425 break;
426 }
427 break;
428 }
429 default :
430 break;
431 }
432 break;
433 }
434 default :
435 break;
436 }
437 break;
438 default :
439 /* unrecognized vendor code */
440 break;
441 }
442 offset += ev_msg->total_size;
443 ev_msg = (struct kern_event_msg *)(void *)&buf.bytes[offset];
444 }
445
446 return;
447 }
448
449
450 static void
451 add_KernelEvent_notification()
452 {
453 CFSocketRef es;
454 CFSocketContext es_context = { 0, NULL, NULL, NULL, NULL };
455 struct kev_request kev_req;
456 CFRunLoopSourceRef rls;
457 int so;
458 int yes = 1;
459
460 /* Open an event socket */
461 so = socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT);
462 if (so == -1) {
463 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("socket() failed"));
464 return;
465 }
466
467 /* establish filter to return all events */
468 kev_req.vendor_code = KEV_VENDOR_APPLE;
469 kev_req.kev_class = KEV_NETWORK_CLASS;
470 kev_req.kev_subclass = KEV_ANY_SUBCLASS;
471 if (ioctl(so, SIOCSKEVFILT, &kev_req) == -1) {
472 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("ioctl(, SIOCSKEVFILT, ) failed"));
473 (void)close(so);
474 return;
475 }
476
477 if (ioctl(so, FIONBIO, &yes) == -1) {
478 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("ioctl(, FIONBIO, ) failed"));
479 (void)close(so);
480 return;
481 }
482
483 /* Create a CFSocketRef for the PF_SYSTEM kernel event socket */
484 es = CFSocketCreateWithNative(NULL,
485 so,
486 kCFSocketReadCallBack,
487 KernelEvent_notification,
488 &es_context);
489
490 /* Create and add a run loop source for the event socket */
491 rls = CFSocketCreateRunLoopSource(NULL, es, -1);
492 CFRelease(es);
493
494 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
495 CFRelease(rls);
496
497 return;
498 }
499
500
501 #pragma mark -
502 #pragma mark Power Management Events
503
504
505 static void
506 power_notification(void *refcon, io_service_t service, natural_t messageType, void *messageArgument)
507 {
508 switch (messageType) {
509 case kIOMessageCanDevicePowerOff :
510 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
511 CFSTR("%s IORegisterForSystemPower: can device power off?"),
512 elapsed());
513 break;
514 case kIOMessageDeviceWillPowerOff :
515 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
516 CFSTR("%s IORegisterForSystemPower: device will power off"),
517 elapsed());
518 break;
519 case kIOMessageDeviceWillNotPowerOff :
520 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
521 CFSTR("%s IORegisterForSystemPower: device will not power off"),
522 elapsed());
523 break;
524 case kIOMessageDeviceHasPoweredOn :
525 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
526 CFSTR("%s IORegisterForSystemPower: device has powered on"),
527 elapsed());
528 break;
529 case kIOMessageCanSystemPowerOff :
530 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
531 CFSTR("%s IORegisterForSystemPower: can system power off?"),
532 elapsed());
533 break;
534 case kIOMessageSystemWillPowerOff :
535 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
536 CFSTR("%s IORegisterForSystemPower: system will power off"),
537 elapsed());
538 break;
539 case kIOMessageSystemWillNotPowerOff :
540 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
541 CFSTR("%s IORegisterForSystemPower: system will not power off"),
542 elapsed());
543 break;
544 case kIOMessageCanSystemSleep :
545 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
546 CFSTR("%s IORegisterForSystemPower: can system sleep?"),
547 elapsed());
548 /*
549 * Idle sleep is about to kick in, but applications have
550 * a chance to allow sleep (by calling IOAllowPowerChange)
551 * or to prevent sleep (by calling IOCancelPowerChange).
552 */
553 IOAllowPowerChange(power, (long)messageArgument);
554 break;
555 case kIOMessageSystemWillSleep :
556 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
557 CFSTR("%s IORegisterForSystemPower: system will sleep"),
558 elapsed());
559 IOAllowPowerChange(power, (long)messageArgument);
560 break;
561 case kIOMessageSystemWillNotSleep :
562 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
563 CFSTR("%s IORegisterForSystemPower: system will not sleep"),
564 elapsed());
565 break;
566 case kIOMessageSystemHasPoweredOn :
567 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
568 CFSTR("%s IORegisterForSystemPower: system has powered on"),
569 elapsed());
570 break;
571 case kIOMessageSystemWillRestart :
572 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
573 CFSTR("%s IORegisterForSystemPower: system will restart"),
574 elapsed());
575 break;
576 case kIOMessageSystemWillPowerOn :
577 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
578 CFSTR("%s IORegisterForSystemPower: system will power on"),
579 elapsed());
580 break;
581 default :
582 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
583 CFSTR("%s IORegisterForSystemPower: message=%08lx"),
584 elapsed(),
585 (long unsigned int)messageType);
586 break;
587 }
588
589 return;
590 }
591
592
593 static void
594 add_power_notification()
595 {
596 io_object_t iterator;
597 IONotificationPortRef notify;
598
599 power = IORegisterForSystemPower(0, &notify, power_notification, &iterator);
600 if (power == MACH_PORT_NULL) {
601 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("IORegisterForSystemPower() failed"));
602 return;
603 }
604
605 CFRunLoopAddSource(CFRunLoopGetCurrent(),
606 IONotificationPortGetRunLoopSource(notify),
607 kCFRunLoopCommonModes);
608
609 return;
610 }
611
612
613 #ifdef kIOPMMessageSleepWakeUUIDChange
614 static void
615 wake_uuid_notification(void *refcon, io_service_t service, natural_t messageType, void *messageArgument)
616 {
617 CFStringRef wake_uuid = NULL;
618
619 if (messageType == kIOPMMessageSleepWakeUUIDChange) {
620 if (messageArgument == kIOPMMessageSleepWakeUUIDSet) {
621 wake_uuid = IORegistryEntryCreateCFProperty(service, CFSTR(kIOPMSleepWakeUUIDKey), NULL, 0);
622 }
623
624 if (wake_uuid != NULL) {
625 char uuid[256];
626
627 _SC_cfstring_to_cstring(wake_uuid, uuid, sizeof(uuid), kCFStringEncodingUTF8);
628 asl_set(log_msg, MSGTRACER_KEY_DOMAIN, MY_MSGTRACER_DOMAIN);
629 asl_set(log_msg, MSGTRACER_KEY_UUID , uuid);
630
631 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
632 CFSTR("%s wake UUID notification: UUID set (%@)"),
633 elapsed(),
634 wake_uuid);
635
636 CFRelease(wake_uuid);
637 } else {
638 asl_unset(log_msg, MSGTRACER_KEY_DOMAIN);
639 asl_unset(log_msg, MSGTRACER_KEY_UUID);
640
641 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
642 CFSTR("%s wake UUID notification: UUID not set"),
643 elapsed());
644 }
645 }
646
647 return;
648 }
649
650
651 static void
652 add_wake_uuid_notification()
653 {
654 kern_return_t kr;
655 io_object_t notification = IO_OBJECT_NULL;
656 IONotificationPortRef notifyPort;
657 io_service_t service;
658
659 notifyPort = IONotificationPortCreate(kIOMasterPortDefault);
660 service = IORegistryEntryFromPath(kIOMasterPortDefault,
661 kIOPowerPlane ":/IOPowerConnection/IOPMrootDomain");
662 kr = IOServiceAddInterestNotification(notifyPort,
663 service,
664 kIOGeneralInterest,
665 wake_uuid_notification,
666 NULL, // refCon
667 &notification);
668 if (kr != KERN_SUCCESS) {
669 SCLOG(NULL, NULL, ASL_LEVEL_ERR,
670 CFSTR("IOServiceAddInterestNotification() failed, kr=0x%x"),
671 kr);
672 return;
673 }
674
675 CFRunLoopAddSource(CFRunLoopGetCurrent(),
676 IONotificationPortGetRunLoopSource(notifyPort),
677 kCFRunLoopDefaultMode);
678
679 wake_uuid_notification(NULL,
680 service,
681 kIOPMMessageSleepWakeUUIDChange,
682 kIOPMMessageSleepWakeUUIDSet);
683
684 return;
685 }
686 #endif // kIOPMMessageSleepWakeUUIDChange
687
688
689 #pragma mark -
690 #pragma mark SCDynamicStore "network" Events
691
692
693 static void
694 NetworkChange_notification(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
695 {
696 CFIndex i;
697 CFIndex nk;
698 CFMutableStringRef str;
699
700 str = CFStringCreateMutable(NULL, 0);
701 CFStringAppendFormat(str,
702 NULL,
703 CFSTR("%s SCDynamicStore \"network\" notification"),
704 elapsed());
705
706 nk = CFArrayGetCount(changedKeys);
707 for (i = 0; i < nk; i++) {
708 CFArrayRef components;
709 CFStringRef key;
710 CFIndex nc;
711
712 key = CFArrayGetValueAtIndex(changedKeys, i);
713
714 components = CFStringCreateArrayBySeparatingStrings(NULL, key, CFSTR("/"));
715 if (components == NULL) {
716 CFStringAppendFormat(str, NULL, CFSTR("\n%@"), key);
717 continue;
718 }
719
720 nc = CFArrayGetCount(components);
721 switch (nc) {
722 case 5 : {
723 CFStringRef entity_id;
724
725 entity_id = CFArrayGetValueAtIndex(components, 4);
726 if (CFEqual(entity_id, kSCEntNetLink)) {
727 CFDictionaryRef dict;
728 const char *val = "?";
729
730 dict = SCDynamicStoreCopyValue(store, key);
731 if (dict != NULL) {
732 CFBooleanRef link;
733
734 link = CFDictionaryGetValue(dict, kSCPropNetLinkActive);
735 if (link != NULL) {
736 val = CFBooleanGetValue(link) ? "up" : "down";
737 }
738
739 CFRelease(dict);
740 }
741 CFStringAppendFormat(str, NULL, CFSTR("\n%@ (%s)"), key, val);
742 } else if (CFEqual(entity_id, kSCEntNetIPv4) ||
743 CFEqual(entity_id, kSCEntNetIPv6) ||
744 CFEqual(entity_id, kSCEntNetDNS)) {
745 CFDictionaryRef dict;
746
747 dict = SCDynamicStoreCopyValue(store, key);
748 if (dict != NULL) {
749 CFStringRef val;
750
751 val = _SCCopyDescription(dict, NULL);
752 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : %@"), key, val);
753 CFRelease(val);
754 CFRelease(dict);
755 } else {
756 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : removed"), key);
757 }
758 } else if (CFEqual(entity_id, kSCEntNetAirPort)) {
759 CFDictionaryRef dict;
760
761 dict = SCDynamicStoreCopyValue(store, key);
762 if (dict != NULL) {
763 CFStringRef ssid_str;
764
765 ssid_str = CFDictionaryGetValue(dict, CFSTR("SSID_STR"));
766 if (ssid_str != NULL) {
767 CFDataRef bssid;
768
769 bssid = CFDictionaryGetValue(dict, CFSTR("BSSID"));
770 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : SSID: %@ BSSID: %s"),
771 key,
772 ssid_str,
773 (bssid != NULL) ? ether_ntoa((struct ether_addr *)CFDataGetBytePtr(bssid)) : "<unknown>");
774 } else {
775 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : no SSID"), key);
776 }
777 CFRelease(dict);
778 } else {
779 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : removed"), key);
780 }
781 } else if (CFEqual(entity_id, kSCEntNetService)) {
782 CFDictionaryRef dict;
783 CFStringRef rank = kSCNetworkServicePrimaryRankDefault;
784
785 dict = SCDynamicStoreCopyValue(store, key);
786 if ((dict == NULL) ||
787 !CFDictionaryGetValueIfPresent(dict,
788 kSCPropNetServicePrimaryRank,
789 (const void **)&rank)) {
790 rank = kSCNetworkServicePrimaryRankDefault;
791 }
792 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : Rank = %@"), key, rank);
793 if (dict != NULL) CFRelease(dict);
794 } else {
795 CFStringAppendFormat(str, NULL, CFSTR("\n%@"), key);
796 }
797 break;
798 }
799
800 case 4 : {
801 static CFStringRef rank_setup_prefix = NULL;
802 static CFStringRef rank_state_prefix = NULL;
803
804 if (rank_setup_prefix == NULL) {
805 rank_setup_prefix = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
806 kSCDynamicStoreDomainSetup,
807 CFSTR(""),
808 NULL);
809 rank_state_prefix = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
810 kSCDynamicStoreDomainState,
811 CFSTR(""),
812 NULL);
813 }
814
815 if (CFStringHasPrefix(key, rank_setup_prefix) ||
816 CFStringHasPrefix(key, rank_state_prefix)) {
817 CFDictionaryRef dict;
818 CFStringRef rank = kSCNetworkServicePrimaryRankDefault;
819
820 dict = SCDynamicStoreCopyValue(store, key);
821 if ((dict == NULL) ||
822 !CFDictionaryGetValueIfPresent(dict,
823 kSCPropNetServicePrimaryRank,
824 (const void **)&rank)) {
825 rank = kSCNetworkServicePrimaryRankDefault;
826 }
827 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : Rank = %@"), key, rank);
828 if (dict != NULL) CFRelease(dict);
829 } else {
830 CFStringAppendFormat(str, NULL, CFSTR("\n%@"), key);
831 }
832 break;
833 }
834
835 case 2 :
836 if (CFEqual(CFArrayGetValueAtIndex(components, 1),
837 CFSTR(kIOPMSystemPowerCapabilitiesKeySuffix))) {
838 CFNumberRef num;
839
840 num = SCDynamicStoreCopyValue(store, key);
841 if (num != NULL) {
842 IOPMSystemPowerStateCapabilities capabilities;
843
844 if (isA_CFNumber(num) &&
845 CFNumberGetValue(num, kCFNumberSInt32Type, &capabilities)) {
846 CFStringAppendFormat(str, NULL, CFSTR("\n%@ (0x%x)"), key, capabilities);
847 }
848
849 CFRelease(num);
850 }
851 } else {
852 CFStringAppendFormat(str, NULL, CFSTR("\n%@"), key);
853 }
854 break;
855
856 default :
857 CFStringAppendFormat(str, NULL, CFSTR("\n%@"), key);
858 break;
859 }
860
861 CFRelease(components);
862 }
863
864 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO, CFSTR("%@"), str);
865 CFRelease(str);
866 return;
867 }
868
869
870 static void
871 add_NetworkChange_keys(CFMutableArrayRef keys,
872 CFMutableArrayRef patterns,
873 CFStringRef entity,
874 Boolean doGlobal,
875 Boolean doService,
876 Boolean doInterface)
877 {
878 CFStringRef key;
879 CFStringRef pattern;
880
881 if (doGlobal) {
882 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainSetup, entity);
883 CFArrayAppendValue(keys, key);
884 CFRelease(key);
885
886 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, entity);
887 CFArrayAppendValue(keys, key);
888 CFRelease(key);
889 }
890
891 if (doService) {
892 pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, kSCCompAnyRegex, entity);
893 CFArrayAppendValue(patterns, pattern);
894 CFRelease(pattern);
895
896 pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, entity);
897 CFArrayAppendValue(patterns, pattern);
898 CFRelease(pattern);
899 }
900
901 if (doInterface) {
902 pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, entity);
903 CFArrayAppendValue(patterns, pattern);
904 CFRelease(pattern);
905 }
906
907 return;
908 }
909
910
911 static void
912 add_NetworkChange_notification()
913 {
914 CFStringRef dns_key;
915 CFStringRef key;
916 CFMutableArrayRef keys;
917 Boolean ok;
918 CFMutableArrayRef patterns;
919 SCDynamicStoreRef store;
920 CFRunLoopSourceRef rls;
921
922 store = SCDynamicStoreCreate(NULL, CFSTR("Logger.bundle-NetworkChange"), NetworkChange_notification, NULL);
923 if (store == NULL) {
924 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreate() failed"));
925 return;
926 }
927
928 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
929 patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
930
931 // Interface list
932
933 key = SCDynamicStoreKeyCreateNetworkInterface(NULL, kSCDynamicStoreDomainState);
934 CFArrayAppendValue(keys, key);
935 CFRelease(key);
936
937 // IPv4
938
939 add_NetworkChange_keys(keys, patterns, kSCEntNetIPv4, TRUE, TRUE, TRUE);
940
941 // IPv6
942
943 add_NetworkChange_keys(keys, patterns, kSCEntNetIPv6, TRUE, TRUE, TRUE);
944
945 // PPP, VPN
946
947 add_NetworkChange_keys(keys, patterns, kSCEntNetPPP, FALSE, TRUE, TRUE);
948 add_NetworkChange_keys(keys, patterns, kSCEntNetVPN, FALSE, TRUE, TRUE);
949 add_NetworkChange_keys(keys, patterns, kSCEntNetL2TP, FALSE, TRUE, TRUE);
950 add_NetworkChange_keys(keys, patterns, kSCEntNetPPTP, FALSE, TRUE, TRUE);
951 add_NetworkChange_keys(keys, patterns, kSCEntNetIPSec, FALSE, TRUE, TRUE);
952
953 // Link
954
955 add_NetworkChange_keys(keys, patterns, kSCEntNetLink, FALSE, FALSE, TRUE);
956
957 // AirPort (e.g. BSSID)
958
959 add_NetworkChange_keys(keys, patterns, kSCEntNetAirPort, FALSE, FALSE, TRUE);
960
961 // DNS
962
963 add_NetworkChange_keys(keys, patterns, kSCEntNetDNS, TRUE, TRUE, TRUE);
964
965 dns_key = CFStringCreateWithCString(NULL,
966 dns_configuration_notify_key(),
967 kCFStringEncodingASCII);
968 key = CFStringCreateWithFormat(NULL, NULL, CFSTR("Notify:%@"), dns_key);
969 CFRelease(dns_key);
970 CFArrayAppendValue(keys, key);
971 CFRelease(key);
972
973 // Proxies
974
975 key = SCDynamicStoreKeyCreateProxies(NULL);
976 CFArrayAppendValue(keys, key);
977 CFRelease(key);
978
979 // Rank
980
981 add_NetworkChange_keys(keys, patterns, NULL, FALSE, TRUE, FALSE); // per-service
982 add_NetworkChange_keys(keys, patterns, kSCEntNetService, FALSE, FALSE, TRUE); // per-interface
983
984 // ComputerName, LocalHostName
985
986 key = SCDynamicStoreKeyCreateComputerName(NULL);
987 CFArrayAppendValue(keys, key);
988 CFRelease(key);
989
990 key = SCDynamicStoreKeyCreateHostNames(NULL);
991 CFArrayAppendValue(keys, key);
992 CFRelease(key);
993
994 // Power Management
995
996 key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@%@"),
997 kSCDynamicStoreDomainState,
998 CFSTR(kIOPMSystemPowerCapabilitiesKeySuffix));
999 CFArrayAppendValue(keys, key);
1000 CFRelease(key);
1001
1002
1003 // Setup monitoring
1004
1005 ok = SCDynamicStoreSetNotificationKeys(store, keys, patterns);
1006 CFRelease(keys);
1007 CFRelease(patterns);
1008 if (!ok) {
1009 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed"));
1010 CFRelease(store);
1011 return;
1012 }
1013
1014 rls = SCDynamicStoreCreateRunLoopSource(NULL, store, -1);
1015 if (rls == NULL) {
1016 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1017 CFRelease(store);
1018 return;
1019 }
1020 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1021 CFRelease(rls);
1022
1023 CFRelease(store);
1024 return;
1025 }
1026
1027
1028 static void
1029 PrimaryService_notification(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
1030 {
1031 CFDictionaryRef entity;
1032 CFStringRef key;
1033 static CFStringRef oldPrimary = NULL;
1034 CFStringRef newPrimary = NULL;
1035
1036 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4);
1037 entity = SCDynamicStoreCopyValue(store, key);
1038 CFRelease(key);
1039 if (isA_CFDictionary(entity) &&
1040 CFDictionaryGetValueIfPresent(entity,
1041 kSCDynamicStorePropNetPrimaryService,
1042 (const void **)&newPrimary) &&
1043 isA_CFString(newPrimary)) {
1044 CFRetain(newPrimary);
1045 } else {
1046 newPrimary = NULL;
1047 }
1048
1049 if (!_SC_CFEqual(oldPrimary, newPrimary)) {
1050 if (newPrimary != NULL) {
1051 CFStringRef newInterface;
1052
1053 newInterface = CFDictionaryGetValue(entity, kSCDynamicStorePropNetPrimaryInterface);
1054 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1055 CFSTR("%s Primary service: %@ (%@)"),
1056 elapsed(),
1057 newPrimary,
1058 newInterface != NULL ? newInterface : CFSTR("?"));
1059 } else {
1060 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1061 CFSTR("%s Primary service: removed"),
1062 elapsed());
1063 }
1064 }
1065
1066 if (oldPrimary != NULL) CFRelease(oldPrimary);
1067 oldPrimary = newPrimary;
1068
1069 if (entity != NULL) CFRelease(entity);
1070 return;
1071 }
1072
1073
1074 static void
1075 add_PrimaryService_notification()
1076 {
1077 CFStringRef key;
1078 CFMutableArrayRef keys;
1079 Boolean ok;
1080 SCDynamicStoreRef store;
1081 CFRunLoopSourceRef rls;
1082
1083 store = SCDynamicStoreCreate(NULL, CFSTR("Logger.bundle-PrimaryService"), PrimaryService_notification, NULL);
1084 if (store == NULL) {
1085 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreate() failed"));
1086 return;
1087 }
1088
1089 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1090 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4);
1091 CFArrayAppendValue(keys, key);
1092 CFRelease(key);
1093
1094 ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL);
1095 CFRelease(keys);
1096 if (!ok) {
1097 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed"));
1098 CFRelease(store);
1099 return;
1100 }
1101
1102 rls = SCDynamicStoreCreateRunLoopSource(NULL, store, -1);
1103 if (rls == NULL) {
1104 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1105 CFRelease(store);
1106 return;
1107 }
1108 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1109 CFRelease(rls);
1110
1111 CFRelease(store);
1112 return;
1113 }
1114
1115
1116 #pragma mark -
1117 #pragma mark Reachability Events
1118
1119
1120 static void
1121 reachability_notification(SCNetworkReachabilityRef ref, SCNetworkReachabilityFlags flags, void *info)
1122 {
1123 CFStringRef hostname = (CFStringRef)info;
1124
1125 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1126 CFSTR("%s reachability changed: %@: flags=0x%08x"),
1127 elapsed(),
1128 hostname,
1129 flags);
1130 return;
1131 }
1132
1133
1134 static void
1135 add_reachability_notification(CFArrayRef hosts)
1136 {
1137 SCNetworkReachabilityContext context = { 0, NULL, CFRetain, CFRelease, CFCopyDescription };
1138 CFIndex i;
1139 CFIndex n;
1140 SCNetworkReachabilityRef target;
1141
1142 struct watch {
1143 in_addr_t addr;
1144 CFStringRef name;
1145 } watchAddresses[] = { { 0, CFSTR("0.0.0.0") },
1146 { IN_LINKLOCALNETNUM, CFSTR("169.254.0.0") },
1147 { (u_int32_t)0xe00000fb, CFSTR("224.0.0.251") },
1148 };
1149
1150 for (i = 0; i < sizeof(watchAddresses)/sizeof(watchAddresses[0]); i++) {
1151 struct sockaddr_in sin;
1152
1153 bzero(&sin, sizeof(sin));
1154 sin.sin_len = sizeof(sin);
1155 sin.sin_family = AF_INET;
1156 sin.sin_addr.s_addr = htonl(watchAddresses[i].addr);
1157
1158 target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin);
1159 if (target == NULL) {
1160 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCNetworkReachabilityCreateWithAddress() failed"));
1161 return;
1162 }
1163
1164 context.info = (void *)watchAddresses[i].name;
1165 if (!SCNetworkReachabilitySetCallback(target, reachability_notification, &context)) {
1166 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCNetworkReachabilitySetCallback() failed"));
1167 CFRelease(target);
1168 return;
1169 }
1170
1171 if (!SCNetworkReachabilityScheduleWithRunLoop(target, CFRunLoopGetCurrent(), kCFRunLoopCommonModes)) {
1172 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCNetworkReachabilityScheduleWithRunLoop() failed"));
1173 CFRelease(target);
1174 return;
1175 }
1176
1177 CFRelease(target);
1178 }
1179
1180 n = (hosts != NULL) ? CFArrayGetCount(hosts) : 0;
1181 for (i = 0; i < n; i++) {
1182 CFStringRef host;
1183 char *nodename;
1184
1185 host = CFArrayGetValueAtIndex(hosts, i);
1186 if (!isA_CFString(host) || (CFStringGetLength(host) == 0)) {
1187 continue;
1188 }
1189
1190 nodename = _SC_cfstring_to_cstring(host, NULL, 0, kCFStringEncodingUTF8);
1191 target = SCNetworkReachabilityCreateWithName(NULL, nodename);
1192 CFAllocatorDeallocate(NULL, nodename);
1193 if (target == NULL) {
1194 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCNetworkReachabilityCreateWithName() failed"));
1195 return;
1196 }
1197
1198 context.info = (void *)host;
1199 if (!SCNetworkReachabilitySetCallback(target, reachability_notification, &context)) {
1200 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCNetworkReachabilitySetCallback() failed"));
1201 CFRelease(target);
1202 return;
1203 }
1204
1205 if (!SCNetworkReachabilityScheduleWithRunLoop(target, CFRunLoopGetCurrent(), kCFRunLoopCommonModes)) {
1206 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCNetworkReachabilityScheduleWithRunLoop() failed"));
1207 CFRelease(target);
1208 return;
1209 }
1210
1211 CFRelease(target);
1212 }
1213
1214 return;
1215 }
1216
1217
1218 #pragma mark -
1219 #pragma mark Console User/Information Events
1220
1221
1222 #if !TARGET_OS_EMBEDDED
1223 static void
1224 console_notification(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
1225 {
1226 gid_t gid;
1227 CFArrayRef info;
1228 CFMutableStringRef str = CFStringCreateMutable(NULL, 0);
1229 uid_t uid;
1230 CFStringRef user;
1231
1232 CFStringAppendFormat(str,
1233 NULL,
1234 CFSTR("%s SCDynamicStore console notification"),
1235 elapsed());
1236
1237 user = SCDynamicStoreCopyConsoleUser(store, &uid, &gid);
1238 if (user != NULL) {
1239 CFStringAppendFormat(str, NULL, CFSTR("\nconsole user = %@"), user);
1240 CFRelease(user);
1241 } else {
1242 CFStringAppendFormat(str, NULL, CFSTR("\nno console user"));
1243 }
1244
1245 info = SCDynamicStoreCopyConsoleInformation(store);
1246 if (info != NULL) {
1247 CFIndex i;
1248 CFIndex n;
1249
1250 n = CFArrayGetCount(info);
1251 for (i = 0; i < n; i++) {
1252 CFDictionaryRef session;
1253 CFNumberRef sessionID;
1254 CFStringRef sessionUserName;
1255 CFBooleanRef sessionOnConsole;
1256
1257 session = CFArrayGetValueAtIndex(info, i);
1258 sessionID = CFDictionaryGetValue(session, kSCConsoleSessionID);
1259 sessionUserName = CFDictionaryGetValue(session, kSCConsoleSessionUserName);
1260 sessionOnConsole = CFDictionaryGetValue(session, kSCConsoleSessionOnConsole);
1261
1262 CFStringAppendFormat(str, NULL, CFSTR("\n%ld : id=%@, user=%@, console=%s"),
1263 i,
1264 sessionID,
1265 sessionUserName != NULL ? sessionUserName : CFSTR("?"),
1266 sessionOnConsole != NULL ? CFBooleanGetValue(sessionOnConsole) ? "yes" : "no" : "?");
1267 }
1268
1269 CFRelease(info);
1270 }
1271
1272 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO, CFSTR("%@"), str);
1273 CFRelease(str);
1274 return;
1275 }
1276
1277
1278 static void
1279 add_console_notification()
1280 {
1281 CFStringRef key;
1282 CFMutableArrayRef keys;
1283 Boolean ok;
1284 SCDynamicStoreRef store;
1285 CFRunLoopSourceRef rls;
1286
1287 store = SCDynamicStoreCreate(NULL, CFSTR("Logger.bundle-console"), console_notification, NULL);
1288 if (store == NULL) {
1289 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreate() failed"));
1290 return;
1291 }
1292
1293 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1294
1295 key = SCDynamicStoreKeyCreateConsoleUser(NULL);
1296 CFArrayAppendValue(keys, key);
1297 CFRelease(key);
1298
1299 ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL);
1300 CFRelease(keys);
1301 if (!ok) {
1302 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed"));
1303 CFRelease(store);
1304 return;
1305 }
1306
1307 rls = SCDynamicStoreCreateRunLoopSource(NULL, store, -1);
1308 if (rls == NULL) {
1309 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1310 CFRelease(store);
1311 return;
1312 }
1313 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1314 CFRelease(rls);
1315
1316 CFRelease(store);
1317 return;
1318 }
1319 #endif // !TARGET_OS_EMBEDDED
1320
1321
1322 #pragma mark -
1323 #pragma mark Directory Services Events
1324
1325
1326 //#include <DirectoryServices/DirServicesPriv.h>
1327 #ifndef kDSStdNotifySearchPolicyChanged
1328 #define kDSStdNotifySearchPolicyChanged "com.apple.DirectoryService.NotifyTypeStandard:SearchPolicyChanged"
1329 #endif
1330
1331
1332 #if !TARGET_OS_EMBEDDED
1333 static void
1334 directoryServices_notification(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
1335 {
1336 CFIndex i;
1337 CFIndex n;
1338 CFMutableStringRef str = CFStringCreateMutable(NULL, 0);
1339
1340 CFStringAppendFormat(str,
1341 NULL,
1342 CFSTR("%s SCDynamicStore DirectoryServices notification"),
1343 elapsed());
1344
1345 n = CFArrayGetCount(changedKeys);
1346 for (i = 0; i < n; i++) {
1347 CFStringRef key;
1348
1349 key = CFArrayGetValueAtIndex(changedKeys, i);
1350 CFStringAppendFormat(str, NULL, CFSTR("\n%@"), key);
1351 }
1352
1353 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO, CFSTR("%@"), str);
1354 CFRelease(str);
1355 return;
1356 }
1357
1358
1359 static void
1360 add_DirectoryServices_notification()
1361 {
1362 CFStringRef key;
1363 CFMutableArrayRef keys;
1364 Boolean ok;
1365 SCDynamicStoreRef store;
1366 CFRunLoopSourceRef rls;
1367
1368 store = SCDynamicStoreCreate(NULL, CFSTR("Logger.bundle-directoryServices"), directoryServices_notification, NULL);
1369 if (store == NULL) {
1370 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreate() failed"));
1371 return;
1372 }
1373
1374 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1375
1376 key = CFSTR(kDSStdNotifySearchPolicyChanged);
1377 CFArrayAppendValue(keys, key);
1378 // CFRelease(key);
1379
1380 ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL);
1381 CFRelease(keys);
1382 if (!ok) {
1383 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed"));
1384 CFRelease(store);
1385 return;
1386 }
1387
1388 rls = SCDynamicStoreCreateRunLoopSource(NULL, store, -1);
1389 if (rls == NULL) {
1390 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1391 CFRelease(store);
1392 return;
1393 }
1394 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1395 CFRelease(rls);
1396
1397 CFRelease(store);
1398 return;
1399 }
1400 #endif // !TARGET_OS_EMBEDDED
1401
1402
1403 #pragma mark -
1404 #pragma mark DNS Configuration Events
1405
1406
1407 static void
1408 dnsinfo_notification(CFMachPortRef port, void *msg, CFIndex size, void *info)
1409 {
1410 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1411 CFSTR("%s dnsinfo notification"),
1412 elapsed());
1413
1414 return;
1415 }
1416
1417
1418 static void
1419 add_dnsinfo_notification()
1420 {
1421 const char *key;
1422 CFMachPortRef mp;
1423 mach_port_t notify_port;
1424 int notify_token;
1425 CFRunLoopSourceRef rls;
1426 uint32_t status;
1427
1428 key = dns_configuration_notify_key();
1429 status = notify_register_mach_port(key, &notify_port, 0, &notify_token);
1430 if (status != NOTIFY_STATUS_OK) {
1431 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("notify_register_mach_port() failed"));
1432 return;
1433 }
1434
1435 mp = _SC_CFMachPortCreateWithPort("Logger/dns_configuration", notify_port, dnsinfo_notification, NULL);
1436 if (mp == NULL) {
1437 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("CFMachPortCreateWithPort() failed"));
1438 (void)notify_cancel(notify_token);
1439 return;
1440 }
1441
1442 rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
1443 if (rls == NULL) {
1444 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1445 CFRelease(mp);
1446 (void)notify_cancel(notify_token);
1447 return;
1448 }
1449 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1450 CFRelease(rls);
1451
1452 CFRelease(mp);
1453 return;
1454 }
1455
1456
1457 #pragma mark -
1458 #pragma mark Network Information Events
1459
1460
1461 static void
1462 nwi_notification(CFMachPortRef port, void *msg, CFIndex size, void *info)
1463 {
1464 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1465 CFSTR("%s network_information notification"),
1466 elapsed());
1467
1468 return;
1469 }
1470
1471
1472 static void
1473 add_nwi_notification()
1474 {
1475 const char *key;
1476 CFMachPortRef mp;
1477 mach_port_t notify_port;
1478 int notify_token;
1479 CFRunLoopSourceRef rls;
1480 uint32_t status;
1481
1482 key = nwi_state_get_notify_key();
1483 status = notify_register_mach_port(key, &notify_port, 0, &notify_token);
1484 if (status != NOTIFY_STATUS_OK) {
1485 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("notify_register_mach_port() failed"));
1486 return;
1487 }
1488
1489 mp = _SC_CFMachPortCreateWithPort("Logger/nwi", notify_port, nwi_notification, NULL);
1490 if (mp == NULL) {
1491 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("CFMachPortCreateWithPort() failed"));
1492 (void)notify_cancel(notify_token);
1493 return;
1494 }
1495
1496 rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
1497 if (rls == NULL) {
1498 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1499 CFRelease(mp);
1500 (void)notify_cancel(notify_token);
1501 return;
1502 }
1503 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1504 CFRelease(rls);
1505
1506 CFRelease(mp);
1507 return;
1508 }
1509
1510
1511 #pragma mark -
1512 #pragma mark Network Configuration Change Events
1513
1514
1515 static void
1516 network_notification(CFMachPortRef port, void *msg, CFIndex size, void *info)
1517 {
1518 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1519 CFSTR("%s network_change notification"),
1520 elapsed());
1521
1522 return;
1523 }
1524
1525
1526 static void
1527 add_network_notification()
1528 {
1529 CFMachPortRef mp;
1530 mach_port_t notify_port;
1531 int notify_token;
1532 CFRunLoopSourceRef rls;
1533 uint32_t status;
1534
1535 status = notify_register_mach_port(_SC_NOTIFY_NETWORK_CHANGE,
1536 &notify_port,
1537 0,
1538 &notify_token);
1539 if (status != NOTIFY_STATUS_OK) {
1540 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("notify_register_mach_port() failed"));
1541 return;
1542 }
1543
1544 mp = _SC_CFMachPortCreateWithPort("Logger/network_change", notify_port, network_notification, NULL);
1545 if (mp == NULL) {
1546 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("CFMachPortCreateWithPort() failed"));
1547 (void)notify_cancel(notify_token);
1548 return;
1549 }
1550
1551 rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
1552 if (rls == NULL) {
1553 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1554 CFRelease(mp);
1555 (void)notify_cancel(notify_token);
1556 return;
1557 }
1558 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1559 CFRelease(rls);
1560
1561 CFRelease(mp);
1562 return;
1563 }
1564
1565
1566 #pragma mark -
1567 #pragma mark SMB Configuration Events
1568
1569
1570 #define SMBCONFIGURATION_NOTIFY_KEY "com.apple.system.SystemConfiguration.smb_configuration"
1571
1572
1573 #if !TARGET_OS_EMBEDDED
1574 static void
1575 smbconf_notification(CFMachPortRef port, void *msg, CFIndex size, void *info)
1576 {
1577 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO,
1578 CFSTR("%s smb.conf notification"),
1579 elapsed());
1580
1581 return;
1582 }
1583
1584
1585 static void
1586 add_smbconf_notification()
1587 {
1588 CFMachPortRef mp;
1589 mach_port_t notify_port;
1590 int notify_token;
1591 CFRunLoopSourceRef rls;
1592 uint32_t status;
1593
1594 status = notify_register_mach_port(SMBCONFIGURATION_NOTIFY_KEY,
1595 &notify_port,
1596 0,
1597 &notify_token);
1598 if (status != NOTIFY_STATUS_OK) {
1599 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("notify_register_mach_port() failed"));
1600 return;
1601 }
1602
1603 mp = _SC_CFMachPortCreateWithPort("Logger/smb_configuration", notify_port, smbconf_notification, NULL);
1604 if (mp == NULL) {
1605 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("CFMachPortCreateWithPort() failed"));
1606 (void)notify_cancel(notify_token);
1607 return;
1608 }
1609
1610 rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
1611 if (rls == NULL) {
1612 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1613 CFRelease(mp);
1614 (void)notify_cancel(notify_token);
1615 return;
1616 }
1617 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1618 CFRelease(rls);
1619
1620 CFRelease(mp);
1621 return;
1622 }
1623 #endif // !TARGET_OS_EMBEDDED
1624
1625
1626 #pragma mark -
1627 #pragma mark pututxline Events
1628
1629
1630 #if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) && !TARGET_OS_EMBEDDED
1631 static const char *
1632 ut_time(struct utmpx *utmpx)
1633 {
1634 static char str[16];
1635 struct tm tm;
1636
1637 (void)localtime_r(&utmpx->ut_tv.tv_sec, &tm);
1638 snprintf(str, sizeof(str), "%2d:%02d:%02d.%03d",
1639 tm.tm_hour,
1640 tm.tm_min,
1641 tm.tm_sec,
1642 utmpx->ut_tv.tv_usec / 1000);
1643
1644 return str;
1645 }
1646
1647
1648 static const char *
1649 ut_id(struct utmpx *utmpx)
1650 {
1651 char *cp;
1652 static char str[16];
1653
1654 cp = utmpx->ut_id + sizeof(utmpx->ut_id);
1655 while(--cp >= utmpx->ut_id && isprint(*cp)) {}
1656 if(cp < utmpx->ut_id) {
1657 snprintf(str, sizeof(str), "%-4.4s", utmpx->ut_id);
1658 } else {
1659 snprintf(str, sizeof(str),
1660 "0x%2.2x%2.2x%2.2x%2.2x",
1661 utmpx->ut_id[0],
1662 utmpx->ut_id[1],
1663 utmpx->ut_id[2],
1664 utmpx->ut_id[3]);
1665 }
1666
1667 return str;
1668 }
1669
1670
1671 static const char *
1672 ut_pid(struct utmpx *utmpx)
1673 {
1674 static char pid[16];
1675
1676 snprintf(pid, sizeof(pid), "%d", utmpx->ut_pid);
1677
1678 return pid;
1679 }
1680
1681
1682 static void
1683 pututxline_notification(CFMachPortRef port, void *msg, CFIndex size, void *info)
1684 {
1685 CFMutableStringRef str = CFStringCreateMutable(NULL, 0);
1686 struct utmpx *utmpx;
1687 utmpx_t utx;
1688
1689 CFStringAppendFormat(str,
1690 NULL,
1691 CFSTR("%s pututxline notification"),
1692 elapsed());
1693
1694 utx = _openutx(NULL);
1695 while ((utmpx = _getutxent(utx)) != NULL) {
1696 const char * entry_id = NULL;
1697 const char * entry_line = NULL;
1698 const char * entry_pid = NULL;
1699 const char * entry_tv = NULL;
1700 const char * entry_type;
1701 const char * entry_user = NULL;
1702 char line[128];
1703 int n;
1704
1705 switch (utmpx->ut_type) {
1706 case BOOT_TIME : // Time of a system boot.
1707 entry_type = "Boot";
1708 entry_tv = ut_time(utmpx);
1709 break;
1710 case DEAD_PROCESS : // A session leader exited.
1711 entry_type = "Dead process";
1712 entry_id = ut_id (utmpx);
1713 entry_pid = ut_pid (utmpx);
1714 entry_tv = ut_time(utmpx);
1715 break;
1716 case EMPTY : // No valid user accounting information.
1717 continue;
1718 case INIT_PROCESS : // A process spawned by init(8).
1719 entry_type = "Init process";
1720 entry_id = ut_id (utmpx);
1721 entry_pid = ut_pid (utmpx);
1722 entry_tv = ut_time(utmpx);
1723 break;
1724 case LOGIN_PROCESS : // The session leader of a logged-in user.
1725 entry_type = "Login";
1726 entry_id = ut_id (utmpx);
1727 entry_user = utmpx->ut_user;
1728 entry_pid = ut_pid (utmpx);
1729 entry_tv = ut_time(utmpx);
1730 break;
1731 case NEW_TIME : // Time after system clock change.
1732 entry_type = "New time";
1733 entry_tv = ut_time(utmpx);
1734 break;
1735 case OLD_TIME : // Time before system clock change.
1736 entry_type = "Old time";
1737 entry_tv = ut_time(utmpx);
1738 break;
1739 case RUN_LVL : // Run level. Provided for compatibility, not used.
1740 entry_type = "Run level";
1741 break;
1742 case USER_PROCESS : // A user process.
1743 entry_type = "User Process";
1744 entry_id = ut_id (utmpx);
1745 entry_user = utmpx->ut_user;
1746 entry_line = utmpx->ut_line;
1747 entry_pid = ut_pid (utmpx);
1748 entry_tv = ut_time(utmpx);
1749 break;
1750 case SHUTDOWN_TIME : // Time of system shutdown
1751 entry_type = "Shutdown time";
1752 entry_tv = ut_time(utmpx);
1753 break;
1754 default :
1755 entry_type = "Unknown";
1756 break;
1757 }
1758
1759 snprintf(line, sizeof(line),
1760 // type time id=0x12345678 pid=12345 user=abcdefgh line
1761 "\n%-13s %2s%12s %3s%-10s %4s%-5s %5s%-8s %5s%s",
1762 entry_type,
1763 entry_tv != NULL ? "@ " : "",
1764 entry_tv != NULL ? entry_tv : "", // hh:mm:ss.ddd
1765 entry_id != NULL ? "id=" : "",
1766 entry_id != NULL ? entry_id : "", // 0x12345678
1767 entry_pid != NULL ? "pid=" : "",
1768 entry_pid != NULL ? entry_pid : "", // #####
1769 entry_user != NULL ? "user=" : "",
1770 entry_user != NULL ? entry_user : "", // <=256 chars
1771 entry_line != NULL ? "line=" : "",
1772 entry_line != NULL ? entry_line : "" // <= 32 chars
1773 );
1774
1775 n = strlen(line) - 1;
1776 while ((n > 0) && (line[n] == ' ')) {
1777 line[n] = '\0';
1778 --n;
1779 }
1780
1781 CFStringAppendFormat(str, NULL, CFSTR("%s"), line);
1782 }
1783 _endutxent(utx);
1784
1785 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO, CFSTR("%@"), str);
1786 CFRelease(str);
1787 return;
1788 }
1789
1790
1791 static void
1792 add_pututxline_notification()
1793 {
1794 CFMachPortRef mp;
1795 mach_port_t notify_port;
1796 int notify_token;
1797 CFRunLoopSourceRef rls;
1798 uint32_t status;
1799
1800 status = notify_register_mach_port(UTMPX_CHANGE_NOTIFICATION, &notify_port, 0, &notify_token);
1801 if (status != NOTIFY_STATUS_OK) {
1802 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("notify_register_mach_port() failed"));
1803 return;
1804 }
1805
1806 mp = _SC_CFMachPortCreateWithPort("Logger/utmpx", notify_port, pututxline_notification, NULL);
1807 if (mp == NULL) {
1808 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("CFMachPortCreateWithPort() failed"));
1809 (void)notify_cancel(notify_token);
1810 return;
1811 }
1812
1813 rls = CFMachPortCreateRunLoopSource(NULL, mp, -1);
1814 if (rls == NULL) {
1815 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1816 CFRelease(mp);
1817 (void)notify_cancel(notify_token);
1818 return;
1819 }
1820 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1821 CFRelease(rls);
1822
1823 CFRelease(mp);
1824 return;
1825 }
1826 #endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) && !TARGET_OS_EMBEDDED
1827
1828
1829 #pragma mark -
1830 #pragma mark BackToMyMac Status Events
1831
1832
1833 #ifndef kDSStdNotifyBTMMStatusChanged
1834 #define kDSStdNotifyBTMMStatusChanged "State:/Network/BackToMyMac"
1835 #endif
1836
1837
1838 #if !TARGET_OS_EMBEDDED
1839 static void
1840 BTMM_notification(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
1841 {
1842 CFIndex i;
1843 CFIndex n;
1844 CFMutableStringRef str = CFStringCreateMutable(NULL, 0);
1845
1846 CFStringAppendFormat(str,
1847 NULL,
1848 CFSTR("%s SCDynamicStore Back to My Mac notification"),
1849 elapsed());
1850
1851 n = CFArrayGetCount(changedKeys);
1852 for (i = 0; i < n; i++) {
1853 CFStringRef key;
1854 CFDictionaryRef dict;
1855
1856 key = CFArrayGetValueAtIndex(changedKeys, i);
1857 dict = SCDynamicStoreCopyValue(store, key);
1858 if (dict != NULL) {
1859 CFStringRef val;
1860
1861 val = _SCCopyDescription(dict, NULL);
1862 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : %@"), key, val);
1863 CFRelease(val);
1864 CFRelease(dict);
1865 } else {
1866 CFStringAppendFormat(str, NULL, CFSTR("\n%@ : removed"), key);
1867 }
1868 }
1869
1870 SCLOG(NULL, log_msg, ~ASL_LEVEL_INFO, CFSTR("%@"), str);
1871 CFRelease(str);
1872 return;
1873 }
1874
1875
1876 static void
1877 add_BTMM_notification()
1878 {
1879 CFStringRef key;
1880 CFMutableArrayRef keys;
1881 Boolean ok;
1882 SCDynamicStoreRef store;
1883 CFRunLoopSourceRef rls;
1884
1885 store = SCDynamicStoreCreate(NULL, CFSTR("Logger.bundle-BackToMyMac"), BTMM_notification, NULL);
1886 if (store == NULL) {
1887 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreate() failed"));
1888 return;
1889 }
1890
1891 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1892
1893 key = CFSTR(kDSStdNotifyBTMMStatusChanged);
1894 CFArrayAppendValue(keys, key);
1895
1896 ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL);
1897 CFRelease(keys);
1898 if (!ok) {
1899 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed"));
1900 CFRelease(store);
1901 return;
1902 }
1903
1904 rls = SCDynamicStoreCreateRunLoopSource(NULL, store, -1);
1905 if (rls == NULL) {
1906 SCLOG(NULL, NULL, ASL_LEVEL_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed"));
1907 CFRelease(store);
1908 return;
1909 }
1910 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
1911 CFRelease(rls);
1912
1913 CFRelease(store);
1914 return;
1915 }
1916 #endif // !TARGET_OS_EMBEDDED
1917
1918
1919 #pragma mark -
1920
1921
1922 static __inline__ Boolean
1923 bValFromDictionary(CFDictionaryRef dict, CFStringRef key)
1924 {
1925 CFBooleanRef bVal;
1926 Boolean result = FALSE;
1927
1928 if ((dict != NULL) &&
1929 CFDictionaryGetValueIfPresent(dict, key, (const void **)&bVal) &&
1930 isA_CFBoolean(bVal)) {
1931 result = CFBooleanGetValue(bVal);
1932 }
1933
1934 return result;
1935 }
1936
1937
1938 void
1939 load(CFBundleRef bundle, Boolean bundleVerbose)
1940 {
1941 CFDictionaryRef config;
1942 Boolean log_all;
1943
1944 verbose = bundleVerbose;
1945
1946 log_msg = asl_new(ASL_TYPE_MSG);
1947 asl_set(log_msg, ASL_KEY_FACILITY, MY_ASL_FACILITY);
1948
1949 elapsed();
1950
1951 config = CFBundleGetInfoDictionary(bundle);
1952 config = isA_CFDictionary(config);
1953 log_all = bValFromDictionary(config, CFSTR("LOG_ALL"));
1954
1955 #ifdef kIOPMMessageSleepWakeUUIDChange
1956 if (log_all || bValFromDictionary(config, CFSTR("LOG_IO_WAKEUUID_EVENTS"))) {
1957 add_wake_uuid_notification();
1958 }
1959 #endif // kIOPMMessageSleepWakeUUIDChange
1960
1961 if (log_all || bValFromDictionary(config, CFSTR("LOG_IO_SYSTEMPOWER_EVENTS"))) {
1962 add_power_notification();
1963 }
1964
1965 if (log_all || bValFromDictionary(config, CFSTR("LOG_NETWORK_KERNEL_EVENTS"))) {
1966 add_KernelEvent_notification();
1967 }
1968
1969 if (log_all || bValFromDictionary(config, CFSTR("LOG_NETWORK_INFORMATION"))) {
1970 add_nwi_notification();
1971 }
1972
1973 if (log_all || bValFromDictionary(config, CFSTR("LOG_NOTIFY_DNS_CONFIGURATION"))) {
1974 add_dnsinfo_notification();
1975 }
1976
1977 if (log_all || bValFromDictionary(config, CFSTR("LOG_NOTIFY_NETWORK_CHANGE"))) {
1978 add_network_notification();
1979 }
1980
1981 #if !TARGET_OS_EMBEDDED
1982 if (log_all || bValFromDictionary(config, CFSTR("LOG_NOTIFY_SMB_CONFIGURATION"))) {
1983 add_smbconf_notification();
1984 }
1985 #endif // !TARGET_OS_EMBEDDED
1986
1987 #if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) && !TARGET_OS_EMBEDDED
1988 if (log_all || bValFromDictionary(config, CFSTR("LOG_NOTIFY_UTMPX_CHANGE"))) {
1989 add_pututxline_notification();
1990 }
1991 #endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) && !TARGET_OS_EMBEDDED
1992
1993 #if !TARGET_OS_EMBEDDED
1994 if (log_all || bValFromDictionary(config, CFSTR("LOG_SC_BTMM_CONFIGURATION"))) {
1995 add_BTMM_notification();
1996 }
1997 #endif // !TARGET_OS_EMBEDDED
1998
1999 #if !TARGET_OS_EMBEDDED
2000 if (log_all || bValFromDictionary(config, CFSTR("LOG_SC_CONSOLEUSER"))) {
2001 add_console_notification();
2002 }
2003 #endif // !TARGET_OS_EMBEDDED
2004
2005 #if !TARGET_OS_EMBEDDED
2006 if (log_all || bValFromDictionary(config, CFSTR("LOG_SC_DIRECTORYSERVICES_SEARCHPOLICY"))) {
2007 add_DirectoryServices_notification();
2008 }
2009 #endif // !TARGET_OS_EMBEDDED
2010
2011 if (log_all || bValFromDictionary(config, CFSTR("LOG_SC_NETWORKCHANGE"))) {
2012 add_NetworkChange_notification();
2013 }
2014
2015 if (log_all || bValFromDictionary(config, CFSTR("LOG_SC_PRIMARYSERVICE"))) {
2016 add_PrimaryService_notification();
2017 }
2018
2019 if (log_all || bValFromDictionary(config, CFSTR("LOG_SC_REACHABILITY"))) {
2020 CFArrayRef hosts = NULL;
2021
2022 if ((config == NULL) ||
2023 !CFDictionaryGetValueIfPresent(config, CFSTR("LOG_SC_REACHABILITY_HOSTS"), (const void **)&hosts) ||
2024 !isA_CFArray(hosts) ||
2025 (CFArrayGetCount(hosts) == 0)) {
2026 hosts = NULL;
2027 }
2028
2029 if (verbose) {
2030 _sc_debug = TRUE;
2031 }
2032
2033 add_reachability_notification(hosts);
2034 }
2035
2036 return;
2037 }
2038
2039 #ifdef MAIN
2040
2041 int
2042 main(int argc, char **argv)
2043 {
2044 _sc_log = FALSE;
2045 _sc_verbose = (argc > 1) ? TRUE : FALSE;
2046 _sc_debug = TRUE;
2047
2048 load(CFBundleGetMainBundle(), (argc > 1) ? TRUE : FALSE);
2049 CFRunLoopRun();
2050 /* not reached */
2051 exit(0);
2052 return 0;
2053 }
2054
2055 #endif /* MAIN */