code:
/*-
 * Copyright (c) 1989 Stephen Deering.
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Stephen Deering of Stanford University.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)ip_mroute.h	8.1 (Berkeley) 6/10/93
 * $FreeBSD: release/9.0.0/sys/netinet/ip_mroute.h 208744 2010-06-02 15:44:43Z zec $
 */

#ifndef _NETINET_IP_MROUTE_H_
#define _NETINET_IP_MROUTE_H_

/*
 * Definitions for IP multicast forwarding.
 *
 * Written by David Waitzman, BBN Labs, August 1988.
 * Modified by Steve Deering, Stanford, February 1989.
 * Modified by Ajit Thyagarajan, PARC, August 1993.
 * Modified by Ajit Thyagarajan, PARC, August 1994.
 * Modified by Ahmed Helmy, SGI, June 1996.
 * Modified by Pavlin Radoslavov, ICSI, October 2002.
 *
 * MROUTING Revision: 3.3.1.3
 * and PIM-SMv2 and PIM-DM support, advanced API support,
 * bandwidth metering and signaling.
 */

/*
 * Multicast Routing set/getsockopt commands.
 */
#define	MRT_INIT	100	/* initialize forwarder */
#define	MRT_DONE	101	/* shut down forwarder */
#define	MRT_ADD_VIF	102	/* create virtual interface */
#define	MRT_DEL_VIF	103	/* delete virtual interface */
#define MRT_ADD_MFC	104	/* insert forwarding cache entry */
#define MRT_DEL_MFC	105	/* delete forwarding cache entry */
#define MRT_VERSION	106	/* get kernel version number */
#define MRT_ASSERT      107     /* enable assert processing */
#define MRT_PIM		MRT_ASSERT /* enable PIM processing */
#define MRT_API_SUPPORT	109	/* supported MRT API */
#define MRT_API_CONFIG	110	/* config MRT API */
#define MRT_ADD_BW_UPCALL 111	/* create bandwidth monitor */
#define MRT_DEL_BW_UPCALL 112	/* delete bandwidth monitor */

/*
 * Types and macros for handling bitmaps with one bit per virtual interface.
 */
#define	MAXVIFS 32
typedef u_long vifbitmap_t;
typedef u_short vifi_t;		/* type of a vif index */
#define ALL_VIFS (vifi_t)-1

#define	VIFM_SET(n, m)		((m) |= (1 << (n)))
#define	VIFM_CLR(n, m)		((m) &= ~(1 << (n)))
#define	VIFM_ISSET(n, m)	((m) & (1 << (n)))
#define	VIFM_CLRALL(m)		((m) = 0x00000000)
#define	VIFM_COPY(mfrom, mto)	((mto) = (mfrom))
#define	VIFM_SAME(m1, m2)	((m1) == (m2))

struct mfc;

/*
 * Argument structure for MRT_ADD_VIF.
 * (MRT_DEL_VIF takes a single vifi_t argument.)
 */
struct vifctl {
	vifi_t	vifc_vifi;		/* the index of the vif to be added */
	u_char	vifc_flags;		/* VIFF_ flags defined below */
	u_char	vifc_threshold;		/* min ttl required to forward on vif */
	u_int	vifc_rate_limit;	/* max rate */
	struct	in_addr vifc_lcl_addr;	/* local interface address */
	struct	in_addr vifc_rmt_addr;	/* remote address (tunnels only) */
};

#define	VIFF_TUNNEL	0x1		/* no-op; retained for old source */
#define VIFF_SRCRT	0x2		/* no-op; retained for old source */
#define VIFF_REGISTER	0x4		/* used for PIM Register encap/decap */

/*
 * Argument structure for MRT_ADD_MFC and MRT_DEL_MFC
 * XXX if you change this, make sure to change struct mfcctl2 as well.
 */
struct mfcctl {
    struct in_addr  mfcc_origin;		/* ip origin of mcasts       */
    struct in_addr  mfcc_mcastgrp;		/* multicast group associated*/
    vifi_t	    mfcc_parent;		/* incoming vif              */
    u_char	    mfcc_ttls[MAXVIFS];		/* forwarding ttls on vifs   */
};

/*
 * The new argument structure for MRT_ADD_MFC and MRT_DEL_MFC overlays
 * and extends the old struct mfcctl.
 */
struct mfcctl2 {
	/* the mfcctl fields */
	struct in_addr	mfcc_origin;		/* ip origin of mcasts	     */
	struct in_addr	mfcc_mcastgrp;		/* multicast group associated*/
	vifi_t		mfcc_parent;		/* incoming vif		     */
	u_char		mfcc_ttls[MAXVIFS];	/* forwarding ttls on vifs   */

	/* extension fields */
	uint8_t		mfcc_flags[MAXVIFS];	/* the MRT_MFC_FLAGS_* flags */
	struct in_addr	mfcc_rp;		/* the RP address            */
};
/*
 * The advanced-API flags.
 *
 * The MRT_MFC_FLAGS_XXX API flags are also used as flags
 * for the mfcc_flags field.
 */
#define	MRT_MFC_FLAGS_DISABLE_WRONGVIF	(1 << 0) /* disable WRONGVIF signals */
#define	MRT_MFC_FLAGS_BORDER_VIF	(1 << 1) /* border vif		     */
#define MRT_MFC_RP			(1 << 8) /* enable RP address	     */
#define MRT_MFC_BW_UPCALL		(1 << 9) /* enable bw upcalls	     */
#define MRT_MFC_FLAGS_ALL		(MRT_MFC_FLAGS_DISABLE_WRONGVIF |    \
					 MRT_MFC_FLAGS_BORDER_VIF)
#define MRT_API_FLAGS_ALL		(MRT_MFC_FLAGS_ALL |		     \
					 MRT_MFC_RP |			     \
					 MRT_MFC_BW_UPCALL)

/*
 * Structure for installing or delivering an upcall if the
 * measured bandwidth is above or below a threshold.
 *
 * User programs (e.g. daemons) may have a need to know when the
 * bandwidth used by some data flow is above or below some threshold.
 * This interface allows the userland to specify the threshold (in
 * bytes and/or packets) and the measurement interval. Flows are
 * all packet with the same source and destination IP address.
 * At the moment the code is only used for multicast destinations
 * but there is nothing that prevents its use for unicast.
 *
 * The measurement interval cannot be shorter than some Tmin (currently, 3s).
 * The threshold is set in packets and/or bytes per_interval.
 *
 * Measurement works as follows:
 *
 * For >= measurements:
 * The first packet marks the start of a measurement interval.
 * During an interval we count packets and bytes, and when we
 * pass the threshold we deliver an upcall and we are done.
 * The first packet after the end of the interval resets the
 * count and restarts the measurement.
 *
 * For <= measurement:
 * We start a timer to fire at the end of the interval, and
 * then for each incoming packet we count packets and bytes.
 * When the timer fires, we compare the value with the threshold,
 * schedule an upcall if we are below, and restart the measurement
 * (reschedule timer and zero counters).
 */

struct bw_data {
	struct timeval	b_time;
	uint64_t	b_packets;
	uint64_t	b_bytes;
};

struct bw_upcall {
	struct in_addr	bu_src;			/* source address            */
	struct in_addr	bu_dst;			/* destination address       */
	uint32_t	bu_flags;		/* misc flags (see below)    */
#define BW_UPCALL_UNIT_PACKETS   (1 << 0)	/* threshold (in packets)    */
#define BW_UPCALL_UNIT_BYTES     (1 << 1)	/* threshold (in bytes)      */
#define BW_UPCALL_GEQ            (1 << 2)	/* upcall if bw >= threshold */
#define BW_UPCALL_LEQ            (1 << 3)	/* upcall if bw <= threshold */
#define BW_UPCALL_DELETE_ALL     (1 << 4)	/* delete all upcalls for s,d*/
	struct bw_data	bu_threshold;		/* the bw threshold	     */
	struct bw_data	bu_measured;		/* the measured bw	     */
};

/* max. number of upcalls to deliver together */
#define BW_UPCALLS_MAX				128
/* min. threshold time interval for bandwidth measurement */
#define BW_UPCALL_THRESHOLD_INTERVAL_MIN_SEC	3
#define BW_UPCALL_THRESHOLD_INTERVAL_MIN_USEC	0

/*
 * The kernel's multicast routing statistics.
 */
struct mrtstat {
    u_long	mrts_mfc_lookups;	/* # forw. cache hash table hits   */
    u_long	mrts_mfc_misses;	/* # forw. cache hash table misses */
    u_long	mrts_upcalls;		/* # calls to multicast routing daemon */
    u_long	mrts_no_route;		/* no route for packet's origin    */
    u_long	mrts_bad_tunnel;	/* malformed tunnel options        */
    u_long	mrts_cant_tunnel;	/* no room for tunnel options      */
    u_long	mrts_wrong_if;		/* arrived on wrong interface	   */
    u_long	mrts_upq_ovflw;		/* upcall Q overflow		   */
    u_long	mrts_cache_cleanups;	/* # entries with no upcalls	   */
    u_long	mrts_drop_sel;		/* pkts dropped selectively        */
    u_long	mrts_q_overflow;	/* pkts dropped - Q overflow       */
    u_long	mrts_pkt2large;		/* pkts dropped - size > BKT SIZE  */
    u_long	mrts_upq_sockfull;	/* upcalls dropped - socket full */
};

#ifdef _KERNEL
#define	MRTSTAT_ADD(name, val)	V_mrtstat.name += (val)
#define	MRTSTAT_INC(name)	MRTSTAT_ADD(name, 1)
#endif

/*
 * Argument structure used by mrouted to get src-grp pkt counts
 */
struct sioc_sg_req {
    struct in_addr src;
    struct in_addr grp;
    u_long pktcnt;
    u_long bytecnt;
    u_long wrong_if;
};

/*
 * Argument structure used by mrouted to get vif pkt counts
 */
struct sioc_vif_req {
    vifi_t vifi;		/* vif number				*/
    u_long icount;		/* Input packet count on vif		*/
    u_long ocount;		/* Output packet count on vif		*/
    u_long ibytes;		/* Input byte count on vif		*/
    u_long obytes;		/* Output byte count on vif		*/
};

/*
 * The kernel's virtual-interface structure.
 */
struct vif {
    u_char		v_flags;	/* VIFF_ flags defined above         */
    u_char		v_threshold;	/* min ttl required to forward on vif*/
    struct in_addr	v_lcl_addr;	/* local interface address           */
    struct in_addr	v_rmt_addr;	/* remote address (tunnels only)     */
    struct ifnet       *v_ifp;		/* pointer to interface              */
    u_long		v_pkt_in;	/* # pkts in on interface            */
    u_long		v_pkt_out;	/* # pkts out on interface           */
    u_long		v_bytes_in;	/* # bytes in on interface	     */
    u_long		v_bytes_out;	/* # bytes out on interface	     */
    struct route	v_route;	/* cached route */
};

#ifdef _KERNEL
/*
 * The kernel's multicast forwarding cache entry structure
 */
struct mfc {
	LIST_ENTRY(mfc)	mfc_hash;
	struct in_addr	mfc_origin;		/* IP origin of mcasts	     */
	struct in_addr  mfc_mcastgrp;		/* multicast group associated*/
	vifi_t		mfc_parent;		/* incoming vif              */
	u_char		mfc_ttls[MAXVIFS];	/* forwarding ttls on vifs   */
	u_long		mfc_pkt_cnt;		/* pkt count for src-grp     */
	u_long		mfc_byte_cnt;		/* byte count for src-grp    */
	u_long		mfc_wrong_if;		/* wrong if for src-grp	     */
	int		mfc_expire;		/* time to clean entry up    */
	struct timeval	mfc_last_assert;	/* last time I sent an assert*/
	uint8_t		mfc_flags[MAXVIFS];	/* the MRT_MFC_FLAGS_* flags */
	struct in_addr	mfc_rp;			/* the RP address	     */
	struct bw_meter	*mfc_bw_meter;		/* list of bandwidth meters  */
	u_long		mfc_nstall;		/* # of packets awaiting mfc */
	TAILQ_HEAD(, rtdetq) mfc_stall;		/* q of packets awaiting mfc */
};
#endif /* _KERNEL */

