]>
Commit | Line | Data |
---|---|---|
91447636 | 1 | /* |
39037602 | 2 | * Copyright (c) 2008-2016 Apple Computer, Inc. All rights reserved. |
91447636 | 3 | * |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
91447636 | 5 | * |
2d21ac55 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. | |
8f6c56a5 | 14 | * |
2d21ac55 A |
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 | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
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. | |
8f6c56a5 | 25 | * |
2d21ac55 | 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. | |
b0d623f7 | 32 | |
91447636 A |
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 | ||
58 | struct sockaddr; | |
59 | ||
60 | /*! | |
61 | @enum sflt_flags | |
62 | @abstract Constants defining mbuf flags. Only the flags listed below | |
2d21ac55 | 63 | can be set or retrieved. |
91447636 A |
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. | |
2d21ac55 A |
69 | @constant SFLT_EXTENDED Indicates that this socket filter utilizes |
70 | the extended fields within the sflt_filter structure. | |
316670eb A |
71 | @constant SFLT_EXTENDED_REGISTRY Indicates that this socket filter |
72 | wants to attach to all the sockets already present on the | |
73 | system. It will also receive notifications for these sockets. | |
91447636 A |
74 | */ |
75 | enum { | |
76 | SFLT_GLOBAL = 0x01, | |
2d21ac55 | 77 | SFLT_PROG = 0x02, |
316670eb A |
78 | SFLT_EXTENDED = 0x04, |
79 | SFLT_EXTENDED_REGISTRY = 0x08 | |
91447636 A |
80 | }; |
81 | typedef u_int32_t sflt_flags; | |
82 | ||
83 | /*! | |
84 | @typedef sflt_handle | |
85 | @abstract A 4 byte identifier used with the SO_NKE socket option to | |
86 | identify the socket filter to be attached. | |
87 | */ | |
88 | typedef u_int32_t sflt_handle; | |
89 | ||
90 | /*! | |
91 | @enum sflt_event_t | |
92 | @abstract Events notify a filter of state changes and other various | |
2d21ac55 | 93 | events related to the socket. These events cannot be prevented |
91447636 A |
94 | or intercepted, only observed. |
95 | @constant sock_evt_connected Indicates this socket has moved to the | |
96 | connected state. | |
97 | @constant sock_evt_disconnected Indicates this socket has moved to | |
98 | the disconnected state. | |
99 | @constant sock_evt_flush_read The read socket buffer has been | |
100 | flushed. | |
101 | @constant sock_evt_shutdown The read and or write side(s) of the | |
102 | connection have been shutdown. The param will point to an | |
103 | integer that indicates the direction that has been shutdown. See | |
104 | 'man 2 shutdown' for more information. | |
2d21ac55 | 105 | @constant sock_evt_cantrecvmore Indicates the socket cannot receive |
91447636 | 106 | more data. |
2d21ac55 | 107 | @constant sock_evt_cantsendmore Indicates the socket cannot send |
91447636 A |
108 | more data. |
109 | @constant sock_evt_closing Indicates the socket is closing. | |
2d21ac55 A |
110 | @constant sock_evt_bound Indicates this socket has moved to the |
111 | bound state (only for PF_INET/PF_INET6 domain). | |
91447636 A |
112 | */ |
113 | enum { | |
114 | sock_evt_connecting = 1, | |
115 | sock_evt_connected = 2, | |
2d21ac55 A |
116 | sock_evt_disconnecting = 3, |
117 | sock_evt_disconnected = 4, | |
91447636 A |
118 | sock_evt_flush_read = 5, |
119 | sock_evt_shutdown = 6, /* param points to an integer specifying how (read, write, or both) see man 2 shutdown */ | |
2d21ac55 A |
120 | sock_evt_cantrecvmore = 7, |
121 | sock_evt_cantsendmore = 8, | |
122 | sock_evt_closing = 9, | |
123 | sock_evt_bound = 10 | |
91447636 A |
124 | }; |
125 | typedef u_int32_t sflt_event_t; | |
126 | ||
127 | /*! | |
128 | @enum sflt_data_flag_t | |
129 | @abstract Inbound and outbound data filters may handle many | |
130 | different types of incoming and outgoing data. These flags help | |
131 | distinguish between normal data, out-of-band data, and records. | |
132 | @constant sock_data_filt_flag_oob Indicates this data is out-of-band | |
133 | data. | |
134 | @constant sock_data_filt_flag_record Indicates this data is a | |
135 | record. This flag is only ever seen on inbound data. | |
136 | */ | |
137 | enum { | |
138 | sock_data_filt_flag_oob = 1, | |
139 | sock_data_filt_flag_record = 2 | |
140 | }; | |
141 | typedef u_int32_t sflt_data_flag_t; | |
142 | ||
2d21ac55 A |
143 | __BEGIN_DECLS |
144 | ||
91447636 A |
145 | /*! |
146 | @typedef sf_unregistered_func | |
b0d623f7 | 147 | |
91447636 A |
148 | @discussion sf_unregistered_func is called to notify the filter it |
149 | has been unregistered. This is the last function the stack will | |
150 | call and this function will only be called once all other | |
151 | function calls in to your filter have completed. Once this | |
152 | function has been called, your kext may safely unload. | |
153 | @param handle The socket filter handle used to identify this filter. | |
154 | */ | |
b0d623f7 | 155 | typedef void (*sf_unregistered_func)(sflt_handle handle); |
91447636 A |
156 | |
157 | /*! | |
158 | @typedef sf_attach_func | |
b0d623f7 | 159 | |
91447636 A |
160 | @discussion sf_attach_func is called to notify the filter it has |
161 | been attached to a socket. The filter may allocate memory for | |
162 | this attachment and use the cookie to track it. This filter is | |
163 | called in one of two cases: | |
164 | 1) You've installed a global filter and a new socket was created. | |
165 | 2) Your non-global socket filter is being attached using the SO_NKE | |
166 | socket option. | |
167 | @param cookie Used to allow the socket filter to set the cookie for | |
168 | this attachment. | |
169 | @param so The socket the filter is being attached to. | |
170 | @result If you return a non-zero value, your filter will not be | |
171 | attached to this socket. | |
172 | */ | |
173 | typedef errno_t (*sf_attach_func)(void **cookie, socket_t so); | |
174 | ||
175 | /*! | |
176 | @typedef sf_detach_func | |
b0d623f7 | 177 | |
91447636 A |
178 | @discussion sf_detach_func is called to notify the filter it has |
179 | been detached from a socket. If the filter allocated any memory | |
180 | for this attachment, it should be freed. This function will | |
181 | be called when the socket is disposed of. | |
182 | @param cookie Cookie value specified when the filter attach was | |
183 | called. | |
184 | @param so The socket the filter is attached to. | |
39037602 | 185 | @discussion If you return a non-zero value, your filter will not be |
91447636 A |
186 | attached to this socket. |
187 | */ | |
b0d623f7 | 188 | typedef void (*sf_detach_func)(void *cookie, socket_t so); |
91447636 A |
189 | |
190 | /*! | |
191 | @typedef sf_notify_func | |
b0d623f7 | 192 | |
91447636 A |
193 | @discussion sf_notify_func is called to notify the filter of various |
194 | state changes and other events occuring on the socket. | |
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 event The type of event that has occurred. | |
199 | @param param Additional information about the event. | |
200 | */ | |
b0d623f7 A |
201 | typedef void (*sf_notify_func)(void *cookie, socket_t so, sflt_event_t event, |
202 | void *param); | |
91447636 A |
203 | |
204 | /*! | |
205 | @typedef sf_getpeername_func | |
b0d623f7 | 206 | |
91447636 A |
207 | @discussion sf_getpeername_func is called to allow a filter to |
208 | to intercept the getpeername function. When called, sa will | |
209 | point to a pointer to a socket address that was malloced | |
210 | in zone M_SONAME. If you want to replace this address, either | |
211 | modify the currenty copy or allocate a new one and free the | |
212 | old one. | |
213 | @param cookie Cookie value specified when the filter attach was | |
214 | called. | |
215 | @param so The socket the filter is attached to. | |
216 | @param sa A pointer to a socket address pointer. | |
217 | @result If you return a non-zero value, processing will stop. If | |
218 | you return EJUSTRETURN, no further filters will be called | |
219 | but a result of zero will be returned to the caller of | |
220 | getpeername. | |
221 | */ | |
b0d623f7 A |
222 | typedef int (*sf_getpeername_func)(void *cookie, socket_t so, |
223 | struct sockaddr **sa); | |
91447636 A |
224 | |
225 | /*! | |
226 | @typedef sf_getsockname_func | |
b0d623f7 | 227 | |
91447636 A |
228 | @discussion sf_getsockname_func is called to allow a filter to |
229 | to intercept the getsockname function. When called, sa will | |
230 | point to a pointer to a socket address that was malloced | |
231 | in zone M_SONAME. If you want to replace this address, either | |
232 | modify the currenty copy or allocate a new one and free the | |
233 | old one. | |
234 | @param cookie Cookie value specified when the filter attach was | |
235 | called. | |
236 | @param so The socket the filter is attached to. | |
237 | @param sa A pointer to a socket address pointer. | |
238 | @result If you return a non-zero value, processing will stop. If | |
239 | you return EJUSTRETURN, no further filters will be called | |
240 | but a result of zero will be returned to the caller of | |
241 | getsockname. | |
242 | */ | |
b0d623f7 A |
243 | typedef int (*sf_getsockname_func)(void *cookie, socket_t so, |
244 | struct sockaddr **sa); | |
91447636 A |
245 | |
246 | /*! | |
247 | @typedef sf_data_in_func | |
b0d623f7 | 248 | |
91447636 | 249 | @discussion sf_data_in_func is called to filter incoming data. If your |
b0d623f7 A |
250 | filter intercepts data for later reinjection, it must queue |
251 | all incoming data to preserve the order of the data. Use | |
252 | sock_inject_data_in to later reinject this data if you return | |
253 | EJUSTRETURN. Warning: This filter is on the data path. Do not | |
254 | spend excesive time. Do not wait for data on another socket. | |
91447636 A |
255 | @param cookie Cookie value specified when the filter attach was |
256 | called. | |
257 | @param so The socket the filter is attached to. | |
258 | @param from The addres the data is from, may be NULL if the socket | |
259 | is connected. | |
260 | @param data The data being received. Control data may appear in the | |
261 | mbuf chain, be sure to check the mbuf types to find control | |
262 | data. | |
263 | @param control Control data being passed separately from the data. | |
264 | @param flags Flags to indicate if this is out of band data or a | |
265 | record. | |
266 | @result Return: | |
267 | 0 - The caller will continue with normal processing of the data. | |
b0d623f7 A |
268 | EJUSTRETURN - The caller will stop processing the data, the |
269 | data will not be freed. | |
270 | Anything Else - The caller will free the data and stop | |
271 | processing. | |
91447636 A |
272 | */ |
273 | typedef errno_t (*sf_data_in_func)(void *cookie, socket_t so, | |
b0d623f7 A |
274 | const struct sockaddr *from, mbuf_t *data, mbuf_t *control, |
275 | sflt_data_flag_t flags); | |
91447636 A |
276 | |
277 | /*! | |
278 | @typedef sf_data_out_func | |
b0d623f7 | 279 | |
91447636 A |
280 | @discussion sf_data_out_func is called to filter outbound data. If |
281 | your filter intercepts data for later reinjection, it must queue | |
282 | all outbound data to preserve the order of the data when | |
283 | reinjecting. Use sock_inject_data_out to later reinject this | |
284 | data. | |
285 | @param cookie Cookie value specified when the filter attach was | |
286 | called. | |
287 | @param so The socket the filter is attached to. | |
39037602 | 288 | @param to The address the data is to, may be NULL if the socket |
91447636 A |
289 | is connected. |
290 | @param data The data being received. Control data may appear in the | |
291 | mbuf chain, be sure to check the mbuf types to find control | |
292 | data. | |
293 | @param control Control data being passed separately from the data. | |
294 | @param flags Flags to indicate if this is out of band data or a | |
295 | record. | |
296 | @result Return: | |
297 | 0 - The caller will continue with normal processing of the data. | |
b0d623f7 A |
298 | EJUSTRETURN - The caller will stop processing the data, |
299 | the data will not be freed. | |
300 | Anything Else - The caller will free the data and stop | |
301 | processing. | |
91447636 A |
302 | */ |
303 | typedef errno_t (*sf_data_out_func)(void *cookie, socket_t so, | |
b0d623f7 A |
304 | const struct sockaddr *to, mbuf_t *data, mbuf_t *control, |
305 | sflt_data_flag_t flags); | |
91447636 A |
306 | |
307 | /*! | |
308 | @typedef sf_connect_in_func | |
b0d623f7 A |
309 | |
310 | @discussion sf_connect_in_func is called to filter inbound connections. | |
311 | A protocol will call this before accepting an incoming | |
312 | connection and placing it on the queue of completed connections. | |
313 | Warning: This filter is on the data path. Do not spend excesive | |
314 | time. Do not wait for data on another socket. | |
91447636 A |
315 | @param cookie Cookie value specified when the filter attach was |
316 | called. | |
317 | @param so The socket the filter is attached to. | |
318 | @param from The address the incoming connection is from. | |
319 | @result Return: | |
b0d623f7 A |
320 | 0 - The caller will continue with normal processing of the |
321 | connection. | |
322 | Anything Else - The caller will rejecting the incoming | |
323 | connection. | |
91447636 A |
324 | */ |
325 | typedef errno_t (*sf_connect_in_func)(void *cookie, socket_t so, | |
b0d623f7 | 326 | const struct sockaddr *from); |
91447636 A |
327 | |
328 | /*! | |
329 | @typedef sf_connect_out_func | |
b0d623f7 | 330 | |
91447636 A |
331 | @discussion sf_connect_out_func is called to filter outbound |
332 | connections. A protocol will call this before initiating an | |
333 | outbound connection. | |
334 | @param cookie Cookie value specified when the filter attach was | |
335 | called. | |
336 | @param so The socket the filter is attached to. | |
337 | @param to The remote address of the outbound connection. | |
338 | @result Return: | |
b0d623f7 A |
339 | 0 - The caller will continue with normal processing of the |
340 | connection. | |
39236c6e A |
341 | EJUSTRETURN - The caller will return with a value of 0 (no error) |
342 | from that point without further processing the connect command. The | |
343 | protocol layer will not see the call. | |
b0d623f7 A |
344 | Anything Else - The caller will rejecting the outbound |
345 | connection. | |
91447636 A |
346 | */ |
347 | typedef errno_t (*sf_connect_out_func)(void *cookie, socket_t so, | |
b0d623f7 | 348 | const struct sockaddr *to); |
91447636 A |
349 | |
350 | /*! | |
351 | @typedef sf_bind_func | |
b0d623f7 | 352 | |
91447636 A |
353 | @discussion sf_bind_func is called before performing a bind |
354 | operation on a socket. | |
355 | @param cookie Cookie value specified when the filter attach was | |
356 | called. | |
357 | @param so The socket the filter is attached to. | |
358 | @param to The local address of the socket will be bound to. | |
359 | @result Return: | |
360 | 0 - The caller will continue with normal processing of the bind. | |
39236c6e A |
361 | EJUSTRETURN - The caller will return with a value of 0 (no error) |
362 | from that point without further processing the bind command. The | |
363 | protocol layer will not see the call. | |
91447636 A |
364 | Anything Else - The caller will rejecting the bind. |
365 | */ | |
366 | typedef errno_t (*sf_bind_func)(void *cookie, socket_t so, | |
b0d623f7 | 367 | const struct sockaddr *to); |
91447636 A |
368 | |
369 | /*! | |
370 | @typedef sf_setoption_func | |
b0d623f7 | 371 | |
91447636 A |
372 | @discussion sf_setoption_func is called before performing setsockopt |
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 | @param opt The socket option to set. | |
378 | @result Return: | |
b0d623f7 A |
379 | 0 - The caller will continue with normal processing of the |
380 | setsockopt. | |
39236c6e A |
381 | EJUSTRETURN - The caller will return with a value of 0 (no error) |
382 | from that point without further propagating the set option | |
383 | command. The socket and protocol layers will not see the call. | |
b0d623f7 A |
384 | Anything Else - The caller will stop processing and return |
385 | this error. | |
91447636 | 386 | */ |
b0d623f7 | 387 | typedef errno_t (*sf_setoption_func)(void *cookie, socket_t so, sockopt_t opt); |
91447636 A |
388 | |
389 | /*! | |
390 | @typedef sf_getoption_func | |
b0d623f7 | 391 | |
91447636 A |
392 | @discussion sf_getoption_func is called before performing getsockopt |
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 opt The socket option to get. | |
398 | @result Return: | |
b0d623f7 A |
399 | 0 - The caller will continue with normal processing of the |
400 | getsockopt. | |
39236c6e A |
401 | EJUSTRETURN - The caller will return with a value of 0 (no error) |
402 | from that point without further propagating the get option | |
403 | command. The socket and protocol layers will not see the call. | |
b0d623f7 A |
404 | Anything Else - The caller will stop processing and return |
405 | this error. | |
91447636 | 406 | */ |
b0d623f7 | 407 | typedef errno_t (*sf_getoption_func)(void *cookie, socket_t so, sockopt_t opt); |
91447636 A |
408 | |
409 | /*! | |
410 | @typedef sf_listen_func | |
b0d623f7 | 411 | |
91447636 A |
412 | @discussion sf_listen_func is called before performing listen |
413 | on a socket. | |
414 | @param cookie Cookie value specified when the filter attach was | |
415 | called. | |
416 | @param so The socket the filter is attached to. | |
417 | @result Return: | |
418 | 0 - The caller will continue with normal processing of listen. | |
39236c6e A |
419 | EJUSTRETURN - The caller will return with a value of 0 (no error) |
420 | from that point without further processing the listen command. The | |
421 | protocol will not see the call. | |
b0d623f7 A |
422 | Anything Else - The caller will stop processing and return |
423 | this error. | |
91447636 A |
424 | */ |
425 | typedef errno_t (*sf_listen_func)(void *cookie, socket_t so); | |
426 | ||
427 | /*! | |
428 | @typedef sf_ioctl_func | |
b0d623f7 | 429 | |
91447636 A |
430 | @discussion sf_ioctl_func is called before performing an ioctl |
431 | on a socket. | |
2d21ac55 A |
432 | |
433 | All undefined ioctls are reserved for future use by Apple. If | |
434 | you need to communicate with your kext using an ioctl, please | |
435 | use SIOCSIFKPI and SIOCGIFKPI. | |
91447636 A |
436 | @param cookie Cookie value specified when the filter attach was |
437 | called. | |
438 | @param so The socket the filter is attached to. | |
439 | @param request The ioctl name. | |
440 | @param argp A pointer to the ioctl parameter. | |
441 | @result Return: | |
b0d623f7 A |
442 | 0 - The caller will continue with normal processing of |
443 | this ioctl. | |
39236c6e A |
444 | EJUSTRETURN - The caller will return with a value of 0 (no error) |
445 | from that point without further processing or propogating | |
446 | the ioctl. | |
b0d623f7 A |
447 | Anything Else - The caller will stop processing and return |
448 | this error. | |
91447636 A |
449 | */ |
450 | typedef errno_t (*sf_ioctl_func)(void *cookie, socket_t so, | |
b0d623f7 | 451 | unsigned long request, const char* argp); |
91447636 | 452 | |
2d21ac55 A |
453 | /*! |
454 | @typedef sf_accept_func | |
455 | ||
456 | @discussion sf_accept_func is called after a socket is dequeued | |
457 | off the completed (incoming) connection list and before | |
458 | the file descriptor is associated with it. A filter can | |
459 | utilize this callback to intercept the accepted socket | |
460 | in order to examine it, prior to returning the socket to | |
461 | the caller of accept. Such a filter may also choose to | |
462 | discard the accepted socket if it wishes to do so. | |
463 | @param cookie Cookie value specified when the filter attach was called. | |
464 | @param so_listen The listening socket. | |
465 | @param so The socket that is about to be accepted. | |
466 | @param local The local address of the about to be accepted socket. | |
467 | @param remote The remote address of the about to be accepted socket. | |
468 | @result Return: | |
469 | 0 - The caller will continue with normal processing of accept. | |
470 | EJUSTRETURN - The to be accepted socket will be disconnected | |
471 | prior to being returned to the caller of accept. No further | |
472 | control or data operations on the socket will be allowed. | |
473 | This is the recommended return value as it has the least | |
474 | amount of impact, especially to applications which don't | |
475 | check the error value returned by accept. | |
476 | Anything Else - The to be accepted socket will be closed and | |
477 | the error will be returned to the caller of accept. | |
478 | Note that socket filter developers are advised to exercise | |
479 | caution when returning non-zero values to the caller, | |
480 | since some applications don't check the error value | |
481 | returned by accept and therefore risk breakage. | |
482 | */ | |
483 | typedef errno_t (*sf_accept_func)(void *cookie, socket_t so_listen, socket_t so, | |
484 | const struct sockaddr *local, const struct sockaddr *remote); | |
485 | ||
91447636 A |
486 | /*! |
487 | @struct sflt_filter | |
488 | @discussion This structure is used to define a socket filter. | |
489 | @field sf_handle A value used to find socket filters by | |
490 | applications. An application can use this value to specify that | |
491 | this filter should be attached when using the SO_NKE socket | |
492 | option. | |
493 | @field sf_flags Indicate whether this filter should be attached to | |
494 | all new sockets or just those that request the filter be | |
2d21ac55 A |
495 | attached using the SO_NKE socket option. If this filter |
496 | utilizes the socket filter extension fields, it must also | |
497 | set SFLT_EXTENDED. | |
91447636 A |
498 | @field sf_name A name used for debug purposes. |
499 | @field sf_unregistered Your function for being notified when your | |
500 | filter has been unregistered. | |
501 | @field sf_attach Your function for handling attaches to sockets. | |
502 | @field sf_detach Your function for handling detaches from sockets. | |
503 | @field sf_notify Your function for handling events. May be null. | |
504 | @field sf_data_in Your function for handling incoming data. May be | |
505 | null. | |
506 | @field sf_data_out Your function for handling outgoing data. May be | |
507 | null. | |
508 | @field sf_connect_in Your function for handling inbound | |
509 | connections. May be null. | |
2d21ac55 | 510 | @field sf_connect_out Your function for handling outbound |
91447636 A |
511 | connections. May be null. |
512 | @field sf_bind Your function for handling binds. May be null. | |
513 | @field sf_setoption Your function for handling setsockopt. May be null. | |
514 | @field sf_getoption Your function for handling getsockopt. May be null. | |
515 | @field sf_listen Your function for handling listen. May be null. | |
516 | @field sf_ioctl Your function for handling ioctls. May be null. | |
2d21ac55 A |
517 | @field sf_len Length of socket filter extension structure; developers |
518 | must initialize this to sizeof sflt_filter_ext structure. | |
519 | This field and all fields following it will only be valid | |
520 | if SFLT_EXTENDED flag is set in sf_flags field. | |
521 | @field sf_ext_accept Your function for handling inbound connections | |
522 | at accept time. May be null. | |
523 | @field sf_ext_rsvd Reserved for future use; you must initialize | |
524 | the reserved fields with zeroes. | |
91447636 A |
525 | */ |
526 | struct sflt_filter { | |
2d21ac55 A |
527 | sflt_handle sf_handle; |
528 | int sf_flags; | |
529 | char *sf_name; | |
530 | ||
531 | sf_unregistered_func sf_unregistered; | |
91447636 A |
532 | sf_attach_func sf_attach; |
533 | sf_detach_func sf_detach; | |
2d21ac55 | 534 | |
91447636 A |
535 | sf_notify_func sf_notify; |
536 | sf_getpeername_func sf_getpeername; | |
537 | sf_getsockname_func sf_getsockname; | |
538 | sf_data_in_func sf_data_in; | |
539 | sf_data_out_func sf_data_out; | |
540 | sf_connect_in_func sf_connect_in; | |
541 | sf_connect_out_func sf_connect_out; | |
542 | sf_bind_func sf_bind; | |
543 | sf_setoption_func sf_setoption; | |
544 | sf_getoption_func sf_getoption; | |
545 | sf_listen_func sf_listen; | |
546 | sf_ioctl_func sf_ioctl; | |
2d21ac55 A |
547 | /* |
548 | * The following are valid only if SFLT_EXTENDED flag is set. | |
549 | * Initialize sf_ext_len to sizeof sflt_filter_ext structure. | |
550 | * Filters must also initialize reserved fields with zeroes. | |
551 | */ | |
552 | struct sflt_filter_ext { | |
553 | unsigned int sf_ext_len; | |
554 | sf_accept_func sf_ext_accept; | |
555 | void *sf_ext_rsvd[5]; /* Reserved */ | |
556 | } sf_ext; | |
557 | #define sf_len sf_ext.sf_ext_len | |
558 | #define sf_accept sf_ext.sf_ext_accept | |
91447636 A |
559 | }; |
560 | ||
561 | /*! | |
562 | @function sflt_register | |
563 | @discussion Registers a socket filter. See 'man 2 socket' for a | |
564 | desciption of domain, type, and protocol. | |
565 | @param filter A structure describing the filter. | |
566 | @param domain The protocol domain these filters will be attached to. | |
3e170ce0 | 567 | Only PF_INET & PF_INET6 domains are supported. |
91447636 A |
568 | @param type The socket type these filters will be attached to. |
569 | @param protocol The protocol these filters will be attached to. | |
570 | @result 0 on success otherwise the errno error. | |
571 | */ | |
b0d623f7 A |
572 | extern errno_t sflt_register(const struct sflt_filter *filter, int domain, |
573 | int type, int protocol); | |
91447636 A |
574 | |
575 | /*! | |
576 | @function sflt_unregister | |
577 | @discussion Unregisters a socket filter. This will not detach the | |
578 | socket filter from all sockets it may be attached to at the | |
579 | time, it will just prevent the socket filter from being attached | |
580 | to any new sockets. | |
581 | @param handle The sf_handle of the socket filter to unregister. | |
582 | @result 0 on success otherwise the errno error. | |
583 | */ | |
b0d623f7 | 584 | extern errno_t sflt_unregister(sflt_handle handle); |
91447636 A |
585 | |
586 | /*! | |
587 | @function sflt_attach | |
588 | @discussion Attaches a socket filter to the specified socket. A | |
589 | filter must be registered before it can be attached. | |
590 | @param socket The socket the filter should be attached to. | |
591 | @param handle The handle of the registered filter to be attached. | |
592 | @result 0 on success otherwise the errno error. | |
593 | */ | |
39037602 | 594 | extern errno_t sflt_attach(socket_t socket, sflt_handle handle); |
91447636 A |
595 | |
596 | /*! | |
597 | @function sflt_detach | |
598 | @discussion Detaches a socket filter from a specified socket. | |
599 | @param socket The socket the filter should be detached from. | |
600 | @param handle The handle of the registered filter to be detached. | |
601 | @result 0 on success otherwise the errno error. | |
602 | */ | |
39037602 | 603 | extern errno_t sflt_detach(socket_t socket, sflt_handle handle); |
91447636 A |
604 | |
605 | /* Functions for manipulating sockets */ | |
606 | /* | |
607 | * Inject data in to the receive buffer of the socket as if it | |
608 | * had come from the network. | |
609 | * | |
610 | * flags should match sflt_data_flag_t | |
611 | */ | |
612 | ||
613 | /*! | |
614 | @function sock_inject_data_in | |
615 | @discussion Inject data in to the receive buffer of the socket as if | |
616 | it had come from the network. | |
617 | @param so The socket to inject the data on. | |
618 | @param from The address the data is from, only necessary on | |
619 | un-connected sockets. A copy of the address will be made, caller | |
620 | is responsible for freeing the address after calling this | |
621 | function. | |
622 | @param data The data and possibly control mbufs. | |
623 | @param control The separate control mbufs. | |
624 | @param flags Flags indicating the type of data. | |
625 | @result 0 on success otherwise the errno error. If the function | |
626 | returns an error, the caller is responsible for freeing the | |
627 | mbuf. | |
628 | */ | |
b0d623f7 A |
629 | extern errno_t sock_inject_data_in(socket_t so, const struct sockaddr *from, |
630 | mbuf_t data, mbuf_t control, sflt_data_flag_t flags); | |
91447636 A |
631 | |
632 | /*! | |
633 | @function sock_inject_data_out | |
634 | @discussion Inject data in to the send buffer of the socket as if it | |
635 | had come from the client. | |
636 | @param so The socket to inject the data on. | |
637 | @param to The address the data should be sent to, only necessary on | |
638 | un-connected sockets. The caller is responsible for freeing the | |
639 | to address after sock_inject_data_out returns. | |
640 | @param data The data and possibly control mbufs. | |
641 | @param control The separate control mbufs. | |
642 | @param flags Flags indicating the type of data. | |
643 | @result 0 on success otherwise the errno error. The data and control | |
644 | values are always freed regardless of return value. | |
645 | */ | |
b0d623f7 A |
646 | extern errno_t sock_inject_data_out(socket_t so, const struct sockaddr *to, |
647 | mbuf_t data, mbuf_t control, sflt_data_flag_t flags); | |
91447636 A |
648 | |
649 | ||
650 | /* | |
651 | * sockopt_t accessors | |
652 | */ | |
653 | ||
654 | enum { | |
655 | sockopt_get = 1, | |
656 | sockopt_set = 2 | |
657 | }; | |
658 | typedef u_int8_t sockopt_dir; | |
659 | ||
660 | /*! | |
661 | @function sockopt_direction | |
2d21ac55 | 662 | @discussion Retrieves the direction of the socket option (Get or |
91447636 A |
663 | Set). |
664 | @param sopt The socket option. | |
665 | @result sock_opt_get or sock_opt_set. | |
666 | */ | |
b0d623f7 | 667 | extern sockopt_dir sockopt_direction(sockopt_t sopt); |
91447636 A |
668 | |
669 | /*! | |
670 | @function sockopt_level | |
2d21ac55 | 671 | @discussion Retrieves the socket option level. (SOL_SOCKET, etc). |
91447636 A |
672 | @param sopt The socket option. |
673 | @result The socket option level. See man 2 setsockopt | |
674 | */ | |
b0d623f7 | 675 | extern int sockopt_level(sockopt_t sopt); |
91447636 A |
676 | |
677 | /*! | |
678 | @function sockopt_name | |
2d21ac55 | 679 | @discussion Retrieves the socket option name. (SO_SNDBUF, etc). |
91447636 A |
680 | @param sopt The socket option. |
681 | @result The socket option name. See man 2 setsockopt | |
682 | */ | |
b0d623f7 | 683 | extern int sockopt_name(sockopt_t sopt); |
91447636 A |
684 | |
685 | /*! | |
686 | @function sockopt_valsize | |
2d21ac55 | 687 | @discussion Retrieves the size of the socket option data. |
91447636 A |
688 | @param sopt The socket option. |
689 | @result The length, in bytes, of the data. | |
690 | */ | |
b0d623f7 | 691 | extern size_t sockopt_valsize(sockopt_t sopt); |
91447636 A |
692 | |
693 | /*! | |
694 | @function sockopt_copyin | |
695 | @discussion Copies the data from the socket option to a buffer. | |
696 | @param sopt The socket option. | |
697 | @param data A pointer to the buffer to copy the data in to. | |
698 | @param length The number of bytes to copy. | |
699 | @result An errno error or zero upon success. | |
700 | */ | |
b0d623f7 | 701 | extern errno_t sockopt_copyin(sockopt_t sopt, void *data, size_t length); |
91447636 A |
702 | |
703 | /*! | |
704 | @function sockopt_copyout | |
705 | @discussion Copies the data from a buffer to a socket option. | |
706 | @param sopt The socket option. | |
707 | @param data A pointer to the buffer to copy the data out of. | |
708 | @param length The number of bytes to copy. | |
709 | @result An errno error or zero upon success. | |
710 | */ | |
b0d623f7 | 711 | extern errno_t sockopt_copyout(sockopt_t sopt, void *data, size_t length); |
6601e61a | 712 | |
2d21ac55 | 713 | __END_DECLS |
b0d623f7 | 714 | #endif /* __KPI_SOCKETFILTER__ */ |