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