]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/kpi_ipfilter.h
xnu-4903.270.47.tar.gz
[apple/xnu.git] / bsd / netinet / kpi_ipfilter.h
1 /*
2 * Copyright (c) 2008-2017 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*!
29 * @header kpi_ipfilter.h
30 * This header defines an API to attach IP filters. IP filters may be
31 * attached to intercept either IPv4 or IPv6 packets. The filters can
32 * intercept all IP packets in to and out of the host regardless of
33 * interface.
34 */
35
36 #ifndef __KPI_IPFILTER__
37 #define __KPI_IPFILTER__
38
39 #include <sys/kernel_types.h>
40
41 /*
42 * ipf_pktopts
43 *
44 * Options for outgoing packets. The options need to be preserved when
45 * re-injecting a packet.
46 */
47 struct ipf_pktopts {
48 u_int32_t ippo_flags;
49 ifnet_t ippo_mcast_ifnet;
50 int ippo_mcast_loop;
51 u_int8_t ippo_mcast_ttl;
52 };
53 #define IPPOF_MCAST_OPTS 0x1
54 #ifdef PRIVATE
55 #define IPPOF_BOUND_IF 0x2
56 #define IPPOF_NO_IFT_CELLULAR 0x4
57 #define IPPOF_SELECT_SRCIF 0x8
58 #define IPPOF_BOUND_SRCADDR 0x10
59 #define IPPOF_SHIFT_IFSCOPE 16
60 #define IPPOF_NO_IFF_EXPENSIVE 0x20
61 #endif /* PRIVATE */
62
63 typedef struct ipf_pktopts *ipf_pktopts_t;
64
65 __BEGIN_DECLS
66
67 /*!
68 * @typedef ipf_input_func
69 *
70 * @discussion ipf_input_func is used to filter incoming ip packets.
71 * The IP filter is called for packets from all interfaces. The
72 * filter is called between when the general IP processing is
73 * handled and when the packet is passed up to the next layer
74 * protocol such as udp or tcp. In the case of encapsulation, such
75 * as UDP in ESP (IPSec), your filter will be called once for ESP
76 * and then again for UDP. This will give your filter an
77 * opportunity to process the ESP header as well as the decrypted
78 * packet. Offset and protocol are used to determine where in the
79 * packet processing is currently occuring. If you're only
80 * interested in TCP or UDP packets, just return 0 if protocol
81 * doesn't match TCP or UDP.
82 * @param cookie The cookie specified when your filter was attached.
83 * @param data The reassembled ip packet, data will start at the ip
84 * header.
85 * @param offset An offset to the next header
86 * (udp/tcp/icmp/esp/etc...).
87 * @param protocol The protocol type (udp/tcp/icmp/etc...) of the IP packet
88 * @result Return:
89 * 0 - The caller will continue with normal processing of the
90 * packet.
91 * EJUSTRETURN - The caller will stop processing the packet,
92 * the packet will not be freed.
93 * Anything Else - The caller will free the packet and stop
94 * processing.
95 */
96 typedef errno_t (*ipf_input_func)(void *cookie, mbuf_t *data, int offset,
97 u_int8_t protocol);
98
99 /*!
100 * @typedef ipf_output_func
101 *
102 * @discussion ipf_output_func is used to filter outbound ip packets.
103 * The IP filter is called for packets to all interfaces. The
104 * filter is called before fragmentation and IPSec processing. If
105 * you need to change the destination IP address, call
106 * ipf_inject_output and return EJUSTRETURN.
107 * @param cookie The cookie specified when your filter was attached.
108 * @param data The ip packet, will contain an IP header followed by the
109 * rest of the IP packet.
110 * @result Return:
111 * 0 - The caller will continue with normal processing of the
112 * packet.
113 * EJUSTRETURN - The caller will stop processing the packet,
114 * the packet will not be freed.
115 * Anything Else - The caller will free the packet and stop
116 * processing.
117 */
118 typedef errno_t (*ipf_output_func)(void *cookie, mbuf_t *data,
119 ipf_pktopts_t options);
120
121 /*!
122 * @typedef ipf_detach_func
123 *
124 * @discussion ipf_detach_func is called to notify your filter that it
125 * has been detached.
126 * @param cookie The cookie specified when your filter was attached.
127 */
128 typedef void (*ipf_detach_func)(void *cookie);
129
130 /*!
131 * @typedef ipf_filter
132 * @discussion This structure is used to define an IP filter for
133 * use with the ipf_addv4 or ipf_addv6 function.
134 * @field cookie A kext defined cookie that will be passed to all
135 * filter functions.
136 * @field name A filter name used for debugging purposes.
137 * @field ipf_input The filter function to handle inbound packets.
138 * @field ipf_output The filter function to handle outbound packets.
139 * @field ipf_detach The filter function to notify of a detach.
140 */
141 struct ipf_filter {
142 void *cookie;
143 const char *name;
144 ipf_input_func ipf_input;
145 ipf_output_func ipf_output;
146 ipf_detach_func ipf_detach;
147 };
148
149 struct opaque_ipfilter;
150 typedef struct opaque_ipfilter *ipfilter_t;
151
152 /*!
153 * @function ipf_addv4
154 * @discussion Attaches an IPv4 ip filter.
155 * @param filter A structure defining the filter.
156 * @param filter_ref A reference to the filter used to detach it.
157 * @result 0 on success otherwise the errno error.
158 */
159 #ifdef KERNEL_PRIVATE
160 extern errno_t ipf_addv4_internal(const struct ipf_filter *filter,
161 ipfilter_t *filter_ref);
162
163 #define ipf_addv4(filter, filter_ref) \
164 ipf_addv4_internal((filter), (filter_ref))
165 #else
166 extern errno_t ipf_addv4(const struct ipf_filter *filter,
167 ipfilter_t *filter_ref);
168 #endif /* KERNEL_PRIVATE */
169
170 /*!
171 * @function ipf_addv6
172 * @discussion Attaches an IPv6 ip filter.
173 * @param filter A structure defining the filter.
174 * @param filter_ref A reference to the filter used to detach it.
175 * @result 0 on success otherwise the errno error.
176 */
177 #ifdef KERNEL_PRIVATE
178 extern errno_t ipf_addv6_internal(const struct ipf_filter *filter,
179 ipfilter_t *filter_ref);
180
181 #define ipf_addv6(filter, filter_ref) \
182 ipf_addv6_internal((filter), (filter_ref))
183 #else
184 extern errno_t ipf_addv6(const struct ipf_filter *filter,
185 ipfilter_t *filter_ref);
186 #endif /* KERNEL_PRIVATE */
187
188 /*!
189 * @function ipf_remove
190 * @discussion Detaches an IPv4 or IPv6 filter.
191 * @param filter_ref The reference to the filter returned from ipf_addv4 or
192 * ipf_addv6.
193 * @result 0 on success otherwise the errno error.
194 */
195 extern errno_t ipf_remove(ipfilter_t filter_ref);
196
197 /*!
198 * @function ipf_inject_input
199 * @discussion Inject an IP packet as though it had just been
200 * reassembled in ip_input. When re-injecting a packet intercepted
201 * by the filter's ipf_input function, an IP filter can pass its
202 * reference to avoid processing the packet twice. This also
203 * prevents ip filters installed before this filter from
204 * getting a chance to process the packet. If the filter modified
205 * the packet, it should not specify the filter ref to give other
206 * filters a chance to process the new packet.
207 *
208 * Caller is responsible for freeing mbuf chain in the event that
209 * ipf_inject_input returns an error.
210 * @param data The complete IPv4 or IPv6 packet, receive interface must
211 * be set.
212 * @param filter_ref The reference to the filter injecting the data
213 * @result 0 on success otherwise the errno error.
214 */
215 extern errno_t ipf_inject_input(mbuf_t data, ipfilter_t filter_ref);
216
217 /*!
218 * @function ipf_inject_output
219 * @discussion Inject an IP packet as though it had just been sent to
220 * ip_output. When re-injecting a packet intercepted by the
221 * filter's ipf_output function, an IP filter can pass its
222 * reference to avoid processing the packet twice. This also
223 * prevents ip filters installed before this filter from getting a
224 * chance to process the packet. If the filter modified the packet,
225 * it should not specify the filter ref to give other filters a
226 * chance to process the new packet.
227 * @param data The complete IPv4 or IPv6 packet.
228 * @param filter_ref The reference to the filter injecting the data
229 * @param options Output options for the packet
230 * @result 0 on success otherwise the errno error. ipf_inject_output
231 * will always free the mbuf.
232 */
233 extern errno_t ipf_inject_output(mbuf_t data, ipfilter_t filter_ref,
234 ipf_pktopts_t options);
235
236 __END_DECLS
237 #endif /* __KPI_IPFILTER__ */