/*
 * Struct used to communicate from kernel to multicast router
 * note the convenient similarity to an IP packet
 */
struct igmpmsg {
    uint32_t	    unused1;
    uint32_t	    unused2;
    u_char	    im_msgtype;			/* what type of message	    */
#define IGMPMSG_NOCACHE		1	/* no MFC in the kernel		    */
#define IGMPMSG_WRONGVIF	2	/* packet came from wrong interface */
#define	IGMPMSG_WHOLEPKT	3	/* PIM pkt for user level encap.    */
#define	IGMPMSG_BW_UPCALL	4	/* BW monitoring upcall		    */
    u_char	    im_mbz;			/* must be zero		    */
    u_char	    im_vif;			/* vif rec'd on		    */
    u_char	    unused3;
    struct in_addr  im_src, im_dst;
};

#ifdef _KERNEL
/*
 * Argument structure used for pkt info. while upcall is made
 */
struct rtdetq {
    TAILQ_ENTRY(rtdetq)	rte_link;
    struct mbuf		*m;		/* A copy of the packet		    */
    struct ifnet	*ifp;		/* Interface pkt came in on	    */
    vifi_t		xmt_vif;	/* Saved copy of imo_multicast_vif  */
};
#define MAX_UPQ	4		/* max. no of pkts in upcall Q */
#endif /* _KERNEL */

/*
 * Structure for measuring the bandwidth and sending an upcall if the
 * measured bandwidth is above or below a threshold.
 */
struct bw_meter {
	struct bw_meter	*bm_mfc_next;		/* next bw meter (same mfc)  */
	struct bw_meter	*bm_time_next;		/* next bw meter (same time) */
	uint32_t	bm_time_hash;		/* the time hash value       */
	struct mfc	*bm_mfc;		/* the corresponding mfc     */
	uint32_t	bm_flags;		/* misc flags (see below)    */
#define BW_METER_UNIT_PACKETS	(1 << 0)	/* threshold (in packets)    */
#define BW_METER_UNIT_BYTES	(1 << 1)	/* threshold (in bytes)      */
#define BW_METER_GEQ		(1 << 2)	/* upcall if bw >= threshold */
#define BW_METER_LEQ		(1 << 3)	/* upcall if bw <= threshold */
#define BW_METER_USER_FLAGS	(BW_METER_UNIT_PACKETS |		\
				 BW_METER_UNIT_BYTES |			\
				 BW_METER_GEQ |				\
				 BW_METER_LEQ)

#define BW_METER_UPCALL_DELIVERED (1 << 24)	/* upcall was delivered      */

	struct bw_data	bm_threshold;		/* the upcall threshold	     */
	struct bw_data	bm_measured;		/* the measured bw	     */
	struct timeval	bm_start_time;		/* abs. time		     */
};

#ifdef _KERNEL

struct sockopt;

extern int	(*ip_mrouter_set)(struct socket *, struct sockopt *);
extern int	(*ip_mrouter_get)(struct socket *, struct sockopt *);
extern int	(*ip_mrouter_done)(void);
extern int	(*mrt_ioctl)(u_long, caddr_t, int);

#endif /* _KERNEL */

#endif /* _NETINET_IP_MROUTE_H_ */


code:
/*	$FreeBSD: release/9.0.0/sys/contrib/ipfilter/netinet/ip_nat.h 180778 2008-07-24 12:35:05Z darrenr $	*/

/*
 * Copyright (C) 1995-2001, 2003 by Darren Reed.
 *
 * See the IPFILTER.LICENCE file for details on licencing.
 *
 * @(#)ip_nat.h	1.5 2/4/96
 * $FreeBSD: release/9.0.0/sys/contrib/ipfilter/netinet/ip_nat.h 180778 2008-07-24 12:35:05Z darrenr $
 * Id: ip_nat.h,v 2.90.2.20 2007/09/25 08:27:32 darrenr Exp $
 */

#ifndef	__IP_NAT_H__
#define	__IP_NAT_H__

#ifndef SOLARIS
#define	SOLARIS	(defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif

#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
#define	SIOCADNAT	_IOW('r', 60, struct ipfobj)
#define	SIOCRMNAT	_IOW('r', 61, struct ipfobj)
#define	SIOCGNATS	_IOWR('r', 62, struct ipfobj)
#define	SIOCGNATL	_IOWR('r', 63, struct ipfobj)
#else
#define	SIOCADNAT	_IOW(r, 60, struct ipfobj)
#define	SIOCRMNAT	_IOW(r, 61, struct ipfobj)
#define	SIOCGNATS	_IOWR(r, 62, struct ipfobj)
#define	SIOCGNATL	_IOWR(r, 63, struct ipfobj)
#endif

#undef	LARGE_NAT	/* define	this if you're setting up a system to NAT
			 * LARGE numbers of networks/hosts - i.e. in the
			 * hundreds or thousands.  In such a case, you should
			 * also change the RDR_SIZE and NAT_SIZE below to more
			 * appropriate sizes.  The figures below were used for
			 * a setup with 1000-2000 networks to NAT.
			 */
#ifndef NAT_SIZE
# ifdef LARGE_NAT
#  define	NAT_SIZE	2047
# else
#  define	NAT_SIZE	127
# endif
#endif
#ifndef RDR_SIZE
# ifdef LARGE_NAT
#  define	RDR_SIZE	2047
# else
#  define	RDR_SIZE	127
# endif
#endif
#ifndef HOSTMAP_SIZE
# ifdef LARGE_NAT
#  define	HOSTMAP_SIZE	8191
# else
#  define	HOSTMAP_SIZE	2047
# endif
#endif
#ifndef NAT_TABLE_MAX
/*
 * This is newly introduced and for the sake of "least surprise", the numbers
 * present aren't what we'd normally use for creating a proper hash table.
 */
# ifdef	LARGE_NAT
#  define	NAT_TABLE_MAX	180000
# else
#  define	NAT_TABLE_MAX	30000
# endif
#endif
#ifndef NAT_TABLE_SZ
# ifdef LARGE_NAT
#  define	NAT_TABLE_SZ	16383
# else
#  define	NAT_TABLE_SZ	2047
# endif
#endif
#ifndef	APR_LABELLEN
#define	APR_LABELLEN	16
#endif
#define	NAT_HW_CKSUM	0x80000000

#define	DEF_NAT_AGE	1200     /* 10 minutes (600 seconds) */

struct ipstate;
struct ap_session;

typedef	struct	nat	{
	ipfmutex_t	nat_lock;
	struct	nat	*nat_next;
	struct	nat	**nat_pnext;
	struct	nat	*nat_hnext[2];
	struct	nat	**nat_phnext[2];
	struct	hostmap	*nat_hm;
	void		*nat_data;
	struct	nat	**nat_me;
	struct	ipstate	*nat_state;
	struct	ap_session	*nat_aps;		/* proxy session */
	frentry_t	*nat_fr;	/* filter rule ptr if appropriate */
	struct	ipnat	*nat_ptr;	/* pointer back to the rule */
	void		*nat_ifps[2];
	void		*nat_sync;
	ipftqent_t	nat_tqe;
	u_32_t		nat_flags;
	u_32_t		nat_sumd[2];	/* ip checksum delta for data segment*/
	u_32_t		nat_ipsumd;	/* ip checksum delta for ip header */
	u_32_t		nat_mssclamp;	/* if != zero clamp MSS to this */
	i6addr_t	nat_inip6;
	i6addr_t	nat_outip6;
	i6addr_t	nat_oip6;		/* other ip */
	U_QUAD_T	nat_pkts[2];
	U_QUAD_T	nat_bytes[2];
	union	{
		udpinfo_t	nat_unu;
		tcpinfo_t	nat_unt;
		icmpinfo_t	nat_uni;
		greinfo_t	nat_ugre;
	} nat_un;
	u_short		nat_oport;		/* other port */
	u_short		nat_use;
	u_char		nat_p;			/* protocol for NAT */
	int		nat_dir;
	int		nat_ref;		/* reference count */
	int		nat_hv[2];
	char		nat_ifnames[2][LIFNAMSIZ];
	int		nat_rev;		/* 0 = forward, 1 = reverse */
	int		nat_redir;		/* copy of in_redir */
	u_32_t		nat_seqnext[2];
} nat_t;

#define	nat_inip	nat_inip6.in4
#define	nat_outip	nat_outip6.in4
#define	nat_oip		nat_oip6.in4
#define	nat_age		nat_tqe.tqe_die
#define	nat_inport	nat_un.nat_unt.ts_sport
#define	nat_outport	nat_un.nat_unt.ts_dport
#define	nat_type	nat_un.nat_uni.ici_type
#define	nat_seq		nat_un.nat_uni.ici_seq
#define	nat_id		nat_un.nat_uni.ici_id
#define	nat_tcpstate	nat_tqe.tqe_state
#define	nat_die		nat_tqe.tqe_die
#define	nat_touched	nat_tqe.tqe_touched

/*
 * Values for nat_dir
 */
#define	NAT_INBOUND	0
#define	NAT_OUTBOUND	1

/*
 * Definitions for nat_flags
 */
#define	NAT_TCP		0x0001	/* IPN_TCP */
#define	NAT_UDP		0x0002	/* IPN_UDP */
#define	NAT_ICMPERR	0x0004	/* IPN_ICMPERR */
#define	NAT_ICMPQUERY	0x0008	/* IPN_ICMPQUERY */
#define	NAT_SEARCH	0x0010
#define	NAT_SLAVE	0x0020	/* Slave connection for a proxy */
#define	NAT_NOTRULEPORT	0x0040	/* Don't use the port # in the NAT rule */

#define	NAT_TCPUDP	(NAT_TCP|NAT_UDP)
#define	NAT_TCPUDPICMP	(NAT_TCP|NAT_UDP|NAT_ICMPERR)
#define	NAT_TCPUDPICMPQ	(NAT_TCP|NAT_UDP|NAT_ICMPQUERY)
#define	NAT_FROMRULE	(NAT_TCP|NAT_UDP)

/* 0x0100 reserved for FI_W_SPORT */
/* 0x0200 reserved for FI_W_DPORT */
/* 0x0400 reserved for FI_W_SADDR */
/* 0x0800 reserved for FI_W_DADDR */
/* 0x1000 reserved for FI_W_NEWFR */
/* 0x2000 reserved for SI_CLONE */
/* 0x4000 reserved for SI_CLONED */
/* 0x8000 reserved for SI_IGNOREPKT */

#define	NAT_DEBUG	0x800000

typedef	struct	ipnat	{
	ipfmutex_t	in_lock;
	struct	ipnat	*in_next;		/* NAT rule list next */
	struct	ipnat	*in_rnext;		/* rdr rule hash next */
	struct	ipnat	**in_prnext;		/* prior rdr next ptr */
	struct	ipnat	*in_mnext;		/* map rule hash next */
	struct	ipnat	**in_pmnext;		/* prior map next ptr */
	struct	ipftq	*in_tqehead[2];
	void		*in_ifps[2];
	void		*in_apr;
	char		*in_comment;
	i6addr_t	in_next6;
	u_long		in_space;
	u_long		in_hits;
	u_int		in_use;
	u_int		in_hv;
	int		in_flineno;		/* conf. file line number */
	u_short		in_pnext;
	u_char		in_v;
	u_char		in_xxx;
	/* From here to the end is covered by IPN_CMPSIZ */
	u_32_t		in_flags;
	u_32_t		in_mssclamp;		/* if != 0 clamp MSS to this */
	u_int		in_age[2];
	int		in_redir;		/* see below for values */
	int		in_p;			/* protocol. */
	i6addr_t	in_in[2];
	i6addr_t	in_out[2];
	i6addr_t	in_src[2];
	frtuc_t		in_tuc;
	u_short		in_port[2];
	u_short		in_ppip;		/* ports per IP. */
	u_short		in_ippip;		/* IP #'s per IP# */
	char		in_ifnames[2][LIFNAMSIZ];
	char		in_plabel[APR_LABELLEN];	/* proxy label. */
	ipftag_t	in_tag;
} ipnat_t;

