/*
* Copyright (c) 2008-2021 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_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__
#ifndef PRIVATE
#include <Availability.h>
#define __NKE_API_DEPRECATED __API_DEPRECATED("Network Kernel Extension KPI is deprecated", macos(10.4, 10.15))
#else
#define __NKE_API_DEPRECATED
#endif /* PRIVATE */
/*
* 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
#ifdef PRIVATE
#define IPPOF_BOUND_IF 0x2
#define IPPOF_NO_IFT_CELLULAR 0x4
#define IPPOF_SELECT_SRCIF 0x8
#define IPPOF_BOUND_SRCADDR 0x10
#define IPPOF_SHIFT_IFSCOPE 16
#define IPPOF_NO_IFF_EXPENSIVE 0x20
#define IPPOF_NO_IFF_CONSTRAINED 0x40
#endif /* PRIVATE */
typedef struct ipf_pktopts *ipf_pktopts_t;
__BEGIN_DECLS
/*!
* @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.
*/
#ifdef KERNEL_PRIVATE
extern errno_t ipf_addv4_internal(const struct ipf_filter *filter,
ipfilter_t *filter_ref);
#define ipf_addv4(filter, filter_ref) \
ipf_addv4_internal((filter), (filter_ref))
#else
extern errno_t ipf_addv4(const struct ipf_filter *filter,
ipfilter_t *filter_ref)
__NKE_API_DEPRECATED;
#endif /* KERNEL_PRIVATE */
/*!
* @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.
*/
#ifdef KERNEL_PRIVATE
extern errno_t ipf_addv6_internal(const struct ipf_filter *filter,
ipfilter_t *filter_ref);
#define ipf_addv6(filter, filter_ref) \
ipf_addv6_internal((filter), (filter_ref))
#else
extern errno_t ipf_addv6(const struct ipf_filter *filter,
ipfilter_t *filter_ref)
__NKE_API_DEPRECATED;
#endif /* KERNEL_PRIVATE */
/*!
* @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.
*/
extern errno_t ipf_remove(ipfilter_t filter_ref)
__NKE_API_DEPRECATED;
/*!
* @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.
*/
extern errno_t ipf_inject_input(mbuf_t data, ipfilter_t filter_ref)
__NKE_API_DEPRECATED;
/*!
* @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.
*/
extern errno_t ipf_inject_output(mbuf_t data, ipfilter_t filter_ref,
ipf_pktopts_t options)
__NKE_API_DEPRECATED;
__END_DECLS
#undef __NKE_API_DEPRECATED
#endif /* __KPI_IPFILTER__ */