| 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 |  | 
|---|