X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/e5568f75972dfc723778653c11cb6b4dc825716a..b226f5e54a60dc81db17b1260381d7dbfea3cdf1:/bsd/sys/kern_control.h?ds=inline diff --git a/bsd/sys/kern_control.h b/bsd/sys/kern_control.h index 04b37c06a..51324ea65 100644 --- a/bsd/sys/kern_control.h +++ b/bsd/sys/kern_control.h @@ -1,238 +1,662 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2004, 2012-2016 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/*! + @header kern_control.h + This header defines an API to communicate between a kernel + extension and a process outside of the kernel. */ +#ifndef KPI_KERN_CONTROL_H +#define KPI_KERN_CONTROL_H -#ifndef SYS_KERN_CONTROL_H -#define SYS_KERN_CONTROL_H #include +#include +#include +#include -#ifdef __APPLE_API_UNSTABLE /* * Define Controller event subclass, and associated events. + * Subclass of KEV_SYSTEM_CLASS */ -/* Subclass of KEV_SYSTEM_CLASS */ -#define KEV_CTL_SUBCLASS 1 +/*! + @defined KEV_CTL_SUBCLASS + @discussion The kernel event subclass for kernel control events. +*/ +#define KEV_CTL_SUBCLASS 2 + +/*! + @defined KEV_CTL_REGISTERED + @discussion The event code indicating a new controller was + registered. The data portion will contain a ctl_event_data. +*/ +#define KEV_CTL_REGISTERED 1 /* a new controller appears */ -#define KEV_CTL_REGISTERED 1 /* a new controller appears */ -#define KEV_CTL_DEREGISTERED 2 /* a controller disappears */ +/*! + @defined KEV_CTL_DEREGISTERED + @discussion The event code indicating a controller was unregistered. + The data portion will contain a ctl_event_data. +*/ +#define KEV_CTL_DEREGISTERED 2 /* a controller disappears */ -/* All KEV_CTL_SUBCLASS events share the same header */ +/*! + @struct ctl_event_data + @discussion This structure is used for KEV_CTL_SUBCLASS kernel + events. + @field ctl_id The kernel control id. + @field ctl_unit The kernel control unit. +*/ struct ctl_event_data { - u_int32_t ctl_id; + u_int32_t ctl_id; /* Kernel Controller ID */ u_int32_t ctl_unit; }; - /* * Controls destined to the Controller Manager. */ -#define CTLIOCGCOUNT _IOR('N', 1, int) /* get number of control structures registered */ +/*! + @defined CTLIOCGCOUNT + @discussion The CTLIOCGCOUNT ioctl can be used to determine the + number of kernel controllers registered. +*/ +#define CTLIOCGCOUNT _IOR('N', 2, int) /* get number of control structures registered */ + +/*! + @defined CTLIOCGINFO + @discussion The CTLIOCGINFO ioctl can be used to convert a kernel + control name to a kernel control id. +*/ +#define CTLIOCGINFO _IOWR('N', 3, struct ctl_info) /* get id from name */ + + +/*! + @defined MAX_KCTL_NAME + @discussion Kernel control names must be no longer than + MAX_KCTL_NAME. +*/ +#define MAX_KCTL_NAME 96 /* - * Controller address structure - * used to establish contact between user client and kernel controller - * sc_id/sc_unit uniquely identify each controller - * sc_id is a 32-bit "signature" obtained by developers from Apple Computer - * sc_unit is a unit number for this sc_id, and is privately used - * by the developper to identify several instances to control + * Controls destined to the Controller Manager. */ -struct sockaddr_ctl -{ - u_char sc_len; /* sizeof(struct sockaddr_ctl) */ +/*! + @struct ctl_info + @discussion This structure is used with the CTLIOCGINFO ioctl to + translate from a kernel control name to a control id. + @field ctl_id The kernel control id, filled out upon return. + @field ctl_name The kernel control name to find. +*/ +struct ctl_info { + u_int32_t ctl_id; /* Kernel Controller ID */ + char ctl_name[MAX_KCTL_NAME]; /* Kernel Controller Name (a C string) */ +}; + + +/*! + @struct sockaddr_ctl + @discussion The controller address structure is used to establish + contact between a user client and a kernel controller. The + sc_id/sc_unit uniquely identify each controller. sc_id is a + unique identifier assigned to the controller. The identifier can + be assigned by the system at registration time or be a 32-bit + creator code obtained from Apple Computer. sc_unit is a unit + number for this sc_id, and is privately used by the kernel + controller to identify several instances of the controller. + @field sc_len The length of the structure. + @field sc_family AF_SYSTEM. + @field ss_sysaddr AF_SYS_KERNCONTROL. + @field sc_id Controller unique identifier. + @field sc_unit Kernel controller private unit number. + @field sc_reserved Reserved, must be set to zero. +*/ +struct sockaddr_ctl { + u_char sc_len; /* depends on size of bundle ID string */ u_char sc_family; /* AF_SYSTEM */ - u_int16_t ss_sysaddr; /* AF_SYS_CONTROL */ - u_int32_t sc_id; /* 32-bit "signature" managed by Apple */ + u_int16_t ss_sysaddr; /* AF_SYS_KERNCONTROL */ + u_int32_t sc_id; /* Controller unique identifier */ u_int32_t sc_unit; /* Developer private unit number */ u_int32_t sc_reserved[5]; }; -#endif /* __APPLE_API_UNSTABLE */ + +#ifdef PRIVATE + +struct xkctl_reg { + u_int32_t xkr_len; + u_int32_t xkr_kind; + u_int32_t xkr_id; + u_int32_t xkr_reg_unit; + u_int32_t xkr_flags; + u_int64_t xkr_kctlref; + u_int32_t xkr_recvbufsize; + u_int32_t xkr_sendbufsize; + u_int32_t xkr_lastunit; + u_int32_t xkr_pcbcount; + u_int64_t xkr_connect; + u_int64_t xkr_disconnect; + u_int64_t xkr_send; + u_int64_t xkr_send_list; + u_int64_t xkr_setopt; + u_int64_t xkr_getopt; + u_int64_t xkr_rcvd; + char xkr_name[MAX_KCTL_NAME]; +}; + +struct xkctlpcb { + u_int32_t xkp_len; + u_int32_t xkp_kind; + u_int64_t xkp_kctpcb; + u_int32_t xkp_unit; + u_int32_t xkp_kctlid; + u_int64_t xkp_kctlref; + char xkp_kctlname[MAX_KCTL_NAME]; +}; + +struct kctlstat { + u_int64_t kcs_reg_total __attribute__((aligned(8))); + u_int64_t kcs_reg_count __attribute__((aligned(8))); + u_int64_t kcs_pcbcount __attribute__((aligned(8))); + u_int64_t kcs_gencnt __attribute__((aligned(8))); + u_int64_t kcs_connections __attribute__((aligned(8))); + u_int64_t kcs_conn_fail __attribute__((aligned(8))); + u_int64_t kcs_send_fail __attribute__((aligned(8))); + u_int64_t kcs_send_list_fail __attribute__((aligned(8))); + u_int64_t kcs_enqueue_fail __attribute__((aligned(8))); + u_int64_t kcs_enqueue_fullsock __attribute__((aligned(8))); + u_int64_t kcs_bad_kctlref __attribute__((aligned(8))); + u_int64_t kcs_tbl_size_too_big __attribute__((aligned(8))); + u_int64_t kcs_enqdata_mb_alloc_fail __attribute__((aligned(8))); + u_int64_t kcs_enqdata_sbappend_fail __attribute__((aligned(8))); +}; + +#endif /* PRIVATE */ #ifdef KERNEL -#ifdef __APPLE_API_UNSTABLE -/* Reference to a controller object */ +#include + +/*! + @typedef kern_ctl_ref + @discussion A control reference is used to track an attached kernel + control. Registering a kernel control will create a kernel + control reference. This reference is required for sending data + or removing the kernel control. This reference will be passed to + callbacks for that kernel control. +*/ typedef void * kern_ctl_ref; -/* Support flags for controllers */ -#define CTL_FLAG_PRIVILEGED 0x1 /* user must be root to contact controller */ +/*! + @defined CTL_FLAG_PRIVILEGED + @discussion The CTL_FLAG_PRIVILEGED flag is passed in ctl_flags. If + this flag is set, only privileged processes may attach to this + kernel control. +*/ +#define CTL_FLAG_PRIVILEGED 0x1 +/*! + @defined CTL_FLAG_REG_ID_UNIT + @discussion The CTL_FLAG_REG_ID_UNIT flag is passed to indicate that + the ctl_id specified should be used. If this flag is not + present, a unique ctl_id will be dynamically assigned to your + kernel control. The CTLIOCGINFO ioctl can be used by the client + to find the dynamically assigned id based on the control name + specified in ctl_name. +*/ +#define CTL_FLAG_REG_ID_UNIT 0x2 +/*! + @defined CTL_FLAG_REG_SOCK_STREAM + @discussion Use the CTL_FLAG_REG_SOCK_STREAM flag when client need to open + socket of type SOCK_STREAM to communicate with the kernel control. + By default kernel control sockets are of type SOCK_DGRAM. +*/ +#define CTL_FLAG_REG_SOCK_STREAM 0x4 + +#ifdef KERNEL_PRIVATE +/*! + @defined CTL_FLAG_REG_EXTENDED + @discussion This flag indicates that this kernel control utilizes the + the extended fields within the kern_ctl_reg structure. +*/ +#define CTL_FLAG_REG_EXTENDED 0x8 + +/*! + @defined CTL_FLAG_REG_CRIT + @discussion This flag indicates that this kernel control utilizes the + the extended fields within the kern_ctl_reg structure. +*/ +#define CTL_FLAG_REG_CRIT 0x10 +#endif /* KERNEL_PRIVATE */ /* Data flags for controllers */ -#define CTL_DATA_NOWAKEUP 0x1 /* don't wake up client yet */ +/*! + @defined CTL_DATA_NOWAKEUP + @discussion The CTL_DATA_NOWAKEUP flag can be used for the enqueue + data and enqueue mbuf functions to indicate that the process + should not be woken up yet. This is useful when you want to + enqueue data using more than one call but only want to wake up + the client after all of the data has been enqueued. +*/ +#define CTL_DATA_NOWAKEUP 0x1 +/*! + @defined CTL_DATA_EOR + @discussion The CTL_DATA_EOR flag can be used for the enqueue + data and enqueue mbuf functions to mark the end of a record. +*/ +#define CTL_DATA_EOR 0x2 -/* - * Controller registration structure, given at registration time +#ifdef KERNEL_PRIVATE +/*! + @defined CTL_DATA_CRIT + @discussion This flag indicates the data is critical to the client + and that it needs to be forced into the socket buffer + by resizing it if needed. +*/ +#define CTL_DATA_CRIT 0x4 +#endif /* KERNEL_PRIVATE */ + +__BEGIN_DECLS + +/*! + @typedef ctl_connect_func + @discussion The ctl_connect_func is used to receive + notification of a client connecting to the kernel control. + @param kctlref The control ref for the kernel control the client is + connecting to. + @param sac The address used to connect to this control. The field sc_unit + contains the unit number of the kernel control instance the client is + connecting to. If CTL_FLAG_REG_ID_UNIT was set when the kernel control + was registered, sc_unit is the ctl_unit of the kern_ctl_reg structure. + If CTL_FLAG_REG_ID_UNIT was not set when the kernel control was + registered, sc_unit is the dynamically allocated unit number of + the new kernel control instance that is used for this connection. + @param unitinfo A placeholder for a pointer to the optional user-defined + private data associated with this kernel control instance. This + opaque info will be provided to the user when the rest of the + callback routines are executed. For example, it can be used + to pass a pointer to an instance-specific data structure in + order for the user to keep track of the states related to this + kernel control instance. + */ +typedef errno_t (*ctl_connect_func)(kern_ctl_ref kctlref, + struct sockaddr_ctl *sac, + void **unitinfo); + +/*! + @typedef ctl_disconnect_func + @discussion The ctl_disconnect_func is used to receive notification + that a client has disconnected from the kernel control. This + usually happens when the socket is closed. If this is the last + socket attached to your kernel control, you may unregister your + kernel control from this callback. + @param kctlref The control ref for the kernel control instance the client has + disconnected from. + @param unit The unit number of the kernel control instance the client has + disconnected from. + @param unitinfo The user-defined private data initialized by the + ctl_connect_func callback. + */ +typedef errno_t (*ctl_disconnect_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo); + +/*! + @typedef ctl_send_func + @discussion The ctl_send_func is used to receive data sent from + the client to the kernel control. + @param kctlref The control ref of the kernel control. + @param unit The unit number of the kernel control instance the client has + connected to. + @param unitinfo The user-defined private data initialized by the + ctl_connect_func callback. + @param m The data sent by the client to the kernel control in an + mbuf chain. Your function is responsible for releasing the + mbuf chain. + @param flags The flags specified by the client when calling + send/sendto/sendmsg (MSG_OOB/MSG_DONTROUTE). + */ +typedef errno_t (*ctl_send_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, + mbuf_t m, int flags); + +/*! + @typedef ctl_setopt_func + @discussion The ctl_setopt_func is used to handle set socket option + calls for the SYSPROTO_CONTROL option level. + @param kctlref The control ref of the kernel control. + @param unit The unit number of the kernel control instance. + @param unitinfo The user-defined private data initialized by the + ctl_connect_func callback. + @param opt The socket option. + @param data A pointer to the socket option data. The data has + already been copied in to the kernel for you. + @param len The length of the socket option data. + */ +typedef errno_t (*ctl_setopt_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, + int opt, void *data, size_t len); + +/*! + @typedef ctl_getopt_func + @discussion The ctl_getopt_func is used to handle client get socket + option requests for the SYSPROTO_CONTROL option level. A buffer + is allocated for storage and passed to your function. The length + of that buffer is also passed. Upon return, you should set *len + to length of the buffer used. In some cases, data may be NULL. + When this happens, *len should be set to the length you would + have returned had data not been NULL. If the buffer is too small, + return an error. + @param kctlref The control ref of the kernel control. + @param unit The unit number of the kernel control instance. + @param unitinfo The user-defined private data initialized by the + ctl_connect_func callback. + @param opt The socket option. + @param data A buffer to copy the results in to. May be NULL, see + discussion. + @param len A pointer to the length of the buffer. This should be set + to the length of the buffer used before returning. + */ +typedef errno_t (*ctl_getopt_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, + int opt, void *data, size_t *len); + +#ifdef KERNEL_PRIVATE +/*! + @typedef ctl_rcvd_func + @discussion The ctl_rcvd_func is called when the client reads data from + the kernel control socket. The kernel control can use this callback + in combination with ctl_getenqueuespace() to avoid overflowing + the socket's receive buffer. When ctl_getenqueuespace() returns + 0 or ctl_enqueuedata()/ctl_enqueuembuf() return ENOBUFS, the + kernel control can wait until this callback is called before + trying to enqueue the data again. + @param kctlref The control ref of the kernel control. + @param unit The unit number of the kernel control instance. + @param unitinfo The user-defined private data initialized by the + ctl_connect_func callback. + @param flags The recv flags. See the recv(2) man page. */ +typedef void (*ctl_rcvd_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, + int flags); + +/*! + @typedef ctl_send_list_func + @discussion The ctl_send_list_func is used to receive data sent from + the client to the kernel control. + @param kctlref The control ref of the kernel control. + @param unit The unit number of the kernel control instance the client has + connected to. + @param unitinfo The user-defined private data initialized by the + ctl_connect_func callback. + @param m The data sent by the client to the kernel control in an + mbuf packet chain. Your function is responsible for releasing + mbuf packet chain. + @param flags The flags specified by the client when calling + send/sendto/sendmsg (MSG_OOB/MSG_DONTROUTE). + */ +typedef errno_t (*ctl_send_list_func)(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo, + mbuf_t m, int flags); + +/*! + @typedef ctl_bind_func + @discussion The ctl_bind_func is an optional function that allows the client + to set up their unitinfo prior to connecting. + @param kctlref The control ref for the kernel control the client is + binding to. + @param sac The address used to connect to this control. The field sc_unit + contains the unit number of the kernel control instance the client is + binding to. If CTL_FLAG_REG_ID_UNIT was set when the kernel control + was registered, sc_unit is the ctl_unit of the kern_ctl_reg structure. + If CTL_FLAG_REG_ID_UNIT was not set when the kernel control was + registered, sc_unit is the dynamically allocated unit number of + the new kernel control instance that is used for this connection. + @param unitinfo A placeholder for a pointer to the optional user-defined + private data associated with this kernel control instance. This + opaque info will be provided to the user when the rest of the + callback routines are executed. For example, it can be used + to pass a pointer to an instance-specific data structure in + order for the user to keep track of the states related to this + kernel control instance. + */ +typedef errno_t (*ctl_bind_func)(kern_ctl_ref kctlref, + struct sockaddr_ctl *sac, + void **unitinfo); +#endif /* KERNEL_PRIVATE */ + +/*! + @struct kern_ctl_reg + @discussion This structure defines the properties of a kernel + control being registered. + @field ctl_name A Bundle ID string of up to MAX_KCTL_NAME bytes (including the ending zero). + This string should not be empty. + @field ctl_id The control ID may be dynamically assigned or it can be a + 32-bit creator code assigned by DTS. + For a DTS assigned creator code the CTL_FLAG_REG_ID_UNIT flag must be set. + For a dynamically assigned control ID, do not set the CTL_FLAG_REG_ID_UNIT flag. + The value of the dynamically assigned control ID is set to this field + when the registration succeeds. + @field ctl_unit A separate unit number to register multiple units that + share the same control ID with DTS assigned creator code when + the CTL_FLAG_REG_ID_UNIT flag is set. + This field is ignored for a dynamically assigned control ID. + @field ctl_flags CTL_FLAG_PRIVILEGED and/or CTL_FLAG_REG_ID_UNIT. + @field ctl_sendsize Override the default send size. If set to zero, + the default send size will be used, and this default value + is set to this field to be retrieved by the caller. + @field ctl_recvsize Override the default receive size. If set to + zero, the default receive size will be used, and this default value + is set to this field to be retrieved by the caller. + @field ctl_connect Specify the function to be called whenever a client + connects to the kernel control. This field must be specified. + @field ctl_disconnect Specify a function to be called whenever a + client disconnects from the kernel control. + @field ctl_send Specify a function to handle data send from the + client to the kernel control. + @field ctl_setopt Specify a function to handle set socket option + operations for the kernel control. + @field ctl_getopt Specify a function to handle get socket option + operations for the kernel control. +*/ struct kern_ctl_reg { - /* control information */ - u_int32_t ctl_id; /* unique id of the controller, provided by DTS */ - u_int32_t ctl_unit; /* unit number for the controller, for the specified id */ - /* a controller can be registered several times with the same id */ - /* but must have a different unit number */ - + /* control information */ + char ctl_name[MAX_KCTL_NAME]; + u_int32_t ctl_id; + u_int32_t ctl_unit; + /* control settings */ - u_int32_t ctl_flags; /* support flags */ - u_int32_t ctl_sendsize; /* override send/receive buffer size */ - u_int32_t ctl_recvsize; /* 0 = use default values */ + u_int32_t ctl_flags; + u_int32_t ctl_sendsize; + u_int32_t ctl_recvsize; /* Dispatch functions */ - - int (*ctl_connect) - (kern_ctl_ref ctlref, void *userdata); - /* Make contact, called when user client calls connect */ - /* the socket with the id/unit of the controller */ - - void (*ctl_disconnect) - (kern_ctl_ref ctlref, void *userdata); - /* Break contact, called when user client */ - /* closes the control socket */ - - int (*ctl_write) - (kern_ctl_ref ctlref, void *userdata, struct mbuf *m); - /* Send data to the controller, called when user client */ - /* writes data to the socket */ - - int (*ctl_set) - (kern_ctl_ref ctlref, void *userdata, int opt, void *data, size_t len); - /* set controller configuration, called when user client */ - /* calls setsockopt() for the socket */ - /* opt is the option number */ - /* data points to the data, already copied in kernel space */ - /* len is the lenght of the data buffer */ - - int (*ctl_get) - (kern_ctl_ref ctlref, void *userdata, int opt, void *data, size_t *len); - /* get controller configuration, called when user client */ - /* calls getsockopt() for the socket */ - /* opt is the option number */ - /* data points to the data buffer of max lenght len */ - /* the controller can directly copy data in the buffer space */ - /* and does not need to worry about copying out the data */ - /* as long as it respects the max buffer lenght */ - /* on input, len contains the maximum buffer length */ - /* on output, len contains the actual buffer lenght */ - /* if data is NULL on input, then, by convention, the controller */ - /* should return in len the lenght of the data it would like */ - /* to return in the subsequent call for that option */ - - /* prepare the future */ - u_int32_t ctl_reserved[4]; /* for future use if needed */ + ctl_connect_func ctl_connect; + ctl_disconnect_func ctl_disconnect; + ctl_send_func ctl_send; + ctl_setopt_func ctl_setopt; + ctl_getopt_func ctl_getopt; +#ifdef KERNEL_PRIVATE + ctl_rcvd_func ctl_rcvd; /* Only valid if CTL_FLAG_REG_EXTENDED is set */ + ctl_send_list_func ctl_send_list; /* Only valid if CTL_FLAG_REG_EXTENDED is set */ + ctl_bind_func ctl_bind; +#endif /* KERNEL_PRIVATE */ }; +/*! + @function ctl_register + @discussion Register a kernel control. This will enable clients to + connect to the kernel control using a PF_SYSTEM socket. + @param userkctl A structure defining the kernel control to be + attached. The ctl_connect callback must be specified, the other callbacks + are optional. If ctl_connect is set to zero, ctl_register fails with + the error code EINVAL. + @param kctlref Upon successful return, the kctlref will contain a + reference to the attached kernel control. This reference is used + to unregister the kernel control. This reference will also be + passed in to the callbacks each time they are called. + @result 0 - Kernel control was registered. + EINVAL - The registration structure was not valid. + ENOMEM - There was insufficient memory. + EEXIST - A controller with that id/unit is already registered. + */ +errno_t +ctl_register(struct kern_ctl_reg *userkctl, kern_ctl_ref *kctlref); -/* - * FUNCTION : - * Register the controller to the controller manager - * For example, can be called from a Kernel Extension Start routine - * - * PARAMETERS : - * userctl : Registration structure containing control information - * and callback functions for the controller. - * Callbacks are optional and can be null. - * A controller with all callbacks set to null would not be very useful. - * userdata : This parameter is for use by the controller and - * will be passed to every callback function - * - * RETURN CODE : - * 0 : No error - * ctlref will be filled with a control reference, - * to use in subsequent call to the controller manager - * EINVAL : Invalid registration structure - * ENOMEM : Not enough memory available to register the controller - * EEXIST : Controller id/unit already registered - */ - -int -ctl_register(struct kern_ctl_reg *userctl, void *userdata, kern_ctl_ref *ctlref); +/*! + @function ctl_deregister + @discussion Unregister a kernel control. A kernel extension must + unregister it's kernel control(s) before unloading. If a kernel + control has clients attached, this call will fail. + @param kctlref The control reference of the control to unregister. + @result 0 - Kernel control was unregistered. + EINVAL - The kernel control reference was invalid. + EBUSY - The kernel control has clients still attached. + */ +errno_t +ctl_deregister(kern_ctl_ref kctlref); -/* - * FUNCTION : - * Deregister the controller - * For example, can be called from a Kernel Extension Stop routine - * - * PARAMETERS : - * ctlref : Reference to the controller previously registered - * - * RETURN CODE : - * 0 : No error, - * The controller manager no longer knows about the controller - * EINVAL : Invalid reference +/*! + @function ctl_enqueuedata + @discussion Send data from the kernel control to the client. + @param kctlref The control reference of the kernel control. + @param unit The unit number of the kernel control instance. + @param data A pointer to the data to send. + @param len The length of data to send. + @param flags Send flags. CTL_DATA_NOWAKEUP and CTL_DATA_EOR are currently + the only supported flags. + @result 0 - Data was enqueued to be read by the client. + EINVAL - Invalid parameters. + EMSGSIZE - The buffer is too large. + ENOBUFS - The queue is full or there are no free mbufs. */ - -int -ctl_deregister(kern_ctl_ref ctlref); +errno_t +ctl_enqueuedata(kern_ctl_ref kctlref, u_int32_t unit, void *data, size_t len, u_int32_t flags); -/* - * FUNCTION : - * Send data to the application in contact with the controller - * ctl_enqueuedata will allocate a mbuf, copy data and enqueue it. - * - * PARAMETERS : - * ctlref : Reference to the controller previously registered - * data : Data to send - * len : Length of the data (maximum lenght of MCLBYTES) - * flags : Flags used when enqueing - * CTL_DATA_NOWAKEUP = just enqueue, don't wake up client - * - * RETURN CODE : - * 0 : No error - * EINVAL: Invalid reference - * EMSGSIZE: The buffer is too large - * ENOTCONN : No user client is connected - * ENOBUFS : Socket buffer is full, or can't get a new mbuf - * The controller should re-enqueue later - */ - -int -ctl_enqueuedata(kern_ctl_ref ctlref, void *data, size_t len, u_int32_t flags); +/*! + @function ctl_enqueuembuf + @discussion Send data stored in an mbuf chain from the kernel + control to the client. The caller is responsible for freeing + the mbuf chain if ctl_enqueuembuf returns an error. + @param kctlref The control reference of the kernel control. + @param unit The unit number of the kernel control instance. + @param m An mbuf chain containing the data to send to the client. + @param flags Send flags. CTL_DATA_NOWAKEUP and CTL_DATA_EOR are currently + the only supported flags. + @result 0 - Data was enqueued to be read by the client. + EINVAL - Invalid parameters. + ENOBUFS - The queue is full. + */ +errno_t +ctl_enqueuembuf(kern_ctl_ref kctlref, u_int32_t unit, mbuf_t m, u_int32_t flags); + +#ifdef PRIVATE +/*! + @function ctl_enqueuembuf_list + @discussion Send data stored in an mbuf packet chain from the kernel + control to the client. The caller is responsible for freeing + the mbuf chain if ctl_enqueuembuf returns an error. + Not valid if ctl_flags contains CTL_FLAG_REG_SOCK_STREAM. + @param kctlref The control reference of the kernel control. + @param unit The unit number of the kernel control instance. + @param m_list An mbuf chain containing the data to send to the client. + @param flags Send flags. CTL_DATA_NOWAKEUP is + the only supported flags. + @param m_remain A pointer to the list of mbuf packets in the chain that + could not be enqueued. + @result 0 - Data was enqueued to be read by the client. + EINVAL - Invalid parameters. + ENOBUFS - The queue is full. + */ +errno_t +ctl_enqueuembuf_list(kern_ctl_ref kctlref, u_int32_t unit, mbuf_t m_list, + u_int32_t flags, mbuf_t *m_remain); + +/*! + @function ctl_getenqueuepacketcount + @discussion Retrieve the number of packets in the socket + receive buffer. + @param kctlref The control reference of the kernel control. + @param unit The unit number of the kernel control instance. + @param pcnt The address where to return the current count. + @result 0 - Success; the packet count is returned to caller. + EINVAL - Invalid parameters. + */ +errno_t +ctl_getenqueuepacketcount(kern_ctl_ref kctlref, u_int32_t unit, u_int32_t *pcnt); + +#endif /* PRIVATE */ + +/*! + @function ctl_getenqueuespace + @discussion Retrieve the amount of space currently available for data to be sent + from the kernel control to the client. + @param kctlref The control reference of the kernel control. + @param unit The unit number of the kernel control instance. + @param space The address where to return the current space available + @result 0 - Success; the amount of space is returned to caller. + EINVAL - Invalid parameters. + */ +errno_t +ctl_getenqueuespace(kern_ctl_ref kctlref, u_int32_t unit, size_t *space); + +/*! + @function ctl_getenqueuereadable + @discussion Retrieve the difference between enqueued bytes and + low-water mark for the socket receive buffer. + @param kctlref The control reference of the kernel control. + @param unit The unit number of the kernel control instance. + @param difference The address at which to return the current difference + between the low-water mark for the socket and the number of bytes + enqueued. 0 indicates that the socket is readable by the client + (the number of bytes in the buffer is above the low-water mark). + @result 0 - Success; the difference is returned to caller. + EINVAL - Invalid parameters. + */ +errno_t +ctl_getenqueuereadable(kern_ctl_ref kctlref, u_int32_t unit, u_int32_t *difference); + +#ifdef KERNEL_PRIVATE + +#include +#include /* - * FUNCTION : - * Send data to the application in contact with the controller - * - * PARAMETERS : - * ctlref : Reference to the controller previously registered - * m : mbuf containing the data to send - * flags : Flags used when enqueing - * CTL_DATA_NOWAKEUP = just enqueue, don't wake up client - * - * RETURN CODE : - * 0 : No error - * EINVAL: Invalid reference - * ENOTCONN : No user client is connected - * ENOBUFS : Socket buffer is full, - * The controller should either free the mbuf or re-enqueue later - */ - -int -ctl_enqueuembuf(kern_ctl_ref ctlref, struct mbuf *m, u_int32_t flags); - -#endif /* __APPLE_API_UNSTABLE */ + * internal structure maintained for each register controller + */ +struct ctl_cb; +struct kctl; +struct socket; +struct socket_info; + +void kctl_fill_socketinfo(struct socket *, struct socket_info *); + +u_int32_t ctl_id_by_name(const char *name); +errno_t ctl_name_by_id(u_int32_t id, char *out_name, size_t maxsize); +#endif /* KERNEL_PRIVATE */ + +__END_DECLS #endif /* KERNEL */ -#endif /* SYS_KERN_CONTROL_H */ +#endif /* KPI_KERN_CONTROL_H */