--- /dev/null
+/*
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*!
+ @header kpi_ipfilter.h
+ This header defines an API to attach IP filters. IP filters may be
+ attached to intercept either IPv4 or IPv6 packets. The filters can
+ intercept all IP packets in to and out of the host regardless of
+ interface.
+ */
+
+#ifndef __KPI_IPFILTER__
+#define __KPI_IPFILTER__
+
+#include <sys/kernel_types.h>
+
+/*
+ * ipf_pktopts
+ *
+ * Options for outgoing packets. The options need to be preserved when
+ * re-injecting a packet.
+ */
+struct ipf_pktopts {
+ u_int32_t ippo_flags;
+ ifnet_t ippo_mcast_ifnet;
+ int ippo_mcast_loop;
+ u_int8_t ippo_mcast_ttl;
+};
+#define IPPOF_MCAST_OPTS 0x1
+
+typedef struct ipf_pktopts* ipf_pktopts_t;
+
+/*!
+ @typedef ipf_input_func
+
+ @discussion ipf_input_func is used to filter incoming ip packets.
+ The IP filter is called for packets from all interfaces. The
+ filter is called between when the general IP processing is
+ handled and when the packet is passed up to the next layer
+ protocol such as udp or tcp. In the case of encapsulation, such
+ as UDP in ESP (IPSec), your filter will be called once for ESP
+ and then again for UDP. This will give your filter an
+ opportunity to process the ESP header as well as the decrypted
+ packet. Offset and protocol are used to determine where in the
+ packet processing is currently occuring. If you're only
+ interested in TCP or UDP packets, just return 0 if protocol
+ doesn't match TCP or UDP.
+ @param cookie The cookie specified when your filter was attached.
+ @param data The reassembled ip packet, data will start at the ip
+ header.
+ @param offset An offset to the next header
+ (udp/tcp/icmp/esp/etc...).
+ @param protocol The protocol type (udp/tcp/icmp/etc...) of the IP packet
+ @result Return:
+ 0 - The caller will continue with normal processing of the packet.
+ EJUSTRETURN - The caller will stop processing the packet, the packet will not be freed.
+ Anything Else - The caller will free the packet and stop processing.
+*/
+typedef errno_t (*ipf_input_func)(void* cookie, mbuf_t *data, int offset, u_int8_t protocol);
+
+/*!
+ @typedef ipf_output_func
+
+ @discussion ipf_output_func is used to filter outbound ip packets.
+ The IP filter is called for packets to all interfaces. The
+ filter is called before fragmentation and IPSec processing. If
+ you need to change the destination IP address, call
+ ipf_inject_output and return EJUSTRETURN.
+ @param cookie The cookie specified when your filter was attached.
+ @param data The ip packet, will contain an IP header followed by the
+ rest of the IP packet.
+ @result Return:
+ 0 - The caller will continue with normal processing of the packet.
+ EJUSTRETURN - The caller will stop processing the packet, the packet will not be freed.
+ Anything Else - The caller will free the packet and stop processing.
+*/
+typedef errno_t (*ipf_output_func)(void* cookie, mbuf_t *data, ipf_pktopts_t options);
+
+/*!
+ @typedef ipf_detach_func
+
+ @discussion ipf_detach_func is called to notify your filter that it
+ has been detached.
+ @param cookie The cookie specified when your filter was attached.
+*/
+typedef void (*ipf_detach_func)(void* cookie);
+
+/*!
+ @typedef ipf_filter
+ @discussion This structure is used to define an IP filter for
+ use with the ipf_addv4 or ipf_addv6 function.
+ @field cookie A kext defined cookie that will be passed to all
+ filter functions.
+ @field name A filter name used for debugging purposes.
+ @field ipf_input The filter function to handle inbound packets.
+ @field ipf_output The filter function to handle outbound packets.
+ @field ipf_detach The filter function to notify of a detach.
+*/
+struct ipf_filter {
+ void* cookie;
+ const char* name;
+ ipf_input_func ipf_input;
+ ipf_output_func ipf_output;
+ ipf_detach_func ipf_detach;
+};
+
+struct opaque_ipfilter;
+typedef struct opaque_ipfilter* ipfilter_t;
+
+/*!
+ @function ipf_addv4
+ @discussion Attaches an IPv4 ip filter.
+ @param filter A structure defining the filter.
+ @param filter_ref A reference to the filter used to detach it.
+ @result 0 on success otherwise the errno error.
+ */
+errno_t ipf_addv4(const struct ipf_filter* filter, ipfilter_t *filter_ref);
+
+/*!
+ @function ipf_addv6
+ @discussion Attaches an IPv6 ip filter.
+ @param filter A structure defining the filter.
+ @param filter_ref A reference to the filter used to detach it.
+ @result 0 on success otherwise the errno error.
+ */
+errno_t ipf_addv6(const struct ipf_filter* filter, ipfilter_t *filter_ref);
+
+/*!
+ @function ipf_remove
+ @discussion Detaches an IPv4 or IPv6 filter.
+ @param filter_ref The reference to the filter returned from ipf_addv4 or
+ ipf_addv6.
+ @result 0 on success otherwise the errno error.
+ */
+errno_t ipf_remove(ipfilter_t filter_ref);
+
+/*!
+ @function ipf_inject_input
+ @discussion Inject an IP packet as though it had just been
+ reassembled in ip_input. When re-injecting a packet intercepted
+ by the filter's ipf_input function, an IP filter can pass its
+ reference to avoid processing the packet twice. This also
+ prevents ip filters installed before this filter from
+ getting a chance to process the packet. If the filter modified
+ the packet, it should not specify the filter ref to give other
+ filters a chance to process the new packet.
+
+ Caller is responsible for freeing mbuf chain in the event that
+ ipf_inject_input returns an error.
+ @param data The complete IPv4 or IPv6 packet, receive interface must
+ be set.
+ @param filter_ref The reference to the filter injecting the data
+ @result 0 on success otherwise the errno error.
+ */
+errno_t ipf_inject_input(mbuf_t data, ipfilter_t filter_ref);
+
+/*!
+ @function ipf_inject_output
+ @discussion Inject an IP packet as though it had just been sent to
+ ip_output. When re-injecting a packet intercepted by the
+ filter's ipf_output function, an IP filter can pass its
+ reference to avoid processing the packet twice. This also
+ prevents ip filters installed before this filter from getting a
+ chance to process the packet. If the filter modified the packet,
+ it should not specify the filter ref to give other filters a
+ chance to process the new packet.
+ @param data The complete IPv4 or IPv6 packet.
+ @param filter_ref The reference to the filter injecting the data
+ @param options Output options for the packet
+ @result 0 on success otherwise the errno error. ipf_inject_output
+ will always free the mbuf.
+ */
+errno_t ipf_inject_output(mbuf_t data, ipfilter_t filter_ref, ipf_pktopts_t options);
+
+#endif /* __KPI_IPFILTER__ */