/*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2012-2016 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
+ *
* 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
* 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.
- *
+ *
* 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,
* 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_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.
+ * @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
#include <sys/appleapiopts.h>
+#include <sys/_types/_u_char.h>
+#include <sys/_types/_u_int16_t.h>
+#include <sys/_types/_u_int32_t.h>
/*
* Define Controller event subclass, and associated events.
*/
/*!
- @defined KEV_CTL_SUBCLASS
- @discussion The kernel event subclass for kernel control events.
-*/
+ * @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.
-*/
+ * @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 */
/*!
- @defined KEV_CTL_DEREGISTERED
- @discussion The event code indicating a controller was unregistered.
- The data portion will contain a ctl_event_data.
-*/
+ * @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 */
/*!
- @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
+ * @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; /* Kernel Controller ID */
- u_int32_t ctl_unit;
+ u_int32_t ctl_id; /* Kernel Controller ID */
+ u_int32_t ctl_unit;
};
/*
*/
/*!
- @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 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 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
+ * @defined MAX_KCTL_NAME
+ * @discussion Kernel control names must be no longer than
+ * MAX_KCTL_NAME.
+ */
+#define MAX_KCTL_NAME 96
/*
* Controls destined to the Controller Manager.
*/
/*!
- @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
+ * @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) */
+ 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
+ * @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_KERNCONTROL */
- u_int32_t sc_id; /* Controller unique identifier */
- u_int32_t sc_unit; /* Developer private unit number */
- u_int32_t sc_reserved[5];
+ u_char sc_len; /* depends on size of bundle ID string */
+ u_char sc_family; /* AF_SYSTEM */
+ 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];
+};
+
+#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
#include <sys/kpi_mbuf.h>
/*!
- @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 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;
/*!
- @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
+ * @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 */
/*!
- @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
+ * @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
+
+#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 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 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);
+ 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 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.
+ 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);
-
-/*!
- @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
-{
+ 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 */
- char ctl_name[MAX_KCTL_NAME];
- u_int32_t ctl_id;
- u_int32_t ctl_unit;
-
- /* control settings */
- u_int32_t ctl_flags;
- u_int32_t ctl_sendsize;
- u_int32_t ctl_recvsize;
-
- /* Dispatch functions */
- 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;
+ char ctl_name[MAX_KCTL_NAME];
+ u_int32_t ctl_id;
+ u_int32_t ctl_unit;
+
+ /* control settings */
+ u_int32_t ctl_flags;
+ u_int32_t ctl_sendsize;
+ u_int32_t ctl_recvsize;
+
+ /* Dispatch functions */
+ 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.
+ * @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 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 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.
*/
errno_t
-ctl_register(struct kern_ctl_reg *userkctl, kern_ctl_ref *kctlref);
-
-/*!
- @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 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 is currently the only
- supported flag.
- @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.
- */
-errno_t
ctl_enqueuedata(kern_ctl_ref kctlref, u_int32_t unit, 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 is currently the only
- supported flag.
- @result 0 - Data was enqueued to be read by the client.
- EINVAL - Invalid parameters.
- ENOBUFS - The queue is full.
- */
-errno_t
+ * @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.
+ * @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
+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 <sys/queue.h>
+#include <libkern/locks.h>
+
+/*
+ * 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 */
#endif /* KERNEL */
#endif /* KPI_KERN_CONTROL_H */
-