xref: /xnu-10002.61.3/bsd/netinet/kpi_ipfilter.h (revision 0f4c859e951fba394238ab619495c4e1d54d0f34)
1 /*
2  * Copyright (c) 2008-2021 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 #ifndef PRIVATE
40 #include <Availability.h>
41 #define __NKE_API_DEPRECATED __API_DEPRECATED("Network Kernel Extension KPI is deprecated", macos(10.4, 10.15))
42 #else
43 #define __NKE_API_DEPRECATED
44 #endif /* PRIVATE */
45 
46 /*
47  * ipf_pktopts
48  *
49  * Options for outgoing packets. The options need to be preserved when
50  * re-injecting a packet.
51  */
52 struct ipf_pktopts {
53 	u_int32_t                       ippo_flags;
54 	ifnet_t                         ippo_mcast_ifnet;
55 	int                             ippo_mcast_loop;
56 	u_int8_t                        ippo_mcast_ttl;
57 };
58 #define IPPOF_MCAST_OPTS            0x1
59 #ifdef PRIVATE
60 #define IPPOF_BOUND_IF              0x2
61 #define IPPOF_NO_IFT_CELLULAR       0x4
62 #define IPPOF_SELECT_SRCIF          0x8
63 #define IPPOF_BOUND_SRCADDR         0x10
64 #define IPPOF_SHIFT_IFSCOPE         16
65 #define IPPOF_NO_IFF_EXPENSIVE      0x20
66 #define IPPOF_NO_IFF_CONSTRAINED    0x40
67 #endif /* PRIVATE */
68 
69 typedef struct ipf_pktopts *ipf_pktopts_t;
70 
71 __BEGIN_DECLS
72 
73 /*!
74  *       @typedef ipf_input_func
75  *
76  *       @discussion ipf_input_func is used to filter incoming ip packets.
77  *               The IP filter is called for packets from all interfaces. The
78  *               filter is called between when the general IP processing is
79  *               handled and when the packet is passed up to the next layer
80  *               protocol such as udp or tcp. In the case of encapsulation, such
81  *               as UDP in ESP (IPsec), your filter will be called once for ESP
82  *               and then again for UDP. This will give your filter an
83  *               opportunity to process the ESP header as well as the decrypted
84  *               packet. Offset and protocol are used to determine where in the
85  *               packet processing is currently occuring. If you're only
86  *               interested in TCP or UDP packets, just return 0 if protocol
87  *               doesn't match TCP or UDP.
88  *       @param cookie The cookie specified when your filter was attached.
89  *       @param data The reassembled ip packet, data will start at the ip
90  *               header.
91  *       @param offset An offset to the next header
92  *               (udp/tcp/icmp/esp/etc...).
93  *       @param protocol The protocol type (udp/tcp/icmp/etc...) of the IP packet
94  *       @result Return:
95  *               0 - The caller will continue with normal processing of the
96  *                       packet.
97  *               EJUSTRETURN - The caller will stop processing the packet,
98  *                       the packet will not be freed.
99  *               Anything Else - The caller will free the packet and stop
100  *                       processing.
101  */
102 typedef errno_t (*ipf_input_func)(void *cookie, mbuf_t *data, int offset,
103     u_int8_t protocol);
104 
105 /*!
106  *       @typedef ipf_output_func
107  *
108  *       @discussion ipf_output_func is used to filter outbound ip packets.
109  *               The IP filter is called for packets to all interfaces. The
110  *               filter is called before fragmentation and IPsec processing. If
111  *               you need to change the destination IP address, call
112  *               ipf_inject_output and return EJUSTRETURN.
113  *       @param cookie The cookie specified when your filter was attached.
114  *       @param data The ip packet, will contain an IP header followed by the
115  *               rest of the IP packet.
116  *       @result Return:
117  *               0 - The caller will continue with normal processing of the
118  *                       packet.
119  *               EJUSTRETURN - The caller will stop processing the packet,
120  *                       the packet will not be freed.
121  *               Anything Else - The caller will free the packet and stop
122  *                       processing.
123  */
124 typedef errno_t (*ipf_output_func)(void *cookie, mbuf_t *data,
125     ipf_pktopts_t options);
126 
127 /*!
128  *       @typedef ipf_detach_func
129  *
130  *       @discussion ipf_detach_func is called to notify your filter that it
131  *               has been detached.
132  *       @param cookie The cookie specified when your filter was attached.
133  */
134 typedef void (*ipf_detach_func)(void *cookie);
135 
136 /*!
137  *       @typedef ipf_filter
138  *       @discussion This structure is used to define an IP filter for
139  *               use with the ipf_addv4 or ipf_addv6 function.
140  *       @field cookie A kext defined cookie that will be passed to all
141  *               filter functions.
142  *       @field name A filter name used for debugging purposes.
143  *       @field ipf_input The filter function to handle inbound packets.
144  *       @field ipf_output The filter function to handle outbound packets.
145  *       @field ipf_detach The filter function to notify of a detach.
146  */
147 struct ipf_filter {
148 	void            *cookie;
149 	const char      *name;
150 	ipf_input_func  ipf_input;
151 	ipf_output_func ipf_output;
152 	ipf_detach_func ipf_detach;
153 };
154 
155 struct opaque_ipfilter;
156 typedef struct opaque_ipfilter *ipfilter_t;
157 
158 /*!
159  *       @function ipf_addv4
160  *       @discussion Attaches an IPv4 ip filter.
161  *       @param filter A structure defining the filter.
162  *       @param filter_ref A reference to the filter used to detach it.
163  *       @result 0 on success otherwise the errno error.
164  */
165 #ifdef KERNEL_PRIVATE
166 extern errno_t ipf_addv4_internal(const struct ipf_filter *filter,
167     ipfilter_t *filter_ref);
168 
169 #define ipf_addv4(filter, filter_ref) \
170     ipf_addv4_internal((filter), (filter_ref))
171 #else
172 extern errno_t ipf_addv4(const struct ipf_filter *filter,
173     ipfilter_t *filter_ref)
174 __NKE_API_DEPRECATED;
175 #endif /* KERNEL_PRIVATE */
176 
177 /*!
178  *       @function ipf_addv6
179  *       @discussion Attaches an IPv6 ip filter.
180  *       @param filter A structure defining the filter.
181  *       @param filter_ref A reference to the filter used to detach it.
182  *       @result 0 on success otherwise the errno error.
183  */
184 #ifdef KERNEL_PRIVATE
185 extern errno_t ipf_addv6_internal(const struct ipf_filter *filter,
186     ipfilter_t *filter_ref);
187 
188 #define ipf_addv6(filter, filter_ref) \
189     ipf_addv6_internal((filter), (filter_ref))
190 #else
191 extern errno_t ipf_addv6(const struct ipf_filter *filter,
192     ipfilter_t *filter_ref)
193 __NKE_API_DEPRECATED;
194 #endif /* KERNEL_PRIVATE */
195 
196 /*!
197  *       @function ipf_remove
198  *       @discussion Detaches an IPv4 or IPv6 filter.
199  *       @param filter_ref The reference to the filter returned from ipf_addv4 or
200  *               ipf_addv6.
201  *       @result 0 on success otherwise the errno error.
202  */
203 extern errno_t ipf_remove(ipfilter_t filter_ref)
204 __NKE_API_DEPRECATED;
205 
206 /*!
207  *       @function ipf_inject_input
208  *       @discussion Inject an IP packet as though it had just been
209  *               reassembled in ip_input. When re-injecting a packet intercepted
210  *               by the filter's ipf_input function, an IP filter can pass its
211  *               reference to avoid processing the packet twice. This also
212  *               prevents ip filters installed before this filter from
213  *               getting a chance to process the packet. If the filter modified
214  *               the packet, it should not specify the filter ref to give other
215  *               filters a chance to process the new packet.
216  *
217  *               Caller is responsible for freeing mbuf chain in the event that
218  *               ipf_inject_input returns an error.
219  *       @param data The complete IPv4 or IPv6 packet, receive interface must
220  *               be set.
221  *       @param filter_ref The reference to the filter injecting the data
222  *       @result 0 on success otherwise the errno error.
223  */
224 extern errno_t ipf_inject_input(mbuf_t data, ipfilter_t filter_ref)
225 __NKE_API_DEPRECATED;
226 
227 /*!
228  *       @function ipf_inject_output
229  *       @discussion Inject an IP packet as though it had just been sent to
230  *               ip_output. When re-injecting a packet intercepted by the
231  *               filter's ipf_output function, an IP filter can pass its
232  *               reference to avoid processing the packet twice. This also
233  *               prevents ip filters installed before this filter from getting a
234  *               chance to process the packet. If the filter modified the packet,
235  *               it should not specify the filter ref to give other filters a
236  *               chance to process the new packet.
237  *       @param data The complete IPv4 or IPv6 packet.
238  *       @param filter_ref The reference to the filter injecting the data
239  *       @param options Output options for the packet
240  *       @result 0 on success otherwise the errno error. ipf_inject_output
241  *               will always free the mbuf.
242  */
243 extern errno_t ipf_inject_output(mbuf_t data, ipfilter_t filter_ref,
244     ipf_pktopts_t options)
245 __NKE_API_DEPRECATED;
246 __END_DECLS
247 #undef __NKE_API_DEPRECATED
248 #endif /* __KPI_IPFILTER__ */
249