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