]> git.saurik.com Git - apple/xnu.git/blame - bsd/sys/kpi_socketfilter.h
xnu-792.17.14.tar.gz
[apple/xnu.git] / bsd / sys / kpi_socketfilter.h
CommitLineData
91447636
A
1/*
2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
3 *
8f6c56a5 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
91447636 5 *
8f6c56a5
A
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
8ad349bb 24 * limitations under the License.
8f6c56a5
A
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
91447636
A
27 */
28/*!
29 @header kpi_socketfilter.h
30 This header defines an API for intercepting communications at the
31 socket layer.
32
33 For the most part, socket filters want to do three things: Filter
34 data in and out, watch for state changes, and intercept a few calls
35 for security. The number of function pointers supplied by a socket
36 filter has been significantly reduced. The filter no longer has any
37 knowledge of socket buffers. The filter no longer intercepts nearly
38 every internal socket call. There are two data filters, an in
39 filter, and an out filter. The in filter occurs before data is
40 placed in the receive socket buffer. This is done to avoid waking
41 the process unnecessarily. The out filter occurs before the data is
42 appended to the send socket buffer. This should cover inbound and
43 outbound data. For monitoring state changes, we've added a notify
44 function that will be called when various events that the filter can
45 not intercept occur. In addition, we've added a few functions that a
46 filter may use to intercept common operations. These functions are:
47 connect (inbound), connect (outbound), bind, set socket option,
48 get socket option, and listen. Bind, listen, connect in, and connect
49 out could be used together to build a fairly comprehensive firewall
50 without having to do much with individual packets.
51 */
52#ifndef __KPI_SOCKETFILTER__
53#define __KPI_SOCKETFILTER__
54
55#include <sys/kernel_types.h>
56#include <sys/kpi_socket.h>
57
58struct sockaddr;
59
60/*!
61 @enum sflt_flags
62 @abstract Constants defining mbuf flags. Only the flags listed below
63 can be set or retreieved.
64 @constant SFLT_GLOBAL Indicates this socket filter should be
65 attached to all new sockets when they're created.
66 @constant SFLT_PROG Indicates this socket filter should be attached
67 only when request by the application using the SO_NKE socket
68 option.
69*/
70enum {
71 SFLT_GLOBAL = 0x01,
72 SFLT_PROG = 0x02
73};
74typedef u_int32_t sflt_flags;
75
76/*!
77 @typedef sflt_handle
78 @abstract A 4 byte identifier used with the SO_NKE socket option to
79 identify the socket filter to be attached.
80*/
81typedef u_int32_t sflt_handle;
82
83/*!
84 @enum sflt_event_t
85 @abstract Events notify a filter of state changes and other various
86 events related to the socket. These events can not be prevented
87 or intercepted, only observed.
88 @constant sock_evt_connected Indicates this socket has moved to the
89 connected state.
90 @constant sock_evt_disconnected Indicates this socket has moved to
91 the disconnected state.
92 @constant sock_evt_flush_read The read socket buffer has been
93 flushed.
94 @constant sock_evt_shutdown The read and or write side(s) of the
95 connection have been shutdown. The param will point to an
96 integer that indicates the direction that has been shutdown. See
97 'man 2 shutdown' for more information.
98 @constant sock_evt_cantrecvmore Indicates the socket can not receive
99 more data.
100 @constant sock_evt_cantsendmore Indicates the socket can not send
101 more data.
102 @constant sock_evt_closing Indicates the socket is closing.
103*/
104enum {
105 sock_evt_connecting = 1,
106 sock_evt_connected = 2,
107 sock_evt_disconnecting = 3,
108 sock_evt_disconnected = 4,
109 sock_evt_flush_read = 5,
110 sock_evt_shutdown = 6, /* param points to an integer specifying how (read, write, or both) see man 2 shutdown */
111 sock_evt_cantrecvmore = 7,
112 sock_evt_cantsendmore = 8,
113 sock_evt_closing = 9
114};
115typedef u_int32_t sflt_event_t;
116
117/*!
118 @enum sflt_data_flag_t
119 @abstract Inbound and outbound data filters may handle many
120 different types of incoming and outgoing data. These flags help
121 distinguish between normal data, out-of-band data, and records.
122 @constant sock_data_filt_flag_oob Indicates this data is out-of-band
123 data.
124 @constant sock_data_filt_flag_record Indicates this data is a
125 record. This flag is only ever seen on inbound data.
126*/
127enum {
128 sock_data_filt_flag_oob = 1,
129 sock_data_filt_flag_record = 2
130};
131typedef u_int32_t sflt_data_flag_t;
132
133/*!
134 @typedef sf_unregistered_func
135
136 @discussion sf_unregistered_func is called to notify the filter it
137 has been unregistered. This is the last function the stack will
138 call and this function will only be called once all other
139 function calls in to your filter have completed. Once this
140 function has been called, your kext may safely unload.
141 @param handle The socket filter handle used to identify this filter.
142*/
143typedef void (*sf_unregistered_func)(sflt_handle handle);
144
145/*!
146 @typedef sf_attach_func
147
148 @discussion sf_attach_func is called to notify the filter it has
149 been attached to a socket. The filter may allocate memory for
150 this attachment and use the cookie to track it. This filter is
151 called in one of two cases:
152 1) You've installed a global filter and a new socket was created.
153 2) Your non-global socket filter is being attached using the SO_NKE
154 socket option.
155 @param cookie Used to allow the socket filter to set the cookie for
156 this attachment.
157 @param so The socket the filter is being attached to.
158 @result If you return a non-zero value, your filter will not be
159 attached to this socket.
160*/
161typedef errno_t (*sf_attach_func)(void **cookie, socket_t so);
162
163/*!
164 @typedef sf_detach_func
165
166 @discussion sf_detach_func is called to notify the filter it has
167 been detached from a socket. If the filter allocated any memory
168 for this attachment, it should be freed. This function will
169 be called when the socket is disposed of.
170 @param cookie Cookie value specified when the filter attach was
171 called.
172 @param so The socket the filter is attached to.
173 @result If you return a non-zero value, your filter will not be
174 attached to this socket.
175*/
176typedef void (*sf_detach_func)(void *cookie, socket_t so);
177
178/*!
179 @typedef sf_notify_func
180
181 @discussion sf_notify_func is called to notify the filter of various
182 state changes and other events occuring on the socket.
183 @param cookie Cookie value specified when the filter attach was
184 called.
185 @param so The socket the filter is attached to.
186 @param event The type of event that has occurred.
187 @param param Additional information about the event.
188*/
189typedef void (*sf_notify_func)(void *cookie, socket_t so,
190 sflt_event_t event, void *param);
191
192/*!
193 @typedef sf_getpeername_func
194
195 @discussion sf_getpeername_func is called to allow a filter to
196 to intercept the getpeername function. When called, sa will
197 point to a pointer to a socket address that was malloced
198 in zone M_SONAME. If you want to replace this address, either
199 modify the currenty copy or allocate a new one and free the
200 old one.
201 @param cookie Cookie value specified when the filter attach was
202 called.
203 @param so The socket the filter is attached to.
204 @param sa A pointer to a socket address pointer.
205 @result If you return a non-zero value, processing will stop. If
206 you return EJUSTRETURN, no further filters will be called
207 but a result of zero will be returned to the caller of
208 getpeername.
209*/
210typedef int (*sf_getpeername_func)(void *cookie, socket_t so,
211 struct sockaddr **sa);
212
213/*!
214 @typedef sf_getsockname_func
215
216 @discussion sf_getsockname_func is called to allow a filter to
217 to intercept the getsockname function. When called, sa will
218 point to a pointer to a socket address that was malloced
219 in zone M_SONAME. If you want to replace this address, either
220 modify the currenty copy or allocate a new one and free the
221 old one.
222 @param cookie Cookie value specified when the filter attach was
223 called.
224 @param so The socket the filter is attached to.
225 @param sa A pointer to a socket address pointer.
226 @result If you return a non-zero value, processing will stop. If
227 you return EJUSTRETURN, no further filters will be called
228 but a result of zero will be returned to the caller of
229 getsockname.
230*/
231typedef int (*sf_getsockname_func)(void *cookie, socket_t so,
232 struct sockaddr **sa);
233
234/*!
235 @typedef sf_data_in_func
236
237 @discussion sf_data_in_func is called to filter incoming data. If your
238 filter intercepts data for later reinjection, it must queue all incoming
239 data to preserve the order of the data. Use sock_inject_data_in to later
240 reinject this data if you return EJUSTRETURN. Warning: This filter is on
241 the data path. Do not spend excesive time. Do not wait for data on
242 another socket.
243 @param cookie Cookie value specified when the filter attach was
244 called.
245 @param so The socket the filter is attached to.
246 @param from The addres the data is from, may be NULL if the socket
247 is connected.
248 @param data The data being received. Control data may appear in the
249 mbuf chain, be sure to check the mbuf types to find control
250 data.
251 @param control Control data being passed separately from the data.
252 @param flags Flags to indicate if this is out of band data or a
253 record.
254 @result Return:
255 0 - The caller will continue with normal processing of the data.
256 EJUSTRETURN - The caller will stop processing the data, the data will not be freed.
257 Anything Else - The caller will free the data and stop processing.
258*/
259typedef errno_t (*sf_data_in_func)(void *cookie, socket_t so,
260 const struct sockaddr *from, mbuf_t *data,
261 mbuf_t *control, sflt_data_flag_t flags);
262
263/*!
264 @typedef sf_data_out_func
265
266 @discussion sf_data_out_func is called to filter outbound data. If
267 your filter intercepts data for later reinjection, it must queue
268 all outbound data to preserve the order of the data when
269 reinjecting. Use sock_inject_data_out to later reinject this
270 data.
271 @param cookie Cookie value specified when the filter attach was
272 called.
273 @param so The socket the filter is attached to.
274 @param from The address the data is from, may be NULL if the socket
275 is connected.
276 @param data The data being received. Control data may appear in the
277 mbuf chain, be sure to check the mbuf types to find control
278 data.
279 @param control Control data being passed separately from the data.
280 @param flags Flags to indicate if this is out of band data or a
281 record.
282 @result Return:
283 0 - The caller will continue with normal processing of the data.
284 EJUSTRETURN - The caller will stop processing the data, the data will not be freed.
285 Anything Else - The caller will free the data and stop processing.
286*/
287typedef errno_t (*sf_data_out_func)(void *cookie, socket_t so,
288 const struct sockaddr *to, mbuf_t *data,
289 mbuf_t *control, sflt_data_flag_t flags);
290
291/*!
292 @typedef sf_connect_in_func
293
294 @discussion sf_connect_in_func is called to filter inbound connections. A
295 protocol will call this before accepting an incoming connection and
296 placing it on the queue of completed connections. Warning: This filter
297 is on the data path. Do not spend excesive time. Do not wait for data on
298 another socket.
299 @param cookie Cookie value specified when the filter attach was
300 called.
301 @param so The socket the filter is attached to.
302 @param from The address the incoming connection is from.
303 @result Return:
304 0 - The caller will continue with normal processing of the connection.
305 Anything Else - The caller will rejecting the incoming connection.
306*/
307typedef errno_t (*sf_connect_in_func)(void *cookie, socket_t so,
308 const struct sockaddr *from);
309
310/*!
311 @typedef sf_connect_out_func
312
313 @discussion sf_connect_out_func is called to filter outbound
314 connections. A protocol will call this before initiating an
315 outbound connection.
316 @param cookie Cookie value specified when the filter attach was
317 called.
318 @param so The socket the filter is attached to.
319 @param to The remote address of the outbound connection.
320 @result Return:
321 0 - The caller will continue with normal processing of the connection.
322 Anything Else - The caller will rejecting the outbound connection.
323*/
324typedef errno_t (*sf_connect_out_func)(void *cookie, socket_t so,
325 const struct sockaddr *to);
326
327/*!
328 @typedef sf_bind_func
329
330 @discussion sf_bind_func is called before performing a bind
331 operation on a socket.
332 @param cookie Cookie value specified when the filter attach was
333 called.
334 @param so The socket the filter is attached to.
335 @param to The local address of the socket will be bound to.
336 @result Return:
337 0 - The caller will continue with normal processing of the bind.
338 Anything Else - The caller will rejecting the bind.
339*/
340typedef errno_t (*sf_bind_func)(void *cookie, socket_t so,
341 const struct sockaddr *to);
342
343/*!
344 @typedef sf_setoption_func
345
346 @discussion sf_setoption_func is called before performing setsockopt
347 on a socket.
348 @param cookie Cookie value specified when the filter attach was
349 called.
350 @param so The socket the filter is attached to.
351 @param opt The socket option to set.
352 @result Return:
353 0 - The caller will continue with normal processing of the setsockopt.
354 Anything Else - The caller will stop processing and return this error.
355*/
356typedef errno_t (*sf_setoption_func)(void *cookie, socket_t so,
357 sockopt_t opt);
358
359/*!
360 @typedef sf_getoption_func
361
362 @discussion sf_getoption_func is called before performing getsockopt
363 on a socket.
364 @param cookie Cookie value specified when the filter attach was
365 called.
366 @param so The socket the filter is attached to.
367 @param opt The socket option to get.
368 @result Return:
369 0 - The caller will continue with normal processing of the getsockopt.
370 Anything Else - The caller will stop processing and return this error.
371*/
372typedef errno_t (*sf_getoption_func)(void *cookie, socket_t so,
373 sockopt_t opt);
374
375/*!
376 @typedef sf_listen_func
377
378 @discussion sf_listen_func is called before performing listen
379 on a socket.
380 @param cookie Cookie value specified when the filter attach was
381 called.
382 @param so The socket the filter is attached to.
383 @result Return:
384 0 - The caller will continue with normal processing of listen.
385 Anything Else - The caller will stop processing and return this error.
386*/
387typedef errno_t (*sf_listen_func)(void *cookie, socket_t so);
388
389/*!
390 @typedef sf_ioctl_func
391
392 @discussion sf_ioctl_func is called before performing an ioctl
393 on a socket.
394 @param cookie Cookie value specified when the filter attach was
395 called.
396 @param so The socket the filter is attached to.
397 @param request The ioctl name.
398 @param argp A pointer to the ioctl parameter.
399 @result Return:
400 0 - The caller will continue with normal processing of this ioctl.
401 Anything Else - The caller will stop processing and return this error.
402*/
403typedef errno_t (*sf_ioctl_func)(void *cookie, socket_t so,
404 u_int32_t request, const char* argp);
405
406/*!
407 @struct sflt_filter
408 @discussion This structure is used to define a socket filter.
409 @field sf_handle A value used to find socket filters by
410 applications. An application can use this value to specify that
411 this filter should be attached when using the SO_NKE socket
412 option.
413 @field sf_flags Indicate whether this filter should be attached to
414 all new sockets or just those that request the filter be
415 attached using the SO_NKE socket option.
416 @field sf_name A name used for debug purposes.
417 @field sf_unregistered Your function for being notified when your
418 filter has been unregistered.
419 @field sf_attach Your function for handling attaches to sockets.
420 @field sf_detach Your function for handling detaches from sockets.
421 @field sf_notify Your function for handling events. May be null.
422 @field sf_data_in Your function for handling incoming data. May be
423 null.
424 @field sf_data_out Your function for handling outgoing data. May be
425 null.
426 @field sf_connect_in Your function for handling inbound
427 connections. May be null.
428 @field sf_connect_in Your function for handling outbound
429 connections. May be null.
430 @field sf_bind Your function for handling binds. May be null.
431 @field sf_setoption Your function for handling setsockopt. May be null.
432 @field sf_getoption Your function for handling getsockopt. May be null.
433 @field sf_listen Your function for handling listen. May be null.
434 @field sf_ioctl Your function for handling ioctls. May be null.
435*/
436struct sflt_filter {
437 sflt_handle sf_handle;
438 int sf_flags;
439 char* sf_name;
440
441 sf_unregistered_func sf_unregistered;
442 sf_attach_func sf_attach;
443 sf_detach_func sf_detach;
444
445 sf_notify_func sf_notify;
446 sf_getpeername_func sf_getpeername;
447 sf_getsockname_func sf_getsockname;
448 sf_data_in_func sf_data_in;
449 sf_data_out_func sf_data_out;
450 sf_connect_in_func sf_connect_in;
451 sf_connect_out_func sf_connect_out;
452 sf_bind_func sf_bind;
453 sf_setoption_func sf_setoption;
454 sf_getoption_func sf_getoption;
455 sf_listen_func sf_listen;
456 sf_ioctl_func sf_ioctl;
457};
458
459/*!
460 @function sflt_register
461 @discussion Registers a socket filter. See 'man 2 socket' for a
462 desciption of domain, type, and protocol.
463 @param filter A structure describing the filter.
464 @param domain The protocol domain these filters will be attached to.
465 @param type The socket type these filters will be attached to.
466 @param protocol The protocol these filters will be attached to.
467 @result 0 on success otherwise the errno error.
468 */
469errno_t sflt_register(const struct sflt_filter *filter, int domain,
470 int type, int protocol);
471
472/*!
473 @function sflt_unregister
474 @discussion Unregisters a socket filter. This will not detach the
475 socket filter from all sockets it may be attached to at the
476 time, it will just prevent the socket filter from being attached
477 to any new sockets.
478 @param handle The sf_handle of the socket filter to unregister.
479 @result 0 on success otherwise the errno error.
480 */
481errno_t sflt_unregister(sflt_handle handle);
482
483/*!
484 @function sflt_attach
485 @discussion Attaches a socket filter to the specified socket. A
486 filter must be registered before it can be attached.
487 @param socket The socket the filter should be attached to.
488 @param handle The handle of the registered filter to be attached.
489 @result 0 on success otherwise the errno error.
490 */
491errno_t sflt_attach(socket_t socket, sflt_handle);
492
493/*!
494 @function sflt_detach
495 @discussion Detaches a socket filter from a specified socket.
496 @param socket The socket the filter should be detached from.
497 @param handle The handle of the registered filter to be detached.
498 @result 0 on success otherwise the errno error.
499 */
500errno_t sflt_detach(socket_t socket, sflt_handle);
501
502/* Functions for manipulating sockets */
503/*
504 * Inject data in to the receive buffer of the socket as if it
505 * had come from the network.
506 *
507 * flags should match sflt_data_flag_t
508 */
509
510/*!
511 @function sock_inject_data_in
512 @discussion Inject data in to the receive buffer of the socket as if
513 it had come from the network.
514 @param so The socket to inject the data on.
515 @param from The address the data is from, only necessary on
516 un-connected sockets. A copy of the address will be made, caller
517 is responsible for freeing the address after calling this
518 function.
519 @param data The data and possibly control mbufs.
520 @param control The separate control mbufs.
521 @param flags Flags indicating the type of data.
522 @result 0 on success otherwise the errno error. If the function
523 returns an error, the caller is responsible for freeing the
524 mbuf.
525 */
526errno_t sock_inject_data_in(socket_t so, const struct sockaddr* from,
527 mbuf_t data, mbuf_t control, sflt_data_flag_t flags);
528
529/*!
530 @function sock_inject_data_out
531 @discussion Inject data in to the send buffer of the socket as if it
532 had come from the client.
533 @param so The socket to inject the data on.
534 @param to The address the data should be sent to, only necessary on
535 un-connected sockets. The caller is responsible for freeing the
536 to address after sock_inject_data_out returns.
537 @param data The data and possibly control mbufs.
538 @param control The separate control mbufs.
539 @param flags Flags indicating the type of data.
540 @result 0 on success otherwise the errno error. The data and control
541 values are always freed regardless of return value.
542 */
543errno_t sock_inject_data_out(socket_t so, const struct sockaddr* to,
544 mbuf_t data, mbuf_t control, sflt_data_flag_t flags);
545
546
547/*
548 * sockopt_t accessors
549 */
550
551enum {
552 sockopt_get = 1,
553 sockopt_set = 2
554};
555typedef u_int8_t sockopt_dir;
556
557/*!
558 @function sockopt_direction
559 @discussion Retreives the direction of the socket option (Get or
560 Set).
561 @param sopt The socket option.
562 @result sock_opt_get or sock_opt_set.
563 */
564sockopt_dir sockopt_direction(sockopt_t sopt);
565
566/*!
567 @function sockopt_level
568 @discussion Retreives the socket option level. (SOL_SOCKET, etc).
569 @param sopt The socket option.
570 @result The socket option level. See man 2 setsockopt
571 */
572int sockopt_level(sockopt_t sopt);
573
574/*!
575 @function sockopt_name
576 @discussion Retreives the socket option name. (SO_SNDBUF, etc).
577 @param sopt The socket option.
578 @result The socket option name. See man 2 setsockopt
579 */
580int sockopt_name(sockopt_t sopt);
581
582/*!
583 @function sockopt_valsize
584 @discussion Retreives the size of the socket option data.
585 @param sopt The socket option.
586 @result The length, in bytes, of the data.
587 */
588size_t sockopt_valsize(sockopt_t sopt);
589
590/*!
591 @function sockopt_copyin
592 @discussion Copies the data from the socket option to a buffer.
593 @param sopt The socket option.
594 @param data A pointer to the buffer to copy the data in to.
595 @param length The number of bytes to copy.
596 @result An errno error or zero upon success.
597 */
598errno_t sockopt_copyin(sockopt_t sopt, void *data, size_t length);
599
600/*!
601 @function sockopt_copyout
602 @discussion Copies the data from a buffer to a socket option.
603 @param sopt The socket option.
604 @param data A pointer to the buffer to copy the data out of.
605 @param length The number of bytes to copy.
606 @result An errno error or zero upon success.
607 */
608errno_t sockopt_copyout(sockopt_t sopt, void *data, size_t length);
609
610#endif