| 1 | /* |
| 2 | * Copyright (c) 2003,2008,2017 Apple Computer, 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_interfacefilter.h |
| 30 | * This header defines an API to attach interface filters. Interface |
| 31 | * filters may be attached to a specific interface. The filters can |
| 32 | * intercept all packets in to and out of the specific interface. In |
| 33 | * addition, the filters may intercept interface specific events and |
| 34 | * ioctls. |
| 35 | */ |
| 36 | |
| 37 | #ifndef __KPI_INTERFACEFILTER__ |
| 38 | #define __KPI_INTERFACEFILTER__ |
| 39 | #include <sys/kernel_types.h> |
| 40 | #include <net/kpi_interface.h> |
| 41 | |
| 42 | #ifndef PRIVATE |
| 43 | #include <Availability.h> |
| 44 | #define __NKE_API_DEPRECATED __API_DEPRECATED("Network Kernel Extension KPI is deprecated", macos(10.4, 10.15.4)) |
| 45 | #else |
| 46 | #define __NKE_API_DEPRECATED |
| 47 | #endif /* PRIVATE */ |
| 48 | |
| 49 | struct kev_msg; |
| 50 | |
| 51 | __BEGIN_DECLS |
| 52 | |
| 53 | /*! |
| 54 | * @typedef iff_input_func |
| 55 | * |
| 56 | * @discussion iff_input_func is used to filter incoming packets. The |
| 57 | * interface is only valid for the duration of the filter call. If |
| 58 | * you need to keep a reference to the interface, be sure to call |
| 59 | * ifnet_reference and ifnet_release. The packets passed to the |
| 60 | * inbound filter are different from those passed to the outbound |
| 61 | * filter. Packets to the inbound filter have the frame header |
| 62 | * passed in separately from the rest of the packet. The outbound |
| 63 | * data filters is passed the whole packet including the frame |
| 64 | * header. |
| 65 | * |
| 66 | * The frame header usually preceeds the data in the mbuf. This |
| 67 | * ensures that the frame header will be a valid pointer as long as |
| 68 | * the mbuf is not freed. If you need to change the frame header to |
| 69 | * point somewhere else, the recommended method is to prepend a new |
| 70 | * frame header to the mbuf chain (mbuf_prepend), set the header to |
| 71 | * point to that data, then call mbuf_adj to move the mbuf data |
| 72 | * pointer back to the start of the packet payload. |
| 73 | * @param cookie The cookie specified when this filter was attached. |
| 74 | * @param interface The interface the packet was recieved on. |
| 75 | * @param protocol The protocol of this packet. If you specified a |
| 76 | * protocol when attaching your filter, the protocol will only ever |
| 77 | * be the protocol you specified. |
| 78 | * @param data The inbound packet, after the frame header as determined |
| 79 | * by the interface. |
| 80 | * @param frame_ptr A pointer to the pointer to the frame header. The |
| 81 | * frame header length can be found by inspecting the interface's |
| 82 | * frame header length (ifnet_hdrlen). |
| 83 | * @result Return: |
| 84 | * 0 - The caller will continue with normal processing of the |
| 85 | * packet. |
| 86 | * EJUSTRETURN - The caller will stop processing the packet, |
| 87 | * the packet will not be freed. |
| 88 | * Anything Else - The caller will free the packet and stop |
| 89 | * processing. |
| 90 | */ |
| 91 | typedef errno_t (*iff_input_func)(void *cookie, ifnet_t interface, |
| 92 | protocol_family_t protocol, mbuf_t *data, char **frame_ptr); |
| 93 | |
| 94 | /*! |
| 95 | * @typedef iff_output_func |
| 96 | * |
| 97 | * @discussion iff_output_func is used to filter fully formed outbound |
| 98 | * packets. The interface is only valid for the duration of the |
| 99 | * filter call. If you need to keep a reference to the interface, |
| 100 | * be sure to call ifnet_reference and ifnet_release. |
| 101 | * @param cookie The cookie specified when this filter was attached. |
| 102 | * @param interface The interface the packet is being transmitted on. |
| 103 | * @param data The fully formed outbound packet in a chain of mbufs. |
| 104 | * The frame header is already included. The filter function may |
| 105 | * modify the packet or return a different mbuf chain. |
| 106 | * @result Return: |
| 107 | * 0 - The caller will continue with normal processing of the |
| 108 | * packet. |
| 109 | * EJUSTRETURN - The caller will stop processing the packet, |
| 110 | * the packet will not be freed. |
| 111 | * Anything Else - The caller will free the packet and stop |
| 112 | * processing. |
| 113 | */ |
| 114 | typedef errno_t (*iff_output_func)(void *cookie, ifnet_t interface, |
| 115 | protocol_family_t protocol, mbuf_t *data); |
| 116 | |
| 117 | /*! |
| 118 | * @typedef iff_event_func |
| 119 | * |
| 120 | * @discussion iff_event_func is used to filter interface specific |
| 121 | * events. The interface is only valid for the duration of the |
| 122 | * filter call. If you need to keep a reference to the interface, |
| 123 | * be sure to call ifnet_reference and ifnet_release. |
| 124 | * @param cookie The cookie specified when this filter was attached. |
| 125 | * @param interface The interface the packet is being transmitted on. |
| 126 | * @param event_msg The kernel event, may not be changed. |
| 127 | */ |
| 128 | typedef void (*iff_event_func)(void *cookie, ifnet_t interface, |
| 129 | protocol_family_t protocol, const struct kev_msg *event_msg); |
| 130 | |
| 131 | /*! |
| 132 | * @typedef iff_ioctl_func |
| 133 | * |
| 134 | * @discussion iff_ioctl_func is used to filter ioctls sent to an |
| 135 | * interface. The interface is only valid for the duration of the |
| 136 | * filter call. If you need to keep a reference to the interface, |
| 137 | * be sure to call ifnet_reference and ifnet_release. |
| 138 | * |
| 139 | * All undefined ioctls are reserved for future use by Apple. If |
| 140 | * you need to communicate with your kext using an ioctl, please |
| 141 | * use SIOCSIFKPI and SIOCGIFKPI. |
| 142 | * @param cookie The cookie specified when this filter was attached. |
| 143 | * @param interface The interface the packet is being transmitted on. |
| 144 | * @param ioctl_cmd The ioctl command. |
| 145 | * @param ioctl_arg A pointer to the ioctl argument. |
| 146 | * @result Return: |
| 147 | * 0 - This filter function handled the ioctl. |
| 148 | * EOPNOTSUPP - This filter function does not understand/did not |
| 149 | * handle this ioctl. |
| 150 | * EJUSTRETURN - This filter function handled the ioctl, |
| 151 | * processing should stop. |
| 152 | * Anything Else - Processing will stop, the error will be |
| 153 | * returned. |
| 154 | */ |
| 155 | typedef errno_t (*iff_ioctl_func)(void *cookie, ifnet_t interface, |
| 156 | protocol_family_t protocol, unsigned long ioctl_cmd, void *ioctl_arg); |
| 157 | |
| 158 | /*! |
| 159 | * @typedef iff_detached_func |
| 160 | * |
| 161 | * @discussion iff_detached_func is called to notify the filter that it |
| 162 | * has been detached from an interface. This is the last call to |
| 163 | * the filter that will be made. A filter may be detached if the |
| 164 | * interface is detached or the detach filter function is called. |
| 165 | * In the case that the interface is being detached, your filter's |
| 166 | * event function will be called with the interface detaching event |
| 167 | * before the your detached function will be called. |
| 168 | * @param cookie The cookie specified when this filter was attached. |
| 169 | * @param interface The interface this filter was detached from. |
| 170 | */ |
| 171 | typedef void (*iff_detached_func)(void *cookie, ifnet_t interface); |
| 172 | |
| 173 | /*! |
| 174 | * @struct iff_filter |
| 175 | * @discussion This structure is used to define an interface filter for |
| 176 | * use with the iflt_attach function. |
| 177 | * @field iff_cookie A kext defined cookie that will be passed to all |
| 178 | * filter functions. |
| 179 | * @field iff_name A filter name used for debugging purposes. |
| 180 | * @field iff_protocol The protocol of the packets this filter is |
| 181 | * interested in. If you specify zero, packets from all protocols |
| 182 | * will be passed to the filter. |
| 183 | * @field iff_input The filter function to handle inbound packets, may |
| 184 | * be NULL. |
| 185 | * @field iff_output The filter function to handle outbound packets, |
| 186 | * may be NULL. |
| 187 | * @field iff_event The filter function to handle interface events, may |
| 188 | * be null. |
| 189 | * @field iff_ioctl The filter function to handle interface ioctls, may |
| 190 | * be null. |
| 191 | * @field iff_detached The filter function used to notify the filter that |
| 192 | * it has been detached. |
| 193 | */ |
| 194 | |
| 195 | struct iff_filter { |
| 196 | void *iff_cookie; |
| 197 | const char *iff_name; |
| 198 | protocol_family_t iff_protocol; |
| 199 | iff_input_func iff_input; |
| 200 | iff_output_func iff_output; |
| 201 | iff_event_func iff_event; |
| 202 | iff_ioctl_func iff_ioctl; |
| 203 | iff_detached_func iff_detached; |
| 204 | }; |
| 205 | |
| 206 | /*! |
| 207 | * @function iflt_attach |
| 208 | * @discussion Attaches an interface filter to an interface. |
| 209 | * @param interface The interface the filter should be attached to. |
| 210 | * @param filter A structure defining the filter. |
| 211 | * @param filter_ref A reference to the filter used to detach. |
| 212 | * @result 0 on success otherwise the errno error. |
| 213 | */ |
| 214 | #ifdef KERNEL_PRIVATE |
| 215 | extern errno_t iflt_attach_internal(ifnet_t interface, const struct iff_filter *filter, |
| 216 | interface_filter_t *filter_ref); |
| 217 | |
| 218 | #define iflt_attach(interface, filter, filter_ref) \ |
| 219 | iflt_attach_internal((interface), (filter), (filter_ref)) |
| 220 | #else |
| 221 | extern errno_t iflt_attach(ifnet_t interface, const struct iff_filter *filter, |
| 222 | interface_filter_t *filter_ref) |
| 223 | __NKE_API_DEPRECATED; |
| 224 | #endif /* KERNEL_PRIVATE */ |
| 225 | |
| 226 | /*! |
| 227 | * @function iflt_detach |
| 228 | * @discussion Detaches an interface filter from an interface. |
| 229 | * @param filter_ref The reference to the filter from iflt_attach. |
| 230 | */ |
| 231 | extern void iflt_detach(interface_filter_t filter_ref) |
| 232 | __NKE_API_DEPRECATED; |
| 233 | |
| 234 | __END_DECLS |
| 235 | #undef __NKE_API_DEPRECATED |
| 236 | #endif /* __KPI_INTERFACEFILTER__ */ |
| 237 | |