1 /* 2 * Copyright (c) 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 /*! 29 * @header kern_control.h 30 * This header defines an API to communicate between a kernel 31 * extension and a process outside of the kernel. 32 */ 33 34 #ifndef KPI_KERN_CONTROL_PRIVATE_H 35 #define KPI_KERN_CONTROL_PRIVATE_H 36 37 #include <sys/kern_control.h> 38 39 struct xkctl_reg { 40 u_int32_t xkr_len; 41 u_int32_t xkr_kind; 42 u_int32_t xkr_id; 43 u_int32_t xkr_reg_unit; 44 u_int32_t xkr_flags; 45 u_int64_t xkr_kctlref; 46 u_int32_t xkr_recvbufsize; 47 u_int32_t xkr_sendbufsize; 48 u_int32_t xkr_lastunit; 49 u_int32_t xkr_pcbcount; 50 u_int64_t xkr_connect; 51 u_int64_t xkr_disconnect; 52 u_int64_t xkr_send; 53 u_int64_t xkr_send_list; 54 u_int64_t xkr_setopt; 55 u_int64_t xkr_getopt; 56 u_int64_t xkr_rcvd; 57 char xkr_name[MAX_KCTL_NAME]; 58 }; 59 60 struct xkctlpcb { 61 u_int32_t xkp_len; 62 u_int32_t xkp_kind; 63 u_int64_t xkp_kctpcb; 64 u_int32_t xkp_unit; 65 u_int32_t xkp_kctlid; 66 u_int64_t xkp_kctlref; 67 char xkp_kctlname[MAX_KCTL_NAME]; 68 }; 69 70 struct kctlstat { 71 u_int64_t kcs_reg_total __attribute__((aligned(8))); 72 u_int64_t kcs_reg_count __attribute__((aligned(8))); 73 u_int64_t kcs_pcbcount __attribute__((aligned(8))); 74 u_int64_t kcs_gencnt __attribute__((aligned(8))); 75 u_int64_t kcs_connections __attribute__((aligned(8))); 76 u_int64_t kcs_conn_fail __attribute__((aligned(8))); 77 u_int64_t kcs_send_fail __attribute__((aligned(8))); 78 u_int64_t kcs_send_list_fail __attribute__((aligned(8))); 79 u_int64_t kcs_enqueue_fail __attribute__((aligned(8))); 80 u_int64_t kcs_enqueue_fullsock __attribute__((aligned(8))); 81 u_int64_t kcs_bad_kctlref __attribute__((aligned(8))); 82 u_int64_t kcs_tbl_size_too_big __attribute__((aligned(8))); 83 u_int64_t kcs_enqdata_mb_alloc_fail __attribute__((aligned(8))); 84 u_int64_t kcs_enqdata_sbappend_fail __attribute__((aligned(8))); 85 }; 86 87 #ifdef KERNEL 88 89 #ifdef KERNEL_PRIVATE 90 /*! 91 * @defined CTL_FLAG_REG_EXTENDED 92 * @discussion This flag indicates that this kernel control utilizes the 93 * the extended fields within the kern_ctl_reg structure. 94 */ 95 #define CTL_FLAG_REG_EXTENDED 0x8 96 97 /*! 98 * @defined CTL_FLAG_REG_CRIT 99 * @discussion This flag indicates that this kernel control utilizes the 100 * the extended fields within the kern_ctl_reg structure. 101 */ 102 #define CTL_FLAG_REG_CRIT 0x10 103 104 /*! 105 * @defined CTL_FLAG_REG_SETUP 106 * @discussion This flag indicates that this kernel control utilizes the 107 * the setup callback field within the kern_ctl_reg structure. 108 */ 109 #define CTL_FLAG_REG_SETUP 0x20 110 111 /*! 112 * @defined CTL_DATA_CRIT 113 * @discussion This flag indicates the data is critical to the client 114 * and that it needs to be forced into the socket buffer 115 * by resizing it if needed. 116 */ 117 #define CTL_DATA_CRIT 0x4 118 #endif /* KERNEL_PRIVATE */ 119 120 __BEGIN_DECLS 121 122 #ifdef KERNEL_PRIVATE 123 /*! 124 * @typedef ctl_rcvd_func 125 * @discussion The ctl_rcvd_func is called when the client reads data from 126 * the kernel control socket. The kernel control can use this callback 127 * in combination with ctl_getenqueuespace() to avoid overflowing 128 * the socket's receive buffer. When ctl_getenqueuespace() returns 129 * 0 or ctl_enqueuedata()/ctl_enqueuembuf() return ENOBUFS, the 130 * kernel control can wait until this callback is called before 131 * trying to enqueue the data again. 132 * @param kctlref The control ref of the kernel control. 133 * @param unit The unit number of the kernel control instance. 134 * @param unitinfo The user-defined private data initialized by the 135 * ctl_connect_func callback. 136 * @param flags The recv flags. See the recv(2) man page. 137 */ 138 typedef void (*ctl_rcvd_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, 139 int flags); 140 141 /*! 142 * @typedef ctl_send_list_func 143 * @discussion The ctl_send_list_func is used to receive data sent from 144 * the client to the kernel control. 145 * @param kctlref The control ref of the kernel control. 146 * @param unit The unit number of the kernel control instance the client has 147 * connected to. 148 * @param unitinfo The user-defined private data initialized by the 149 * ctl_connect_func callback. 150 * @param m The data sent by the client to the kernel control in an 151 * mbuf packet chain. Your function is responsible for releasing 152 * mbuf packet chain. 153 * @param flags The flags specified by the client when calling 154 * send/sendto/sendmsg (MSG_OOB/MSG_DONTROUTE). 155 */ 156 typedef errno_t (*ctl_send_list_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, 157 mbuf_t m, int flags); 158 159 /*! 160 * @typedef ctl_bind_func 161 * @discussion The ctl_bind_func is an optional function that allows the client 162 * to set up their unitinfo prior to connecting. 163 * @param kctlref The control ref for the kernel control the client is 164 * binding to. 165 * @param sac The address used to connect to this control. The field sc_unit 166 * contains the unit number of the kernel control instance the client is 167 * binding to. If CTL_FLAG_REG_ID_UNIT was set when the kernel control 168 * was registered, sc_unit is the ctl_unit of the kern_ctl_reg structure. 169 * If CTL_FLAG_REG_ID_UNIT was not set when the kernel control was 170 * registered, sc_unit is the dynamically allocated unit number of 171 * the new kernel control instance that is used for this connection. 172 * @param unitinfo A placeholder for a pointer to the optional user-defined 173 * private data associated with this kernel control instance. This 174 * opaque info will be provided to the user when the rest of the 175 * callback routines are executed. For example, it can be used 176 * to pass a pointer to an instance-specific data structure in 177 * order for the user to keep track of the states related to this 178 * kernel control instance. 179 */ 180 typedef errno_t (*ctl_bind_func)(kern_ctl_ref kctlref, 181 struct sockaddr_ctl *sac, 182 void **unitinfo); 183 184 /*! 185 * @typedef ctl_setup_func 186 * @discussion The ctl_setup_func is an optional function that allows the client 187 * to pick a unit number in the case that the caller hasn't specified one 188 * @param unit A placeholder for a pointer to the unit number that is selected with 189 * this kernel control instance 190 * @param unitinfo A placeholder for a pointer to the optional user-defined 191 * private data associated with this kernel control instance. This 192 * opaque info will be provided to the user when the rest of the 193 * callback routines are executed. For example, it can be used 194 * to pass a pointer to an instance-specific data structure in 195 * order for the user to keep track of the states related to this 196 * kernel control instance. 197 */ 198 typedef errno_t (*ctl_setup_func)(u_int32_t *unit, void **unitinfo); 199 #endif /* KERNEL_PRIVATE */ 200 201 #ifdef KERN_CTL_REG_OPAQUE 202 /*! 203 * @struct kern_ctl_reg 204 * @discussion This structure defines the properties of a kernel 205 * control being registered. 206 * @field ctl_name A Bundle ID string of up to MAX_KCTL_NAME bytes (including the ending zero). 207 * This string should not be empty. 208 * @field ctl_id The control ID may be dynamically assigned or it can be a 209 * 32-bit creator code assigned by DTS. 210 * For a DTS assigned creator code the CTL_FLAG_REG_ID_UNIT flag must be set. 211 * For a dynamically assigned control ID, do not set the CTL_FLAG_REG_ID_UNIT flag. 212 * The value of the dynamically assigned control ID is set to this field 213 * when the registration succeeds. 214 * @field ctl_unit A separate unit number to register multiple units that 215 * share the same control ID with DTS assigned creator code when 216 * the CTL_FLAG_REG_ID_UNIT flag is set. 217 * This field is ignored for a dynamically assigned control ID. 218 * @field ctl_flags CTL_FLAG_PRIVILEGED and/or CTL_FLAG_REG_ID_UNIT. 219 * @field ctl_sendsize Override the default send size. If set to zero, 220 * the default send size will be used, and this default value 221 * is set to this field to be retrieved by the caller. 222 * @field ctl_recvsize Override the default receive size. If set to 223 * zero, the default receive size will be used, and this default value 224 * is set to this field to be retrieved by the caller. 225 * @field ctl_connect Specify the function to be called whenever a client 226 * connects to the kernel control. This field must be specified. 227 * @field ctl_disconnect Specify a function to be called whenever a 228 * client disconnects from the kernel control. 229 * @field ctl_send Specify a function to handle data send from the 230 * client to the kernel control. 231 * @field ctl_setopt Specify a function to handle set socket option 232 * operations for the kernel control. 233 * @field ctl_getopt Specify a function to handle get socket option 234 * operations for the kernel control. 235 */ 236 struct kern_ctl_reg { 237 /* control information */ 238 char ctl_name[MAX_KCTL_NAME]; 239 u_int32_t ctl_id; 240 u_int32_t ctl_unit; 241 242 /* control settings */ 243 u_int32_t ctl_flags; 244 u_int32_t ctl_sendsize; 245 u_int32_t ctl_recvsize; 246 247 /* Dispatch functions */ 248 ctl_connect_func ctl_connect; 249 ctl_disconnect_func ctl_disconnect; 250 ctl_send_func ctl_send; 251 ctl_setopt_func ctl_setopt; 252 ctl_getopt_func ctl_getopt; 253 ctl_rcvd_func ctl_rcvd; /* Only valid if CTL_FLAG_REG_EXTENDED is set */ 254 ctl_send_list_func ctl_send_list;/* Only valid if CTL_FLAG_REG_EXTENDED is set */ 255 ctl_bind_func ctl_bind; 256 ctl_setup_func ctl_setup; 257 }; 258 #endif /* KERN_CTL_REG_OPAQUE */ 259 260 /*! 261 * @function ctl_enqueuembuf_list 262 * @discussion Send data stored in an mbuf packet chain from the kernel 263 * control to the client. The caller is responsible for freeing 264 * the mbuf chain if ctl_enqueuembuf returns an error. 265 * Not valid if ctl_flags contains CTL_FLAG_REG_SOCK_STREAM. 266 * @param kctlref The control reference of the kernel control. 267 * @param unit The unit number of the kernel control instance. 268 * @param m_list An mbuf chain containing the data to send to the client. 269 * @param flags Send flags. CTL_DATA_NOWAKEUP is 270 * the only supported flags. 271 * @param m_remain A pointer to the list of mbuf packets in the chain that 272 * could not be enqueued. 273 * @result 0 - Data was enqueued to be read by the client. 274 * EINVAL - Invalid parameters. 275 * ENOBUFS - The queue is full. 276 */ 277 errno_t 278 ctl_enqueuembuf_list(kern_ctl_ref kctlref, u_int32_t unit, mbuf_t m_list, 279 u_int32_t flags, mbuf_t *m_remain); 280 281 /*! 282 * @function ctl_getenqueuepacketcount 283 * @discussion Retrieve the number of packets in the socket 284 * receive buffer. 285 * @param kctlref The control reference of the kernel control. 286 * @param unit The unit number of the kernel control instance. 287 * @param pcnt The address where to return the current count. 288 * @result 0 - Success; the packet count is returned to caller. 289 * EINVAL - Invalid parameters. 290 */ 291 errno_t 292 ctl_getenqueuepacketcount(kern_ctl_ref kctlref, u_int32_t unit, u_int32_t *pcnt); 293 294 #ifdef KERNEL_PRIVATE 295 296 #include <sys/queue.h> 297 #include <libkern/locks.h> 298 299 /* 300 * internal structure maintained for each register controller 301 */ 302 struct ctl_cb; 303 struct kctl; 304 struct socket; 305 struct socket_info; 306 307 void kctl_fill_socketinfo(struct socket *, struct socket_info *); 308 309 u_int32_t ctl_id_by_name(const char *); 310 errno_t ctl_name_by_id(u_int32_t, char *__counted_by(maxsize), size_t maxsize); 311 312 extern const u_int32_t ctl_maxunit; 313 #endif /* KERNEL_PRIVATE */ 314 315 __END_DECLS 316 #endif /* KERNEL */ 317 318 #endif /* KPI_KERN_CONTROL_PRIVATE_H */ 319