#define	in_pmin		in_port[0]	/* Also holds static redir port */
#define	in_pmax		in_port[1]
#define	in_nextip	in_next6.in4
#define	in_nip		in_next6.in4.s_addr
#define	in_inip		in_in[0].in4.s_addr
#define	in_inmsk	in_in[1].in4.s_addr
#define	in_outip	in_out[0].in4.s_addr
#define	in_outmsk	in_out[1].in4.s_addr
#define	in_srcip	in_src[0].in4.s_addr
#define	in_srcmsk	in_src[1].in4.s_addr
#define	in_scmp		in_tuc.ftu_scmp
#define	in_dcmp		in_tuc.ftu_dcmp
#define	in_stop		in_tuc.ftu_stop
#define	in_dtop		in_tuc.ftu_dtop
#define	in_sport	in_tuc.ftu_sport
#define	in_dport	in_tuc.ftu_dport

/*
 * Bit definitions for in_flags
 */
#define	IPN_ANY		0x00000
#define	IPN_TCP		0x00001
#define	IPN_UDP		0x00002
#define	IPN_TCPUDP	(IPN_TCP|IPN_UDP)
#define	IPN_ICMPERR	0x00004
#define	IPN_TCPUDPICMP	(IPN_TCP|IPN_UDP|IPN_ICMPERR)
#define	IPN_ICMPQUERY	0x00008
#define	IPN_TCPUDPICMPQ	(IPN_TCP|IPN_UDP|IPN_ICMPQUERY)
#define	IPN_RF		(IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR)
#define	IPN_AUTOPORTMAP	0x00010
#define	IPN_IPRANGE	0x00020
#define	IPN_FILTER	0x00040
#define	IPN_SPLIT	0x00080
#define	IPN_ROUNDR	0x00100
#define	IPN_NOTSRC	0x04000
#define	IPN_NOTDST	0x08000
#define	IPN_DYNSRCIP	0x10000	/* dynamic src IP# */
#define	IPN_DYNDSTIP	0x20000	/* dynamic dst IP# */
#define	IPN_DELETE	0x40000
#define	IPN_STICKY	0x80000
#define	IPN_FRAG	0x100000
#define	IPN_FIXEDDPORT	0x200000
#define	IPN_FINDFORWARD	0x400000
#define	IPN_IN		0x800000
#define	IPN_SEQUENTIAL	0x1000000
#define	IPN_USERFLAGS	(IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\
			 IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|\
			 IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY|\
			 IPN_SEQUENTIAL)

/*
 * Values for in_redir
 */
#define	NAT_MAP		0x01
#define	NAT_REDIRECT	0x02
#define	NAT_BIMAP	(NAT_MAP|NAT_REDIRECT)
#define	NAT_MAPBLK	0x04

#define	MAPBLK_MINPORT	1024	/* don't use reserved ports for src port */
#define	USABLE_PORTS	(65536 - MAPBLK_MINPORT)

#define	IPN_CMPSIZ	(sizeof(ipnat_t) - offsetof(ipnat_t, in_flags))

typedef	struct	natlookup {
	struct	in_addr	nl_inip;
	struct	in_addr	nl_outip;
	struct	in_addr	nl_realip;
	int	nl_flags;
	u_short	nl_inport;
	u_short	nl_outport;
	u_short	nl_realport;
} natlookup_t;

typedef struct  nat_save    {
	void	*ipn_next;
	struct	nat	ipn_nat;
	struct	ipnat	ipn_ipnat;
	struct	frentry ipn_fr;
	int	ipn_dsize;
	char	ipn_data[4];
} nat_save_t;

#define	ipn_rule	ipn_nat.nat_fr

typedef	struct	natget	{
	void	*ng_ptr;
	int	ng_sz;
} natget_t;

/*
 * This structure gets used to help NAT sessions keep the same NAT rule (and
 * thus translation for IP address) when:
 * (a) round-robin redirects are in use
 * (b) different IP add
 */
typedef	struct	hostmap	{
	struct	hostmap	*hm_hnext;
	struct	hostmap	**hm_phnext;
	struct	hostmap	*hm_next;
	struct	hostmap	**hm_pnext;
	struct	ipnat	*hm_ipnat;
	struct	in_addr	hm_srcip;
	struct	in_addr	hm_dstip;
	struct	in_addr	hm_mapip;
	u_32_t		hm_port;
	int		hm_ref;
} hostmap_t;

/*
 * Structure used to pass information in to nat_newmap and nat_newrdr.
 */
typedef struct	natinfo	{
	ipnat_t		*nai_np;
	u_32_t		nai_sum1;
	u_32_t		nai_sum2;
	u_32_t		nai_nflags;
	u_32_t		nai_flags;
	struct	in_addr	nai_ip;
	u_short		nai_port;
	u_short		nai_nport;
	u_short		nai_sport;
	u_short		nai_dport;
} natinfo_t;

typedef	struct	natstat	{
	u_long	ns_mapped[2];
	u_long	ns_rules;
	u_long	ns_added;
	u_long	ns_expire;
	u_long	ns_inuse;
	u_long	ns_logged;
	u_long	ns_logfail;
	u_long	ns_memfail;
	u_long	ns_badnat;
	u_long	ns_addtrpnt;
	nat_t	**ns_table[2];
	hostmap_t **ns_maptable;
	ipnat_t	*ns_list;
	void	*ns_apslist;
	u_int	ns_wilds;
	u_int	ns_nattab_sz;
	u_int	ns_nattab_max;
	u_int	ns_rultab_sz;
	u_int	ns_rdrtab_sz;
	u_int	ns_trpntab_sz;
	u_int	ns_hostmap_sz;
	nat_t	*ns_instances;
	hostmap_t *ns_maplist;
	u_long	*ns_bucketlen[2];
	u_long	ns_ticks;
	u_int	ns_orphans;
} natstat_t;

typedef	struct	natlog {
	struct	in_addr	nl_origip;
	struct	in_addr	nl_outip;
	struct	in_addr	nl_inip;
	u_short	nl_origport;
	u_short	nl_outport;
	u_short	nl_inport;
	u_short	nl_type;
	int	nl_rule;
	U_QUAD_T	nl_pkts[2];
	U_QUAD_T	nl_bytes[2];
	u_char	nl_p;
} natlog_t;

#define	NL_NEWMAP	NAT_MAP
#define	NL_NEWRDR	NAT_REDIRECT
#define	NL_NEWBIMAP	NAT_BIMAP
#define	NL_NEWBLOCK	NAT_MAPBLK
#define	NL_DESTROY	0xfffc
#define	NL_CLONE	0xfffd
#define	NL_FLUSH	0xfffe
#define	NL_EXPIRE	0xffff

#define	NAT_HASH_FN(k,l,m)	(((k) + ((k) >> 12) + l) % (m))

#define	LONG_SUM(in)	(((in) & 0xffff) + ((in) >> 16))

#define	CALC_SUMD(s1, s2, sd) { \
			    (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
			    (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
			    /* Do it twice */ \
			    (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
			    (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
			    /* Because ~1 == -2, We really need ~1 == -1 */ \
			    if ((s1) > (s2)) (s2)--; \
			    (sd) = (s2) - (s1); \
			    (sd) = ((sd) & 0xffff) + ((sd) >> 16); }

#define	NAT_SYSSPACE		0x80000000
#define	NAT_LOCKHELD		0x40000000

extern	u_int	ipf_nattable_sz;
extern	u_int	ipf_nattable_max;
extern	u_int	ipf_natrules_sz;
extern	u_int	ipf_rdrrules_sz;
extern	u_int	ipf_hostmap_sz;
extern	u_int	fr_nat_maxbucket;
extern	u_int	fr_nat_maxbucket_reset;
extern	int	fr_nat_lock;
extern	int	fr_nat_doflush;
extern	void	fr_natsync __P((void *));
extern	u_long	fr_defnatage;
extern	u_long	fr_defnaticmpage;
extern	u_long	fr_defnatipage;
	/* nat_table[0] -> hashed list sorted by inside (ip, port) */
	/* nat_table[1] -> hashed list sorted by outside (ip, port) */
extern	nat_t	**nat_table[2];
extern	nat_t	*nat_instances;
extern	ipnat_t	*nat_list;
extern	ipnat_t	**nat_rules;
extern	ipnat_t	**rdr_rules;
extern	ipftq_t	*nat_utqe;
extern	natstat_t	nat_stats;

#if defined(__OpenBSD__)
extern	void	nat_ifdetach __P((void *));
#endif
extern	int	fr_nat_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *));
extern	int	fr_natinit __P((void));
extern	nat_t	*nat_new __P((fr_info_t *, ipnat_t *, nat_t **, u_int, int));
extern	nat_t	*nat_outlookup __P((fr_info_t *, u_int, u_int, struct in_addr,
				 struct in_addr));
extern	void	fix_datacksum __P((u_short *, u_32_t));
extern	nat_t	*nat_inlookup __P((fr_info_t *, u_int, u_int, struct in_addr,
				struct in_addr));
extern	nat_t	*nat_tnlookup __P((fr_info_t *, int));
extern	nat_t	*nat_maplookup __P((void *, u_int, struct in_addr,
				struct in_addr));
extern	nat_t	*nat_lookupredir __P((natlookup_t *));
extern	nat_t	*nat_icmperrorlookup __P((fr_info_t *, int));
extern	nat_t	*nat_icmperror __P((fr_info_t *, u_int *, int));
extern	void	nat_delete __P((struct nat *, int));
extern	int	nat_insert __P((nat_t *, int));

extern	int	fr_checknatout __P((fr_info_t *, u_32_t *));
extern	int	fr_natout __P((fr_info_t *, nat_t *, int, u_32_t));
extern	int	fr_checknatin __P((fr_info_t *, u_32_t *));
extern	int	fr_natin __P((fr_info_t *, nat_t *, int, u_32_t));
extern	void	fr_natunload __P((void));
extern	void	fr_natexpire __P((void));
extern	void	nat_log __P((struct nat *, u_int));
extern	void	fix_incksum __P((fr_info_t *, u_short *, u_32_t));
extern	void	fix_outcksum __P((fr_info_t *, u_short *, u_32_t));
extern	void	fr_ipnatderef __P((ipnat_t **));
extern	void	fr_natderef __P((nat_t **));
extern	u_short	*nat_proto __P((fr_info_t *, nat_t *, u_int));
extern	void	nat_update __P((fr_info_t *, nat_t *, ipnat_t *));
extern	void	fr_setnatqueue __P((nat_t *, int));
extern	void	fr_hostmapdel __P((hostmap_t **));

#endif /* __IP_NAT_H__ */

repo_name: veiledmerc/mira

license: mit


code:
/*
 * Copyright (c) 1982, 1986, 1993
 *	The Regents of the University of California.
 * Copyright (c) 2005 Andre Oppermann, Internet Business Solutions AG.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/netinet/ip_options.h 189343 2009-03-04 02:51:22Z bms $
 */

#ifndef _NETINET_IP_OPTIONS_H_
#define	_NETINET_IP_OPTIONS_H_

struct ipoptrt {
        struct  in_addr dst;                    /* final destination */
        char    nop;                            /* one NOP to align */
        char    srcopt[IPOPT_OFFSET + 1];       /* OPTVAL, OLEN and OFFSET */
        struct  in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)];
};

struct ipopt_tag {
	struct	m_tag tag;			/* m_tag */
	int	ip_nhops;
	struct	ipoptrt ip_srcrt;
};

extern	int	ip_doopts;		/* process or ignore IP options */

int		 ip_checkrouteralert(struct mbuf *);
int		 ip_dooptions(struct mbuf *, int);
struct mbuf	*ip_insertoptions(struct mbuf *, struct mbuf *, int *);
int		 ip_optcopy(struct ip *, struct ip *);
int		 ip_pcbopts(struct inpcb *, int, struct mbuf *);
void		 ip_stripoptions(struct mbuf *, struct mbuf *);
struct mbuf	*ip_srcroute(struct mbuf *);

#endif /* !_NETINET_IP_OPTIONS_H_ */


code:
/*
 * Copyright (C) 1993-2001, 2003 by Darren Reed.
 *
 * See the IPFILTER.LICENCE file for details on licencing.
 *
 * $Id: ip_pool.h,v 2.26.2.6 2007/10/10 09:51:43 darrenr Exp $
 */

