]> git.saurik.com Git - apple/configd.git/blobdiff - Plugins/KernelEventMonitor/eventmon.c
configd-453.16.tar.gz
[apple/configd.git] / Plugins / KernelEventMonitor / eventmon.c
index 9c74f178935002911a7224f7505021fb04317772..c2cad274232cbc7d19cd99bfdd07c86709d001c3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008, 2010, 2011 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include "ev_dlil.h"
 #include "ev_ipv4.h"
 #include "ev_ipv6.h"
-#include "ev_appletalk.h"
-
 #include <notify.h>
 
+// from ip_fw2.c
+#define KEV_LOG_SUBCLASS       10
+
 static const char *inetEventName[] = {
        "",
        "INET address added",
@@ -71,6 +72,7 @@ static const char *inetEventName[] = {
        "INET broadcast address changed",
        "INET netmask changed",
        "INET ARP collision",
+       "INET port in use",
 };
 
 static const char *dlEventName[] = {
@@ -90,17 +92,17 @@ static const char *dlEventName[] = {
        "KEV_DL_LINK_ON",
        "KEV_DL_PROTO_ATTACHED",
        "KEV_DL_PROTO_DETACHED",
-};
-
-static const char *atalkEventName[] = {
-       "",
-       "KEV_ATALK_ENABLED",
-       "KEV_ATALK_DISABLED",
-       "KEV_ATALK_ZONEUPDATED",
-       "KEV_ATALK_ROUTERUP",
-       "KEV_ATALK_ROUTERUP_INVALID",
-       "KEV_ATALK_ROUTERDOWN",
-       "KEV_ATALK_ZONELISTCHANGED"
+       "KEV_DL_LINK_ADDRESS_CHANGED",
+       "KEV_DL_WAKEFLAGS_CHANGED",
+#ifdef KEV_DL_IF_IDLE_ROUTE_REFCNT
+       "KEV_DL_IF_IDLE_ROUTE_REFCNT",
+#endif
+#ifdef  KEV_DL_IFCAP_CHANGED
+       "KEV_DL_IFCAP_CHANGED",
+#endif
+#ifdef  KEV_DL_LINK_QUALITY_METRIC_CHANGED
+       "KEV_DL_LINK_QUALITY_METRIC_CHANGED",
+#endif
 };
 
 static const char *inet6EventName[] = {
@@ -113,12 +115,17 @@ static const char *inet6EventName[] = {
        "KEV_INET6_DEFROUTER"
 };
 
+#ifdef KEV_ND6_SUBCLASS
+static const char *nd6EventNameString[] = {
+       "",
+       "KEV_ND6_RA"
+};
+#endif // KEV_ND6_SUBCLASS
 
 __private_extern__ Boolean             network_changed = FALSE;
 __private_extern__ SCDynamicStoreRef   store           = NULL;
 __private_extern__ Boolean             _verbose        = FALSE;
 
-
 __private_extern__
 int
 dgram_socket(int domain)
@@ -133,7 +140,7 @@ ifflags_set(int s, char * name, short flags)
     int                ret;
 
     bzero(&ifr, sizeof(ifr));
-    strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+    strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
     ret = ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr);
     if (ret == -1) {
                return (ret);
@@ -149,7 +156,7 @@ ifflags_clear(int s, char * name, short flags)
     int                ret;
 
     bzero(&ifr, sizeof(ifr));
-    strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+    strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
     ret = ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr);
     if (ret == -1) {
                return (ret);
@@ -201,8 +208,12 @@ logEvent(CFStringRef evStr, struct kern_event_msg *ev_msg)
        int     i;
        int     j;
 
-       SCLog(_verbose, LOG_DEBUG, CFSTR("%@ event:"), evStr);
-       SCLog(_verbose, LOG_DEBUG,
+       if (!_verbose) {
+               return;
+       }
+
+       SCLog(TRUE, LOG_DEBUG, CFSTR("%@ event:"), evStr);
+       SCLog(TRUE, LOG_DEBUG,
              CFSTR("  Event size=%d, id=%d, vendor=%d, class=%d, subclass=%d, code=%d"),
              ev_msg->total_size,
              ev_msg->id,
@@ -211,14 +222,14 @@ logEvent(CFStringRef evStr, struct kern_event_msg *ev_msg)
              ev_msg->kev_subclass,
              ev_msg->event_code);
        for (i = 0, j = KEV_MSG_HEADER_SIZE; j < ev_msg->total_size; i++, j+=4) {
-               SCLog(_verbose, LOG_DEBUG, CFSTR("  Event data[%2d] = %08lx"), i, ev_msg->event_data[i]);
+               SCLog(TRUE, LOG_DEBUG, CFSTR("  Event data[%2d] = %08lx"), i, ev_msg->event_data[i]);
        }
 }
 
 static const char *
 inetEventNameString(uint32_t event_code)
 {
-       if (event_code <= KEV_INET_ARPCOLLISION) {
+       if (event_code < sizeof(inetEventName) / sizeof(inetEventName[0])) {
                return (inetEventName[event_code]);
        }
        return ("New Apple network INET subcode");
@@ -227,7 +238,7 @@ inetEventNameString(uint32_t event_code)
 static const char *
 inet6EventNameString(uint32_t event_code)
 {
-       if (event_code <= KEV_INET6_DEFROUTER) {
+       if (event_code < sizeof(inet6EventName) / sizeof(inet6EventName[0])) {
                return (inet6EventName[event_code]);
        }
        return ("New Apple network INET6 subcode");
@@ -236,22 +247,12 @@ inet6EventNameString(uint32_t event_code)
 static const char *
 dlEventNameString(uint32_t event_code)
 {
-       if (event_code <= KEV_DL_PROTO_DETACHED) {
+       if (event_code < sizeof(dlEventName) / sizeof(dlEventName[0])) {
                return (dlEventName[event_code]);
        }
        return ("New Apple network DL subcode");
 }
 
-static const char *
-atalkEventNameString(uint32_t event_code)
-{
-       if (event_code <= KEV_ATALK_ZONELISTCHANGED) {
-               return (atalkEventName[event_code]);
-       }
-       return ("New Apple network AppleTalk subcode");
-}
-
-
 static void
 copy_if_name(struct net_event_data * ev, char * ifr_name, int ifr_len)
 {
@@ -266,7 +267,7 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg)
        int                             dataLen = (ev_msg->total_size - KEV_MSG_HEADER_SIZE);
        void *                          event_data = &ev_msg->event_data[0];
        Boolean                         handled = TRUE;
-       char                            ifr_name[IFNAMSIZ + 1];
+       char                            ifr_name[IFNAMSIZ];
 
        switch (ev_msg->kev_subclass) {
                case KEV_INET_SUBCLASS : {
@@ -305,6 +306,7 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg)
                                                                 ev->hw_addr);
                                        break;
                                }
+#if    !TARGET_OS_IPHONE
                                case KEV_INET_PORTINUSE : {
                                        struct kev_in_portinuse * ev;
                                        ev = (struct kev_in_portinuse *)event_data;
@@ -315,6 +317,7 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg)
                                        port_in_use_ipv4(ev->port, ev->req_pid);
                                        break;
                                }
+#endif /* !TARGET_OS_IPHONE */
                                default :
                                        handled = FALSE;
                                        break;
@@ -389,17 +392,6 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg)
                                        interface_detaching(ifr_name);
                                        break;
 
-                               case KEV_DL_SIFFLAGS :
-                               case KEV_DL_SIFMETRICS :
-                               case KEV_DL_SIFMTU :
-                               case KEV_DL_SIFPHYS :
-                               case KEV_DL_SIFMEDIA :
-                               case KEV_DL_SIFGENERIC :
-                               case KEV_DL_ADDMULTI :
-                               case KEV_DL_DELMULTI :
-                                       handled = FALSE;
-                                       break;
-
                                case KEV_DL_PROTO_ATTACHED :
                                case KEV_DL_PROTO_DETACHED : {
                                        struct kev_dl_proto_data * protoEvent;
@@ -419,6 +411,21 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg)
                                        break;
                                }
 
+#ifdef KEV_DL_IF_IDLE_ROUTE_REFCNT
+                               case KEV_DL_IF_IDLE_ROUTE_REFCNT: {
+                                       /*
+                                        * interface route refcnt idle
+                                        */
+                                       if (dataLen < sizeof(*ev)) {
+                                               handled = FALSE;
+                                               break;
+                                       }
+                                       copy_if_name(ev, ifr_name, sizeof(ifr_name));
+                                       interface_update_idle_state(ifr_name);
+                                       break;
+                               }
+#endif // KEV_DL_IF_IDLE_ROUTE_REFCNT
+
                                case KEV_DL_LINK_OFF :
                                case KEV_DL_LINK_ON :
                                        /*
@@ -432,42 +439,48 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg)
                                        link_update_status(ifr_name, FALSE);
                                        break;
 
+#ifdef  KEV_DL_LINK_QUALITY_METRIC_CHANGED
+                               case KEV_DL_LINK_QUALITY_METRIC_CHANGED: {
+                                       struct kev_dl_link_quality_metric_data * lqm_data;
+                                       lqm_data = (struct kev_dl_link_quality_metric_data *) event_data;
+
+                                       if (dataLen < sizeof(*ev)) {
+                                               handled = FALSE;
+                                               break;
+                                       }
+                                       copy_if_name(ev, ifr_name, sizeof(ifr_name));
+                                       interface_update_quality_metric(ifr_name,
+                                                                  lqm_data->link_quality_metric);
+                                       break;
+                               }
+#endif  // KEV_DL_LINK_QUALITY_METRIC_CHANGED
+
+                               case KEV_DL_SIFFLAGS :
+                               case KEV_DL_SIFMETRICS :
+                               case KEV_DL_SIFMTU :
+                               case KEV_DL_SIFPHYS :
+                               case KEV_DL_SIFMEDIA :
+                               case KEV_DL_SIFGENERIC :
+                               case KEV_DL_ADDMULTI :
+                               case KEV_DL_DELMULTI :
+                               case KEV_DL_LINK_ADDRESS_CHANGED :
+                               case KEV_DL_WAKEFLAGS_CHANGED :
+#ifdef  KEV_DL_IFCAP_CHANGED
+                               case KEV_DL_IFCAP_CHANGED :
+#endif // KEV_DL_IFCAP_CHANGED
+                                       break;
+
                                default :
                                        handled = FALSE;
                                        break;
                        }
                        break;
                }
-               case KEV_ATALK_SUBCLASS: {
-                       struct kev_atalk_data * ev;
-
-                       eventName = atalkEventNameString(ev_msg->event_code);
-                       ev = (struct kev_atalk_data *)event_data;
-                       if (dataLen < sizeof(*ev)) {
-                               handled = FALSE;
-                               break;
-                       }
-                       copy_if_name(&ev->link_data, ifr_name, sizeof(ifr_name));
+#ifdef KEV_ND6_SUBCLASS
+               case KEV_ND6_SUBCLASS : {
+                       eventName = nd6EventNameString(ev_msg->event_code);
                        switch (ev_msg->event_code) {
-                               case KEV_ATALK_ENABLED:
-                                       interface_update_atalk_address(ev, ifr_name);
-                                       break;
-
-                               case KEV_ATALK_DISABLED:
-                                       interface_update_shutdown_atalk();
-                                       break;
-
-                               case KEV_ATALK_ZONEUPDATED:
-                                       interface_update_atalk_zone(ev, ifr_name);
-                                       break;
-
-                               case KEV_ATALK_ROUTERUP:
-                               case KEV_ATALK_ROUTERUP_INVALID:
-                               case KEV_ATALK_ROUTERDOWN:
-                                       interface_update_appletalk(NULL, ifr_name);
-                                       break;
-
-                               case KEV_ATALK_ZONELISTCHANGED:
+                               case KEV_KEV_ND6_RA :
                                        break;
 
                                default :
@@ -476,6 +489,10 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg)
                        }
                        break;
                }
+#endif // KEV_ND6_SUBCLASS
+               case KEV_LOG_SUBCLASS : {
+                       break;
+               }
                default :
                        handled = FALSE;
                        break;
@@ -493,27 +510,16 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg)
        return;
 }
 
-
-static void
-processEvent_Apple_IOKit(struct kern_event_msg *ev_msg)
-{
-       switch (ev_msg->kev_subclass) {
-               default :
-                       logEvent(CFSTR("New Apple IOKit subclass"), ev_msg);
-                       break;
-       }
-
-       return;
-}
-
-
 static void
 eventCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
 {
        int                     so              = CFSocketGetNative(s);
        int                     status;
-       char                    buf[1024];
-       struct kern_event_msg   *ev_msg         = (struct kern_event_msg *)&buf[0];
+       union {
+               char                    bytes[1024];
+               struct kern_event_msg   ev_msg1;        // first kernel event
+       } buf;
+       struct kern_event_msg   *ev_msg         = &buf.ev_msg1;
        int                     offset          = 0;
 
        status = recv(so, &buf, sizeof(buf), 0);
@@ -537,7 +543,10 @@ eventCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const
                                                processEvent_Apple_Network(ev_msg);
                                                break;
                                        case KEV_IOKIT_CLASS :
-                                               processEvent_Apple_IOKit(ev_msg);
+                                       case KEV_SYSTEM_CLASS :
+                                       case KEV_APPLESHARE_CLASS :
+                                       case KEV_FIREWALL_CLASS :
+                                       case KEV_IEEE80211_CLASS :
                                                break;
                                        default :
                                                /* unrecognized (Apple) event class */
@@ -551,7 +560,7 @@ eventCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const
                                break;
                }
                offset += ev_msg->total_size;
-               ev_msg = (struct kern_event_msg *)&buf[offset];
+               ev_msg = (struct kern_event_msg *)(void *)&buf.bytes[offset];
        }
 
        cache_write(store);
@@ -568,7 +577,6 @@ eventCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const
 
 }
 
-
 __private_extern__
 void
 prime_KernelEventMonitor()
@@ -617,12 +625,6 @@ prime_KernelEventMonitor()
         */
        interface_update_ipv6(ifap, NULL);
 
-       /*
-        * update AppleTalk network addresses already assigned
-        * to the interfaces.
-        */
-       interface_update_appletalk(ifap, NULL);
-
        freeifaddrs(ifap);
 
  done:
@@ -638,29 +640,27 @@ prime_KernelEventMonitor()
        return;
 }
 
