| 1 | /* |
| 2 | * Copyright (c) 2000-2004, 2012-2016 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_H |
| 35 | #define KPI_KERN_CONTROL_H |
| 36 | |
| 37 | |
| 38 | #include <sys/appleapiopts.h> |
| 39 | #include <sys/_types/_u_char.h> |
| 40 | #include <sys/_types/_u_int16_t.h> |
| 41 | #include <sys/_types/_u_int32_t.h> |
| 42 | #include <sys/_types/_u_int64_t.h> |
| 43 | |
| 44 | /* |
| 45 | * Define Controller event subclass, and associated events. |
| 46 | * Subclass of KEV_SYSTEM_CLASS |
| 47 | */ |
| 48 | |
| 49 | /*! |
| 50 | * @defined KEV_CTL_SUBCLASS |
| 51 | * @discussion The kernel event subclass for kernel control events. |
| 52 | */ |
| 53 | #define KEV_CTL_SUBCLASS 2 |
| 54 | |
| 55 | /*! |
| 56 | * @defined KEV_CTL_REGISTERED |
| 57 | * @discussion The event code indicating a new controller was |
| 58 | * registered. The data portion will contain a ctl_event_data. |
| 59 | */ |
| 60 | #define KEV_CTL_REGISTERED 1 /* a new controller appears */ |
| 61 | |
| 62 | /*! |
| 63 | * @defined KEV_CTL_DEREGISTERED |
| 64 | * @discussion The event code indicating a controller was unregistered. |
| 65 | * The data portion will contain a ctl_event_data. |
| 66 | */ |
| 67 | #define KEV_CTL_DEREGISTERED 2 /* a controller disappears */ |
| 68 | |
| 69 | /*! |
| 70 | * @struct ctl_event_data |
| 71 | * @discussion This structure is used for KEV_CTL_SUBCLASS kernel |
| 72 | * events. |
| 73 | * @field ctl_id The kernel control id. |
| 74 | * @field ctl_unit The kernel control unit. |
| 75 | */ |
| 76 | struct ctl_event_data { |
| 77 | u_int32_t ctl_id; /* Kernel Controller ID */ |
| 78 | u_int32_t ctl_unit; |
| 79 | }; |
| 80 | |
| 81 | /* |
| 82 | * Controls destined to the Controller Manager. |
| 83 | */ |
| 84 | |
| 85 | /*! |
| 86 | * @defined CTLIOCGCOUNT |
| 87 | * @discussion The CTLIOCGCOUNT ioctl can be used to determine the |
| 88 | * number of kernel controllers registered. |
| 89 | */ |
| 90 | #define CTLIOCGCOUNT _IOR('N', 2, int) /* get number of control structures registered */ |
| 91 | |
| 92 | /*! |
| 93 | * @defined CTLIOCGINFO |
| 94 | * @discussion The CTLIOCGINFO ioctl can be used to convert a kernel |
| 95 | * control name to a kernel control id. |
| 96 | */ |
| 97 | #define CTLIOCGINFO _IOWR('N', 3, struct ctl_info) /* get id from name */ |
| 98 | |
| 99 | |
| 100 | /*! |
| 101 | * @defined MAX_KCTL_NAME |
| 102 | * @discussion Kernel control names must be no longer than |
| 103 | * MAX_KCTL_NAME. |
| 104 | */ |
| 105 | #define MAX_KCTL_NAME 96 |
| 106 | |
| 107 | /* |
| 108 | * Controls destined to the Controller Manager. |
| 109 | */ |
| 110 | |
| 111 | /*! |
| 112 | * @struct ctl_info |
| 113 | * @discussion This structure is used with the CTLIOCGINFO ioctl to |
| 114 | * translate from a kernel control name to a control id. |
| 115 | * @field ctl_id The kernel control id, filled out upon return. |
| 116 | * @field ctl_name The kernel control name to find. |
| 117 | */ |
| 118 | struct ctl_info { |
| 119 | u_int32_t ctl_id; /* Kernel Controller ID */ |
| 120 | char ctl_name[MAX_KCTL_NAME]; /* Kernel Controller Name (a C string) */ |
| 121 | }; |
| 122 | |
| 123 | |
| 124 | /*! |
| 125 | * @struct sockaddr_ctl |
| 126 | * @discussion The controller address structure is used to establish |
| 127 | * contact between a user client and a kernel controller. The |
| 128 | * sc_id/sc_unit uniquely identify each controller. sc_id is a |
| 129 | * unique identifier assigned to the controller. The identifier can |
| 130 | * be assigned by the system at registration time or be a 32-bit |
| 131 | * creator code obtained from Apple Computer. sc_unit is a unit |
| 132 | * number for this sc_id, and is privately used by the kernel |
| 133 | * controller to identify several instances of the controller. |
| 134 | * @field sc_len The length of the structure. |
| 135 | * @field sc_family AF_SYSTEM. |
| 136 | * @field ss_sysaddr AF_SYS_KERNCONTROL. |
| 137 | * @field sc_id Controller unique identifier. |
| 138 | * @field sc_unit Kernel controller private unit number. |
| 139 | * @field sc_reserved Reserved, must be set to zero. |
| 140 | */ |
| 141 | struct sockaddr_ctl { |
| 142 | u_char sc_len; /* depends on size of bundle ID string */ |
| 143 | u_char sc_family; /* AF_SYSTEM */ |
| 144 | u_int16_t ss_sysaddr; /* AF_SYS_KERNCONTROL */ |
| 145 | u_int32_t sc_id; /* Controller unique identifier */ |
| 146 | u_int32_t sc_unit; /* Developer private unit number */ |
| 147 | u_int32_t sc_reserved[5]; |
| 148 | }; |
| 149 | |
| 150 | #ifdef PRIVATE |
| 151 | |
| 152 | struct xkctl_reg { |
| 153 | u_int32_t xkr_len; |
| 154 | u_int32_t xkr_kind; |
| 155 | u_int32_t xkr_id; |
| 156 | u_int32_t xkr_reg_unit; |
| 157 | u_int32_t xkr_flags; |
| 158 | u_int64_t xkr_kctlref; |
| 159 | u_int32_t xkr_recvbufsize; |
| 160 | u_int32_t xkr_sendbufsize; |
| 161 | u_int32_t xkr_lastunit; |
| 162 | u_int32_t xkr_pcbcount; |
| 163 | u_int64_t xkr_connect; |
| 164 | u_int64_t xkr_disconnect; |
| 165 | u_int64_t xkr_send; |
| 166 | u_int64_t xkr_send_list; |
| 167 | u_int64_t xkr_setopt; |
| 168 | u_int64_t xkr_getopt; |
| 169 | u_int64_t xkr_rcvd; |
| 170 | char xkr_name[MAX_KCTL_NAME]; |
| 171 | }; |
| 172 | |
| 173 | struct xkctlpcb { |
| 174 | u_int32_t xkp_len; |
| 175 | u_int32_t xkp_kind; |
| 176 | u_int64_t xkp_kctpcb; |
| 177 | u_int32_t xkp_unit; |
| 178 | u_int32_t xkp_kctlid; |
| 179 | u_int64_t xkp_kctlref; |
| 180 | char xkp_kctlname[MAX_KCTL_NAME]; |
| 181 | }; |
| 182 | |
| 183 | struct kctlstat { |
| 184 | u_int64_t kcs_reg_total __attribute__((aligned(8))); |
| 185 | u_int64_t kcs_reg_count __attribute__((aligned(8))); |
| 186 | u_int64_t kcs_pcbcount __attribute__((aligned(8))); |
| 187 | u_int64_t kcs_gencnt __attribute__((aligned(8))); |
| 188 | u_int64_t kcs_connections __attribute__((aligned(8))); |
| 189 | u_int64_t kcs_conn_fail __attribute__((aligned(8))); |
| 190 | u_int64_t kcs_send_fail __attribute__((aligned(8))); |
| 191 | u_int64_t kcs_send_list_fail __attribute__((aligned(8))); |
| 192 | u_int64_t kcs_enqueue_fail __attribute__((aligned(8))); |
| 193 | u_int64_t kcs_enqueue_fullsock __attribute__((aligned(8))); |
| 194 | u_int64_t kcs_bad_kctlref __attribute__((aligned(8))); |
| 195 | u_int64_t kcs_tbl_size_too_big __attribute__((aligned(8))); |
| 196 | u_int64_t kcs_enqdata_mb_alloc_fail __attribute__((aligned(8))); |
| 197 | u_int64_t kcs_enqdata_sbappend_fail __attribute__((aligned(8))); |
| 198 | }; |
| 199 | |
| 200 | #endif /* PRIVATE */ |
| 201 | |
| 202 | #ifdef KERNEL |
| 203 | |
| 204 | #include <sys/kpi_mbuf.h> |
| 205 | |
| 206 | /*! |
| 207 | * @typedef kern_ctl_ref |
| 208 | * @discussion A control reference is used to track an attached kernel |
| 209 | * control. Registering a kernel control will create a kernel |
| 210 | * control reference. This reference is required for sending data |
| 211 | * or removing the kernel control. This reference will be passed to |
| 212 | * callbacks for that kernel control. |
| 213 | */ |
| 214 | typedef void * kern_ctl_ref; |
| 215 | |
| 216 | /*! |
| 217 | * @defined CTL_FLAG_PRIVILEGED |
| 218 | * @discussion The CTL_FLAG_PRIVILEGED flag is passed in ctl_flags. If |
| 219 | * this flag is set, only privileged processes may attach to this |
| 220 | * kernel control. |
| 221 | */ |
| 222 | #define CTL_FLAG_PRIVILEGED 0x1 |
| 223 | /*! |
| 224 | * @defined CTL_FLAG_REG_ID_UNIT |
| 225 | * @discussion The CTL_FLAG_REG_ID_UNIT flag is passed to indicate that |
| 226 | * the ctl_id specified should be used. If this flag is not |
| 227 | * present, a unique ctl_id will be dynamically assigned to your |
| 228 | * kernel control. The CTLIOCGINFO ioctl can be used by the client |
| 229 | * to find the dynamically assigned id based on the control name |
| 230 | * specified in ctl_name. |
| 231 | */ |
| 232 | #define CTL_FLAG_REG_ID_UNIT 0x2 |
| 233 | /*! |
| 234 | * @defined CTL_FLAG_REG_SOCK_STREAM |
| 235 | * @discussion Use the CTL_FLAG_REG_SOCK_STREAM flag when client need to open |
| 236 | * socket of type SOCK_STREAM to communicate with the kernel control. |
| 237 | * By default kernel control sockets are of type SOCK_DGRAM. |
| 238 | */ |
| 239 | #define CTL_FLAG_REG_SOCK_STREAM 0x4 |
| 240 | |
| 241 | #ifdef KERNEL_PRIVATE |
| 242 | /*! |
| 243 | * @defined CTL_FLAG_REG_EXTENDED |
| 244 | * @discussion This flag indicates that this kernel control utilizes the |
| 245 | * the extended fields within the kern_ctl_reg structure. |
| 246 | */ |
| 247 | #define CTL_FLAG_REG_EXTENDED 0x8 |
| 248 | |
| 249 | /*! |
| 250 | * @defined CTL_FLAG_REG_CRIT |
| 251 | * @discussion This flag indicates that this kernel control utilizes the |
| 252 | * the extended fields within the kern_ctl_reg structure. |
| 253 | */ |
| 254 | #define CTL_FLAG_REG_CRIT 0x10 |
| 255 | |
| 256 | /*! |
| 257 | * @defined CTL_FLAG_REG_SETUP |
| 258 | * @discussion This flag indicates that this kernel control utilizes the |
| 259 | * the setup callback field within the kern_ctl_reg structure. |
| 260 | */ |
| 261 | #define CTL_FLAG_REG_SETUP 0x20 |
| 262 | #endif /* KERNEL_PRIVATE */ |
| 263 | |
| 264 | /* Data flags for controllers */ |
| 265 | /*! |
| 266 | * @defined CTL_DATA_NOWAKEUP |
| 267 | * @discussion The CTL_DATA_NOWAKEUP flag can be used for the enqueue |
| 268 | * data and enqueue mbuf functions to indicate that the process |
| 269 | * should not be woken up yet. This is useful when you want to |
| 270 | * enqueue data using more than one call but only want to wake up |
| 271 | * the client after all of the data has been enqueued. |
| 272 | */ |
| 273 | #define CTL_DATA_NOWAKEUP 0x1 |
| 274 | |
| 275 | /*! |
| 276 | * @defined CTL_DATA_EOR |
| 277 | * @discussion The CTL_DATA_EOR flag can be used for the enqueue |
| 278 | * data and enqueue mbuf functions to mark the end of a record. |
| 279 | */ |
| 280 | #define CTL_DATA_EOR 0x2 |
| 281 | |
| 282 | #ifdef KERNEL_PRIVATE |
| 283 | /*! |
| 284 | * @defined CTL_DATA_CRIT |
| 285 | * @discussion This flag indicates the data is critical to the client |
| 286 | * and that it needs to be forced into the socket buffer |
| 287 | * by resizing it if needed. |
| 288 | */ |
| 289 | #define CTL_DATA_CRIT 0x4 |
| 290 | #endif /* KERNEL_PRIVATE */ |
| 291 | |
| 292 | __BEGIN_DECLS |
| 293 | |
| 294 | /*! |
| 295 | * @typedef ctl_connect_func |
| 296 | * @discussion The ctl_connect_func is used to receive |
| 297 | * notification of a client connecting to the kernel control. |
| 298 | * @param kctlref The control ref for the kernel control the client is |
| 299 | * connecting to. |
| 300 | * @param sac The address used to connect to this control. The field sc_unit |
| 301 | * contains the unit number of the kernel control instance the client is |
| 302 | * connecting to. If CTL_FLAG_REG_ID_UNIT was set when the kernel control |
| 303 | * was registered, sc_unit is the ctl_unit of the kern_ctl_reg structure. |
| 304 | * If CTL_FLAG_REG_ID_UNIT was not set when the kernel control was |
| 305 | * registered, sc_unit is the dynamically allocated unit number of |
| 306 | * the new kernel control instance that is used for this connection. |
| 307 | * @param unitinfo A placeholder for a pointer to the optional user-defined |
| 308 | * private data associated with this kernel control instance. This |
| 309 | * opaque info will be provided to the user when the rest of the |
| 310 | * callback routines are executed. For example, it can be used |
| 311 | * to pass a pointer to an instance-specific data structure in |
| 312 | * order for the user to keep track of the states related to this |
| 313 | * kernel control instance. |
| 314 | */ |
| 315 | typedef errno_t (*ctl_connect_func)(kern_ctl_ref kctlref, |
| 316 | struct sockaddr_ctl *sac, |
| 317 | void **unitinfo); |
| 318 | |
| 319 | /*! |
| 320 | * @typedef ctl_disconnect_func |
| 321 | * @discussion The ctl_disconnect_func is used to receive notification |
| 322 | * that a client has disconnected from the kernel control. This |
| 323 | * usually happens when the socket is closed. If this is the last |
| 324 | * socket attached to your kernel control, you may unregister your |
| 325 | * kernel control from this callback. |
| 326 | * @param kctlref The control ref for the kernel control instance the client has |
| 327 | * disconnected from. |
| 328 | * @param unit The unit number of the kernel control instance the client has |
| 329 | * disconnected from. |
| 330 | * @param unitinfo The user-defined private data initialized by the |
| 331 | * ctl_connect_func callback. |
| 332 | */ |
| 333 | typedef errno_t (*ctl_disconnect_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo); |
| 334 | |
| 335 | /*! |
| 336 | * @typedef ctl_send_func |
| 337 | * @discussion The ctl_send_func is used to receive data sent from |
| 338 | * the client to the kernel control. |
| 339 | * @param kctlref The control ref of the kernel control. |
| 340 | * @param unit The unit number of the kernel control instance the client has |
| 341 | * connected to. |
| 342 | * @param unitinfo The user-defined private data initialized by the |
| 343 | * ctl_connect_func callback. |
| 344 | * @param m The data sent by the client to the kernel control in an |
| 345 | * mbuf chain. Your function is responsible for releasing the |
| 346 | * mbuf chain. |
| 347 | * @param flags The flags specified by the client when calling |
| 348 | * send/sendto/sendmsg (MSG_OOB/MSG_DONTROUTE). |
| 349 | */ |
| 350 | typedef errno_t (*ctl_send_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, |
| 351 | mbuf_t m, int flags); |
| 352 | |
| 353 | /*! |
| 354 | * @typedef ctl_setopt_func |
| 355 | * @discussion The ctl_setopt_func is used to handle set socket option |
| 356 | * calls for the SYSPROTO_CONTROL option level. |
| 357 | * @param kctlref The control ref of the kernel control. |
| 358 | * @param unit The unit number of the kernel control instance. |
| 359 | * @param unitinfo The user-defined private data initialized by the |
| 360 | * ctl_connect_func callback. |
| 361 | * @param opt The socket option. |
| 362 | * @param data A pointer to the socket option data. The data has |
| 363 | * already been copied in to the kernel for you. |
| 364 | * @param len The length of the socket option data. |
| 365 | */ |
| 366 | typedef errno_t (*ctl_setopt_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, |
| 367 | int opt, void *data, size_t len); |
| 368 | |
| 369 | /*! |
| 370 | * @typedef ctl_getopt_func |
| 371 | * @discussion The ctl_getopt_func is used to handle client get socket |
| 372 | * option requests for the SYSPROTO_CONTROL option level. A buffer |
| 373 | * is allocated for storage and passed to your function. The length |
| 374 | * of that buffer is also passed. Upon return, you should set *len |
| 375 | * to length of the buffer used. In some cases, data may be NULL. |
| 376 | * When this happens, *len should be set to the length you would |
| 377 | * have returned had data not been NULL. If the buffer is too small, |
| 378 | * return an error. |
| 379 | * @param kctlref The control ref of the kernel control. |
| 380 | * @param unit The unit number of the kernel control instance. |
| 381 | * @param unitinfo The user-defined private data initialized by the |
| 382 | * ctl_connect_func callback. |
| 383 | * @param opt The socket option. |
| 384 | * @param data A buffer to copy the results in to. May be NULL, see |
| 385 | * discussion. |
| 386 | * @param len A pointer to the length of the buffer. This should be set |
| 387 | * to the length of the buffer used before returning. |
| 388 | */ |
| 389 | typedef errno_t (*ctl_getopt_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, |
| 390 | int opt, void *data, size_t *len); |
| 391 | |
| 392 | #ifdef KERNEL_PRIVATE |
| 393 | /*! |
| 394 | * @typedef ctl_rcvd_func |
| 395 | * @discussion The ctl_rcvd_func is called when the client reads data from |
| 396 | * the kernel control socket. The kernel control can use this callback |
| 397 | * in combination with ctl_getenqueuespace() to avoid overflowing |
| 398 | * the socket's receive buffer. When ctl_getenqueuespace() returns |
| 399 | * 0 or ctl_enqueuedata()/ctl_enqueuembuf() return ENOBUFS, the |
| 400 | * kernel control can wait until this callback is called before |
| 401 | * trying to enqueue the data again. |
| 402 | * @param kctlref The control ref of the kernel control. |
| 403 | * @param unit The unit number of the kernel control instance. |
| 404 | * @param unitinfo The user-defined private data initialized by the |
| 405 | * ctl_connect_func callback. |
| 406 | * @param flags The recv flags. See the recv(2) man page. |
| 407 | */ |
| 408 | typedef void (*ctl_rcvd_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, |
| 409 | int flags); |
| 410 | |
| 411 | /*! |
| 412 | * @typedef ctl_send_list_func |
| 413 | * @discussion The ctl_send_list_func is used to receive data sent from |
| 414 | * the client to the kernel control. |
| 415 | * @param kctlref The control ref of the kernel control. |
| 416 | * @param unit The unit number of the kernel control instance the client has |
| 417 | * connected to. |
| 418 | * @param unitinfo The user-defined private data initialized by the |
| 419 | * ctl_connect_func callback. |
| 420 | * @param m The data sent by the client to the kernel control in an |
| 421 | * mbuf packet chain. Your function is responsible for releasing |
| 422 | * mbuf packet chain. |
| 423 | * @param flags The flags specified by the client when calling |
| 424 | * send/sendto/sendmsg (MSG_OOB/MSG_DONTROUTE). |
| 425 | */ |
| 426 | typedef errno_t (*ctl_send_list_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, |
| 427 | mbuf_t m, int flags); |
| 428 | |
| 429 | /*! |
| 430 | * @typedef ctl_bind_func |
| 431 | * @discussion The ctl_bind_func is an optional function that allows the client |
| 432 | * to set up their unitinfo prior to connecting. |
| 433 | * @param kctlref The control ref for the kernel control the client is |
| 434 | * binding to. |
| 435 | * @param sac The address used to connect to this control. The field sc_unit |
| 436 | * contains the unit number of the kernel control instance the client is |
| 437 | * binding to. If CTL_FLAG_REG_ID_UNIT was set when the kernel control |
| 438 | * was registered, sc_unit is the ctl_unit of the kern_ctl_reg structure. |
| 439 | * If CTL_FLAG_REG_ID_UNIT was not set when the kernel control was |
| 440 | * registered, sc_unit is the dynamically allocated unit number of |
| 441 | * the new kernel control instance that is used for this connection. |
| 442 | * @param unitinfo A placeholder for a pointer to the optional user-defined |
| 443 | * private data associated with this kernel control instance. This |
| 444 | * opaque info will be provided to the user when the rest of the |
| 445 | * callback routines are executed. For example, it can be used |
| 446 | * to pass a pointer to an instance-specific data structure in |
| 447 | * order for the user to keep track of the states related to this |
| 448 | * kernel control instance. |
| 449 | */ |
| 450 | typedef errno_t (*ctl_bind_func)(kern_ctl_ref kctlref, |
| 451 | struct sockaddr_ctl *sac, |
| 452 | void **unitinfo); |
| 453 | |
| 454 | /*! |
| 455 | * @typedef ctl_setup_func |
| 456 | * @discussion The ctl_setup_func is an optional function that allows the client |
| 457 | * to pick a unit number in the case that the caller hasn't specified one |
| 458 | * @param unit A placeholder for a pointer to the unit number that is selected with |
| 459 | * this kernel control instance |
| 460 | * @param unitinfo A placeholder for a pointer to the optional user-defined |
| 461 | * private data associated with this kernel control instance. This |
| 462 | * opaque info will be provided to the user when the rest of the |
| 463 | * callback routines are executed. For example, it can be used |
| 464 | * to pass a pointer to an instance-specific data structure in |
| 465 | * order for the user to keep track of the states related to this |
| 466 | * kernel control instance. |
| 467 | */ |
| 468 | typedef errno_t (*ctl_setup_func)(u_int32_t *unit, void **unitinfo); |
| 469 | #endif /* KERNEL_PRIVATE */ |
| 470 | |
| 471 | /*! |
| 472 | * @struct kern_ctl_reg |
| 473 | * @discussion This structure defines the properties of a kernel |
| 474 | * control being registered. |
| 475 | * @field ctl_name A Bundle ID string of up to MAX_KCTL_NAME bytes (including the ending zero). |
| 476 | * This string should not be empty. |
| 477 | * @field ctl_id The control ID may be dynamically assigned or it can be a |
| 478 | * 32-bit creator code assigned by DTS. |
| 479 | * For a DTS assigned creator code the CTL_FLAG_REG_ID_UNIT flag must be set. |
| 480 | * For a dynamically assigned control ID, do not set the CTL_FLAG_REG_ID_UNIT flag. |
| 481 | * The value of the dynamically assigned control ID is set to this field |
| 482 | * when the registration succeeds. |
| 483 | * @field ctl_unit A separate unit number to register multiple units that |
| 484 | * share the same control ID with DTS assigned creator code when |
| 485 | * the CTL_FLAG_REG_ID_UNIT flag is set. |
| 486 | * This field is ignored for a dynamically assigned control ID. |
| 487 | * @field ctl_flags CTL_FLAG_PRIVILEGED and/or CTL_FLAG_REG_ID_UNIT. |
| 488 | * @field ctl_sendsize Override the default send size. If set to zero, |
| 489 | * the default send size will be used, and this default value |
| 490 | * is set to this field to be retrieved by the caller. |
| 491 | * @field ctl_recvsize Override the default receive size. If set to |
| 492 | * zero, the default receive size will be used, and this default value |
| 493 | * is set to this field to be retrieved by the caller. |
| 494 | * @field ctl_connect Specify the function to be called whenever a client |
| 495 | * connects to the kernel control. This field must be specified. |
| 496 | * @field ctl_disconnect Specify a function to be called whenever a |
| 497 | * client disconnects from the kernel control. |
| 498 | * @field ctl_send Specify a function to handle data send from the |
| 499 | * client to the kernel control. |
| 500 | * @field ctl_setopt Specify a function to handle set socket option |
| 501 | * operations for the kernel control. |
| 502 | * @field ctl_getopt Specify a function to handle get socket option |
| 503 | * operations for the kernel control. |
| 504 | */ |
| 505 | struct kern_ctl_reg { |
| 506 | /* control information */ |
| 507 | char ctl_name[MAX_KCTL_NAME]; |
| 508 | u_int32_t ctl_id; |
| 509 | u_int32_t ctl_unit; |
| 510 | |
| 511 | /* control settings */ |
| 512 | u_int32_t ctl_flags; |
| 513 | u_int32_t ctl_sendsize; |
| 514 | u_int32_t ctl_recvsize; |
| 515 | |
| 516 | /* Dispatch functions */ |
| 517 | ctl_connect_func ctl_connect; |
| 518 | ctl_disconnect_func ctl_disconnect; |
| 519 | ctl_send_func ctl_send; |
| 520 | ctl_setopt_func ctl_setopt; |
| 521 | ctl_getopt_func ctl_getopt; |
| 522 | #ifdef KERNEL_PRIVATE |
| 523 | ctl_rcvd_func ctl_rcvd; /* Only valid if CTL_FLAG_REG_EXTENDED is set */ |
| 524 | ctl_send_list_func ctl_send_list;/* Only valid if CTL_FLAG_REG_EXTENDED is set */ |
| 525 | ctl_bind_func ctl_bind; |
| 526 | ctl_setup_func ctl_setup; |
| 527 | #endif /* KERNEL_PRIVATE */ |
| 528 | }; |
| 529 | |
| 530 | /*! |
| 531 | * @function ctl_register |
| 532 | * @discussion Register a kernel control. This will enable clients to |
| 533 | * connect to the kernel control using a PF_SYSTEM socket. |
| 534 | * @param userkctl A structure defining the kernel control to be |
| 535 | * attached. The ctl_connect callback must be specified, the other callbacks |
| 536 | * are optional. If ctl_connect is set to zero, ctl_register fails with |
| 537 | * the error code EINVAL. |
| 538 | * @param kctlref Upon successful return, the kctlref will contain a |
| 539 | * reference to the attached kernel control. This reference is used |
| 540 | * to unregister the kernel control. This reference will also be |
| 541 | * passed in to the callbacks each time they are called. |
| 542 | * @result 0 - Kernel control was registered. |
| 543 | * EINVAL - The registration structure was not valid. |
| 544 | * ENOMEM - There was insufficient memory. |
| 545 | * EEXIST - A controller with that id/unit is already registered. |
| 546 | */ |
| 547 | errno_t |
| 548 | ctl_register(struct kern_ctl_reg *userkctl, kern_ctl_ref *kctlref); |
| 549 | |
| 550 | /*! |
| 551 | * @function ctl_deregister |
| 552 | * @discussion Unregister a kernel control. A kernel extension must |
| 553 | * unregister it's kernel control(s) before unloading. If a kernel |
| 554 | * control has clients attached, this call will fail. |
| 555 | * @param kctlref The control reference of the control to unregister. |
| 556 | * @result 0 - Kernel control was unregistered. |
| 557 | * EINVAL - The kernel control reference was invalid. |
| 558 | * EBUSY - The kernel control has clients still attached. |
| 559 | */ |
| 560 | errno_t |
| 561 | ctl_deregister(kern_ctl_ref kctlref); |
| 562 | |
| 563 | /*! |
| 564 | * @function ctl_enqueuedata |
| 565 | * @discussion Send data from the kernel control to the client. |
| 566 | * @param kctlref The control reference of the kernel control. |
| 567 | * @param unit The unit number of the kernel control instance. |
| 568 | * @param data A pointer to the data to send. |
| 569 | * @param len The length of data to send. |
| 570 | * @param flags Send flags. CTL_DATA_NOWAKEUP and CTL_DATA_EOR are currently |
| 571 | * the only supported flags. |
| 572 | * @result 0 - Data was enqueued to be read by the client. |
| 573 | * EINVAL - Invalid parameters. |
| 574 | * EMSGSIZE - The buffer is too large. |
| 575 | * ENOBUFS - The queue is full or there are no free mbufs. |
| 576 | */ |
| 577 | errno_t |
| 578 | ctl_enqueuedata(kern_ctl_ref kctlref, u_int32_t unit, void *data, size_t len, u_int32_t flags); |
| 579 | |
| 580 | /*! |
| 581 | * @function ctl_enqueuembuf |
| 582 | * @discussion Send data stored in an mbuf chain from the kernel |
| 583 | * control to the client. The caller is responsible for freeing |
| 584 | * the mbuf chain if ctl_enqueuembuf returns an error. |
| 585 | * @param kctlref The control reference of the kernel control. |
| 586 | * @param unit The unit number of the kernel control instance. |
| 587 | * @param m An mbuf chain containing the data to send to the client. |
| 588 | * @param flags Send flags. CTL_DATA_NOWAKEUP and CTL_DATA_EOR are currently |
| 589 | * the only supported flags. |
| 590 | * @result 0 - Data was enqueued to be read by the client. |
| 591 | * EINVAL - Invalid parameters. |
| 592 | * ENOBUFS - The queue is full. |
| 593 | */ |
| 594 | errno_t |
| 595 | ctl_enqueuembuf(kern_ctl_ref kctlref, u_int32_t unit, mbuf_t m, u_int32_t flags); |
| 596 | |
| 597 | #ifdef PRIVATE |
| 598 | /*! |
| 599 | * @function ctl_enqueuembuf_list |
| 600 | * @discussion Send data stored in an mbuf packet chain from the kernel |
| 601 | * control to the client. The caller is responsible for freeing |
| 602 | * the mbuf chain if ctl_enqueuembuf returns an error. |
| 603 | * Not valid if ctl_flags contains CTL_FLAG_REG_SOCK_STREAM. |
| 604 | * @param kctlref The control reference of the kernel control. |
| 605 | * @param unit The unit number of the kernel control instance. |
| 606 | * @param m_list An mbuf chain containing the data to send to the client. |
| 607 | * @param flags Send flags. CTL_DATA_NOWAKEUP is |
| 608 | * the only supported flags. |
| 609 | * @param m_remain A pointer to the list of mbuf packets in the chain that |
| 610 | * could not be enqueued. |
| 611 | * @result 0 - Data was enqueued to be read by the client. |
| 612 | * EINVAL - Invalid parameters. |
| 613 | * ENOBUFS - The queue is full. |
| 614 | */ |
| 615 | errno_t |
| 616 | ctl_enqueuembuf_list(kern_ctl_ref kctlref, u_int32_t unit, mbuf_t m_list, |
| 617 | u_int32_t flags, mbuf_t *m_remain); |
| 618 | |
| 619 | /*! |
| 620 | * @function ctl_getenqueuepacketcount |
| 621 | * @discussion Retrieve the number of packets in the socket |
| 622 | * receive buffer. |
| 623 | * @param kctlref The control reference of the kernel control. |
| 624 | * @param unit The unit number of the kernel control instance. |
| 625 | * @param pcnt The address where to return the current count. |
| 626 | * @result 0 - Success; the packet count is returned to caller. |
| 627 | * EINVAL - Invalid parameters. |
| 628 | */ |
| 629 | errno_t |
| 630 | ctl_getenqueuepacketcount(kern_ctl_ref kctlref, u_int32_t unit, u_int32_t *pcnt); |
| 631 | |
| 632 | #endif /* PRIVATE */ |
| 633 | |
| 634 | /*! |
| 635 | * @function ctl_getenqueuespace |
| 636 | * @discussion Retrieve the amount of space currently available for data to be sent |
| 637 | * from the kernel control to the client. |
| 638 | * @param kctlref The control reference of the kernel control. |
| 639 | * @param unit The unit number of the kernel control instance. |
| 640 | * @param space The address where to return the current space available |
| 641 | * @result 0 - Success; the amount of space is returned to caller. |
| 642 | * EINVAL - Invalid parameters. |
| 643 | */ |
| 644 | errno_t |
| 645 | ctl_getenqueuespace(kern_ctl_ref kctlref, u_int32_t unit, size_t *space); |
| 646 | |
| 647 | /*! |
| 648 | * @function ctl_getenqueuereadable |
| 649 | * @discussion Retrieve the difference between enqueued bytes and |
| 650 | * low-water mark for the socket receive buffer. |
| 651 | * @param kctlref The control reference of the kernel control. |
| 652 | * @param unit The unit number of the kernel control instance. |
| 653 | * @param difference The address at which to return the current difference |
| 654 | * between the low-water mark for the socket and the number of bytes |
| 655 | * enqueued. 0 indicates that the socket is readable by the client |
| 656 | * (the number of bytes in the buffer is above the low-water mark). |
| 657 | * @result 0 - Success; the difference is returned to caller. |
| 658 | * EINVAL - Invalid parameters. |
| 659 | */ |
| 660 | errno_t |
| 661 | ctl_getenqueuereadable(kern_ctl_ref kctlref, u_int32_t unit, u_int32_t *difference); |
| 662 | |
| 663 | #ifdef KERNEL_PRIVATE |
| 664 | |
| 665 | #include <sys/queue.h> |
| 666 | #include <libkern/locks.h> |
| 667 | |
| 668 | /* |
| 669 | * internal structure maintained for each register controller |
| 670 | */ |
| 671 | struct ctl_cb; |
| 672 | struct kctl; |
| 673 | struct socket; |
| 674 | struct socket_info; |
| 675 | |
| 676 | void kctl_fill_socketinfo(struct socket *, struct socket_info *); |
| 677 | |
| 678 | u_int32_t ctl_id_by_name(const char *name); |
| 679 | errno_t ctl_name_by_id(u_int32_t id, char *out_name, size_t maxsize); |
| 680 | |
| 681 | extern const u_int32_t ctl_maxunit; |
| 682 | #endif /* KERNEL_PRIVATE */ |
| 683 | |
| 684 | __END_DECLS |
| 685 | #endif /* KERNEL */ |
| 686 | |
| 687 | #endif /* KPI_KERN_CONTROL_H */ |
| 688 | |