#ifndef	__IP_POOL_H__
#define	__IP_POOL_H__

#if defined(_KERNEL) && !defined(__osf__) && !defined(__hpux) && \
    !defined(linux) && !defined(sun) && !defined(AIX)
# include <net/radix.h>
extern void rn_freehead __P((struct radix_node_head *));
# define FreeS(p, z)		KFREES(p, z)
extern int max_keylen;
#else
# if defined(__osf__) || defined(__hpux) || defined(sun)
#  include "radix_ipf_local.h"
#  define radix_mask ipf_radix_mask
#  define radix_node ipf_radix_node
#  define radix_node_head ipf_radix_node_head
# else
#  include "radix_ipf.h"
# endif
#endif
#include "netinet/ip_lookup.h"

#define	IP_POOL_NOMATCH		0
#define	IP_POOL_POSITIVE	1

typedef	struct ip_pool_node {
	struct	radix_node	ipn_nodes[2];
	addrfamily_t		ipn_addr;
	addrfamily_t		ipn_mask;
	int			ipn_info;
	int			ipn_ref;
char			ipn_name[FR_GROUPLEN];
u_long			ipn_hits;
	struct ip_pool_node	*ipn_next, **ipn_pnext;
} ip_pool_node_t;

typedef	struct ip_pool_s {
	struct ip_pool_s	*ipo_next;
	struct ip_pool_s	**ipo_pnext;
	struct radix_node_head	*ipo_head;
	ip_pool_node_t	*ipo_list;
	u_long		ipo_hits;
	int		ipo_unit;
	int		ipo_flags;
	int		ipo_ref;
	char		ipo_name[FR_GROUPLEN];
} ip_pool_t;

#define	IPOOL_DELETE	0x01
#define	IPOOL_ANON	0x02

typedef	struct	ip_pool_stat	{
	u_long		ipls_pools;
	u_long		ipls_tables;
	u_long		ipls_nodes;
	ip_pool_t	*ipls_list[IPL_LOGSIZE];
} ip_pool_stat_t;

extern	ip_pool_stat_t	ipoolstat;
extern	ip_pool_t	*ip_pool_list[IPL_LOGSIZE];

extern	int	ip_pool_search __P((void *, int, void *));
extern	int	ip_pool_init __P((void));
extern	void	ip_pool_fini __P((void));
extern	int	ip_pool_create __P((iplookupop_t *));
extern	int	ip_pool_insert __P((ip_pool_t *, i6addr_t *, i6addr_t *, int));
extern	int	ip_pool_remove __P((ip_pool_t *, ip_pool_node_t *));
extern	int	ip_pool_destroy __P((int, char *));
extern	void	ip_pool_free __P((ip_pool_t *));
extern	void	ip_pool_deref __P((ip_pool_t *));
extern	void	ip_pool_node_deref __P((ip_pool_node_t *));
extern	void	*ip_pool_find __P((int, char *));
extern	ip_pool_node_t *ip_pool_findeq __P((ip_pool_t *,
					  addrfamily_t *, addrfamily_t *));
extern	int	ip_pool_flush __P((iplookupflush_t *));
extern	int	ip_pool_statistics __P((iplookupop_t *));
extern	int	ip_pool_getnext __P((ipftoken_t *, ipflookupiter_t *));
extern	void	ip_pool_iterderef __P((u_int, int, void *));

#endif /* __IP_POOL_H__ */


code:
/*	$FreeBSD: release/9.0.0/sys/contrib/ipfilter/netinet/ip_proxy.h 170268 2007-06-04 02:54:36Z darrenr $	*/

/*
 * Copyright (C) 1997-2001 by Darren Reed.
 *
 * See the IPFILTER.LICENCE file for details on licencing.
 *
 * $FreeBSD: release/9.0.0/sys/contrib/ipfilter/netinet/ip_proxy.h 170268 2007-06-04 02:54:36Z darrenr $
 * Id: ip_proxy.h,v 2.31.2.2 2005/03/12 19:33:48 darrenr Exp
 */

#ifndef	__IP_PROXY_H__
#define	__IP_PROXY_H__

#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif

#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
#define	SIOCPROXY	_IOWR('r', 64, struct ap_control)
#else
#define	SIOCPROXY	_IOWR(r, 64, struct ap_control)
#endif

#ifndef	APR_LABELLEN
#define	APR_LABELLEN	16
#endif
#define	AP_SESS_SIZE	53

struct	nat;
struct	ipnat;
struct	ipstate;

typedef	struct	ap_tcp {
	u_short	apt_sport;	/* source port */
	u_short	apt_dport;	/* destination port */
	short	apt_sel[2];	/* {seq,ack}{off,min} set selector */
	short	apt_seqoff[2];	/* sequence # difference */
	u_32_t	apt_seqmin[2];	/* don't change seq-off until after this */
	short	apt_ackoff[2];	/* sequence # difference */
	u_32_t	apt_ackmin[2];	/* don't change seq-off until after this */
	u_char	apt_state[2];	/* connection state */
} ap_tcp_t;

typedef	struct	ap_udp {
	u_short	apu_sport;	/* source port */
	u_short	apu_dport;	/* destination port */
} ap_udp_t;

typedef	struct ap_session {
	struct	aproxy	*aps_apr;
	union {
		struct	ap_tcp	apu_tcp;
		struct	ap_udp	apu_udp;
	} aps_un;
	u_int	aps_flags;
	U_QUAD_T aps_bytes;	/* bytes sent */
	U_QUAD_T aps_pkts;	/* packets sent */
	void	*aps_nat;	/* pointer back to nat struct */
	void	*aps_data;	/* private data */
	int	aps_p;		/* protocol */
	int	aps_psiz;	/* size of private data */
	struct	ap_session	*aps_hnext;
	struct	ap_session	*aps_next;
} ap_session_t;

#define	aps_sport	aps_un.apu_tcp.apt_sport
#define	aps_dport	aps_un.apu_tcp.apt_dport
#define	aps_sel		aps_un.apu_tcp.apt_sel
#define	aps_seqoff	aps_un.apu_tcp.apt_seqoff
#define	aps_seqmin	aps_un.apu_tcp.apt_seqmin
#define	aps_state	aps_un.apu_tcp.apt_state
#define	aps_ackoff	aps_un.apu_tcp.apt_ackoff
#define	aps_ackmin	aps_un.apu_tcp.apt_ackmin

typedef	struct	ap_control {
	char	apc_label[APR_LABELLEN];
	u_char	apc_p;
	/*
	 * The following fields are upto the proxy's apr_ctl routine to deal
	 * with.  When the proxy gets this in kernel space, apc_data will
	 * point to a malloc'd region of memory of apc_dsize bytes.  If the
	 * proxy wants to keep that memory, it must set apc_data to NULL
	 * before it returns.  It is expected if this happens that it will
	 * take care to free it in apr_fini or otherwise as appropriate.
	 * apc_cmd is provided as a standard place to put simple commands,
	 * with apc_arg being available to put a simple arg.
	 */
	u_long	apc_cmd;
	u_long	apc_arg;
	void	*apc_data;
	size_t	apc_dsize;
} ap_ctl_t;

typedef	struct	aproxy	{
	struct	aproxy	*apr_next;
	char	apr_label[APR_LABELLEN];	/* Proxy label # */
	u_char	apr_p;		/* protocol */
	int	apr_ref;	/* +1 per rule referencing it */
	int	apr_flags;
	int	(* apr_init) __P((void));
	void	(* apr_fini) __P((void));
	int	(* apr_new) __P((fr_info_t *, ap_session_t *, struct nat *));
	void	(* apr_del) __P((ap_session_t *));
	int	(* apr_inpkt) __P((fr_info_t *, ap_session_t *, struct nat *));
	int	(* apr_outpkt) __P((fr_info_t *, ap_session_t *, struct nat *));
	int	(* apr_match) __P((fr_info_t *, ap_session_t *, struct nat *));
	int	(* apr_ctl) __P((struct aproxy *, struct ap_control *));
} aproxy_t;

#define	APR_DELETE	1

#define	APR_ERR(x)	((x) << 16)
#define	APR_EXIT(x)	(((x) >> 16) & 0xffff)
#define	APR_INC(x)	((x) & 0xffff)

/*
 * Generic #define's to cover missing things in the kernel
 */
#ifndef isdigit
#define isdigit(x)	((x) >= '0' && (x) <= '9')
#endif
#ifndef isupper
#define isupper(x)	(((unsigned)(x) >= 'A') && ((unsigned)(x) <= 'Z'))
#endif
#ifndef islower
#define islower(x)	(((unsigned)(x) >= 'a') && ((unsigned)(x) <= 'z'))
#endif
#ifndef isalpha
#define isalpha(x)	(isupper(x) || islower(x))
#endif
#ifndef toupper
#define toupper(x)	(isupper(x) ? (x) : (x) - 'a' + 'A')
#endif
#ifndef isspace
#define isspace(x)	(((x) == ' ') || ((x) == '\r') || ((x) == '\n') || \
			 ((x) == '\t') || ((x) == '\b'))
#endif

/*
 * This is the scratch buffer size used to hold strings from the TCP stream
 * that we may want to parse.  It's an arbitrary size, really, but it must
 * be at least as large as IPF_FTPBUFSZ.
 */
#define	FTP_BUFSZ	120

/*
 * This buffer, however, doesn't need to be nearly so big.  It just needs to
 * be able to squeeze in the largest command it needs to rewrite, Which ones
 * does it rewrite? EPRT, PORT, 227 replies.
 */
#define	IPF_FTPBUFSZ	80	/* This *MUST* be >= 53! */

typedef struct  ftpside {
	char	*ftps_rptr;
	char	*ftps_wptr;
	void	*ftps_ifp;
	u_32_t	ftps_seq[2];
	u_32_t	ftps_len;
	int	ftps_junk;	/* 2 = no cr/lf yet, 1 = cannot parse */
	int	ftps_cmds;
	char	ftps_buf[FTP_BUFSZ];
} ftpside_t;

typedef struct  ftpinfo {
	int 	  	ftp_passok;
	int		ftp_incok;
	ftpside_t	ftp_side[2];
} ftpinfo_t;

/*
 * For the irc proxy.
 */
typedef	struct	ircinfo {
	size_t	irc_len;
	char	*irc_snick;
	char	*irc_dnick;
	char	*irc_type;
	char	*irc_arg;
	char	*irc_addr;
	u_32_t	irc_ipnum;
	u_short	irc_port;
} ircinfo_t;

/*
 * Real audio proxy structure and #defines
 */
typedef	struct	raudio_s {
	int	rap_seenpna;
	int	rap_seenver;
	int	rap_version;
	int	rap_eos;	/* End Of Startup */
	int	rap_gotid;
	int	rap_gotlen;
	int	rap_mode;
	int	rap_sdone;
	u_short	rap_plport;
	u_short	rap_prport;
	u_short	rap_srport;
	char	rap_svr[19];
	u_32_t	rap_sbf;	/* flag to indicate which of the 19 bytes have
				 * been filled
				 */
	u_32_t	rap_sseq;
} raudio_t;

#define	RA_ID_END	0
#define	RA_ID_UDP	1
#define	RA_ID_ROBUST	7

#define	RAP_M_UDP	1
#define	RAP_M_ROBUST	2
#define	RAP_M_TCP	4
#define	RAP_M_UDP_ROBUST	(RAP_M_UDP|RAP_M_ROBUST)

/*
 * MSN RPC proxy
 */
typedef	struct	msnrpcinfo	{
	u_int		mri_flags;
	int		mri_cmd[2];
	u_int		mri_valid;
	struct	in_addr	mri_raddr;
	u_short		mri_rport;
} msnrpcinfo_t;

/*
 * IPSec proxy
 */
typedef	u_32_t	ipsec_cookie_t[2];

typedef struct ipsec_pxy {
	ipsec_cookie_t	ipsc_icookie;
	ipsec_cookie_t	ipsc_rcookie;
	int		ipsc_rckset;
	ipnat_t		ipsc_rule;
	nat_t		*ipsc_nat;
	struct ipstate	*ipsc_state;
} ipsec_pxy_t;

