1 /* 2 * Copyright (c) 2000-2025 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 KERNEL 247 /*! 248 * @define N_KEV_VECTORS 249 * @discussion The maximum number of kev_d_vectors for a kernel event. 250 */ 251 #define N_KEV_VECTORS 5 252 253 /*! 254 * @struct kev_d_vectors 255 * @discussion This structure is used to append some data to a kernel 256 * event. 257 * @field data_length The length of data. 258 * @field data_ptr A pointer to data. 259 */ 260 struct kev_d_vectors { 261 u_int32_t data_length; /* Length of the event data */ 262 void *data_ptr; /* Pointer to event data */ 263 }; 264 265 /*! 266 * @struct kev_msg 267 * @discussion This structure is used when posting a kernel event. 268 * @field vendor_code The vendor code assigned by kev_vendor_code_find. 269 * @field kev_class The event's class. 270 * @field kev_class The event's subclass. 271 * @field kev_class The event's code. 272 * @field dv An array of vectors describing additional data to be appended 273 * to the kernel event. 274 */ 275 struct kev_msg { 276 u_int32_t vendor_code; /* For non-Apple extensibility */ 277 u_int32_t kev_class; /* Layer of event source */ 278 u_int32_t kev_subclass; /* Component within layer */ 279 u_int32_t event_code; /* The event code */ 280 struct kev_d_vectors dv[N_KEV_VECTORS]; /* Up to n data vectors */ 281 }; 282 283 /*! 284 * @function kev_vendor_code_find 285 * @discussion Lookup a vendor_code given a unique string. If the vendor 286 * code has not been used since launch, a unique integer will be 287 * assigned for that string. Vendor codes will remain the same 288 * until the machine is rebooted. 289 * @param vendor_string A bundle style vendor identifier(i.e. com.apple). 290 * @param vendor_code Upon return, a unique vendor code for use when 291 * posting kernel events. 292 * @result May return ENOMEM if memory constraints prevent allocation of a 293 * new vendor code. 294 */ 295 errno_t kev_vendor_code_find(const char *vendor_string, u_int32_t *vendor_code); 296 297 /*! 298 * @function kev_msg_post 299 * @discussion Post a kernel event message. 300 * @param event_msg A structure defining the kernel event message to post. 301 * @result Will return zero upon success. May return a number of errors 302 * depending on the type of failure. EINVAL indicates that there 303 * was something wrong with the kerne event. The vendor code of 304 * the kernel event must be assigned using kev_vendor_code_find. 305 * If the message is too large, EMSGSIZE will be returned. 306 */ 307 errno_t kev_msg_post(struct kev_msg *event_msg); 308 309 #endif /* KERNEL */ 310 #if defined(PRIVATE) && !defined(MODULES_SUPPORTED) 311 #include <sys/kern_event_private.h> 312 #endif /* PRIVATE && !MODULES_SUPPORTED */ 313 #endif /* SYS_KERN_EVENT_H */ 314