1 /* 2 * Copyright (c) 2000-2021 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 * @defined KEV_NKE_CLASS 104 * @discussion NKE kernel event class. 105 */ 106 #define KEV_NKE_CLASS 7 107 108 #define KEV_NKE_ALF_SUBCLASS 1 109 #define KEV_NKE_ALF_STATE_CHANGED 1 110 111 /* 112 * The following struct is KPI, but it was originally defined with a trailing 113 * array member of size one, intended to be used as a Variable-Length Array. 114 * That's problematic because the compiler doesn't know that the array is 115 * accessed out-of-bounds and can assume it isn't. This makes 116 * -Warray-bounds-pointer-arithmetic sad. We can't just change the code because 117 * it requires users to also change their uses of the class, at a minimum 118 * because kern_event_msg's size changes when making the last member a VLA. This 119 * macro allows users of this KPI to opt-in to the new behavior. 120 */ 121 #if defined(XNU_KERN_EVENT_DATA_IS_VLA) 122 #define XNU_KERN_EVENT_DATA_SIZE /* nothing, it's a VLA */ 123 #else 124 #define XNU_KERN_EVENT_DATA_SIZE 1 125 #endif 126 127 /*! 128 * @struct kern_event_msg 129 * @discussion This structure is prepended to all kernel events. This 130 * structure is used to determine the format of the remainder of 131 * the kernel event. This structure will appear on all messages 132 * received on a kernel event socket. To post a kernel event, a 133 * slightly different structure is used. 134 * @field total_size Total size of the kernel event message including the 135 * header. 136 * @field vendor_code The vendor code indicates which vendor generated the 137 * kernel event. This gives every vendor a unique set of classes 138 * and subclasses to use. Use the SIOCGKEVVENDOR ioctl to look up 139 * vendor codes for vendors other than Apple. Apple uses 140 * KEV_VENDOR_APPLE. 141 * @field kev_class The class of the kernel event. 142 * @field kev_subclass The subclass of the kernel event. 143 * @field id Monotonically increasing value. 144 * @field event_code The event code. 145 * @field event_data Any additional data about this event. Format will 146 * depend on the vendor_code, kev_class, kev_subclass, and 147 * event_code. The length of the event_data can be determined 148 * using total_size - KEV_MSG_HEADER_SIZE. 149 */ 150 struct kern_event_msg { 151 u_int32_t total_size; /* Size of entire event msg */ 152 u_int32_t vendor_code; /* For non-Apple extensibility */ 153 u_int32_t kev_class; /* Layer of event source */ 154 u_int32_t kev_subclass; /* Component within layer */ 155 u_int32_t id; /* Monotonically increasing value */ 156 u_int32_t event_code; /* unique code */ 157 u_int32_t event_data[XNU_KERN_EVENT_DATA_SIZE]; /* One or more data words */ 158 }; 159 160 /*! 161 * @defined KEV_MSG_HEADER_SIZE 162 * @discussion Size of the header portion of the kern_event_msg structure. 163 * This accounts for everything right up to event_data. The size 164 * of the data can be found by subtracting KEV_MSG_HEADER_SIZE 165 * from the total size from the kern_event_msg. 166 */ 167 #define KEV_MSG_HEADER_SIZE (offsetof(struct kern_event_msg, event_data[0])) 168 169 /*! 170 * @struct kev_request 171 * @discussion This structure is used with the SIOCSKEVFILT and 172 * SIOCGKEVFILT to set and get the control filter setting for a 173 * kernel control socket. 174 * @field total_size Total size of the kernel event message including the 175 * header. 176 * @field vendor_code All kernel events that don't match this vendor code 177 * will be ignored. KEV_ANY_VENDOR can be used to receive kernel 178 * events with any vendor code. 179 * @field kev_class All kernel events that don't match this class will be 180 * ignored. KEV_ANY_CLASS can be used to receive kernel events with 181 * any class. 182 * @field kev_subclass All kernel events that don't match this subclass 183 * will be ignored. KEV_ANY_SUBCLASS can be used to receive kernel 184 * events with any subclass. 185 */ 186 struct kev_request { 187 u_int32_t vendor_code; 188 u_int32_t kev_class; 189 u_int32_t kev_subclass; 190 }; 191 192 /*! 193 * @defined KEV_VENDOR_CODE_MAX_STR_LEN 194 * @discussion This define sets the maximum length of a string that can be 195 * used to identify a vendor or kext when looking up a vendor code. 196 */ 197 #define KEV_VENDOR_CODE_MAX_STR_LEN 200 198 199 /*! 200 * @struct kev_vendor_code 201 * @discussion This structure is used with the SIOCGKEVVENDOR ioctl to 202 * convert from a string identifying a kext or vendor, in the 203 * form of a bundle identifier, to a vendor code. 204 * @field vendor_code After making the SIOCGKEVVENDOR ioctl call, this will 205 * be filled in with the vendor code if there is one. 206 * @field vendor_string A bundle style identifier. 207 */ 208 #pragma pack(4) 209 struct kev_vendor_code { 210 u_int32_t vendor_code; 211 char vendor_string[KEV_VENDOR_CODE_MAX_STR_LEN]; 212 }; 213 #pragma pack() 214 215 /*! 216 * @defined SIOCGKEVID 217 * @discussion Retrieve the current event id. Each event generated will 218 * have a new id. The next event to be generated will have an id 219 * of id+1. 220 */ 221 #define SIOCGKEVID _IOR('e', 1, u_int32_t) 222 223 /*! 224 * @defined SIOCSKEVFILT 225 * @discussion Set the kernel event filter for this socket. Kernel events 226 * not matching this filter will not be received on this socket. 227 */ 228 #define SIOCSKEVFILT _IOW('e', 2, struct kev_request) 229 230 /*! 231 * @defined SIOCGKEVFILT 232 * @discussion Retrieve the kernel event filter for this socket. Kernel 233 * events not matching this filter will not be received on this 234 * socket. 235 */ 236 #define SIOCGKEVFILT _IOR('e', 3, struct kev_request) 237 238 /*! 239 * @defined SIOCGKEVVENDOR 240 * @discussion Lookup the vendor code for the specified vendor. ENOENT will 241 * be returned if a vendor code for that vendor string does not 242 * exist. 243 */ 244 #define SIOCGKEVVENDOR _IOWR('e', 4, struct kev_vendor_code) 245 246 #ifdef PRIVATE 247 struct xkevtpcb { 248 u_int32_t kep_len; 249 u_int32_t kep_kind; 250 u_int64_t kep_evtpcb; 251 u_int32_t kep_vendor_code_filter; 252 u_int32_t kep_class_filter; 253 u_int32_t kep_subclass_filter; 254 }; 255 256 struct kevtstat { 257 u_int64_t kes_pcbcount __attribute__((aligned(8))); 258 u_int64_t kes_gencnt __attribute__((aligned(8))); 259 u_int64_t kes_badvendor __attribute__((aligned(8))); 260 u_int64_t kes_toobig __attribute__((aligned(8))); 261 u_int64_t kes_nomem __attribute__((aligned(8))); 262 u_int64_t kes_fullsock __attribute__((aligned(8))); 263 u_int64_t kes_posted __attribute__((aligned(8))); 264 }; 265 #endif /* PRIVATE */ 266 267 #ifdef KERNEL 268 /*! 269 * @define N_KEV_VECTORS 270 * @discussion The maximum number of kev_d_vectors for a kernel event. 271 */ 272 #define N_KEV_VECTORS 5 273 274 /*! 275 * @struct kev_d_vectors 276 * @discussion This structure is used to append some data to a kernel 277 * event. 278 * @field data_length The length of data. 279 * @field data_ptr A pointer to data. 280 */ 281 struct kev_d_vectors { 282 u_int32_t data_length; /* Length of the event data */ 283 void *data_ptr; /* Pointer to event data */ 284 }; 285 286 /*! 287 * @struct kev_msg 288 * @discussion This structure is used when posting a kernel event. 289 * @field vendor_code The vendor code assigned by kev_vendor_code_find. 290 * @field kev_class The event's class. 291 * @field kev_class The event's subclass. 292 * @field kev_class The event's code. 293 * @field dv An array of vectors describing additional data to be appended 294 * to the kernel event. 295 */ 296 struct kev_msg { 297 u_int32_t vendor_code; /* For non-Apple extensibility */ 298 u_int32_t kev_class; /* Layer of event source */ 299 u_int32_t kev_subclass; /* Component within layer */ 300 u_int32_t event_code; /* The event code */ 301 struct kev_d_vectors dv[N_KEV_VECTORS]; /* Up to n data vectors */ 302 }; 303 304 /*! 305 * @function kev_vendor_code_find 306 * @discussion Lookup a vendor_code given a unique string. If the vendor 307 * code has not been used since launch, a unique integer will be 308 * assigned for that string. Vendor codes will remain the same 309 * until the machine is rebooted. 310 * @param vendor_string A bundle style vendor identifier(i.e. com.apple). 311 * @param vendor_code Upon return, a unique vendor code for use when 312 * posting kernel events. 313 * @result May return ENOMEM if memory constraints prevent allocation of a 314 * new vendor code. 315 */ 316 errno_t kev_vendor_code_find(const char *vendor_string, u_int32_t *vendor_code); 317 318 /*! 319 * @function kev_msg_post 320 * @discussion Post a kernel event message. 321 * @param event_msg A structure defining the kernel event message to post. 322 * @result Will return zero upon success. May return a number of errors 323 * depending on the type of failure. EINVAL indicates that there 324 * was something wrong with the kerne event. The vendor code of 325 * the kernel event must be assigned using kev_vendor_code_find. 326 * If the message is too large, EMSGSIZE will be returned. 327 */ 328 errno_t kev_msg_post(struct kev_msg *event_msg); 329 330 #ifdef PRIVATE 331 /* 332 * Internal version of kev_msg_post. Allows posting Apple vendor code kernel 333 * events. 334 */ 335 int kev_post_msg(struct kev_msg *event); 336 int kev_post_msg_nowait(struct kev_msg *event); 337 338 LIST_HEAD(kern_event_head, kern_event_pcb); 339 340 struct kern_event_pcb { 341 decl_lck_mtx_data(, evp_mtx); /* per-socket mutex */ 342 LIST_ENTRY(kern_event_pcb) evp_link; /* glue on list of all PCBs */ 343 struct socket *evp_socket; /* pointer back to socket */ 344 u_int32_t evp_vendor_code_filter; 345 u_int32_t evp_class_filter; 346 u_int32_t evp_subclass_filter; 347 }; 348 349 #define sotoevpcb(so) ((struct kern_event_pcb *)((so)->so_pcb)) 350 351 #endif /* PRIVATE */ 352 #endif /* KERNEL */ 353 #endif /* SYS_KERN_EVENT_H */ 354