/*
 * PPTP proxy
 */
typedef	struct pptp_side {
	u_32_t		pptps_nexthdr;
	u_32_t		pptps_next;
	int		pptps_state;
	int		pptps_gothdr;
	int		pptps_len;
	int		pptps_bytes;
	char		*pptps_wptr;
	char		pptps_buffer[512];
} pptp_side_t;

typedef	struct pptp_pxy {
	ipnat_t		pptp_rule;
	nat_t		*pptp_nat;
	struct ipstate	*pptp_state;
	u_short		pptp_call[2];
	pptp_side_t	pptp_side[2];
} pptp_pxy_t;

/*
 * Sun RPCBIND proxy
 */
#define RPCB_MAXMSG	888
#define RPCB_RES_PMAP	0	/* Response contains a v2 port. */
#define RPCB_RES_STRING	1	/* " " " v3 (GETADDR) string. */
#define RPCB_RES_LIST	2	/* " " " v4 (GETADDRLIST) list. */
#define RPCB_MAXREQS	32	/* Arbitrary limit on tracked transactions */

#define RPCB_REQMIN	40
#define RPCB_REQMAX	888
#define RPCB_REPMIN	20
#define	RPCB_REPMAX	604	/* XXX double check this! */

/*
 * These macros determine the number of bytes between p and the end of
 * r->rs_buf relative to l.
 */
#define RPCB_BUF_END(r) (char *)((r)->rm_msgbuf + (r)->rm_buflen)
#define RPCB_BUF_GEQ(r, p, l)   \
        ((RPCB_BUF_END((r)) > (char *)(p)) &&           \
         ((RPCB_BUF_END((r)) - (char *)(p)) >= (l)))
#define	RPCB_BUF_EQ(r, p, l)                            \
        (RPCB_BUF_END((r)) == ((char *)(p) + (l)))

/*
 * The following correspond to RPC(B) detailed in RFC183[13].
 */
#define RPCB_CALL		0
#define RPCB_REPLY		1
#define RPCB_MSG_VERSION	2
#define RPCB_PROG		100000
#define RPCB_GETPORT		3
#define RPCB_GETADDR		3
#define RPCB_GETADDRLIST	11
#define RPCB_MSG_ACCEPTED	0
#define RPCB_MSG_DENIED		1

/* BEGIN (Generic XDR structures) */
typedef struct xdr_string {
	u_32_t	*xs_len;
	char	*xs_str;
} xdr_string_t;

typedef struct xdr_auth {
	/* u_32_t	xa_flavor; */
	xdr_string_t	xa_string;
} xdr_auth_t;

typedef struct xdr_uaddr {
	u_32_t		xu_ip;
	u_short         xu_port;
	xdr_string_t	xu_str;
} xdr_uaddr_t;

typedef	struct xdr_proto {
	u_int		xp_proto;
	xdr_string_t	xp_str;
} xdr_proto_t;

#define xu_xslen	xu_str.xs_len
#define xu_xsstr	xu_str.xs_str
#define	xp_xslen	xp_str.xs_len
#define xp_xsstr	xp_str.xs_str
/* END (Generic XDR structures) */

/* BEGIN (RPC call structures) */
typedef struct pmap_args {
	/* u_32_t	pa_prog; */
	/* u_32_t	pa_vers; */
	u_32_t		*pa_prot;
	/* u_32_t	pa_port; */
} pmap_args_t;

typedef struct rpcb_args {
	/* u_32_t	*ra_prog; */
	/* u_32_t	*ra_vers; */
	xdr_proto_t	ra_netid;
	xdr_uaddr_t	ra_maddr;
	/* xdr_string_t	ra_owner; */
} rpcb_args_t;

typedef struct rpc_call {
	/* u_32_t	rc_rpcvers; */
	/* u_32_t	rc_prog; */
	u_32_t	*rc_vers;
	u_32_t	*rc_proc;
	xdr_auth_t	rc_authcred;
	xdr_auth_t	rc_authverf;
	union {
		pmap_args_t	ra_pmapargs;
		rpcb_args_t	ra_rpcbargs;
	} rpcb_args;
} rpc_call_t;

#define	rc_pmapargs	rpcb_args.ra_pmapargs
#define rc_rpcbargs	rpcb_args.ra_rpcbargs
/* END (RPC call structures) */

/* BEGIN (RPC reply structures) */
typedef struct rpcb_entry {
	xdr_uaddr_t	re_maddr;
	xdr_proto_t	re_netid;
	/* u_32_t	re_semantics; */
	xdr_string_t	re_family;
	xdr_proto_t	re_proto;
	u_32_t		*re_more; /* 1 == another entry follows */
} rpcb_entry_t;

typedef struct rpcb_listp {
	u_32_t		*rl_list; /* 1 == list follows */
	int		rl_cnt;
	rpcb_entry_t	rl_entries[2]; /* TCP / UDP only */
} rpcb_listp_t;

typedef struct rpc_resp {
	/* u_32_t	rr_acceptdeny; */
	/* Omitted 'message denied' fork; we don't care about rejects. */
	xdr_auth_t	rr_authverf;
	/* u_32_t		*rr_astat;	*/
	union {
		u_32_t		*resp_pmap;
		xdr_uaddr_t	resp_getaddr;
		rpcb_listp_t	resp_getaddrlist;
	} rpcb_reply;
} rpc_resp_t;

#define	rr_v2	rpcb_reply.resp_pmap
#define rr_v3	rpcb_reply.resp_getaddr
#define	rr_v4	rpcb_reply.resp_getaddrlist
/* END (RPC reply structures) */

/* BEGIN (RPC message structure & macros) */
typedef struct rpc_msg {
	char	rm_msgbuf[RPCB_MAXMSG];	/* RPCB data buffer */
	u_int	rm_buflen;
	u_32_t	*rm_xid;
	/* u_32_t Call vs Reply */
	union {
		rpc_call_t	rb_call;
		rpc_resp_t	rb_resp;
	} rm_body;
} rpc_msg_t;

#define rm_call		rm_body.rb_call
#define rm_resp		rm_body.rb_resp
/* END (RPC message structure & macros) */

/*
 * These code paths aren't hot enough to warrant per transaction
 * mutexes.
 */
typedef struct rpcb_xact {
	struct	rpcb_xact	*rx_next;
	struct	rpcb_xact	**rx_pnext;
	u_32_t	rx_xid;		/* RPC transmission ID */
	u_int	rx_type;	/* RPCB response type */
	u_int	rx_ref;         /* reference count */
	u_int	rx_proto;	/* transport protocol (v2 only) */
} rpcb_xact_t;

typedef struct rpcb_session {
        ipfmutex_t	rs_rxlock;
	rpcb_xact_t	*rs_rxlist;
} rpcb_session_t;

/*
 * For an explanation, please see the following:
 *   RFC1832 - Sections 3.11, 4.4, and 4.5.
 */
#define XDRALIGN(x)	((((x) % 4) != 0) ? ((((x) + 3) / 4) * 4) : (x))

extern	ap_session_t	*ap_sess_tab[AP_SESS_SIZE];
extern	ap_session_t	*ap_sess_list;
extern	aproxy_t	ap_proxies[];
extern	int		ippr_ftp_pasvonly;
extern	int		ipf_proxy_debug;

extern	int	appr_add __P((aproxy_t *));
extern	int	appr_ctl __P((ap_ctl_t *));
extern	int	appr_del __P((aproxy_t *));
extern	int	appr_init __P((void));
extern	void	appr_unload __P((void));
extern	int	appr_ok __P((fr_info_t *, tcphdr_t *, struct ipnat *));
extern	int	appr_match __P((fr_info_t *, struct nat *));
extern	void	appr_free __P((aproxy_t *));
extern	void	aps_free __P((ap_session_t *));
extern	int	appr_check __P((fr_info_t *, struct nat *));
extern	aproxy_t	*appr_lookup __P((u_int, char *));
extern	int	appr_new __P((fr_info_t *, struct nat *));
extern	int	appr_ioctl __P((caddr_t, ioctlcmd_t, int, void *));

#endif /* __IP_PROXY_H__ */


code:
/*	$FreeBSD: release/9.0.0/sys/contrib/ipfilter/netinet/ip_rules.h 145517 2005-04-25 18:15:41Z darrenr $	*/

extern int ipfrule_add __P((void));
extern int ipfrule_remove __P((void));

extern frentry_t *ipfrule_match_out_ __P((fr_info_t *, u_32_t *));
extern frentry_t *ipf_rules_out_[1];

extern int ipfrule_add_out_ __P((void));
extern int ipfrule_remove_out_ __P((void));

extern frentry_t *ipfrule_match_in_ __P((fr_info_t *, u_32_t *));
extern frentry_t *ipf_rules_in_[1];

extern int ipfrule_add_in_ __P((void));
extern int ipfrule_remove_in_ __P((void));


code:
/*
 * Copyright (C) 1993-2001 by Darren Reed.
 *
 * See the IPFILTER.LICENCE file for details on licencing.
 *
 * @(#)ip_fil.h	1.35 6/5/96
 * $Id: ip_scan.h,v 2.9.2.2 2006/07/14 06:12:19 darrenr Exp $
 */

#ifndef __IP_SCAN_H__
#define __IP_SCAN_H__ 1

#ifdef sun
# include <sys/ioccom.h>
#endif

#define	IPSCAN_NAME	"/dev/ipscan"
#define	IPL_SCAN	IPSCAN_NAME
#define	ISC_TLEN	16

struct fr_info;
struct frentry;
struct ip;
struct ipstate;

#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
# define	SIOCADSCA	_IOWR('r', 60, struct ipscan *)
# define	SIOCRMSCA	_IOWR('r', 61, struct ipscan *)
# define	SIOCGSCST	_IOWR('r', 62, struct ipscan *)
#else
# define	SIOCADSCA	_IOWR(r, 60, struct ipscan *)
# define	SIOCRMSCA	_IOWR(r, 61, struct ipscan *)
# define	SIOCGSCST	_IOWR(r, 62, struct ipscan *)
#endif

struct	action	{
	int		act_val;	/* what to do */
	struct	in_addr	act_ip;		/* redirect IP# */
	u_short		act_port;	/* redirect port number */
	int		act_else;	/* what to do */
	struct	in_addr	act_eip;	/* redirect IP# */
	u_short		act_eport;	/* redirect port number */
};

typedef	struct	sinfo {
	char	s_txt[ISC_TLEN];	/* text to match */
	char	s_msk[ISC_TLEN];	/* mask of the above to check */
	int	s_len;			/* length of server text */
} sinfo_t;

typedef	struct	ipscan	{
	struct	ipscan	*ipsc_next;
	struct	ipscan	**ipsc_pnext;
	char		ipsc_tag[ISC_TLEN];	/* table entry protocol tag */
	sinfo_t		ipsc_si[2];	/* client/server side information */
	int		ipsc_hits;	/* times this has been matched */
	int		ipsc_active;	/* # of active matches */
	int		ipsc_fref;	/* # of references from filter rules */
	int		ipsc_sref;	/* # of references from state entries */
	struct	action	ipsc_act;
} ipscan_t;

#define	ipsc_cl		ipsc_si[0]
#define	ipsc_sl		ipsc_si[1]
#define	ipsc_ctxt	ipsc_cl.s_txt
#define	ipsc_cmsk	ipsc_cl.s_msk
#define	ipsc_clen	ipsc_cl.s_len
#define	ipsc_stxt	ipsc_sl.s_txt
#define	ipsc_smsk	ipsc_sl.s_msk
#define	ipsc_slen	ipsc_sl.s_len
#define	ipsc_action	ipsc_act.act_val
#define	ipsc_ip		ipsc_act.act_ip
#define	ipsc_port	ipsc_act.act_port
#define	ipsc_else	ipsc_act.act_else
#define	ipsc_eip	ipsc_act.act_eip
#define	ipsc_eport	ipsc_act.act_eport

#define	ISC_A_NONE	0
#define	ISC_A_TRACK	1
#define	ISC_A_CLOSE	2
#define	ISC_A_REDIRECT	3

