/* * Copyright (C) 1993-2001, 2003 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ip_fil.h 1.35 6/5/96 * $Id: ip_fil.h,v 2.170.2.22 2005/07/16 05:55:35 darrenr Exp $ * * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * * Copyright (c) 2014, Joyent, Inc. All rights reserved. */ #ifndef __IP_FIL_H__ #define __IP_FIL_H__ #include "netinet/ip_compat.h" #include #ifdef SOLARIS #undef SOLARIS #endif #if (defined(sun) && (defined(__svr4__) || defined(__SVR4))) #define SOLARIS (1) #else #define SOLARIS (0) #endif #ifndef __P # ifdef __STDC__ # define __P(x) x # else # define __P(x) () # endif #endif #if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51) # define SIOCADAFR _IOW('r', 60, struct ipfobj) # define SIOCRMAFR _IOW('r', 61, struct ipfobj) # define SIOCSETFF _IOW('r', 62, u_int) # define SIOCGETFF _IOR('r', 63, u_int) # define SIOCGETFS _IOWR('r', 64, struct ipfobj) # define SIOCIPFFL _IOWR('r', 65, int) # define SIOCIPFFB _IOR('r', 66, int) # define SIOCADIFR _IOW('r', 67, struct ipfobj) # define SIOCRMIFR _IOW('r', 68, struct ipfobj) # define SIOCSWAPA _IOR('r', 69, u_int) # define SIOCINAFR _IOW('r', 70, struct ipfobj) # define SIOCINIFR _IOW('r', 71, struct ipfobj) # define SIOCFRENB _IOW('r', 72, u_int) # define SIOCFRSYN _IOW('r', 73, u_int) # define SIOCFRZST _IOWR('r', 74, struct ipfobj) # define SIOCZRLST _IOWR('r', 75, struct ipfobj) # define SIOCAUTHW _IOWR('r', 76, struct ipfobj) # define SIOCAUTHR _IOWR('r', 77, struct ipfobj) # define SIOCATHST _IOWR('r', 78, struct ipfobj) # define SIOCSTLCK _IOWR('r', 79, u_int) # define SIOCSTPUT _IOWR('r', 80, struct ipfobj) # define SIOCSTGET _IOWR('r', 81, struct ipfobj) # define SIOCSTGSZ _IOWR('r', 82, struct ipfobj) # define SIOCGFRST _IOWR('r', 83, struct ipfobj) # define SIOCSETLG _IOWR('r', 84, int) # define SIOCGETLG _IOWR('r', 85, int) # define SIOCFUNCL _IOWR('r', 86, struct ipfunc_resolve) # define SIOCIPFGETNEXT _IOWR('r', 87, struct ipfobj) # define SIOCIPFGET _IOWR('r', 88, struct ipfobj) # define SIOCIPFSET _IOWR('r', 89, struct ipfobj) # define SIOCIPFL6 _IOWR('r', 90, int) # define SIOCIPFLP _IOWR('r', 91, int) # define SIOCIPFITER _IOWR('r', 92, struct ipfobj) # define SIOCGENITER _IOWR('r', 93, struct ipfobj) # define SIOCGTABL _IOWR('r', 94, struct ipfobj) # define SIOCIPFDELTOK _IOWR('r', 95, int) # define SIOCLOOKUPITER _IOWR('r', 96, struct ipfobj) #else # define SIOCADAFR _IOW(r, 60, struct ipfobj) # define SIOCRMAFR _IOW(r, 61, struct ipfobj) # define SIOCSETFF _IOW(r, 62, u_int) # define SIOCGETFF _IOR(r, 63, u_int) # define SIOCGETFS _IOWR(r, 64, struct ipfobj) # define SIOCIPFFL _IOWR(r, 65, int) # define SIOCIPFFB _IOR(r, 66, int) # define SIOCADIFR _IOW(r, 67, struct ipfobj) # define SIOCRMIFR _IOW(r, 68, struct ipfobj) # define SIOCSWAPA _IOR(r, 69, u_int) # define SIOCINAFR _IOW(r, 70, struct ipfobj) # define SIOCINIFR _IOW(r, 71, struct ipfobj) # define SIOCFRENB _IOW(r, 72, u_int) # define SIOCFRSYN _IOW(r, 73, u_int) # define SIOCFRZST _IOWR(r, 74, struct ipfobj) # define SIOCZRLST _IOWR(r, 75, struct ipfobj) # define SIOCAUTHW _IOWR(r, 76, struct ipfobj) # define SIOCAUTHR _IOWR(r, 77, struct ipfobj) # define SIOCATHST _IOWR(r, 78, struct ipfobj) # define SIOCSTLCK _IOWR(r, 79, u_int) # define SIOCSTPUT _IOWR(r, 80, struct ipfobj) # define SIOCSTGET _IOWR(r, 81, struct ipfobj) # define SIOCSTGSZ _IOWR(r, 82, struct ipfobj) # define SIOCGFRST _IOWR(r, 83, struct ipfobj) # define SIOCSETLG _IOWR(r, 84, int) # define SIOCGETLG _IOWR(r, 85, int) # define SIOCFUNCL _IOWR(r, 86, struct ipfunc_resolve) # define SIOCIPFGETNEXT _IOWR(r, 87, struct ipfobj) # define SIOCIPFGET _IOWR(r, 88, struct ipfobj) # define SIOCIPFSET _IOWR(r, 89, struct ipfobj) # define SIOCIPFL6 _IOWR(r, 90, int) # define SIOCIPFLP _IOWR(r, 91, int) # define SIOCIPFITER _IOWR(r, 92, struct ipfobj) # define SIOCGENITER _IOWR(r, 93, struct ipfobj) # define SIOCGTABL _IOWR(r, 94, struct ipfobj) # define SIOCIPFDELTOK _IOWR(r, 95, int) # define SIOCLOOKUPITER _IOWR(r, 96, struct ipfobj) #endif #define SIOCADDFR SIOCADAFR #define SIOCDELFR SIOCRMAFR #define SIOCINSFR SIOCINAFR # define SIOCIPFZONESET _IOWR('r', 97, struct ipfzoneobj) /* * What type of table is getting flushed? */ #define NAT_FLUSH 1 #define STATE_FLUSH 2 /* * What table flush options are available? */ #define FLUSH_LIST 0 #define FLUSH_TABLE_ALL 1 /* Flush entire table */ #define FLUSH_TABLE_CLOSING 2 /* Flush "closing" entries" */ #define FLUSH_TABLE_EXTRA 3 /* Targetted flush: almost closed, long idle */ #define VALID_TABLE_FLUSH_OPT(x) ((x) >= 1 && (x) <= 3) /* * Define the default hi and lo watermarks used when flushing the * tables. The values represent percent full of respective tables. */ #define NAT_FLUSH_HI 95 #define NAT_FLUSH_LO 75 #define ST_FLUSH_HI 95 #define ST_FLUSH_LO 75 /* * How full are the tables? */ #define NAT_TAB_WATER_LEVEL(x) ((x)->ifs_nat_stats.ns_inuse * 100 \ / (x)->ifs_ipf_nattable_max) #define ST_TAB_WATER_LEVEL(x) ((x)->ifs_ips_num * 100 \ / (x)->ifs_fr_statemax) struct ipscan; struct ifnet; typedef struct ipf_stack ipf_stack_t; typedef struct fr_info fr_info_t; typedef int (* lookupfunc_t) __P((void *, int, void *, fr_info_t *, ipf_stack_t *)); /* * i6addr is used as a container for both IPv4 and IPv6 addresses, as well * as other types of objects, depending on its qualifier. */ #ifdef USE_INET6 typedef union i6addr { u_32_t i6[4]; struct in_addr in4; struct in6_addr in6; void *vptr[2]; lookupfunc_t lptr[2]; } i6addr_t; #define in6_addr8 in6.s6_addr #else typedef union i6addr { u_32_t i6[4]; struct in_addr in4; void *vptr[2]; lookupfunc_t lptr[2]; } i6addr_t; #endif #define in4_addr in4.s_addr #define iplookupnum i6[0] #define iplookuptype i6[1] /* * NOTE: These DO overlap the above on 64bit systems and this IS recognised. */ #define iplookupptr vptr[0] #define iplookupfunc lptr[1] #define I60(x) (((i6addr_t *)(x))->i6[0]) #define I61(x) (((i6addr_t *)(x))->i6[1]) #define I62(x) (((i6addr_t *)(x))->i6[2]) #define I63(x) (((i6addr_t *)(x))->i6[3]) #define HI60(x) ntohl(((i6addr_t *)(x))->i6[0]) #define HI61(x) ntohl(((i6addr_t *)(x))->i6[1]) #define HI62(x) ntohl(((i6addr_t *)(x))->i6[2]) #define HI63(x) ntohl(((i6addr_t *)(x))->i6[3]) #define IP6_EQ(a,b) ((I63(a) == I63(b)) && (I62(a) == I62(b)) && \ (I61(a) == I61(b)) && (I60(a) == I60(b))) #define IP6_NEQ(a,b) ((I63(a) != I63(b)) || (I62(a) != I62(b)) || \ (I61(a) != I61(b)) || (I60(a) != I60(b))) #define IP6_ISZERO(a) ((I60(a) | I61(a) | I62(a) | I63(a)) == 0) #define IP6_NOTZERO(a) ((I60(a) | I61(a) | I62(a) | I63(a)) != 0) #define IP6_ISONES(a) ((I63(a) == 0xffffffff) && (I62(a) == 0xffffffff) && \ (I61(a) == 0xffffffff) && (I60(a) == 0xffffffff)) #define IP6_GT(a,b) (ntohl(HI60(a)) > ntohl(HI60(b)) || \ (HI60(a) == HI60(b) && \ (ntohl(HI61(a)) > ntohl(HI61(b)) || \ (HI61(a) == HI61(b) && \ (ntohl(HI62(a)) > ntohl(HI62(b)) || \ (HI62(a) == HI62(b) && \ ntohl(HI63(a)) > ntohl(HI63(b)))))))) #define IP6_LT(a,b) (ntohl(HI60(a)) < ntohl(HI60(b)) || \ (HI60(a) == HI60(b) && \ (ntohl(HI61(a)) < ntohl(HI61(b)) || \ (HI61(a) == HI61(b) && \ (ntohl(HI62(a)) < ntohl(HI62(b)) || \ (HI62(a) == HI62(b) && \ ntohl(HI63(a)) < ntohl(HI63(b)))))))) #define NLADD(n,x) htonl(ntohl(n) + (x)) #define IP6_INC(a) \ { i6addr_t *_i6 = (i6addr_t *)(a); \ _i6->i6[3] = NLADD(_i6->i6[3], 1); \ if (_i6->i6[3] == 0) { \ _i6->i6[2] = NLADD(_i6->i6[2], 1); \ if (_i6->i6[2] == 0) { \ _i6->i6[1] = NLADD(_i6->i6[1], 1); \ if (_i6->i6[1] == 0) { \ _i6->i6[0] = NLADD(_i6->i6[0], 1); \ } \ } \ } \ } #define IP6_ADD(a,x,d) \ { i6addr_t *_s = (i6addr_t *)(a); \ i6addr_t *_d = (i6addr_t *)(d); \ _d->i6[3] = NLADD(_s->i6[3], x); \ if (ntohl(_d->i6[3]) < ntohl(_s->i6[3])) { \ _d->i6[2] = NLADD(_d->i6[2], 1); \ if (ntohl(_d->i6[2]) < ntohl(_s->i6[2])) { \ _d->i6[1] = NLADD(_d->i6[1], 1); \ if (ntohl(_d->i6[1]) < ntohl(_s->i6[1])) { \ _d->i6[0] = NLADD(_d->i6[0], 1); \ } \ } \ } \ } #define IP6_AND(a,b,d) { i6addr_t *_s1 = (i6addr_t *)(a); \ i6addr_t *_s2 = (i6addr_t *)(b); \ i6addr_t *_d = (i6addr_t *)(d); \ _d->i6[0] = _s1->i6[0] & _s2->i6[0]; \ _d->i6[1] = _s1->i6[1] & _s2->i6[1]; \ _d->i6[2] = _s1->i6[2] & _s2->i6[2]; \ _d->i6[3] = _s1->i6[3] & _s2->i6[3]; \ } #define IP6_MASKEQ(a,m,b) \ (((I60(a) & I60(m)) == I60(b)) && \ ((I61(a) & I61(m)) == I61(b)) && \ ((I62(a) & I62(m)) == I62(b)) && \ ((I63(a) & I63(m)) == I63(b))) #define IP6_MASKNEQ(a,m,b) \ (((I60(a) & I60(m)) != I60(b)) || \ ((I61(a) & I61(m)) != I61(b)) || \ ((I62(a) & I62(m)) != I62(b)) || \ ((I63(a) & I63(m)) != I63(b))) #define IP6_MERGE(a,b,c) \ { i6addr_t *_d, *_s1, *_s2; \ _d = (i6addr_t *)(a); \ _s1 = (i6addr_t *)(b); \ _s2 = (i6addr_t *)(c); \ _d->i6[0] |= _s1->i6[0] & ~_s2->i6[0]; \ _d->i6[1] |= _s1->i6[1] & ~_s2->i6[1]; \ _d->i6[2] |= _s1->i6[2] & ~_s2->i6[2]; \ _d->i6[3] |= _s1->i6[3] & ~_s2->i6[3]; \ } typedef struct fr_ip { u_32_t fi_v:4; /* IP version */ u_32_t fi_xx:4; /* spare */ u_32_t fi_tos:8; /* IP packet TOS */ u_32_t fi_ttl:8; /* IP packet TTL */ u_32_t fi_p:8; /* IP packet protocol */ u_32_t fi_optmsk; /* bitmask composed from IP options */ i6addr_t fi_src; /* source address from packet */ i6addr_t fi_dst; /* destination address from packet */ u_short fi_secmsk; /* bitmask composed from IP security options */ u_short fi_auth; /* authentication code from IP sec. options */ u_32_t fi_flx; /* packet flags */ u_32_t fi_tcpmsk; /* TCP options set/reset */ u_32_t fi_res1; /* RESERVED */ } fr_ip_t; /* * For use in fi_flx */ #define FI_TCPUDP 0x0001 /* TCP/UCP implied comparison*/ #define FI_OPTIONS 0x0002 #define FI_FRAG 0x0004 #define FI_SHORT 0x0008 #define FI_NATED 0x0010 #define FI_MULTICAST 0x0020 #define FI_BROADCAST 0x0040 #define FI_MBCAST 0x0080 #define FI_STATE 0x0100 #define FI_BADNAT 0x0200 #define FI_BAD 0x0400 #define FI_OOW 0x0800 /* Out of state window, else match */ #define FI_ICMPERR 0x1000 #define FI_FRAGBODY 0x2000 #define FI_BADSRC 0x4000 #define FI_LOWTTL 0x8000 #define FI_CMP 0xcf03 /* Not FI_FRAG,FI_NATED,FI_FRAGTAIL,broadcast */ #define FI_ICMPCMP 0x0003 /* Flags we can check for ICMP error packets */ #define FI_WITH 0xeffe /* Not FI_TCPUDP */ #define FI_V6EXTHDR 0x10000 #define FI_COALESCE 0x20000 #define FI_ICMPQUERY 0x40000 #define FI_NEWNAT 0x80000 #define FI_MOREFRAG 0x100000 #define FI_GENERATED 0x200000 /* new packet generated by ipf */ #define FI_NEG_OOW 0x10000000 /* packet underflows TCP window */ #define FI_NOCKSUM 0x20000000 /* don't do a L4 checksum validation */ #define FI_DONTCACHE 0x40000000 /* don't cache the result */ #define FI_IGNORE 0x80000000 #define fi_saddr fi_src.in4.s_addr #define fi_daddr fi_dst.in4.s_addr #define fi_srcnum fi_src.iplookupnum #define fi_dstnum fi_dst.iplookupnum #define fi_srctype fi_src.iplookuptype #define fi_dsttype fi_dst.iplookuptype #define fi_srcptr fi_src.iplookupptr #define fi_dstptr fi_dst.iplookupptr #define fi_srcfunc fi_src.iplookupfunc #define fi_dstfunc fi_dst.iplookupfunc /* * These are both used by the state and NAT code to indicate that one port or * the other should be treated as a wildcard. * NOTE: When updating, check bit masks in ip_state.h and update there too. */ #define SI_W_SPORT 0x00000100 #define SI_W_DPORT 0x00000200 #define SI_WILDP (SI_W_SPORT|SI_W_DPORT) #define SI_W_SADDR 0x00000400 #define SI_W_DADDR 0x00000800 #define SI_WILDA (SI_W_SADDR|SI_W_DADDR) #define SI_NEWFR 0x00001000 #define SI_CLONE 0x00002000 #define SI_CLONED 0x00004000 struct fr_info { void *fin_ifp; /* interface packet is `on' */ fr_ip_t fin_fi; /* IP Packet summary */ union { u_short fid_16[2]; /* TCP/UDP ports, ICMP code/type */ u_32_t fid_32; } fin_dat; int fin_out; /* in or out ? 1 == out, 0 == in */ int fin_rev; /* state only: 1 = reverse */ u_short fin_hlen; /* length of IP header in bytes */ u_char fin_tcpf; /* TCP header flags (SYN, ACK, etc) */ u_char fin_icode; /* ICMP error to return */ u_32_t fin_rule; /* rule # last matched */ char fin_group[FR_GROUPLEN]; /* group number, -1 for none */ struct frentry *fin_fr; /* last matching rule */ void *fin_dp; /* start of data past IP header */ int fin_dlen; /* length of data portion of packet */ int fin_plen; int fin_ipoff; /* # bytes from buffer start to hdr */ u_32_t fin_id; /* IP packet id field */ u_short fin_off; int fin_depth; /* Group nesting depth */ int fin_error; /* Error code to return */ u_int fin_pktnum; void *fin_nattag; union { ip_t *fip_ip; #ifdef USE_INET6 ip6_t *fip_ip6; #endif } fin_ipu; mb_t **fin_mp; /* pointer to pointer to mbuf */ mb_t *fin_m; /* pointer to mbuf */ #ifdef MENTAT mb_t *fin_qfm; /* pointer to mblk where pkt starts */ void *fin_qpi; ipf_stack_t *fin_ifs; #endif #ifdef __sgi void *fin_hbuf; #endif }; #define fin_ip fin_ipu.fip_ip #define fin_ip6 fin_ipu.fip_ip6 #define fin_v fin_fi.fi_v #define fin_p fin_fi.fi_p #define fin_flx fin_fi.fi_flx #define fin_optmsk fin_fi.fi_optmsk #define fin_secmsk fin_fi.fi_secmsk #define fin_auth fin_fi.fi_auth #define fin_src fin_fi.fi_src.in4 #define fin_saddr fin_fi.fi_saddr #define fin_dst fin_fi.fi_dst.in4 #define fin_daddr fin_fi.fi_daddr #define fin_data fin_dat.fid_16 #define fin_sport fin_dat.fid_16[0] #define fin_dport fin_dat.fid_16[1] #define fin_ports fin_dat.fid_32 #ifdef USE_INET6 # define fin_src6 fin_fi.fi_src # define fin_dst6 fin_fi.fi_dst # define fin_dstip6 fin_fi.fi_dst.in6 # define fin_srcip6 fin_fi.fi_src.in6 #endif #define IPF_IN 0 #define IPF_OUT 1 typedef struct frentry *(*ipfunc_t) __P((fr_info_t *, u_32_t *)); typedef int (*ipfuncinit_t) __P((struct frentry *, ipf_stack_t *)); typedef struct ipfunc_resolve { char ipfu_name[32]; ipfunc_t ipfu_addr; ipfuncinit_t ipfu_init; } ipfunc_resolve_t; /* * Size for compares on fr_info structures */ #define FI_CSIZE offsetof(fr_info_t, fin_icode) #define FI_LCSIZE offsetof(fr_info_t, fin_dp) /* * Size for copying cache fr_info structure */ #define FI_COPYSIZE offsetof(fr_info_t, fin_dp) /* * Structure for holding IPFilter's tag information */ #define IPFTAG_LEN 16 typedef struct { union { u_32_t iptu_num[4]; char iptu_tag[IPFTAG_LEN]; } ipt_un; int ipt_not; } ipftag_t; #define ipt_tag ipt_un.iptu_tag #define ipt_num ipt_un.iptu_num /* * This structure is used to hold information about the next hop for where * to forward a packet. */ typedef struct frdest { void *fd_ifp; i6addr_t fd_ip6; char fd_ifname[LIFNAMSIZ]; } frdest_t; #define fd_ip fd_ip6.in4 /* * This structure holds information about a port comparison. */ typedef struct frpcmp { int frp_cmp; /* data for port comparisons */ u_short frp_port; /* top port for <> and >< */ u_short frp_top; /* top port for <> and >< */ } frpcmp_t; #define FR_NONE 0 #define FR_EQUAL 1 #define FR_NEQUAL 2 #define FR_LESST 3 #define FR_GREATERT 4 #define FR_LESSTE 5 #define FR_GREATERTE 6 #define FR_OUTRANGE 7 #define FR_INRANGE 8 #define FR_INCRANGE 9 /* * Structure containing all the relevant TCP things that can be checked in * a filter rule. */ typedef struct frtuc { u_char ftu_tcpfm; /* tcp flags mask */ u_char ftu_tcpf; /* tcp flags */ frpcmp_t ftu_src; frpcmp_t ftu_dst; } frtuc_t; #define ftu_scmp ftu_src.frp_cmp #define ftu_dcmp ftu_dst.frp_cmp #define ftu_sport ftu_src.frp_port #define ftu_dport ftu_dst.frp_port #define ftu_stop ftu_src.frp_top #define ftu_dtop ftu_dst.frp_top #define FR_TCPFMAX 0x3f /* * This structure makes up what is considered to be the IPFilter specific * matching components of a filter rule, as opposed to the data structures * used to define the result which are in frentry_t and not here. */ typedef struct fripf { fr_ip_t fri_ip; fr_ip_t fri_mip; /* mask structure */ u_short fri_icmpm; /* data for ICMP packets (mask) */ u_short fri_icmp; frtuc_t fri_tuc; int fri_satype; /* addres type */ int fri_datype; /* addres type */ int fri_sifpidx; /* doing dynamic addressing */ int fri_difpidx; /* index into fr_ifps[] to use when */ } fripf_t; #define fri_dstnum fri_ip.fi_dstnum #define fri_srcnum fri_mip.fi_srcnum #define fri_dstptr fri_ip.fi_dstptr #define fri_srcptr fri_mip.fi_srcptr #define FRI_NORMAL 0 /* Normal address */ #define FRI_DYNAMIC 1 /* dynamic address */ #define FRI_LOOKUP 2 /* address is a pool # */ #define FRI_RANGE 3 /* address/mask is a range */ #define FRI_NETWORK 4 /* network address from if */ #define FRI_BROADCAST 5 /* broadcast address from if */ #define FRI_PEERADDR 6 /* Peer address for P-to-P */ #define FRI_NETMASKED 7 /* network address with netmask from if */ typedef struct frentry * (* frentfunc_t) __P((fr_info_t *)); typedef struct frentry { ipfmutex_t fr_lock; struct frentry *fr_next; struct frentry **fr_grp; struct ipscan *fr_isc; void *fr_ifas[4]; void *fr_ptr; /* for use with fr_arg */ char *fr_comment; /* text comment for rule */ int fr_ref; /* reference count - for grouping */ int fr_statecnt; /* state count - for limit rules */ /* * These are only incremented when a packet matches this rule and * it is the last match */ U_QUAD_T fr_hits; U_QUAD_T fr_bytes; /* * For PPS rate limiting */ struct timeval fr_lastpkt; int fr_curpps; union { void *fru_data; caddr_t fru_caddr; fripf_t *fru_ipf; frentfunc_t fru_func; } fr_dun; /* * Fields after this may not change whilst in the kernel. */ ipfunc_t fr_func; /* call this function */ int fr_dsize; int fr_pps; int fr_statemax; /* max reference count */ int fr_flineno; /* line number from conf file */ u_32_t fr_type; u_32_t fr_flags; /* per-rule flags && options (see below) */ u_32_t fr_logtag; /* user defined log tag # */ u_32_t fr_collect; /* collection number */ u_int fr_arg; /* misc. numeric arg for rule */ u_int fr_loglevel; /* syslog log facility + priority */ u_int fr_age[2]; /* non-TCP timeouts */ u_char fr_v; u_char fr_icode; /* return ICMP code */ char fr_group[FR_GROUPLEN]; /* group to which this rule belongs */ char fr_grhead[FR_GROUPLEN]; /* group # which this rule starts */ ipftag_t fr_nattag; char fr_ifnames[4][LIFNAMSIZ]; char fr_isctag[16]; frdest_t fr_tifs[2]; /* "to"/"reply-to" interface */ frdest_t fr_dif; /* duplicate packet interface */ /* * This must be last and will change after loaded into the kernel. */ u_int fr_cksum; /* checksum on filter rules for performance */ } frentry_t; #define fr_caddr fr_dun.fru_caddr #define fr_data fr_dun.fru_data #define fr_dfunc fr_dun.fru_func #define fr_ipf fr_dun.fru_ipf #define fr_ip fr_ipf->fri_ip #define fr_mip fr_ipf->fri_mip #define fr_icmpm fr_ipf->fri_icmpm #define fr_icmp fr_ipf->fri_icmp #define fr_tuc fr_ipf->fri_tuc #define fr_satype fr_ipf->fri_satype #define fr_datype fr_ipf->fri_datype #define fr_sifpidx fr_ipf->fri_sifpidx #define fr_difpidx fr_ipf->fri_difpidx #define fr_proto fr_ip.fi_p #define fr_mproto fr_mip.fi_p #define fr_ttl fr_ip.fi_ttl #define fr_mttl fr_mip.fi_ttl #define fr_tos fr_ip.fi_tos #define fr_mtos fr_mip.fi_tos #define fr_tcpfm fr_tuc.ftu_tcpfm #define fr_tcpf fr_tuc.ftu_tcpf #define fr_scmp fr_tuc.ftu_scmp #define fr_dcmp fr_tuc.ftu_dcmp #define fr_dport fr_tuc.ftu_dport #define fr_sport fr_tuc.ftu_sport #define fr_stop fr_tuc.ftu_stop #define fr_dtop fr_tuc.ftu_dtop #define fr_dst fr_ip.fi_dst.in4 #define fr_daddr fr_ip.fi_dst.in4.s_addr #define fr_src fr_ip.fi_src.in4 #define fr_saddr fr_ip.fi_src.in4.s_addr #define fr_dmsk fr_mip.fi_dst.in4 #define fr_dmask fr_mip.fi_dst.in4.s_addr #define fr_smsk fr_mip.fi_src.in4 #define fr_smask fr_mip.fi_src.in4.s_addr #define fr_dstnum fr_ip.fi_dstnum #define fr_srcnum fr_ip.fi_srcnum #define fr_dsttype fr_ip.fi_dsttype #define fr_srctype fr_ip.fi_srctype #define fr_dstptr fr_mip.fi_dstptr #define fr_srcptr fr_mip.fi_srcptr #define fr_dstfunc fr_mip.fi_dstfunc #define fr_srcfunc fr_mip.fi_srcfunc #define fr_optbits fr_ip.fi_optmsk #define fr_optmask fr_mip.fi_optmsk #define fr_secbits fr_ip.fi_secmsk #define fr_secmask fr_mip.fi_secmsk #define fr_authbits fr_ip.fi_auth #define fr_authmask fr_mip.fi_auth #define fr_flx fr_ip.fi_flx #define fr_mflx fr_mip.fi_flx #define fr_ifname fr_ifnames[0] #define fr_oifname fr_ifnames[2] #define fr_ifa fr_ifas[0] #define fr_oifa fr_ifas[2] #define fr_tif fr_tifs[0] #define fr_rif fr_tifs[1] #define FR_NOLOGTAG 0 #define FR_CMPSIZ (sizeof(struct frentry) - \ offsetof(struct frentry, fr_func)) /* * fr_type */ #define FR_T_NONE 0 #define FR_T_IPF 1 /* IPF structures */ #define FR_T_BPFOPC 2 /* BPF opcode */ #define FR_T_CALLFUNC 3 /* callout to function in fr_func only */ #define FR_T_COMPIPF 4 /* compiled C code */ #define FR_T_BUILTIN 0x80000000 /* rule is in kernel space */ /* * fr_flags */ #define FR_CALL 0x00000 /* call rule */ #define FR_BLOCK 0x00001 /* do not allow packet to pass */ #define FR_PASS 0x00002 /* allow packet to pass */ #define FR_AUTH 0x00003 /* use authentication */ #define FR_PREAUTH 0x00004 /* require preauthentication */ #define FR_ACCOUNT 0x00005 /* Accounting rule */ #define FR_SKIP 0x00006 /* skip rule */ #define FR_DIVERT 0x00007 /* divert rule */ #define FR_CMDMASK 0x0000f #define FR_LOG 0x00010 /* Log */ #define FR_LOGB 0x00011 /* Log-fail */ #define FR_LOGP 0x00012 /* Log-pass */ #define FR_LOGMASK (FR_LOG|FR_CMDMASK) #define FR_CALLNOW 0x00020 /* call another function (fr_func) if matches */ #define FR_NOTSRCIP 0x00040 #define FR_NOTDSTIP 0x00080 #define FR_QUICK 0x00100 /* match & stop processing list */ #define FR_KEEPFRAG 0x00200 /* keep fragment information */ #define FR_KEEPSTATE 0x00400 /* keep `connection' state information */ #define FR_FASTROUTE 0x00800 /* bypass normal routing */ #define FR_RETRST 0x01000 /* Return TCP RST packet - reset connection */ #define FR_RETICMP 0x02000 /* Return ICMP unreachable packet */ #define FR_FAKEICMP 0x03000 /* Return ICMP unreachable with fake source */ #define FR_OUTQUE 0x04000 /* outgoing packets */ #define FR_INQUE 0x08000 /* ingoing packets */ #define FR_LOGBODY 0x10000 /* Log the body */ #define FR_LOGFIRST 0x20000 /* Log the first byte if state held */ #define FR_LOGORBLOCK 0x40000 /* block the packet if it can't be logged */ #define FR_DUP 0x80000 /* duplicate packet */ #define FR_FRSTRICT 0x100000 /* strict frag. cache */ #define FR_STSTRICT 0x200000 /* strict keep state */ #define FR_NEWISN 0x400000 /* new ISN for outgoing TCP */ #define FR_NOICMPERR 0x800000 /* do not match ICMP errors in state */ #define FR_STATESYNC 0x1000000 /* synchronize state to slave */ #define FR_NOMATCH 0x8000000 /* no match occured */ /* 0x10000000 FF_LOGPASS */ /* 0x20000000 FF_LOGBLOCK */ /* 0x40000000 FF_LOGNOMATCH */ /* 0x80000000 FF_BLOCKNONIP */ #define FR_COPIED 0x40000000 /* copied from user space */ #define FR_INACTIVE 0x80000000 /* only used when flush'ing rules */ #define FR_RETMASK (FR_RETICMP|FR_RETRST|FR_FAKEICMP) #define FR_ISBLOCK(x) (((x) & FR_CMDMASK) == FR_BLOCK) #define FR_ISPASS(x) (((x) & FR_CMDMASK) == FR_PASS) #define FR_ISAUTH(x) (((x) & FR_CMDMASK) == FR_AUTH) #define FR_ISPREAUTH(x) (((x) & FR_CMDMASK) == FR_PREAUTH) #define FR_ISACCOUNT(x) (((x) & FR_CMDMASK) == FR_ACCOUNT) #define FR_ISSKIP(x) (((x) & FR_CMDMASK) == FR_SKIP) #define FR_ISNOMATCH(x) ((x) & FR_NOMATCH) #define FR_INOUT (FR_INQUE|FR_OUTQUE) /* * recognized flags for SIOCGETFF and SIOCSETFF, and get put in fr_flags */ #define FF_LOGPASS 0x10000000 #define FF_LOGBLOCK 0x20000000 #define FF_LOGNOMATCH 0x40000000 #define FF_LOGGING (FF_LOGPASS|FF_LOGBLOCK|FF_LOGNOMATCH) #define FF_BLOCKNONIP 0x80000000 /* Solaris2 Only */ /* * Structure that passes information on what/how to flush to the kernel. */ typedef struct ipfflush { int ipflu_how; int ipflu_arg; } ipfflush_t; /* * */ typedef struct ipfgetctl { u_int ipfg_min; /* min value */ u_int ipfg_current; /* current value */ u_int ipfg_max; /* max value */ u_int ipfg_default; /* default value */ u_int ipfg_steps; /* value increments */ char ipfg_name[40]; /* tag name for this control */ } ipfgetctl_t; typedef struct ipfsetctl { int ipfs_which; /* 0 = min 1 = current 2 = max 3 = default */ u_int ipfs_value; /* min value */ char ipfs_name[40]; /* tag name for this control */ } ipfsetctl_t; /* * Some of the statistics below are in their own counters, but most are kept * in this single structure so that they can all easily be collected and * copied back as required. * * NOTE: when changing, keep in sync with kstats (below). */ typedef struct filterstats { u_long fr_pass; /* packets allowed */ u_long fr_block; /* packets denied */ u_long fr_nom; /* packets which don't match any rule */ u_long fr_short; /* packets which are short */ u_long fr_ppkl; /* packets allowed and logged */ u_long fr_bpkl; /* packets denied and logged */ u_long fr_npkl; /* packets unmatched and logged */ u_long fr_pkl; /* packets logged */ u_long fr_skip; /* packets to be logged but buffer full */ u_long fr_ret; /* packets for which a return is sent */ u_long fr_acct; /* packets for which counting was performed */ u_long fr_bnfr; /* bad attempts to allocate fragment state */ u_long fr_nfr; /* new fragment state kept */ u_long fr_cfr; /* add new fragment state but complete pkt */ u_long fr_bads; /* bad attempts to allocate packet state */ u_long fr_ads; /* new packet state kept */ u_long fr_chit; /* cached hit */ u_long fr_tcpbad; /* TCP checksum check failures */ u_long fr_pull[2]; /* good and bad pullup attempts */ u_long fr_badsrc; /* source received doesn't match route */ u_long fr_badttl; /* TTL in packet doesn't reach minimum */ u_long fr_bad; /* bad IP packets to the filter */ u_long fr_ipv6; /* IPv6 packets in/out */ u_long fr_ppshit; /* dropped because of pps ceiling */ u_long fr_ipud; /* IP id update failures */ } filterstats_t; /* * kstat "copy" of the above - keep in sync! * also keep in sync with initialisation code in solaris.c, ipf_kstat_init(). */ typedef struct filter_kstats { kstat_named_t fks_pass; /* see above for comments */ kstat_named_t fks_block; kstat_named_t fks_nom; kstat_named_t fks_short; kstat_named_t fks_ppkl; kstat_named_t fks_bpkl; kstat_named_t fks_npkl; kstat_named_t fks_pkl; kstat_named_t fks_skip; kstat_named_t fks_ret; kstat_named_t fks_acct; kstat_named_t fks_bnfr; kstat_named_t fks_nfr; kstat_named_t fks_cfr; kstat_named_t fks_bads; kstat_named_t fks_ads; kstat_named_t fks_chit; kstat_named_t fks_tcpbad; kstat_named_t fks_pull[2]; kstat_named_t fks_badsrc; kstat_named_t fks_badttl; kstat_named_t fks_bad; kstat_named_t fks_ipv6; kstat_named_t fks_ppshit; kstat_named_t fks_ipud; } filter_kstats_t; /* * Log structure. Each packet header logged is prepended by one of these. * Following this in the log records read from the device will be an ipflog * structure which is then followed by any packet data. */ typedef struct iplog { u_32_t ipl_magic; u_int ipl_count; struct timeval ipl_time; size_t ipl_dsize; struct iplog *ipl_next; } iplog_t; #define ipl_sec ipl_time.tv_sec #define ipl_usec ipl_time.tv_usec #define IPL_MAGIC 0x49504c4d /* 'IPLM' */ #define IPL_MAGIC_NAT 0x49504c4e /* 'IPLN' */ #define IPL_MAGIC_STATE 0x49504c53 /* 'IPLS' */ #define IPLOG_SIZE sizeof(iplog_t) typedef struct ipflog { #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \ (defined(OpenBSD) && (OpenBSD >= 199603)) #else u_int fl_unit; #endif u_32_t fl_rule; u_32_t fl_flags; u_32_t fl_lflags; u_32_t fl_logtag; ipftag_t fl_nattag; u_short fl_plen; /* extra data after hlen */ u_short fl_loglevel; /* syslog log level */ char fl_group[FR_GROUPLEN]; u_char fl_hlen; /* length of IP headers saved */ u_char fl_dir; u_char fl_xxx[2]; /* pad */ char fl_ifname[LIFNAMSIZ]; } ipflog_t; #ifndef IPF_LOGGING # define IPF_LOGGING 0 #endif #ifndef IPF_DEFAULT_PASS # define IPF_DEFAULT_PASS FR_PASS #endif #define DEFAULT_IPFLOGSIZE 8192 #ifndef IPFILTER_LOGSIZE # define IPFILTER_LOGSIZE DEFAULT_IPFLOGSIZE #else # if IPFILTER_LOGSIZE < DEFAULT_IPFLOGSIZE # error IPFILTER_LOGSIZE too small. Must be >= DEFAULT_IPFLOGSIZE # endif #endif #define IPF_OPTCOPY 0x07ff00 /* bit mask of copied options */ /* * Device filenames for reading log information. Use ipf on Solaris2 because * ipl is already a name used by something else. */ #ifndef IPL_NAME # ifdef SOLARIS # define IPL_NAME "/dev/ipf" # else # define IPL_NAME "/dev/ipl" # endif #endif /* * Pathnames for various IP Filter control devices. Used by LKM * and userland, so defined here. */ #define IPNAT_NAME "/dev/ipnat" #define IPSTATE_NAME "/dev/ipstate" #define IPAUTH_NAME "/dev/ipauth" #define IPSYNC_NAME "/dev/ipsync" #define IPSCAN_NAME "/dev/ipscan" #define IPLOOKUP_NAME "/dev/iplookup" #define IPL_LOGIPF 0 /* Minor device #'s for accessing logs */ #define IPL_LOGNAT 1 #define IPL_LOGSTATE 2 #define IPL_LOGAUTH 3 #define IPL_LOGSYNC 4 #define IPL_LOGSCAN 5 #define IPL_LOGLOOKUP 6 #define IPL_LOGCOUNT 7 #define IPL_LOGMAX 7 #define IPL_LOGSIZE (IPL_LOGMAX + 1) #define IPL_LOGALL -1 #define IPL_LOGNONE -2 /* * For SIOCGETFS */ typedef struct friostat { struct filterstats f_st[2]; struct frentry *f_ipf[2][2]; struct frentry *f_acct[2][2]; struct frentry *f_ipf6[2][2]; struct frentry *f_acct6[2][2]; struct frentry *f_auth; struct frgroup *f_groups[IPL_LOGSIZE][2]; u_long f_froute[2]; u_long f_ticks; int f_locks[IPL_LOGMAX]; size_t f_kmutex_sz; size_t f_krwlock_sz; int f_defpass; /* default pass - from fr_pass */ int f_active; /* 1 or 0 - active rule set */ int f_running; /* 1 if running, else 0 */ int f_logging; /* 1 if enabled, else 0 */ int f_features; char f_version[32]; /* version string */ } friostat_t; #define f_fin f_ipf[0] #define f_fin6 f_ipf6[0] #define f_fout f_ipf[1] #define f_fout6 f_ipf6[1] #define f_acctin f_acct[0] #define f_acctin6 f_acct6[0] #define f_acctout f_acct[1] #define f_acctout6 f_acct6[1] #define IPF_FEAT_LKM 0x001 #define IPF_FEAT_LOG 0x002 #define IPF_FEAT_LOOKUP 0x004 #define IPF_FEAT_BPF 0x008 #define IPF_FEAT_COMPILED 0x010 #define IPF_FEAT_CKSUM 0x020 #define IPF_FEAT_SYNC 0x040 #define IPF_FEAT_SCAN 0x080 #define IPF_FEAT_IPV6 0x100 typedef struct optlist { u_short ol_val; int ol_bit; } optlist_t; /* * Group list structure. */ typedef struct frgroup { struct frgroup *fg_next; struct frentry *fg_head; struct frentry *fg_start; u_32_t fg_flags; int fg_ref; char fg_name[FR_GROUPLEN]; } frgroup_t; #define FG_NAME(g) (*(g)->fg_name == '\0' ? "" : (g)->fg_name) /* * Used by state and NAT tables */ typedef struct icmpinfo { u_short ici_id; u_short ici_seq; u_char ici_type; } icmpinfo_t; typedef struct udpinfo { u_short us_sport; u_short us_dport; } udpinfo_t; typedef struct tcpdata { u_32_t td_end; u_32_t td_maxend; u_32_t td_maxwin; u_32_t td_winscale; u_32_t td_maxseg; int td_winflags; } tcpdata_t; #define TCP_WSCALE_MAX 14 #define TCP_WSCALE_SEEN 0x00000001 #define TCP_WSCALE_FIRST 0x00000002 #define TCP_SACK_PERMIT 0x00000004 typedef struct tcpinfo { u_short ts_sport; u_short ts_dport; tcpdata_t ts_data[2]; } tcpinfo_t; /* * Structures to define a GRE header as seen in a packet. */ struct grebits { u_32_t grb_C:1; u_32_t grb_R:1; u_32_t grb_K:1; u_32_t grb_S:1; u_32_t grb_s:1; u_32_t grb_recur:1; u_32_t grb_A:1; u_32_t grb_flags:3; u_32_t grb_ver:3; u_short grb_ptype; }; typedef struct grehdr { union { struct grebits gru_bits; u_short gru_flags; } gr_un; u_short gr_len; u_short gr_call; } grehdr_t; #define gr_flags gr_un.gru_flags #define gr_bits gr_un.gru_bits #define gr_ptype gr_bits.grb_ptype #define gr_C gr_bits.grb_C #define gr_R gr_bits.grb_R #define gr_K gr_bits.grb_K #define gr_S gr_bits.grb_S #define gr_s gr_bits.grb_s #define gr_recur gr_bits.grb_recur #define gr_A gr_bits.grb_A #define gr_ver gr_bits.grb_ver /* * GRE information tracked by "keep state" */ typedef struct greinfo { u_short gs_call[2]; u_short gs_flags; u_short gs_ptype; } greinfo_t; #define GRE_REV(x) ((ntohs(x) >> 13) & 7) /* * Format of an Authentication header */ typedef struct authhdr { u_char ah_next; u_char ah_plen; u_short ah_reserved; u_32_t ah_spi; u_32_t ah_seq; /* Following the sequence number field is 0 or more bytes of */ /* authentication data, as specified by ah_plen - RFC 2402. */ } authhdr_t; /* * Timeout tail queue list member */ typedef struct ipftqent { struct ipftqent **tqe_pnext; struct ipftqent *tqe_next; struct ipftq *tqe_ifq; void *tqe_parent; /* pointer back to NAT/state struct */ u_long tqe_die; /* when this entriy is to die */ u_long tqe_touched; int tqe_flags; int tqe_state[2]; /* current state of this entry */ } ipftqent_t; #define TQE_RULEBASED 0x00000001 /* * Timeout tail queue head for IPFilter */ typedef struct ipftq { ipfmutex_t ifq_lock; u_int ifq_ttl; ipftqent_t *ifq_head; ipftqent_t **ifq_tail; struct ipftq *ifq_next; struct ipftq **ifq_pnext; int ifq_ref; u_int ifq_flags; } ipftq_t; #define IFQF_USER 0x01 /* User defined aging */ #define IFQF_DELETE 0x02 /* Marked for deletion */ #define IFQF_PROXY 0x04 /* Timeout queue in use by a proxy */ #define IPF_HZ_MULT 1 #define IPF_HZ_DIVIDE 2 /* How many times a second ipfilter */ /* checks its timeout queues. */ #define IPF_TTLVAL(x) (((x) / IPF_HZ_MULT) * IPF_HZ_DIVIDE) /* * Structure to define address for pool lookups. */ typedef struct { u_char adf_len; sa_family_t adf_family; i6addr_t adf_addr; } addrfamily_t; /* * Object structure description. For passing through in ioctls. */ typedef struct ipfobj { u_32_t ipfo_rev; /* IPFilter version number */ u_32_t ipfo_size; /* size of object at ipfo_ptr */ void *ipfo_ptr; /* pointer to object */ int ipfo_type; /* type of object being pointed to */ int ipfo_offset; /* bytes from ipfo_ptr where to start */ u_char ipfo_xxxpad[32]; /* reserved for future use */ } ipfobj_t; /* * ioctl struct for setting what zone further ioctls will act on. ipfz_gz is a * boolean: set it to 1 to operate on the GZ-controlled stack. */ typedef struct ipfzoneobj { u_32_t ipfz_gz; /* GZ stack boolean */ char ipfz_zonename[ZONENAME_MAX]; /* zone to act on */ } ipfzoneobj_t; #if defined(_KERNEL) /* Set ipfs_zoneid to this if no zone has been set: */ #define IPFS_ZONE_UNSET -2 typedef struct ipf_devstate { zoneid_t ipfs_zoneid; minor_t ipfs_minor; boolean_t ipfs_gz; } ipf_devstate_t; #endif #define IPFOBJ_FRENTRY 0 /* struct frentry */ #define IPFOBJ_IPFSTAT 1 /* struct friostat */ #define IPFOBJ_IPFINFO 2 /* struct fr_info */ #define IPFOBJ_AUTHSTAT 3 /* struct fr_authstat */ #define IPFOBJ_FRAGSTAT 4 /* struct ipfrstat */ #define IPFOBJ_IPNAT 5 /* struct ipnat */ #define IPFOBJ_NATSTAT 6 /* struct natstat */ #define IPFOBJ_STATESAVE 7 /* struct ipstate_save */ #define IPFOBJ_NATSAVE 8 /* struct nat_save */ #define IPFOBJ_NATLOOKUP 9 /* struct natlookup */ #define IPFOBJ_IPSTATE 10 /* struct ipstate */ #define IPFOBJ_STATESTAT 11 /* struct ips_stat */ #define IPFOBJ_FRAUTH 12 /* struct frauth */ #define IPFOBJ_TUNEABLE 13 /* struct ipftune */ #define IPFOBJ_NAT 14 /* struct nat */ #define IPFOBJ_IPFITER 15 /* struct ipfruleiter */ #define IPFOBJ_GENITER 16 /* struct ipfgeniter */ #define IPFOBJ_GTABLE 17 /* struct ipftable */ #define IPFOBJ_LOOKUPITER 18 /* struct ipflookupiter */ #define IPFOBJ_COUNT 19 /* How many #defines are above this? */ typedef union ipftunevalptr { void *ipftp_void; u_long *ipftp_long; u_int *ipftp_int; u_short *ipftp_short; u_char *ipftp_char; } ipftunevalptr_t; typedef struct ipftuneable { ipftunevalptr_t ipft_una; char *ipft_name; u_long ipft_min; u_long ipft_max; int ipft_sz; int ipft_flags; struct ipftuneable *ipft_next; } ipftuneable_t; #define ipft_addr ipft_una.ipftp_void #define ipft_plong ipft_una.ipftp_long #define ipft_pint ipft_una.ipftp_int #define ipft_pshort ipft_una.ipftp_short #define ipft_pchar ipft_una.ipftp_char #define IPFT_RDONLY 1 /* read-only */ #define IPFT_WRDISABLED 2 /* write when disabled only */ typedef union ipftuneval { u_long ipftu_long; u_int ipftu_int; u_short ipftu_short; u_char ipftu_char; } ipftuneval_t; typedef struct ipftune { void *ipft_cookie; ipftuneval_t ipft_un; u_long ipft_min; u_long ipft_max; int ipft_sz; int ipft_flags; char ipft_name[80]; } ipftune_t; #define ipft_vlong ipft_un.ipftu_long #define ipft_vint ipft_un.ipftu_int #define ipft_vshort ipft_un.ipftu_short #define ipft_vchar ipft_un.ipftu_char /* * ipfruleiter is iterator structure used for filter rules. */ typedef struct ipfruleiter { int iri_ver; int iri_inout; char iri_group[FR_GROUPLEN]; int iri_active; int iri_nrules; frentry_t *iri_rule; } ipfruleiter_t; /* Values for iri_inout */ #define F_IN 0 #define F_OUT 1 #define F_ACIN 2 #define F_ACOUT 3 /* * ipfgeniter is generic iterator structure used for nat rules, * hostmap entries and nat table entries. */ typedef struct ipfgeniter { int igi_type; /* type of data we're looking at */ int igi_nitems; void *igi_data; } ipfgeniter_t; #define IPFGENITER_IPF 0 #define IPFGENITER_NAT 1 #define IPFGENITER_IPNAT 2 #define IPFGENITER_FRAG 3 #define IPFGENITER_AUTH 4 #define IPFGENITER_STATE 5 #define IPFGENITER_NATFRAG 6 #define IPFGENITER_HOSTMAP 7 #define IPFGENITER_LOOKUP 8 typedef struct ipftable { int ita_type; void *ita_table; } ipftable_t; typedef struct ipftoken { struct ipftoken *ipt_next; struct ipftoken **ipt_pnext; void *ipt_ctx; void *ipt_data; u_long ipt_die; int ipt_type; int ipt_uid; int ipt_subtype; int ipt_alive; } ipftoken_t; /* * sync commands */ #define IPFSYNC_RESYNC 0 #define IPFSYNC_NEWIFP 1 #define IPFSYNC_OLDIFP 2 /* ** HPUX Port */ #ifdef __hpux /* HP-UX locking sequence deadlock detection module lock MAJOR ID */ # define IPF_SMAJ 0 /* temp assignment XXX, not critical */ #endif #if !defined(CDEV_MAJOR) && defined (__FreeBSD_version) && \ (__FreeBSD_version >= 220000) # define CDEV_MAJOR 79 #endif /* * Post NetBSD 1.2 has the PFIL interface for packet filters. This turns * on those hooks. We don't need any special mods in non-IP Filter code * with this! */ #if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \ (defined(NetBSD1_2) && NetBSD1_2 > 1) || \ (defined(__FreeBSD__) && (__FreeBSD_version >= 500043)) # if (NetBSD >= 199905) # define PFIL_HOOKS # endif # ifdef PFIL_HOOKS # define NETBSD_PF # endif #endif #ifndef _KERNEL extern int fr_check __P((struct ip *, int, void *, int, mb_t **, ipf_stack_t *)); extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **, ipf_stack_t *)); extern int ipf_log __P((void)); extern struct ifnet *get_unit __P((char *, int, ipf_stack_t *)); extern char *get_ifname __P((struct ifnet *)); # if defined(__NetBSD__) || defined(__OpenBSD__) || \ (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) extern int frrequest __P((int, u_long, caddr_t, int, int, ipf_stack_t *)); # else extern int iplioctl __P((int, ioctlcmd_t, caddr_t, int)); # endif extern int iplopen __P((dev_t, int)); extern int iplclose __P((dev_t, int)); extern void m_freem __P((mb_t *)); #else /* #ifndef _KERNEL */ extern phy_if_t get_unit __P((char *, int, ipf_stack_t *)); # if defined(__NetBSD__) && defined(PFIL_HOOKS) extern void ipfilterattach __P((int)); # endif extern int ipl_enable __P((void)); extern int ipl_disable __P((void)); # ifdef MENTAT extern int fr_check __P((struct ip *, int, void *, int, void *, mblk_t **, ipf_stack_t *)); # if SOLARIS # if SOLARIS2 >= 7 extern int iplioctl __P((dev_t, int, intptr_t, int, cred_t *, int *)); # else extern int iplioctl __P((dev_t, int, int *, int, cred_t *, int *)); # endif # if SOLARIS2 >= 10 && defined(_KERNEL) extern int fr_make_rst __P((fr_info_t *)); extern int fr_make_icmp __P((fr_info_t *)); extern void fr_calc_chksum __P((fr_info_t *, mb_t *)); extern ipf_stack_t *ipf_find_stack(const zoneid_t, ipf_devstate_t *); # endif extern int iplopen __P((dev_t *, int, int, cred_t *)); extern int iplclose __P((dev_t, int, int, cred_t *)); extern int iplread __P((dev_t, uio_t *, cred_t *)); extern int iplwrite __P((dev_t, uio_t *, cred_t *)); # endif # ifdef __hpux extern int iplopen __P((dev_t, int, intptr_t, int)); extern int iplclose __P((dev_t, int, int)); extern int iplioctl __P((dev_t, int, caddr_t, int)); extern int iplread __P((dev_t, uio_t *)); extern int iplwrite __P((dev_t, uio_t *)); extern int iplselect __P((dev_t, int)); # endif extern int ipfsync __P((ipf_stack_t *)); extern int fr_qout __P((queue_t *, mblk_t *)); # else /* MENTAT */ extern int fr_check __P((struct ip *, int, void *, int, mb_t **, ipf_stack_t *)); extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **, ipf_stack_t *)); extern size_t mbufchainlen __P((mb_t *)); # ifdef __sgi # include extern int iplioctl __P((dev_t, int, caddr_t, int, cred_t *, int *)); extern int iplopen __P((dev_t *, int, int, cred_t *)); extern int iplclose __P((dev_t, int, int, cred_t *)); extern int iplread __P((dev_t, uio_t *, cred_t *)); extern int iplwrite __P((dev_t, uio_t *, cred_t *)); extern int ipfsync __P((ipf_stack_t *)); extern int ipfilter_sgi_attach __P((void)); extern void ipfilter_sgi_detach __P((void)); extern void ipfilter_sgi_intfsync __P((void)); # else # ifdef IPFILTER_LKM extern int iplidentify __P((char *)); # endif # if (_BSDI_VERSION >= 199510) || (__FreeBSD_version >= 220000) || \ (NetBSD >= 199511) || defined(__OpenBSD__) # if defined(__NetBSD__) || (_BSDI_VERSION >= 199701) || \ defined(__OpenBSD__) || (__FreeBSD_version >= 300000) # if (__FreeBSD_version >= 500024) # if (__FreeBSD_version >= 502116) extern int iplioctl __P((struct cdev*, u_long, caddr_t, int, struct thread *)); # else extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct thread *)); # endif /* __FreeBSD_version >= 502116 */ # else extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); # endif /* __FreeBSD_version >= 500024 */ # else extern int iplioctl __P((dev_t, int, caddr_t, int, struct proc *)); # endif # if (__FreeBSD_version >= 500024) # if (__FreeBSD_version >= 502116) extern int iplopen __P((struct cdev*, int, int, struct thread *)); extern int iplclose __P((struct cdev*, int, int, struct thread *)); # else extern int iplopen __P((dev_t, int, int, struct thread *)); extern int iplclose __P((dev_t, int, int, struct thread *)); # endif /* __FreeBSD_version >= 502116 */ # else extern int iplopen __P((dev_t, int, int, struct proc *)); extern int iplclose __P((dev_t, int, int, struct proc *)); # endif /* __FreeBSD_version >= 500024 */ # else # ifdef linux extern int iplioctl __P((struct inode *, struct file *, u_int, u_long)); # else extern int iplopen __P((dev_t, int)); extern int iplclose __P((dev_t, int)); extern int iplioctl __P((dev_t, int, caddr_t, int)); # endif # endif /* (_BSDI_VERSION >= 199510) */ # if BSD >= 199306 # if (__FreeBSD_version >= 502116) extern int iplread __P((struct cdev*, struct uio *, int)); extern int iplwrite __P((struct cdev*, struct uio *, int)); # else extern int iplread __P((dev_t, struct uio *, int)); extern int iplwrite __P((dev_t, struct uio *, int)); # endif /* __FreeBSD_version >= 502116 */ # else # ifndef linux extern int iplread __P((dev_t, struct uio *)); extern int iplwrite __P((dev_t, struct uio *)); # endif # endif /* BSD >= 199306 */ # endif /* __ sgi */ # endif /* MENTAT */ #endif /* #ifndef _KERNEL */ extern char *memstr __P((char *, char *, int, int)); extern int count4bits __P((u_32_t)); extern int count6bits __P((u_32_t *)); extern int frrequest __P((int, ioctlcmd_t, caddr_t, int, int, ipf_stack_t *)); extern char *getifname __P((struct ifnet *)); extern int iplattach __P((ipf_stack_t *)); extern int ipldetach __P((ipf_stack_t *)); extern u_short ipf_cksum __P((u_short *, int)); extern int copyinptr __P((void *, void *, size_t)); extern int copyoutptr __P((void *, void *, size_t)); extern int fr_fastroute __P((mb_t *, mb_t **, fr_info_t *, frdest_t *)); extern int fr_inobj __P((void *, void *, int)); extern int fr_inobjsz __P((void *, void *, int, int)); extern int fr_ioctlswitch __P((int, void *, ioctlcmd_t, int, int, void *, ipf_stack_t *)); extern int fr_ipftune __P((ioctlcmd_t, void *, ipf_stack_t *)); extern int fr_outobj __P((void *, void *, int)); extern int fr_outobjsz __P((void *, void *, int, int)); extern void *fr_pullup __P((mb_t *, fr_info_t *, int)); extern void fr_resolvedest __P((struct frdest *, int, ipf_stack_t *)); extern int fr_resolvefunc __P((void *)); extern void *fr_resolvenic __P((char *, int, ipf_stack_t *)); extern int fr_send_icmp_err __P((int, fr_info_t *, int)); extern int fr_send_reset __P((fr_info_t *)); #if (__FreeBSD_version < 490000) || !defined(_KERNEL) extern int ppsratecheck __P((struct timeval *, int *, int)); #endif extern ipftq_t *fr_addtimeoutqueue __P((ipftq_t **, u_int, ipf_stack_t *)); extern void fr_deletequeueentry __P((ipftqent_t *)); extern int fr_deletetimeoutqueue __P((ipftq_t *)); extern void fr_freetimeoutqueue __P((ipftq_t *, ipf_stack_t *)); extern void fr_movequeue __P((ipftqent_t *, ipftq_t *, ipftq_t *, ipf_stack_t *)); extern void fr_queueappend __P((ipftqent_t *, ipftq_t *, void *, ipf_stack_t *)); extern void fr_queueback __P((ipftqent_t *, ipf_stack_t *)); extern void fr_queuefront __P((ipftqent_t *)); extern void fr_checkv4sum __P((fr_info_t *)); extern int fr_checkl4sum __P((fr_info_t *)); extern int fr_ifpfillv4addr __P((int, struct sockaddr_in *, struct sockaddr_in *, struct in_addr *, struct in_addr *)); extern int fr_coalesce __P((fr_info_t *)); #ifdef USE_INET6 extern void fr_checkv6sum __P((fr_info_t *)); extern int fr_ifpfillv6addr __P((int, struct sockaddr_in6 *, struct sockaddr_in6 *, struct in_addr *, struct in_addr *)); #endif #define IPFILTER_COMPAT extern int fr_incomptrans __P((ipfobj_t *, void *)); extern int fr_outcomptrans __P((ipfobj_t *, void *)); extern int fr_addipftune __P((ipftuneable_t *, ipf_stack_t *)); extern int fr_delipftune __P((ipftuneable_t *, ipf_stack_t *)); extern int frflush __P((minor_t, int, int, ipf_stack_t *)); extern void frsync __P((int, int, void *, char *, ipf_stack_t *)); #if SOLARIS2 >= 10 extern void fr_ifindexsync __P((void *, void *, ipf_stack_t *)); #endif extern frgroup_t *fr_addgroup __P((char *, void *, u_32_t, minor_t, int, ipf_stack_t *)); extern int fr_derefrule __P((frentry_t **, ipf_stack_t *)); extern void fr_delgroup __P((char *, minor_t, int, ipf_stack_t *)); extern frgroup_t *fr_findgroup __P((char *, minor_t, int, frgroup_t ***, ipf_stack_t *)); extern int fr_loginit __P((ipf_stack_t *)); extern int ipflog_clear __P((minor_t, ipf_stack_t *)); extern int ipflog_read __P((minor_t, struct uio *, ipf_stack_t *)); extern int ipflog __P((fr_info_t *, u_int)); extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int, ipf_stack_t *)); extern void fr_logunload __P((ipf_stack_t *)); extern frentry_t *fr_acctpkt __P((fr_info_t *, u_32_t *)); extern int fr_copytolog __P((int, char *, int)); extern u_short fr_cksum __P((mb_t *, ip_t *, int, void *)); extern void fr_deinitialise __P((ipf_stack_t *)); extern frentry_t *fr_dolog __P((fr_info_t *, u_32_t *)); extern frentry_t *fr_dstgrpmap __P((fr_info_t *, u_32_t *)); extern void fr_fixskip __P((frentry_t **, frentry_t *, int)); extern void fr_forgetifp __P((void *, ipf_stack_t *)); extern frentry_t *fr_getrulen __P((int, char *, u_32_t, ipf_stack_t *)); extern void fr_getstat __P((struct friostat *, ipf_stack_t *)); extern int fr_ifpaddr __P((int, int, void *, struct in_addr *, struct in_addr *, ipf_stack_t *)); extern int fr_initialise __P((ipf_stack_t *)); extern int fr_lock __P((caddr_t, int *)); extern int fr_makefrip __P((int, ip_t *, fr_info_t *)); extern int fr_matchtag __P((ipftag_t *, ipftag_t *)); extern int fr_matchicmpqueryreply __P((int, icmpinfo_t *, struct icmp *, int)); extern u_32_t fr_newisn __P((fr_info_t *)); extern u_short fr_nextipid __P((fr_info_t *)); extern int fr_rulen __P((int, frentry_t *, ipf_stack_t *)); extern int fr_scanlist __P((fr_info_t *, u_32_t)); extern frentry_t *fr_srcgrpmap __P((fr_info_t *, u_32_t *)); extern int fr_tcpudpchk __P((fr_info_t *, frtuc_t *)); extern int fr_verifysrc __P((fr_info_t *fin)); extern int fr_zerostats __P((char *, ipf_stack_t *)); extern ipftoken_t *ipf_findtoken __P((int, int, void *, ipf_stack_t *)); extern int ipf_getnextrule __P((ipftoken_t *, void *, ipf_stack_t *)); extern void ipf_expiretokens __P((ipf_stack_t *)); extern void ipf_freetoken __P((ipftoken_t *, ipf_stack_t *)); extern int ipf_deltoken __P((int, int, void *, ipf_stack_t *)); extern int ipf_genericiter __P((void *, int, void *, ipf_stack_t *)); extern int ipf_extraflush __P((int, ipftq_t *, ipftq_t *, ipf_stack_t *)); extern int ipf_flushclosing __P((int, int, ipftq_t *, ipftq_t *, ipf_stack_t *)); extern int ipf_earlydrop __P((int, ipftq_t *, int, ipf_stack_t *)); #ifndef ipf_random extern u_32_t ipf_random __P((void)); #endif #if defined(_KERNEL) extern int fr_setzoneid __P((ipf_devstate_t *, void *)); #endif extern char ipfilter_version[]; #ifdef USE_INET6 extern int icmptoicmp6types[ICMP_MAXTYPE+1]; extern int icmptoicmp6unreach[ICMP_MAX_UNREACH]; extern int icmpreplytype6[ICMP6_MAXTYPE + 1]; #endif extern int icmpreplytype4[ICMP_MAXTYPE + 1]; extern frentry_t *ipfrule_match __P((fr_info_t *)); extern void ipftuneable_alloc(ipf_stack_t *); extern void ipftuneable_free(ipf_stack_t *); #endif /* __IP_FIL_H__ */