kern_event.h
1 /* 2 * Copyright (c) 2000-2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 /* Copyright (c) 1998, 1999 Apple Computer, Inc. All Rights Reserved */ 29 /*! 30 * @header kern_event.h 31 * This header defines in-kernel functions for generating kernel events as 32 * well as functions for receiving kernel events using a kernel event 33 * socket. 34 */ 35 36 #ifndef SYS_KERN_EVENT_H 37 #define SYS_KERN_EVENT_H 38 39 #include <sys/appleapiopts.h> 40 #include <sys/ioccom.h> 41 #include <sys/sys_domain.h> 42 43 #define KEV_SNDSPACE (4 * 1024) 44 #define KEV_RECVSPACE (32 * 1024) 45 46 #define KEV_ANY_VENDOR 0 47 #define KEV_ANY_CLASS 0 48 #define KEV_ANY_SUBCLASS 0 49 50 /* 51 * Vendor Code 52 */ 53 54 /*! 55 * @defined KEV_VENDOR_APPLE 56 * @discussion Apple generated kernel events use the hard coded vendor code 57 * value of 1. Third party kernel events use a dynamically allocated vendor 58 * code. The vendor code can be found using the SIOCGKEVVENDOR ioctl. 59 */ 60 #define KEV_VENDOR_APPLE 1 61 62 /* 63 * Definition of top-level classifications for KEV_VENDOR_APPLE 64 */ 65 66 /*! 67 * @defined KEV_NETWORK_CLASS 68 * @discussion Network kernel event class. 69 */ 70 #define KEV_NETWORK_CLASS 1 71 72 /*! 73 * @defined KEV_IOKIT_CLASS 74 * @discussion IOKit kernel event class. 75 */ 76 #define KEV_IOKIT_CLASS 2 77 78 /*! 79 * @defined KEV_SYSTEM_CLASS 80 * @discussion System kernel event class. 81 */ 82 #define KEV_SYSTEM_CLASS 3 83 84 /*! 85 * @defined KEV_APPLESHARE_CLASS 86 * @discussion AppleShare kernel event class. 87 */ 88 #define KEV_APPLESHARE_CLASS 4 89 90 /*! 91 * @defined KEV_FIREWALL_CLASS 92 * @discussion Firewall kernel event class. 93 */ 94 #define KEV_FIREWALL_CLASS 5 95 96 /*! 97 * @defined KEV_IEEE80211_CLASS 98 * @discussion IEEE 802.11 kernel event class. 99 */ 100 #define KEV_IEEE80211_CLASS 6 101 102 /* 103 * The following struct is KPI, but it was originally defined with a trailing 104 * array member of size one, intended to be used as a Variable-Length Array. 105 * That's problematic because the compiler doesn't know that the array is 106 * accessed out-of-bounds and can assume it isn't. This makes 107 * -Warray-bounds-pointer-arithmetic sad. We can't just change the code because 108 * it requires users to also change their uses of the class, at a minimum 109 * because kern_event_msg's size changes when making the last member a VLA. This 110 * macro allows users of this KPI to opt-in to the new behavior. 111 */ 112 #if defined(XNU_KERN_EVENT_DATA_IS_VLA) 113 #define XNU_KERN_EVENT_DATA_SIZE /* nothing, it's a VLA */ 114 #else 115 #define XNU_KERN_EVENT_DATA_SIZE 1 116 #endif 117 118 /*! 119 * @struct kern_event_msg 120 * @discussion This structure is prepended to all kernel events. This 121 * structure is used to determine the format of the remainder of 122 * the kernel event. This structure will appear on all messages 123 * received on a kernel event socket. To post a kernel event, a 124 * slightly different structure is used. 125 * @field total_size Total size of the kernel event message including the 126 * header. 127 * @field vendor_code The vendor code indicates which vendor generated the 128 * kernel event. This gives every vendor a unique set of classes 129 * and subclasses to use. Use the SIOCGKEVVENDOR ioctl to look up 130 * vendor codes for vendors other than Apple. Apple uses 131 * KEV_VENDOR_APPLE. 132 * @field kev_class The class of the kernel event. 133 * @field kev_subclass The subclass of the kernel event. 134 * @field id Monotonically increasing value. 135 * @field event_code The event code. 136 * @field event_data Any additional data about this event. Format will 137 * depend on the vendor_code, kev_class, kev_subclass, and 138 * event_code. The length of the event_data can be determined 139 * using total_size - KEV_MSG_HEADER_SIZE. 140 */ 141 struct kern_event_msg { 142 u_int32_t total_size; /* Size of entire event msg */ 143 u_int32_t vendor_code; /* For non-Apple extensibility */ 144 u_int32_t kev_class; /* Layer of event source */ 145 u_int32_t kev_subclass; /* Component within layer */ 146 u_int32_t id; /* Monotonically increasing value */ 147 u_int32_t event_code; /* unique code */ 148 u_int32_t event_data[XNU_KERN_EVENT_DATA_SIZE]; /* One or more data words */ 149 }; 150 151 /*! 152 * @defined KEV_MSG_HEADER_SIZE 153 * @discussion Size of the header portion of the kern_event_msg structure. 154 * This accounts for everything right up to event_data. The size 155 * of the data can be found by subtracting KEV_MSG_HEADER_SIZE 156 * from the total size from the kern_event_msg. 157 */ 158 #define KEV_MSG_HEADER_SIZE (offsetof(struct kern_event_msg, event_data[0])) 159 160 /*! 161 * @struct kev_request 162 * @discussion This structure is used with the SIOCSKEVFILT and 163 * SIOCGKEVFILT to set and get the control filter setting for a 164 * kernel control socket. 165 * @field total_size Total size of the kernel event message including the 166 * header. 167 * @field vendor_code All kernel events that don't match this vendor code 168 * will be ignored. KEV_ANY_VENDOR can be used to receive kernel 169 * events with any vendor code. 170 * @field kev_class All kernel events that don't match this class will be 171 * ignored. KEV_ANY_CLASS can be used to receive kernel events with 172 * any class. 173 * @field kev_subclass All kernel events that don't match this subclass 174 * will be ignored. KEV_ANY_SUBCLASS can be used to receive kernel 175 * events with any subclass. 176 */ 177 struct kev_request { 178 u_int32_t vendor_code; 179 u_int32_t kev_class; 180 u_int32_t kev_subclass; 181 }; 182 183 /*! 184 * @defined KEV_VENDOR_CODE_MAX_STR_LEN 185 * @discussion This define sets the maximum length of a string that can be 186 * used to identify a vendor or kext when looking up a vendor code. 187 */ 188 #define KEV_VENDOR_CODE_MAX_STR_LEN 200 189 190 /*! 191 * @struct kev_vendor_code 192 * @discussion This structure is used with the SIOCGKEVVENDOR ioctl to 193 * convert from a string identifying a kext or vendor, in the 194 * form of a bundle identifier, to a vendor code. 195 * @field vendor_code After making the SIOCGKEVVENDOR ioctl call, this will 196 * be filled in with the vendor code if there is one. 197 * @field vendor_string A bundle style identifier. 198 */ 199 #pragma pack(4) 200 struct kev_vendor_code { 201 u_int32_t vendor_code; 202 char vendor_string[KEV_VENDOR_CODE_MAX_STR_LEN]; 203 }; 204 #pragma pack() 205 206 /*! 207 * @defined SIOCGKEVID 208 * @discussion Retrieve the current event id. Each event generated will 209 * have a new id. The next event to be generated will have an id 210 * of id+1. 211 */ 212 #define SIOCGKEVID _IOR('e', 1, u_int32_t) 213 214 /*! 215 * @defined SIOCSKEVFILT 216 * @discussion Set the kernel event filter for this socket. Kernel events 217 * not matching this filter will not be received on this socket. 218 */ 219 #define SIOCSKEVFILT _IOW('e', 2, struct kev_request) 220 221 /*! 222 * @defined SIOCGKEVFILT 223 * @discussion Retrieve the kernel event filter for this socket. Kernel 224 * events not matching this filter will not be received on this 225 * socket. 226 */ 227 #define SIOCGKEVFILT _IOR('e', 3, struct kev_request) 228 229 /*! 230 * @defined SIOCGKEVVENDOR 231 * @discussion Lookup the vendor code for the specified vendor. ENOENT will 232 * be returned if a vendor code for that vendor string does not 233 * exist. 234 */ 235 #define SIOCGKEVVENDOR _IOWR('e', 4, struct kev_vendor_code) 236 237 #ifdef PRIVATE 238 struct xkevtpcb { 239 u_int32_t kep_len; 240 u_int32_t kep_kind; 241 u_int64_t kep_evtpcb; 242 u_int32_t kep_vendor_code_filter; 243 u_int32_t kep_class_filter; 244 u_int32_t kep_subclass_filter; 245 }; 246 247 struct kevtstat { 248 u_int64_t kes_pcbcount __attribute__((aligned(8))); 249 u_int64_t kes_gencnt __attribute__((aligned(8))); 250 u_int64_t kes_badvendor __attribute__((aligned(8))); 251 u_int64_t kes_toobig __attribute__((aligned(8))); 252 u_int64_t kes_nomem __attribute__((aligned(8))); 253 u_int64_t kes_fullsock __attribute__((aligned(8))); 254 u_int64_t kes_posted __attribute__((aligned(8))); 255 }; 256 #endif /* PRIVATE */ 257 258 #ifdef KERNEL 259 /*! 260 * @define N_KEV_VECTORS 261 * @discussion The maximum number of kev_d_vectors for a kernel event. 262 */ 263 #define N_KEV_VECTORS 5 264 265 /*! 266 * @struct kev_d_vectors 267 * @discussion This structure is used to append some data to a kernel 268 * event. 269 * @field data_length The length of data. 270 * @field data_ptr A pointer to data. 271 */ 272 struct kev_d_vectors { 273 u_int32_t data_length; /* Length of the event data */ 274 void *data_ptr; /* Pointer to event data */ 275 }; 276 277 /*! 278 * @struct kev_msg 279 * @discussion This structure is used when posting a kernel event. 280 * @field vendor_code The vendor code assigned by kev_vendor_code_find. 281 * @field kev_class The event's class. 282 * @field kev_class The event's subclass. 283 * @field kev_class The event's code. 284 * @field dv An array of vectors describing additional data to be appended 285 * to the kernel event. 286 */ 287 struct kev_msg { 288 u_int32_t vendor_code; /* For non-Apple extensibility */ 289 u_int32_t kev_class; /* Layer of event source */ 290 u_int32_t kev_subclass; /* Component within layer */ 291 u_int32_t event_code; /* The event code */ 292 struct kev_d_vectors dv[N_KEV_VECTORS]; /* Up to n data vectors */ 293 }; 294 295 /*! 296 * @function kev_vendor_code_find 297 * @discussion Lookup a vendor_code given a unique string. If the vendor 298 * code has not been used since launch, a unique integer will be 299 * assigned for that string. Vendor codes will remain the same 300 * until the machine is rebooted. 301 * @param vendor_string A bundle style vendor identifier(i.e. com.apple). 302 * @param vendor_code Upon return, a unique vendor code for use when 303 * posting kernel events. 304 * @result May return ENOMEM if memory constraints prevent allocation of a 305 * new vendor code. 306 */ 307 errno_t kev_vendor_code_find(const char *vendor_string, u_int32_t *vendor_code); 308 309 /*! 310 * @function kev_msg_post 311 * @discussion Post a kernel event message. 312 * @param event_msg A structure defining the kernel event message to post. 313 * @result Will return zero upon success. May return a number of errors 314 * depending on the type of failure. EINVAL indicates that there 315 * was something wrong with the kerne event. The vendor code of 316 * the kernel event must be assigned using kev_vendor_code_find. 317 * If the message is too large, EMSGSIZE will be returned. 318 */ 319 errno_t kev_msg_post(struct kev_msg *event_msg); 320 321 #ifdef PRIVATE 322 /* 323 * Internal version of kev_msg_post. Allows posting Apple vendor code kernel 324 * events. 325 */ 326 int kev_post_msg(struct kev_msg *event); 327 328 LIST_HEAD(kern_event_head, kern_event_pcb); 329 330 struct kern_event_pcb { 331 decl_lck_mtx_data(, evp_mtx); /* per-socket mutex */ 332 LIST_ENTRY(kern_event_pcb) evp_link; /* glue on list of all PCBs */ 333 struct socket *evp_socket; /* pointer back to socket */ 334 u_int32_t evp_vendor_code_filter; 335 u_int32_t evp_class_filter; 336 u_int32_t evp_subclass_filter; 337 }; 338 339 #define sotoevpcb(so) ((struct kern_event_pcb *)((so)->so_pcb)) 340 341 #endif /* PRIVATE */ 342 #endif /* KERNEL */ 343 #endif /* SYS_KERN_EVENT_H */