typedef	struct	ipscanstat	{
	struct	ipscan	*iscs_list;
	u_long		iscs_acted;
	u_long		iscs_else;
	int		iscs_entries;
} ipscanstat_t;

extern	int fr_scan_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *));
extern	int ipsc_init __P((void));
extern	int ipsc_attachis __P((struct ipstate *));
extern	int ipsc_attachfr __P((struct frentry *));
extern	int ipsc_detachis __P((struct ipstate *));
extern	int ipsc_detachfr __P((struct frentry *));
extern	int ipsc_packet __P((struct fr_info *, struct ipstate *));
extern	void fr_scanunload __P((void));

#endif /* __IP_SCAN_H__ */


code:
/*	$FreeBSD: release/9.0.0/sys/contrib/ipfilter/netinet/ip_state.h 172776 2007-10-18 21:52:14Z darrenr $	*/

/*
 * Copyright (C) 1995-2001 by Darren Reed.
 *
 * See the IPFILTER.LICENCE file for details on licencing.
 *
 * @(#)ip_state.h	1.3 1/12/96 (C) 1995 Darren Reed
 * $FreeBSD: release/9.0.0/sys/contrib/ipfilter/netinet/ip_state.h 172776 2007-10-18 21:52:14Z darrenr $
 * Id: ip_state.h,v 2.68.2.10 2007/10/16 09:33:24 darrenr Exp $
 */
#ifndef	__IP_STATE_H__
#define	__IP_STATE_H__

#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
# define	SIOCDELST	_IOW('r', 61, struct ipfobj)
#else
# define	SIOCDELST	_IOW(r, 61, struct ipfobj)
#endif

struct ipscan;

#ifndef	IPSTATE_SIZE
# define	IPSTATE_SIZE	5737
#endif
#ifndef	IPSTATE_MAX
# define	IPSTATE_MAX	4013	/* Maximum number of states held */
#endif

#define	SEQ_GE(a,b)	((int)((a) - (b)) >= 0)
#define	SEQ_GT(a,b)	((int)((a) - (b)) > 0)

typedef struct ipstate {
	ipfmutex_t	is_lock;
	struct	ipstate	*is_next;
	struct	ipstate	**is_pnext;
	struct	ipstate	*is_hnext;
	struct	ipstate	**is_phnext;
	struct	ipstate	**is_me;
	void		*is_ifp[4];
	void		*is_sync;
	frentry_t	*is_rule;
	struct	ipftq	*is_tqehead[2];
	struct	ipscan	*is_isc;
	U_QUAD_T	is_pkts[4];
	U_QUAD_T	is_bytes[4];
	U_QUAD_T	is_icmppkts[4];
	struct	ipftqent is_sti;
	u_int	is_frage[2];
	int	is_ref;			/* reference count */
	int	is_isninc[2];
	u_short	is_sumd[2];
	i6addr_t	is_src;
	i6addr_t	is_dst;
	u_int	is_pass;
	u_char	is_p;			/* Protocol */
	u_char	is_v;
	u_32_t	is_hv;
	u_32_t	is_tag;
	u_32_t	is_opt[2];		/* packet options set */
	u_32_t	is_optmsk[2];		/*    "      "    mask */
	u_short	is_sec;			/* security options set */
	u_short	is_secmsk;		/*    "        "    mask */
	u_short	is_auth;		/* authentication options set */
	u_short	is_authmsk;		/*    "              "    mask */
	union {
		icmpinfo_t	is_ics;
		tcpinfo_t	is_ts;
		udpinfo_t	is_us;
		greinfo_t	is_ug;
	} is_ps;
	u_32_t	is_flags;
	int	is_flx[2][2];
	u_32_t	is_rulen;		/* rule number when created */
	u_32_t	is_s0[2];
	u_short	is_smsk[2];
	char	is_group[FR_GROUPLEN];
	char	is_sbuf[2][16];
	char	is_ifname[4][LIFNAMSIZ];
} ipstate_t;

#define	is_die		is_sti.tqe_die
#define	is_state	is_sti.tqe_state
#define	is_touched	is_sti.tqe_touched
#define	is_saddr	is_src.in4.s_addr
#define	is_daddr	is_dst.in4.s_addr
#define	is_icmp		is_ps.is_ics
#define	is_type		is_icmp.ici_type
#define	is_code		is_icmp.ici_code
#define	is_tcp		is_ps.is_ts
#define	is_udp		is_ps.is_us
#define is_send		is_tcp.ts_data[0].td_end
#define is_dend		is_tcp.ts_data[1].td_end
#define is_maxswin	is_tcp.ts_data[0].td_maxwin
#define is_maxdwin	is_tcp.ts_data[1].td_maxwin
#define is_maxsend	is_tcp.ts_data[0].td_maxend
#define is_maxdend	is_tcp.ts_data[1].td_maxend
#define	is_swinscale	is_tcp.ts_data[0].td_winscale
#define	is_dwinscale	is_tcp.ts_data[1].td_winscale
#define	is_swinflags	is_tcp.ts_data[0].td_winflags
#define	is_dwinflags	is_tcp.ts_data[1].td_winflags
#define	is_sport	is_tcp.ts_sport
#define	is_dport	is_tcp.ts_dport
#define	is_ifpin	is_ifp[0]
#define	is_ifpout	is_ifp[2]
#define	is_gre		is_ps.is_ug
#define	is_call		is_gre.gs_call

#define	IS_WSPORT	SI_W_SPORT	/* 0x00100 */
#define	IS_WDPORT	SI_W_DPORT	/* 0x00200 */
#define	IS_WSADDR	SI_W_SADDR	/* 0x00400 */
#define	IS_WDADDR	SI_W_DADDR	/* 0x00800 */
#define	IS_NEWFR	SI_NEWFR	/* 0x01000 */
#define	IS_CLONE	SI_CLONE	/* 0x02000 */
#define	IS_CLONED	SI_CLONED	/* 0x04000 */
#define	IS_TCPFSM			   0x10000
#define	IS_STRICT			   0x20000
#define	IS_ISNSYN			   0x40000
#define	IS_ISNACK			   0x80000
#define	IS_STATESYNC			   0x100000
/*
 * IS_SC flags are for scan-operations that need to be recognised in state.
 */
#define	IS_SC_CLIENT			0x10000000
#define	IS_SC_SERVER			0x20000000
#define	IS_SC_MATCHC			0x40000000
#define	IS_SC_MATCHS			0x80000000
#define	IS_SC_MATCHALL	(IS_SC_MATCHC|IS_SC_MATCHC)
#define	IS_SC_ALL	(IS_SC_MATCHC|IS_SC_MATCHC|IS_SC_CLIENT|IS_SC_SERVER)

/*
 * Flags that can be passed into fr_addstate
 */
#define	IS_INHERITED			0x0fffff00

#define	TH_OPENING	(TH_SYN|TH_ACK)
/*
 * is_flags:
 * Bits 0 - 3 are use as a mask with the current packet's bits to check for
 * whether it is short, tcp/udp, a fragment or the presence of IP options.
 * Bits 4 - 7 are set from the initial packet and contain what the packet
 * anded with bits 0-3 must match.
 * Bits 8,9 are used to indicate wildcard source/destination port matching.
 * Bits 10,11 are reserved for other wildcard flag compatibility.
 * Bits 12,13 are for scaning.
 */

typedef	struct	ipstate_save	{
	void	*ips_next;
	struct	ipstate	ips_is;
	struct	frentry	ips_fr;
} ipstate_save_t;

#define	ips_rule	ips_is.is_rule

typedef	struct	ipslog	{
	U_QUAD_T	isl_pkts[4];
	U_QUAD_T	isl_bytes[4];
	i6addr_t	isl_src;
	i6addr_t	isl_dst;
	u_32_t	isl_tag;
	u_short	isl_type;
	union {
		u_short	isl_filler[2];
		u_short	isl_ports[2];
		u_short	isl_icmp;
	} isl_ps;
	u_char	isl_v;
	u_char	isl_p;
	u_char	isl_flags;
	u_char	isl_state[2];
	u_32_t	isl_rulen;
	char	isl_group[FR_GROUPLEN];
} ipslog_t;

#define	isl_sport	isl_ps.isl_ports[0]
#define	isl_dport	isl_ps.isl_ports[1]
#define	isl_itype	isl_ps.isl_icmp

#define	ISL_NEW			0
#define	ISL_CLONE		1
#define	ISL_EXPIRE		0xffff
#define	ISL_FLUSH		0xfffe
#define	ISL_REMOVE		0xfffd
#define	ISL_INTERMEDIATE	0xfffc
#define	ISL_KILLED		0xfffb
#define	ISL_ORPHAN		0xfffa
#define	ISL_UNLOAD		0xfff9

typedef	struct	ips_stat {
	u_long	iss_hits;
	u_long	iss_miss;
	u_long	iss_max;
	u_long	iss_maxref;
	u_long	iss_tcp;
	u_long	iss_udp;
	u_long	iss_icmp;
	u_long	iss_nomem;
	u_long	iss_expire;
	u_long	iss_fin;
	u_long	iss_active;
	u_long	iss_logged;
	u_long	iss_logfail;
	u_long	iss_inuse;
	u_long	iss_wild;
	u_long	iss_killed;
	u_long	iss_ticks;
	u_long	iss_bucketfull;
	int	iss_statesize;
	int	iss_statemax;
	ipstate_t **iss_table;
	ipstate_t *iss_list;
	u_long	*iss_bucketlen;
	ipftq_t	*iss_tcptab;
} ips_stat_t;

extern	u_long	fr_tcpidletimeout;
extern	u_long	fr_tcpclosewait;
extern	u_long	fr_tcplastack;
extern	u_long	fr_tcptimeout;
extern	u_long	fr_tcpclosed;
extern	u_long	fr_tcphalfclosed;
extern	u_long	fr_udptimeout;
extern	u_long	fr_udpacktimeout;
extern	u_long	fr_icmptimeout;
extern	u_long	fr_icmpacktimeout;
extern	u_long	fr_iptimeout;
extern	int	fr_statemax;
extern	int	fr_statesize;
extern	int	fr_state_lock;
extern	int	fr_state_maxbucket;
extern	int	fr_state_maxbucket_reset;
extern	ipstate_t	*ips_list;
extern	ipftq_t	*ips_utqe;
extern	ipftq_t	ips_tqtqb[IPF_TCP_NSTATES];

extern	int	fr_stateinit __P((void));
extern	ipstate_t *fr_addstate __P((fr_info_t *, ipstate_t **, u_int));
extern	frentry_t *fr_checkstate __P((struct fr_info *, u_32_t *));
extern	ipstate_t *fr_stlookup __P((fr_info_t *, tcphdr_t *, ipftq_t **));
extern	void	fr_statesync __P((void *));
extern	void	fr_timeoutstate __P((void));
extern	int	fr_tcp_age __P((struct ipftqent *, struct fr_info *,
				struct ipftq *, int));
extern	int	fr_tcpinwindow __P((struct fr_info *, struct tcpdata *,
				    struct tcpdata *, tcphdr_t *, int));
extern	void	fr_stateunload __P((void));
extern	void	ipstate_log __P((struct ipstate *, u_int));
extern	int	fr_state_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *));
extern	void	fr_stinsert __P((struct ipstate *, int));
extern	void	fr_sttab_init __P((struct ipftq *));
extern	void	fr_sttab_destroy __P((struct ipftq *));
extern	void	fr_updatestate __P((fr_info_t *, ipstate_t *, ipftq_t *));
extern	void	fr_statederef __P((ipstate_t **));
extern	void	fr_setstatequeue __P((ipstate_t *, int));

#endif /* __IP_STATE_H__ */


code:
/*
 * Copyright (C) 1993-2001 by Darren Reed.
 *
 * See the IPFILTER.LICENCE file for details on licencing.
 *
 * @(#)ip_fil.h	1.35 6/5/96
 * $Id: ip_sync.h,v 2.11.2.4 2006/07/14 06:12:20 darrenr Exp $
 */

#ifndef __IP_SYNC_H__
#define __IP_SYNC_H__

