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