-
 static CFStringRef
 kevSocketCopyDescription(const void *info)
 {
        return CFStringCreateWithFormat(NULL, NULL, CFSTR("<kernel event socket>"));
 }
 
-
 __private_extern__
 void
 load_KernelEventMonitor(CFBundleRef bundle, Boolean bundleVerbose)
 {
-       int                     so;
-       int                     status;
-       struct kev_request      kev_req;
-       CFSocketRef             es;
        CFSocketContext         context = { 0
                                          , (void *)1
                                          , NULL
                                          , NULL
                                          , kevSocketCopyDescription
                                          };
+       CFSocketRef             es;
+       struct kev_request      kev_req;
        CFRunLoopSourceRef      rls;
+       int                     so;
+       int                     status;
 
        if (bundleVerbose) {
                _verbose = TRUE;
@@ -683,10 +683,10 @@ load_KernelEventMonitor(CFBundleRef bundle, Boolean bundleVerbose)
        /* Open an event socket */
        so = socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT);
        if (so != -1) {
-               /* establish filter to return all events */
-               kev_req.vendor_code  = 0;
-               kev_req.kev_class    = 0;       /* Not used if vendor_code is 0 */
-               kev_req.kev_subclass = 0;       /* Not used if either kev_class OR vendor_code are 0 */
+               /* establish filter to return events of interest */
+               kev_req.vendor_code  = KEV_VENDOR_APPLE;
+               kev_req.kev_class    = KEV_NETWORK_CLASS;
+               kev_req.kev_subclass = KEV_ANY_SUBCLASS;
                status = ioctl(so, SIOCSKEVFILT, &kev_req);
                if (status) {
                        SCLog(TRUE, LOG_ERR, CFSTR("could not establish event filter, ioctl() failed: %s"), strerror(errno));
@@ -715,11 +715,11 @@ load_KernelEventMonitor(CFBundleRef bundle, Boolean bundleVerbose)
        }
 
        /* Create a CFSocketRef for the PF_SYSTEM kernel event socket */
-       es  = CFSocketCreateWithNative(NULL,
-                                      so,
-                                      kCFSocketReadCallBack,
-                                      eventCallback,
-                                      &context);
+       es = CFSocketCreateWithNative(NULL,
+                                     so,
+                                     kCFSocketReadCallBack,
+                                     eventCallback,
+                                     &context);
 
        /* Create and add a run loop source for the event socket */
        rls = CFSocketCreateRunLoopSource(NULL, es, 0);
@@ -750,12 +750,6 @@ load_KernelEventMonitor(CFBundleRef bundle, Boolean bundleVerbose)
 #undef getIF
 #undef updateStore
 
-#define getIF          getIF_at
-#define updateStore    updateStore_at
-#include "ev_appletalk.c"
-#undef getIF
-#undef updateStore
-
 int
 main(int argc, char **argv)
 {