typedef	struct	synchdr	{
	u_32_t		sm_magic;	/* magic */
	u_char		sm_v;		/* version: 4,6 */
	u_char		sm_p;		/* protocol */
	u_char		sm_cmd;		/* command */
	u_char		sm_table;	/* NAT, STATE, etc */
	u_int		sm_num;		/* table entry number */
	int		sm_rev;		/* forward/reverse */
	int		sm_len;		/* length of the data section */
	struct	synclist	*sm_sl;		/* back pointer to parent */
} synchdr_t;

#define SYNHDRMAGIC 0x0FF51DE5

/*
 * Commands
 * No delete required as expirey will take care of that!
 */
#define	SMC_CREATE	0	/* pass ipstate_t after synchdr_t */
#define	SMC_UPDATE	1
#define	SMC_MAXCMD	1

/*
 * Tables
 */
#define	SMC_NAT		0
#define	SMC_STATE	1
#define	SMC_MAXTBL	1

/*
 * Only TCP requires "more" information than just a reference to the entry
 * for which an update is being made.
 */
typedef	struct	synctcp_update	{
	u_long		stu_age;
	tcpdata_t	stu_data[2];
	int		stu_state[2];
} synctcp_update_t;

typedef	struct	synclist	{
	struct	synclist	*sl_next;
	struct	synclist	**sl_pnext;
	int			sl_idx;		/* update index */
	struct	synchdr		sl_hdr;
	union	{
		struct	ipstate	*slu_ips;
		struct	nat	*slu_ipn;
		void		*slu_ptr;
	} sl_un;
} synclist_t;

#define	sl_ptr	sl_un.slu_ptr
#define	sl_ips	sl_un.slu_ips
#define	sl_ipn	sl_un.slu_ipn
#define	sl_magic sl_hdr.sm_magic
#define	sl_v	sl_hdr.sm_v
#define	sl_p	sl_hdr.sm_p
#define	sl_cmd	sl_hdr.sm_cmd
#define	sl_rev	sl_hdr.sm_rev
#define	sl_table	sl_hdr.sm_table
#define	sl_num	sl_hdr.sm_num
#define	sl_len	sl_hdr.sm_len

/*
 * NOTE: SYNCLOG_SZ is defined *low*.  It should be the next power of two
 * up for whatever number of packets per second you expect to see.  Be
 * warned: this index's a table of large elements (upto 272 bytes in size
 * each), and thus a size of 8192, for example, results in a 2MB table.
 * The lesson here is not to use small machines for running fast firewalls
 * (100BaseT) in sync, where you might have upwards of 10k pps.
 */
#define	SYNCLOG_SZ	256

typedef	struct	synclogent	{
	struct	synchdr	sle_hdr;
	union	{
		struct	ipstate	sleu_ips;
		struct	nat	sleu_ipn;
	} sle_un;
} synclogent_t;

typedef	struct	syncupdent	{		/* 28 or 32 bytes */
	struct	synchdr	sup_hdr;
	struct	synctcp_update	sup_tcp;
} syncupdent_t;

extern	synclogent_t	synclog[SYNCLOG_SZ];

extern	int fr_sync_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *));
extern	synclist_t *ipfsync_new __P((int, fr_info_t *, void *));
extern	void ipfsync_del __P((synclist_t *));
extern	void ipfsync_update __P((int, fr_info_t *, synclist_t *));
extern	int ipfsync_init __P((void));
extern	int ipfsync_nat __P((synchdr_t *sp, void *data));
extern	int ipfsync_state __P((synchdr_t *sp, void *data));
extern	int ipfsync_read __P((struct uio *uio));
extern	int ipfsync_write __P((struct uio *uio));
extern	int ipfsync_canread __P((void));
extern	int ipfsync_canwrite __P((void));

#endif /* IP_SYNC */


code:
/*-
 * Copyright (c) 1982, 1986, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)ip_var.h	8.2 (Berkeley) 1/9/95
 * $FreeBSD: release/9.0.0/sys/netinet/ip_var.h 223666 2011-06-29 10:06:58Z ae $
 */

#ifndef _NETINET_IP_VAR_H_
#define	_NETINET_IP_VAR_H_

#include <sys/queue.h>

/*
 * Overlay for ip header used by other protocols (tcp, udp).
 */
struct ipovly {
	u_char	ih_x1[9];		/* (unused) */
	u_char	ih_pr;			/* protocol */
	u_short	ih_len;			/* protocol length */
	struct	in_addr ih_src;		/* source internet address */
	struct	in_addr ih_dst;		/* destination internet address */
};

#ifdef _KERNEL
/*
 * Ip reassembly queue structure.  Each fragment
 * being reassembled is attached to one of these structures.
 * They are timed out after ipq_ttl drops to 0, and may also
 * be reclaimed if memory becomes tight.
 */
struct ipq {
	TAILQ_ENTRY(ipq) ipq_list;	/* to other reass headers */
	u_char	ipq_ttl;		/* time for reass q to live */
	u_char	ipq_p;			/* protocol of this fragment */
	u_short	ipq_id;			/* sequence id for reassembly */
	struct mbuf *ipq_frags;		/* to ip headers of fragments */
	struct	in_addr ipq_src,ipq_dst;
	u_char	ipq_nfrags;		/* # frags in this packet */
	struct label *ipq_label;	/* MAC label */
};
#endif /* _KERNEL */

/*
 * Structure stored in mbuf in inpcb.ip_options
 * and passed to ip_output when ip options are in use.
 * The actual length of the options (including ipopt_dst)
 * is in m_len.
 */
#define MAX_IPOPTLEN	40

struct ipoption {
	struct	in_addr ipopt_dst;	/* first-hop dst if source routed */
	char	ipopt_list[MAX_IPOPTLEN];	/* options proper */
};

/*
 * Structure attached to inpcb.ip_moptions and
 * passed to ip_output when IP multicast options are in use.
 * This structure is lazy-allocated.
 */
struct ip_moptions {
	struct	ifnet *imo_multicast_ifp; /* ifp for outgoing multicasts */
	struct in_addr imo_multicast_addr; /* ifindex/addr on MULTICAST_IF */
	u_long	imo_multicast_vif;	/* vif num outgoing multicasts */
	u_char	imo_multicast_ttl;	/* TTL for outgoing multicasts */
	u_char	imo_multicast_loop;	/* 1 => hear sends if a member */
	u_short	imo_num_memberships;	/* no. memberships this socket */
	u_short	imo_max_memberships;	/* max memberships this socket */
	struct	in_multi **imo_membership;	/* group memberships */
	struct	in_mfilter *imo_mfilters;	/* source filters */
};

struct	ipstat {
	u_long	ips_total;		/* total packets received */
	u_long	ips_badsum;		/* checksum bad */
	u_long	ips_tooshort;		/* packet too short */
	u_long	ips_toosmall;		/* not enough data */
	u_long	ips_badhlen;		/* ip header length < data size */
	u_long	ips_badlen;		/* ip length < ip header length */
	u_long	ips_fragments;		/* fragments received */
	u_long	ips_fragdropped;	/* frags dropped (dups, out of space) */
	u_long	ips_fragtimeout;	/* fragments timed out */
	u_long	ips_forward;		/* packets forwarded */
	u_long	ips_fastforward;	/* packets fast forwarded */
	u_long	ips_cantforward;	/* packets rcvd for unreachable dest */
	u_long	ips_redirectsent;	/* packets forwarded on same net */
	u_long	ips_noproto;		/* unknown or unsupported protocol */
	u_long	ips_delivered;		/* datagrams delivered to upper level*/
	u_long	ips_localout;		/* total ip packets generated here */
	u_long	ips_odropped;		/* lost packets due to nobufs, etc. */
	u_long	ips_reassembled;	/* total packets reassembled ok */
	u_long	ips_fragmented;		/* datagrams successfully fragmented */
	u_long	ips_ofragments;		/* output fragments created */
	u_long	ips_cantfrag;		/* don't fragment flag was set, etc. */
	u_long	ips_badoptions;		/* error in option processing */
	u_long	ips_noroute;		/* packets discarded due to no route */
	u_long	ips_badvers;		/* ip version != 4 */
	u_long	ips_rawout;		/* total raw ip packets generated */
	u_long	ips_toolong;		/* ip length > max ip packet size */
	u_long	ips_notmember;		/* multicasts for unregistered grps */
	u_long	ips_nogif;		/* no match gif found */
	u_long	ips_badaddr;		/* invalid address on header */
};

#ifdef _KERNEL

#include <net/vnet.h>

/*
 * In-kernel consumers can use these accessor macros directly to update
 * stats.
 */
#define	IPSTAT_ADD(name, val)	V_ipstat.name += (val)
#define	IPSTAT_SUB(name, val)	V_ipstat.name -= (val)
#define	IPSTAT_INC(name)	IPSTAT_ADD(name, 1)
#define	IPSTAT_DEC(name)	IPSTAT_SUB(name, 1)

/*
 * Kernel module consumers must use this accessor macro.
 */
void	kmod_ipstat_inc(int statnum);
#define	KMOD_IPSTAT_INC(name)						\
	kmod_ipstat_inc(offsetof(struct ipstat, name) / sizeof(u_long))
void	kmod_ipstat_dec(int statnum);
#define	KMOD_IPSTAT_DEC(name)						\
	kmod_ipstat_dec(offsetof(struct ipstat, name) / sizeof(u_long))

/* flags passed to ip_output as last parameter */
#define	IP_FORWARDING		0x1		/* most of ip header exists */
#define	IP_RAWOUTPUT		0x2		/* raw ip header exists */
#define	IP_SENDONES		0x4		/* send all-ones broadcast */
#define	IP_SENDTOIF		0x8		/* send on specific ifnet */
#define IP_ROUTETOIF		SO_DONTROUTE	/* 0x10 bypass routing tables */
#define IP_ALLOWBROADCAST	SO_BROADCAST	/* 0x20 can send broadcast packets */

/*
 * mbuf flag used by ip_fastfwd
 */
#define	M_FASTFWD_OURS		M_PROTO1	/* changed dst to local */

#ifdef __NO_STRICT_ALIGNMENT
#define IP_HDR_ALIGNED_P(ip)	1
#else
#define IP_HDR_ALIGNED_P(ip)	((((intptr_t) (ip)) & 3) == 0)
#endif

struct ip;
struct inpcb;
struct route;
struct sockopt;

VNET_DECLARE(struct ipstat, ipstat);
VNET_DECLARE(u_short, ip_id);			/* ip packet ctr, for ids */
VNET_DECLARE(int, ip_defttl);			/* default IP ttl */
VNET_DECLARE(int, ipforwarding);		/* ip forwarding */
#ifdef IPSTEALTH
VNET_DECLARE(int, ipstealth);			/* stealth forwarding */
#endif
extern u_char	ip_protox[];
VNET_DECLARE(struct socket *, ip_rsvpd);	/* reservation protocol daemon*/
VNET_DECLARE(struct socket *, ip_mrouter);	/* multicast routing daemon */
extern int	(*legal_vif_num)(int);
extern u_long	(*ip_mcast_src)(int);
VNET_DECLARE(int, rsvp_on);
extern struct	pr_usrreqs rip_usrreqs;

#define	V_ipstat		VNET(ipstat)
#define	V_ip_id			VNET(ip_id)
#define	V_ip_defttl		VNET(ip_defttl)
#define	V_ipforwarding		VNET(ipforwarding)
#ifdef IPSTEALTH
#define	V_ipstealth		VNET(ipstealth)
#endif
#define	V_ip_rsvpd		VNET(ip_rsvpd)
#define	V_ip_mrouter		VNET(ip_mrouter)
#define	V_rsvp_on		VNET(rsvp_on)

void	inp_freemoptions(struct ip_moptions *);
int	inp_getmoptions(struct inpcb *, struct sockopt *);
int	inp_setmoptions(struct inpcb *, struct sockopt *);

int	ip_ctloutput(struct socket *, struct sockopt *sopt);
void	ip_drain(void);
int	ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
	    u_long if_hwassist_flags, int sw_csum);
void	ip_forward(struct mbuf *m, int srcrt);
void	ip_init(void);
#ifdef VIMAGE
void	ip_destroy(void);
#endif
extern int
	(*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
	    struct ip_moptions *);
