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