int	ip_output(struct mbuf *,
	    struct mbuf *, struct route *, int, struct ip_moptions *,
	    struct inpcb *);
int	ipproto_register(short);
int	ipproto_unregister(short);
struct mbuf *
	ip_reass(struct mbuf *);
struct in_ifaddr *
	ip_rtaddr(struct in_addr, u_int fibnum);
void	ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
	    struct mbuf *);
void	ip_slowtimo(void);
u_int16_t	ip_randomid(void);
int	rip_ctloutput(struct socket *, struct sockopt *);
void	rip_ctlinput(int, struct sockaddr *, void *);
void	rip_init(void);
#ifdef VIMAGE
void	rip_destroy(void);
#endif
void	rip_input(struct mbuf *, int);
int	rip_output(struct mbuf *, struct socket *, u_long);
void	ipip_input(struct mbuf *, int);
void	rsvp_input(struct mbuf *, int);
int	ip_rsvp_init(struct socket *);
int	ip_rsvp_done(void);
extern int	(*ip_rsvp_vif)(struct socket *, struct sockopt *);
extern void	(*ip_rsvp_force_done)(struct socket *);
extern void	(*rsvp_input_p)(struct mbuf *m, int off);

VNET_DECLARE(struct pfil_head, inet_pfil_hook);	/* packet filter hooks */
#define	V_inet_pfil_hook	VNET(inet_pfil_hook)

void	in_delayed_cksum(struct mbuf *m);

/* Hooks for ipfw, dummynet, divert etc. Most are declared in raw_ip.c */
/*
 * Reference to an ipfw or packet filter rule that can be carried
 * outside critical sections.
 * A rule is identified by rulenum:rule_id which is ordered.
 * In version chain_id the rule can be found in slot 'slot', so
 * we don't need a lookup if chain_id == chain->id.
 *
 * On exit from the firewall this structure refers to the rule after
 * the matching one (slot points to the new rule; rulenum:rule_id-1
 * is the matching rule), and additional info (e.g. info often contains
 * the insn argument or tablearg in the low 16 bits, in host format).
 * On entry, the structure is valid if slot>0, and refers to the starting
 * rules. 'info' contains the reason for reinject, e.g. divert port,
 * divert direction, and so on.
 */
struct ipfw_rule_ref {
	uint32_t	slot;		/* slot for matching rule	*/
	uint32_t	rulenum;	/* matching rule number		*/
	uint32_t	rule_id;	/* matching rule id		*/
	uint32_t	chain_id;	/* ruleset id			*/
	uint32_t	info;		/* see below			*/
};

enum {
	IPFW_INFO_MASK	= 0x0000ffff,
	IPFW_INFO_OUT	= 0x00000000,	/* outgoing, just for convenience */
	IPFW_INFO_IN	= 0x80000000,	/* incoming, overloads dir */
	IPFW_ONEPASS	= 0x40000000,	/* One-pass, do not reinject */
	IPFW_IS_MASK	= 0x30000000,	/* which source ? */
	IPFW_IS_DIVERT	= 0x20000000,
	IPFW_IS_DUMMYNET =0x10000000,
	IPFW_IS_PIPE	= 0x08000000,	/* pip1=1, queue = 0 */
};
#define MTAG_IPFW	1148380143	/* IPFW-tagged cookie */
#define MTAG_IPFW_RULE	1262273568	/* rule reference */
#define	MTAG_IPFW_CALL	1308397630	/* call stack */

struct ip_fw_args;
typedef int	(*ip_fw_chk_ptr_t)(struct ip_fw_args *args);
typedef int	(*ip_fw_ctl_ptr_t)(struct sockopt *);
VNET_DECLARE(ip_fw_chk_ptr_t, ip_fw_chk_ptr);
VNET_DECLARE(ip_fw_ctl_ptr_t, ip_fw_ctl_ptr);
#define	V_ip_fw_chk_ptr		VNET(ip_fw_chk_ptr)
#define	V_ip_fw_ctl_ptr		VNET(ip_fw_ctl_ptr)

/* Divert hooks. */
extern void	(*ip_divert_ptr)(struct mbuf *m, int incoming);
/* ng_ipfw hooks -- XXX make it the same as divert and dummynet */
extern int	(*ng_ipfw_input_p)(struct mbuf **, int,
			struct ip_fw_args *, int);

extern int	(*ip_dn_ctl_ptr)(struct sockopt *);
extern int	(*ip_dn_io_ptr)(struct mbuf **, int, struct ip_fw_args *);

VNET_DECLARE(int, ip_do_randomid);
#define	V_ip_do_randomid	VNET(ip_do_randomid)
#define	ip_newid()	((V_ip_do_randomid != 0) ? ip_randomid() : \
			    htons(V_ip_id++))

#endif /* _KERNEL */

#endif /* !_NETINET_IP_VAR_H_ */


code:
/*	$FreeBSD: release/9.0.0/sys/contrib/ipfilter/netinet/ipl.h 172776 2007-10-18 21:52:14Z darrenr $	*/

/*
 * Copyright (C) 1993-2001, 2003 by Darren Reed.
 *
 * See the IPFILTER.LICENCE file for details on licencing.
 *
 * @(#)ipl.h	1.21 6/5/96
 * $FreeBSD: release/9.0.0/sys/contrib/ipfilter/netinet/ipl.h 172776 2007-10-18 21:52:14Z darrenr $
 * Id: ipl.h,v 2.52.2.30 2007/10/16 09:41:00 darrenr Exp $
 */

#ifndef	__IPL_H__
#define	__IPL_H__

#define	IPL_VERSION	"IP Filter: v4.1.28"

#define	IPFILTER_VERSION	4012800

#endif


code:
/*-
 * Copyright (c) 1996-2000
 * University of Southern California/Information Sciences Institute.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/netinet/pim.h 139823 2005-01-07 01:45:51Z imp $
 */

#ifndef _NETINET_PIM_H_
#define _NETINET_PIM_H_

/*
 * Protocol Independent Multicast (PIM) definitions.
 * RFC 2362, June 1998.
 *
 * Written by Ahmed Helmy, USC/SGI, July 1996.
 * Modified by George Edmond Eddy (Rusty), ISI, February 1998.
 * Modified by Pavlin Radoslavov, USC/ISI, May 1998, October 2000.
 */

#include <sys/types.h>

#ifndef _PIM_VT
#ifndef BYTE_ORDER
# error BYTE_ORDER is not defined!
#endif
#if (BYTE_ORDER != BIG_ENDIAN) && (BYTE_ORDER != LITTLE_ENDIAN)
# error BYTE_ORDER must be defined to either BIG_ENDIAN or LITTLE_ENDIAN
#endif
#endif /* ! _PIM_VT */

/*
 * PIM packet header
 */
struct pim {
#ifdef _PIM_VT
	uint8_t		pim_vt;		/* PIM version and message type	*/
#else /* ! _PIM_VT   */
#if BYTE_ORDER == BIG_ENDIAN
	u_int		pim_vers:4,	/* PIM protocol version		*/
			pim_type:4;	/* PIM message type		*/
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
	u_int		pim_type:4,	/* PIM message type		*/
			pim_vers:4;	/* PIM protocol version		*/
#endif
#endif /* ! _PIM_VT  */
	uint8_t		pim_reserved;	/* Reserved			*/
	uint16_t	pim_cksum;	/* IP-style checksum		*/
};
/* KAME-related name backward compatibility */
#define pim_ver pim_vers
#define pim_rsv pim_reserved

#ifdef _PIM_VT
#define PIM_MAKE_VT(v, t)	(0xff & (((v) << 4) | (0x0f & (t))))
#define PIM_VT_V(x)		(((x) >> 4) & 0x0f)
#define PIM_VT_T(x)		((x) & 0x0f)
#endif /* _PIM_VT */

#define PIM_VERSION		2
#define PIM_MINLEN		8	/* PIM message min. length	*/
#define PIM_REG_MINLEN	(PIM_MINLEN+20)	/* PIM Register hdr + inner IPv4 hdr */
#define PIM6_REG_MINLEN	(PIM_MINLEN+40)	/* PIM Register hdr + inner IPv6 hdr */

/*
 * PIM message types
 */
#define PIM_HELLO		0x0	/* PIM-SM and PIM-DM		*/
#define PIM_REGISTER		0x1	/* PIM-SM only			*/
#define PIM_REGISTER_STOP	0x2	/* PIM-SM only			*/
#define PIM_JOIN_PRUNE		0x3	/* PIM-SM and PIM-DM		*/
#define PIM_BOOTSTRAP		0x4	/* PIM-SM only			*/
#define PIM_ASSERT		0x5	/* PIM-SM and PIM-DM		*/
#define PIM_GRAFT		0x6	/* PIM-DM only			*/
#define PIM_GRAFT_ACK		0x7	/* PIM-DM only			*/
#define PIM_CAND_RP_ADV		0x8	/* PIM-SM only			*/
#define PIM_ALL_DF_ELECTION	0xa	/* Bidir-PIM-SM only		*/

/*
 * PIM-Register message flags
 */
#define PIM_BORDER_REGISTER 0x80000000U	/* The Border bit (host-order)	*/
#define PIM_NULL_REGISTER   0x40000000U	/* The Null-Register bit (host-order)*/

/*
 * All-PIM-Routers IPv4 and IPv6 multicast addresses
 */
#define INADDR_ALLPIM_ROUTERS_GROUP	(uint32_t)0xe000000dU  /* 224.0.0.13 */
#define IN6ADDR_LINKLOCAL_ALLPIM_ROUTERS	"ff02::d"
#define IN6ADDR_LINKLOCAL_ALLPIM_ROUTERS_INIT				\
	{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		\
	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d }}}

#endif /* _NETINET_PIM_H_ */


code:
/*-
 * Copyright (c) 1998-2000
 * University of Southern California/Information Sciences Institute.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/netinet/pim_var.h 208744 2010-06-02 15:44:43Z zec $
 */

#ifndef _NETINET_PIM_VAR_H_
#define _NETINET_PIM_VAR_H_

/*
 * Protocol Independent Multicast (PIM),
 * kernel variables and implementation-specific definitions.
 *
 * Written by George Edmond Eddy (Rusty), ISI, February 1998.
 * Modified by Pavlin Radoslavov, USC/ISI, May 1998, Aug 1999, October 2000.
 * Modified by Hitoshi Asaeda, WIDE, August 1998.
 */

/*
 * PIM statistics kept in the kernel
 */
struct pimstat {
	u_quad_t pims_rcv_total_msgs;	   /* total PIM messages received    */
	u_quad_t pims_rcv_total_bytes;	   /* total PIM bytes received	     */
	u_quad_t pims_rcv_tooshort;	   /* rcvd with too few bytes	     */
	u_quad_t pims_rcv_badsum;	   /* rcvd with bad checksum	     */
	u_quad_t pims_rcv_badversion;	   /* rcvd bad PIM version	     */
	u_quad_t pims_rcv_registers_msgs;  /* rcvd regs. msgs (data only)    */
	u_quad_t pims_rcv_registers_bytes; /* rcvd regs. bytes (data only)   */
	u_quad_t pims_rcv_registers_wrongiif; /* rcvd regs. on wrong iif     */
	u_quad_t pims_rcv_badregisters;	   /* rcvd invalid registers	     */
	u_quad_t pims_snd_registers_msgs;  /* sent regs. msgs (data only)    */
	u_quad_t pims_snd_registers_bytes; /* sent regs. bytes (data only)   */
};

#ifdef _KERNEL
#define	PIMSTAT_ADD(name, val)	V_pimstat.name += (val)
#define	PIMSTAT_INC(name)	PIMSTAT_ADD(name, 1)
#endif

/*
 * Names for PIM sysctl objects
 */
#define PIMCTL_STATS		1	/* statistics (read-only) */
#define PIMCTL_MAXID		2

#define PIMCTL_NAMES {			\
	{ 0, 0 },			\
	{ "stats", CTLTYPE_STRUCT },	\
}

#ifdef _KERNEL

void pim_input(struct mbuf *, int);
SYSCTL_DECL(_net_inet_pim);
#endif

#endif /* _NETINET_PIM_VAR_H_ */