1 /*
   2  * Copyright (C) 1993-2001, 2003 by Darren Reed.
   3  *
   4  * See the IPFILTER.LICENCE file for details on licencing.
   5  *
   6  * @(#)ip_fil.h 1.35 6/5/96
   7  * $Id: ip_fil.h,v 2.170.2.22 2005/07/16 05:55:35 darrenr Exp $
   8  *
   9  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  10  *
  11  * Copyright 2019, Joyent, Inc.
  12  */
  13 
  14 #ifndef __IP_FIL_H__
  15 #define __IP_FIL_H__
  16 
  17 #include "netinet/ip_compat.h"
  18 #include <sys/zone.h>
  19 #include <sys/uuid.h>
  20 
  21 #ifdef  SOLARIS
  22 #undef  SOLARIS
  23 #endif
  24 #if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
  25 #define SOLARIS (1)
  26 #else
  27 #define SOLARIS (0)
  28 #endif
  29 
  30 #ifndef __P
  31 # ifdef __STDC__
  32 #  define       __P(x)  x
  33 # else
  34 #  define       __P(x)  ()
  35 # endif
  36 #endif
  37 
  38 #if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51)
  39 # define        SIOCADAFR       _IOW('r', 60, struct ipfobj)
  40 # define        SIOCRMAFR       _IOW('r', 61, struct ipfobj)
  41 # define        SIOCSETFF       _IOW('r', 62, u_int)
  42 # define        SIOCGETFF       _IOR('r', 63, u_int)
  43 # define        SIOCGETFS       _IOWR('r', 64, struct ipfobj)
  44 # define        SIOCIPFFL       _IOWR('r', 65, int)
  45 # define        SIOCIPFFB       _IOR('r', 66, int)
  46 # define        SIOCADIFR       _IOW('r', 67, struct ipfobj)
  47 # define        SIOCRMIFR       _IOW('r', 68, struct ipfobj)
  48 # define        SIOCSWAPA       _IOR('r', 69, u_int)
  49 # define        SIOCINAFR       _IOW('r', 70, struct ipfobj)
  50 # define        SIOCINIFR       _IOW('r', 71, struct ipfobj)
  51 # define        SIOCFRENB       _IOW('r', 72, u_int)
  52 # define        SIOCFRSYN       _IOW('r', 73, u_int)
  53 # define        SIOCFRZST       _IOWR('r', 74, struct ipfobj)
  54 # define        SIOCZRLST       _IOWR('r', 75, struct ipfobj)
  55 # define        SIOCAUTHW       _IOWR('r', 76, struct ipfobj)
  56 # define        SIOCAUTHR       _IOWR('r', 77, struct ipfobj)
  57 # define        SIOCATHST       _IOWR('r', 78, struct ipfobj)
  58 # define        SIOCSTLCK       _IOWR('r', 79, u_int)
  59 # define        SIOCSTPUT       _IOWR('r', 80, struct ipfobj)
  60 # define        SIOCSTGET       _IOWR('r', 81, struct ipfobj)
  61 # define        SIOCSTGSZ       _IOWR('r', 82, struct ipfobj)
  62 # define        SIOCGFRST       _IOWR('r', 83, struct ipfobj)
  63 # define        SIOCSETLG       _IOWR('r', 84, int)
  64 # define        SIOCGETLG       _IOWR('r', 85, int)
  65 # define        SIOCFUNCL       _IOWR('r', 86, struct ipfunc_resolve)
  66 # define        SIOCIPFGETNEXT  _IOWR('r', 87, struct ipfobj)
  67 # define        SIOCIPFGET      _IOWR('r', 88, struct ipfobj)
  68 # define        SIOCIPFSET      _IOWR('r', 89, struct ipfobj)
  69 # define        SIOCIPFL6       _IOWR('r', 90, int)
  70 # define        SIOCIPFLP       _IOWR('r', 91, int)
  71 # define        SIOCIPFITER     _IOWR('r', 92, struct ipfobj)
  72 # define        SIOCGENITER     _IOWR('r', 93, struct ipfobj)
  73 # define        SIOCGTABL       _IOWR('r', 94, struct ipfobj)
  74 # define        SIOCIPFDELTOK   _IOWR('r', 95, int)
  75 # define        SIOCLOOKUPITER  _IOWR('r', 96, struct ipfobj)
  76 #else
  77 # define        SIOCADAFR       _IOW(r, 60, struct ipfobj)
  78 # define        SIOCRMAFR       _IOW(r, 61, struct ipfobj)
  79 # define        SIOCSETFF       _IOW(r, 62, u_int)
  80 # define        SIOCGETFF       _IOR(r, 63, u_int)
  81 # define        SIOCGETFS       _IOWR(r, 64, struct ipfobj)
  82 # define        SIOCIPFFL       _IOWR(r, 65, int)
  83 # define        SIOCIPFFB       _IOR(r, 66, int)
  84 # define        SIOCADIFR       _IOW(r, 67, struct ipfobj)
  85 # define        SIOCRMIFR       _IOW(r, 68, struct ipfobj)
  86 # define        SIOCSWAPA       _IOR(r, 69, u_int)
  87 # define        SIOCINAFR       _IOW(r, 70, struct ipfobj)
  88 # define        SIOCINIFR       _IOW(r, 71, struct ipfobj)
  89 # define        SIOCFRENB       _IOW(r, 72, u_int)
  90 # define        SIOCFRSYN       _IOW(r, 73, u_int)
  91 # define        SIOCFRZST       _IOWR(r, 74, struct ipfobj)
  92 # define        SIOCZRLST       _IOWR(r, 75, struct ipfobj)
  93 # define        SIOCAUTHW       _IOWR(r, 76, struct ipfobj)
  94 # define        SIOCAUTHR       _IOWR(r, 77, struct ipfobj)
  95 # define        SIOCATHST       _IOWR(r, 78, struct ipfobj)
  96 # define        SIOCSTLCK       _IOWR(r, 79, u_int)
  97 # define        SIOCSTPUT       _IOWR(r, 80, struct ipfobj)
  98 # define        SIOCSTGET       _IOWR(r, 81, struct ipfobj)
  99 # define        SIOCSTGSZ       _IOWR(r, 82, struct ipfobj)
 100 # define        SIOCGFRST       _IOWR(r, 83, struct ipfobj)
 101 # define        SIOCSETLG       _IOWR(r, 84, int)
 102 # define        SIOCGETLG       _IOWR(r, 85, int)
 103 # define        SIOCFUNCL       _IOWR(r, 86, struct ipfunc_resolve)
 104 # define        SIOCIPFGETNEXT  _IOWR(r, 87, struct ipfobj)
 105 # define        SIOCIPFGET      _IOWR(r, 88, struct ipfobj)
 106 # define        SIOCIPFSET      _IOWR(r, 89, struct ipfobj)
 107 # define        SIOCIPFL6       _IOWR(r, 90, int)
 108 # define        SIOCIPFLP       _IOWR(r, 91, int)
 109 # define        SIOCIPFITER     _IOWR(r, 92, struct ipfobj)
 110 # define        SIOCGENITER     _IOWR(r, 93, struct ipfobj)
 111 # define        SIOCGTABL       _IOWR(r, 94, struct ipfobj)
 112 # define        SIOCIPFDELTOK   _IOWR(r, 95, int)
 113 # define        SIOCLOOKUPITER  _IOWR(r, 96, struct ipfobj)
 114 #endif
 115 #define SIOCADDFR       SIOCADAFR
 116 #define SIOCDELFR       SIOCRMAFR
 117 #define SIOCINSFR       SIOCINAFR
 118 # define        SIOCIPFZONESET  _IOWR('r', 97, struct ipfzoneobj)
 119 # define        SIOCIPFCFWCFG   _IOWR('r', 98, struct ipfcfwcfg)
 120 
 121 /*
 122  * What type of table is getting flushed?
 123  */
 124 
 125 #define NAT_FLUSH       1
 126 #define STATE_FLUSH     2
 127 
 128 /*
 129  * What table flush options are available?
 130  */
 131 
 132 #define FLUSH_LIST      0
 133 #define FLUSH_TABLE_ALL         1       /* Flush entire table */
 134 #define FLUSH_TABLE_CLOSING     2       /* Flush "closing" entries" */
 135 #define FLUSH_TABLE_EXTRA       3       /* Targetted flush: almost closed, long idle */
 136 
 137 #define VALID_TABLE_FLUSH_OPT(x)        ((x) >= 1 && (x) <= 3)
 138 
 139 /*
 140  * Define the default hi and lo watermarks used when flushing the
 141  * tables.  The values represent percent full of respective tables.
 142  */
 143 
 144 #define NAT_FLUSH_HI    95
 145 #define NAT_FLUSH_LO    75
 146 
 147 #define ST_FLUSH_HI     95
 148 #define ST_FLUSH_LO     75
 149 
 150 /*
 151  * How full are the tables?
 152  */
 153 
 154 #define NAT_TAB_WATER_LEVEL(x)  ((x)->ifs_nat_stats.ns_inuse * 100 \
 155                                 / (x)->ifs_ipf_nattable_max)
 156 
 157 #define ST_TAB_WATER_LEVEL(x)   ((x)->ifs_ips_num * 100 \
 158                                 / (x)->ifs_fr_statemax)
 159 
 160 struct ipscan;
 161 struct ifnet;
 162 
 163 typedef struct ipf_stack ipf_stack_t;
 164 typedef struct fr_info fr_info_t;
 165 
 166 typedef int     (* lookupfunc_t) __P((void *, int, void *, fr_info_t *, ipf_stack_t *));
 167 
 168 /*
 169  * i6addr is used as a container for both IPv4 and IPv6 addresses, as well
 170  * as other types of objects, depending on its qualifier.
 171  */
 172 #ifdef  USE_INET6
 173 typedef union   i6addr  {
 174         u_32_t  i6[4];
 175         struct  in_addr in4;
 176         struct  in6_addr in6;
 177         void    *vptr[2];
 178         lookupfunc_t    lptr[2];
 179 } i6addr_t;
 180 #define in6_addr8       in6.s6_addr
 181 #else
 182 typedef union   i6addr  {
 183         u_32_t  i6[4];
 184         struct  in_addr in4;
 185         void    *vptr[2];
 186         lookupfunc_t    lptr[2];
 187 } i6addr_t;
 188 #endif
 189 
 190 #define in4_addr        in4.s_addr
 191 #define iplookupnum     i6[0]
 192 #define iplookuptype    i6[1]
 193 /*
 194  * NOTE: These DO overlap the above on 64bit systems and this IS recognised.
 195  */
 196 #define iplookupptr     vptr[0]
 197 #define iplookupfunc    lptr[1]
 198 
 199 #define I60(x)  (((i6addr_t *)(x))->i6[0])
 200 #define I61(x)  (((i6addr_t *)(x))->i6[1])
 201 #define I62(x)  (((i6addr_t *)(x))->i6[2])
 202 #define I63(x)  (((i6addr_t *)(x))->i6[3])
 203 #define HI60(x) ntohl(((i6addr_t *)(x))->i6[0])
 204 #define HI61(x) ntohl(((i6addr_t *)(x))->i6[1])
 205 #define HI62(x) ntohl(((i6addr_t *)(x))->i6[2])
 206 #define HI63(x) ntohl(((i6addr_t *)(x))->i6[3])
 207 
 208 #define IP6_EQ(a,b)     ((I63(a) == I63(b)) && (I62(a) == I62(b)) && \
 209                          (I61(a) == I61(b)) && (I60(a) == I60(b)))
 210 #define IP6_NEQ(a,b)    ((I63(a) != I63(b)) || (I62(a) != I62(b)) || \
 211                          (I61(a) != I61(b)) || (I60(a) != I60(b)))
 212 #define IP6_ISZERO(a)   ((I60(a) | I61(a) | I62(a) | I63(a)) == 0)
 213 #define IP6_NOTZERO(a)  ((I60(a) | I61(a) | I62(a) | I63(a)) != 0)
 214 #define IP6_ISONES(a)   ((I63(a) == 0xffffffff) && (I62(a) == 0xffffffff) && \
 215                          (I61(a) == 0xffffffff) && (I60(a) == 0xffffffff))
 216 #define IP6_GT(a,b)     (ntohl(HI60(a)) > ntohl(HI60(b)) || \
 217                          (HI60(a) == HI60(b) && \
 218                           (ntohl(HI61(a)) > ntohl(HI61(b)) || \
 219                            (HI61(a) == HI61(b) && \
 220                             (ntohl(HI62(a)) > ntohl(HI62(b)) || \
 221                              (HI62(a) == HI62(b) && \
 222                               ntohl(HI63(a)) > ntohl(HI63(b))))))))
 223 #define IP6_LT(a,b)     (ntohl(HI60(a)) < ntohl(HI60(b)) || \
 224                          (HI60(a) == HI60(b) && \
 225                           (ntohl(HI61(a)) < ntohl(HI61(b)) || \
 226                            (HI61(a) == HI61(b) && \
 227                             (ntohl(HI62(a)) < ntohl(HI62(b)) || \
 228                              (HI62(a) == HI62(b) && \
 229                               ntohl(HI63(a)) < ntohl(HI63(b))))))))
 230 #define NLADD(n,x)      htonl(ntohl(n) + (x))
 231 #define IP6_INC(a)      \
 232                 { i6addr_t *_i6 = (i6addr_t *)(a); \
 233                   _i6->i6[3] = NLADD(_i6->i6[3], 1); \
 234                   if (_i6->i6[3] == 0) { \
 235                         _i6->i6[2] = NLADD(_i6->i6[2], 1); \
 236                         if (_i6->i6[2] == 0) { \
 237                                 _i6->i6[1] = NLADD(_i6->i6[1], 1); \
 238                                 if (_i6->i6[1] == 0) { \
 239                                         _i6->i6[0] = NLADD(_i6->i6[0], 1); \
 240                                 } \
 241                         } \
 242                   } \
 243                 }
 244 #define IP6_ADD(a,x,d)  \
 245                 { i6addr_t *_s = (i6addr_t *)(a); \
 246                   i6addr_t *_d = (i6addr_t *)(d); \
 247                   _d->i6[3] = NLADD(_s->i6[3], x); \
 248                   if (ntohl(_d->i6[3]) < ntohl(_s->i6[3])) { \
 249                         _d->i6[2] = NLADD(_d->i6[2], 1); \
 250                         if (ntohl(_d->i6[2]) < ntohl(_s->i6[2])) { \
 251                                 _d->i6[1] = NLADD(_d->i6[1], 1); \
 252                                 if (ntohl(_d->i6[1]) < ntohl(_s->i6[1])) { \
 253                                         _d->i6[0] = NLADD(_d->i6[0], 1); \
 254                                 } \
 255                         } \
 256                   } \
 257                 }
 258 #define IP6_AND(a,b,d)  { i6addr_t *_s1 = (i6addr_t *)(a); \
 259                           i6addr_t *_s2 = (i6addr_t *)(b); \
 260                           i6addr_t *_d = (i6addr_t *)(d); \
 261                           _d->i6[0] = _s1->i6[0] & _s2->i6[0]; \
 262                           _d->i6[1] = _s1->i6[1] & _s2->i6[1]; \
 263                           _d->i6[2] = _s1->i6[2] & _s2->i6[2]; \
 264                           _d->i6[3] = _s1->i6[3] & _s2->i6[3]; \
 265                         }
 266 #define IP6_MASKEQ(a,m,b) \
 267                         (((I60(a) & I60(m)) == I60(b)) && \
 268                          ((I61(a) & I61(m)) == I61(b)) && \
 269                          ((I62(a) & I62(m)) == I62(b)) && \
 270                          ((I63(a) & I63(m)) == I63(b)))
 271 #define IP6_MASKNEQ(a,m,b) \
 272                         (((I60(a) & I60(m)) != I60(b)) || \
 273                          ((I61(a) & I61(m)) != I61(b)) || \
 274                          ((I62(a) & I62(m)) != I62(b)) || \
 275                          ((I63(a) & I63(m)) != I63(b)))
 276 #define IP6_MERGE(a,b,c) \
 277                         { i6addr_t *_d, *_s1, *_s2; \
 278                           _d = (i6addr_t *)(a); \
 279                           _s1 = (i6addr_t *)(b); \
 280                           _s2 = (i6addr_t *)(c); \
 281                           _d->i6[0] |= _s1->i6[0] & ~_s2->i6[0]; \
 282                           _d->i6[1] |= _s1->i6[1] & ~_s2->i6[1]; \
 283                           _d->i6[2] |= _s1->i6[2] & ~_s2->i6[2]; \
 284                           _d->i6[3] |= _s1->i6[3] & ~_s2->i6[3]; \
 285                         }
 286 
 287 
 288 typedef struct  fr_ip   {
 289         u_32_t  fi_v:4;         /* IP version */
 290         u_32_t  fi_xx:4;        /* spare */
 291         u_32_t  fi_tos:8;       /* IP packet TOS */
 292         u_32_t  fi_ttl:8;       /* IP packet TTL */
 293         u_32_t  fi_p:8;         /* IP packet protocol */
 294         u_32_t  fi_optmsk;      /* bitmask composed from IP options */
 295         i6addr_t fi_src;        /* source address from packet */
 296         i6addr_t fi_dst;        /* destination address from packet */
 297         u_short fi_secmsk;      /* bitmask composed from IP security options */
 298         u_short fi_auth;        /* authentication code from IP sec. options */
 299         u_32_t  fi_flx;         /* packet flags */
 300         u_32_t  fi_tcpmsk;      /* TCP options set/reset */
 301         u_32_t  fi_res1;        /* RESERVED */
 302 } fr_ip_t;
 303 
 304 /*
 305  * For use in fi_flx
 306  */
 307 #define FI_TCPUDP       0x0001  /* TCP/UCP implied comparison*/
 308 #define FI_OPTIONS      0x0002
 309 #define FI_FRAG         0x0004
 310 #define FI_SHORT        0x0008
 311 #define FI_NATED        0x0010
 312 #define FI_MULTICAST    0x0020
 313 #define FI_BROADCAST    0x0040
 314 #define FI_MBCAST       0x0080
 315 #define FI_STATE        0x0100
 316 #define FI_BADNAT       0x0200
 317 #define FI_BAD          0x0400
 318 #define FI_OOW          0x0800  /* Out of state window, else match */
 319 #define FI_ICMPERR      0x1000
 320 #define FI_FRAGBODY     0x2000
 321 #define FI_BADSRC       0x4000
 322 #define FI_LOWTTL       0x8000
 323 #define FI_CMP          0xcf03  /* Not FI_FRAG,FI_NATED,FI_FRAGTAIL,broadcast */
 324 #define FI_ICMPCMP      0x0003  /* Flags we can check for ICMP error packets */
 325 #define FI_WITH         0xeffe  /* Not FI_TCPUDP */
 326 #define FI_V6EXTHDR     0x10000
 327 #define FI_COALESCE     0x20000
 328 #define FI_ICMPQUERY    0x40000
 329 #define FI_NEWNAT       0x80000
 330 #define FI_MOREFRAG     0x100000
 331 #define FI_NEG_OOW      0x10000000      /* packet underflows TCP window */
 332 #define FI_NOCKSUM      0x20000000      /* don't do a L4 checksum validation */
 333 #define FI_DONTCACHE    0x40000000      /* don't cache the result */
 334 #define FI_IGNORE       0x80000000
 335 
 336 #define fi_saddr        fi_src.in4.s_addr
 337 #define fi_daddr        fi_dst.in4.s_addr
 338 #define fi_srcnum       fi_src.iplookupnum
 339 #define fi_dstnum       fi_dst.iplookupnum
 340 #define fi_srctype      fi_src.iplookuptype
 341 #define fi_dsttype      fi_dst.iplookuptype
 342 #define fi_srcptr       fi_src.iplookupptr
 343 #define fi_dstptr       fi_dst.iplookupptr
 344 #define fi_srcfunc      fi_src.iplookupfunc
 345 #define fi_dstfunc      fi_dst.iplookupfunc
 346 
 347 
 348 /*
 349  * These are both used by the state and NAT code to indicate that one port or
 350  * the other should be treated as a wildcard.
 351  * NOTE: When updating, check bit masks in ip_state.h and update there too.
 352  */
 353 #define SI_W_SPORT      0x00000100
 354 #define SI_W_DPORT      0x00000200
 355 #define SI_WILDP        (SI_W_SPORT|SI_W_DPORT)
 356 #define SI_W_SADDR      0x00000400
 357 #define SI_W_DADDR      0x00000800
 358 #define SI_WILDA        (SI_W_SADDR|SI_W_DADDR)
 359 #define SI_NEWFR        0x00001000
 360 #define SI_CLONE        0x00002000
 361 #define SI_CLONED       0x00004000
 362 
 363 
 364 
 365 
 366 struct  fr_info {
 367         void    *fin_ifp;               /* interface packet is `on' */
 368         fr_ip_t fin_fi;         /* IP Packet summary */
 369         union   {
 370                 u_short fid_16[2];      /* TCP/UDP ports, ICMP code/type */
 371                 u_32_t  fid_32;
 372         } fin_dat;
 373         int     fin_out;                /* in or out ? 1 == out, 0 == in */
 374         int     fin_rev;                /* state only: 1 = reverse */
 375         u_short fin_hlen;               /* length of IP header in bytes */
 376         u_char  fin_tcpf;               /* TCP header flags (SYN, ACK, etc) */
 377         u_char  fin_icode;              /* ICMP error to return */
 378         u_32_t  fin_rule;               /* rule # last matched */
 379         char    fin_group[FR_GROUPLEN]; /* group number, -1 for none */
 380         struct  frentry *fin_fr;        /* last matching rule */
 381         void    *fin_dp;                /* start of data past IP header */
 382         int     fin_dlen;               /* length of data portion of packet */
 383         int     fin_plen;
 384         int     fin_ipoff;              /* # bytes from buffer start to hdr */
 385         u_32_t  fin_id;                 /* IP packet id field */
 386         u_short fin_off;
 387         int     fin_depth;              /* Group nesting depth */
 388         int     fin_error;              /* Error code to return */
 389         u_int   fin_pktnum;
 390         void    *fin_nattag;
 391         union {
 392                 ip_t    *fip_ip;
 393 #ifdef  USE_INET6
 394                 ip6_t   *fip_ip6;
 395 #endif
 396         } fin_ipu;
 397         mb_t    **fin_mp;               /* pointer to pointer to mbuf */
 398         mb_t    *fin_m;                 /* pointer to mbuf */
 399 #ifdef  MENTAT
 400         mb_t    *fin_qfm;               /* pointer to mblk where pkt starts */
 401         void    *fin_qpi;
 402         ipf_stack_t *fin_ifs;
 403 #endif
 404 #ifdef  __sgi
 405         void    *fin_hbuf;
 406 #endif
 407 };
 408 
 409 #define fin_ip          fin_ipu.fip_ip
 410 #define fin_ip6         fin_ipu.fip_ip6
 411 #define fin_v           fin_fi.fi_v
 412 #define fin_p           fin_fi.fi_p
 413 #define fin_flx         fin_fi.fi_flx
 414 #define fin_optmsk      fin_fi.fi_optmsk
 415 #define fin_secmsk      fin_fi.fi_secmsk
 416 #define fin_auth        fin_fi.fi_auth
 417 #define fin_src         fin_fi.fi_src.in4
 418 #define fin_saddr       fin_fi.fi_saddr
 419 #define fin_dst         fin_fi.fi_dst.in4
 420 #define fin_daddr       fin_fi.fi_daddr
 421 #define fin_data        fin_dat.fid_16
 422 #define fin_sport       fin_dat.fid_16[0]
 423 #define fin_dport       fin_dat.fid_16[1]
 424 #define fin_ports       fin_dat.fid_32
 425 
 426 #ifdef  USE_INET6
 427 # define        fin_src6        fin_fi.fi_src
 428 # define        fin_dst6        fin_fi.fi_dst
 429 # define        fin_dstip6      fin_fi.fi_dst.in6
 430 # define        fin_srcip6      fin_fi.fi_src.in6
 431 #endif
 432 
 433 #define IPF_IN  0
 434 #define IPF_OUT 1
 435 
 436 typedef struct frentry  *(*ipfunc_t) __P((fr_info_t *, u_32_t *));
 437 typedef int             (*ipfuncinit_t) __P((struct frentry *,
 438                                              ipf_stack_t *));
 439 
 440 typedef struct  ipfunc_resolve  {
 441         char            ipfu_name[32];
 442         ipfunc_t        ipfu_addr;
 443         ipfuncinit_t    ipfu_init;
 444 } ipfunc_resolve_t;
 445 
 446 /*
 447  * Size for compares on fr_info structures
 448  */
 449 #define FI_CSIZE        offsetof(fr_info_t, fin_icode)
 450 #define FI_LCSIZE       offsetof(fr_info_t, fin_dp)
 451 
 452 /*
 453  * Size for copying cache fr_info structure
 454  */
 455 #define FI_COPYSIZE     offsetof(fr_info_t, fin_dp)
 456 
 457 /*
 458  * Structure for holding IPFilter's tag information
 459  */
 460 #define IPFTAG_LEN      16
 461 typedef struct  {
 462         union   {
 463                 u_32_t  iptu_num[4];
 464                 char    iptu_tag[IPFTAG_LEN];
 465         } ipt_un;
 466         int     ipt_not;
 467 } ipftag_t;
 468 
 469 #define ipt_tag ipt_un.iptu_tag
 470 #define ipt_num ipt_un.iptu_num
 471 
 472 
 473 /*
 474  * This structure is used to hold information about the next hop for where
 475  * to forward a packet.
 476  */
 477 typedef struct  frdest  {
 478         void    *fd_ifp;
 479         i6addr_t        fd_ip6;
 480         char    fd_ifname[LIFNAMSIZ];
 481 } frdest_t;
 482 
 483 #define fd_ip   fd_ip6.in4
 484 
 485 
 486 /*
 487  * This structure holds information about a port comparison.
 488  */
 489 typedef struct  frpcmp  {
 490         int     frp_cmp;        /* data for port comparisons */
 491         u_short frp_port;       /* top port for <> and >< */
 492         u_short frp_top;        /* top port for <> and >< */
 493 } frpcmp_t;
 494 
 495 #define FR_NONE 0
 496 #define FR_EQUAL 1
 497 #define FR_NEQUAL 2
 498 #define FR_LESST 3
 499 #define FR_GREATERT 4
 500 #define FR_LESSTE 5
 501 #define FR_GREATERTE 6
 502 #define FR_OUTRANGE 7
 503 #define FR_INRANGE 8
 504 #define FR_INCRANGE 9
 505 
 506 /*
 507  * Structure containing all the relevant TCP things that can be checked in
 508  * a filter rule.
 509  */
 510 typedef struct  frtuc   {
 511         u_char          ftu_tcpfm;      /* tcp flags mask */
 512         u_char          ftu_tcpf;       /* tcp flags */
 513         frpcmp_t        ftu_src;
 514         frpcmp_t        ftu_dst;
 515 } frtuc_t;
 516 
 517 #define ftu_scmp        ftu_src.frp_cmp
 518 #define ftu_dcmp        ftu_dst.frp_cmp
 519 #define ftu_sport       ftu_src.frp_port
 520 #define ftu_dport       ftu_dst.frp_port
 521 #define ftu_stop        ftu_src.frp_top
 522 #define ftu_dtop        ftu_dst.frp_top
 523 
 524 #define FR_TCPFMAX      0x3f
 525 
 526 /*
 527  * This structure makes up what is considered to be the IPFilter specific
 528  * matching components of a filter rule, as opposed to the data structures
 529  * used to define the result which are in frentry_t and not here.
 530  */
 531 typedef struct  fripf   {
 532         fr_ip_t fri_ip;
 533         fr_ip_t fri_mip;        /* mask structure */
 534 
 535         u_short fri_icmpm;              /* data for ICMP packets (mask) */
 536         u_short fri_icmp;
 537 
 538         frtuc_t fri_tuc;
 539         int     fri_satype;             /* addres type */
 540         int     fri_datype;             /* addres type */
 541         int     fri_sifpidx;            /* doing dynamic addressing */
 542         int     fri_difpidx;            /* index into fr_ifps[] to use when */
 543 } fripf_t;
 544 
 545 #define fri_dstnum      fri_ip.fi_dstnum
 546 #define fri_srcnum      fri_mip.fi_srcnum
 547 #define fri_dstptr      fri_ip.fi_dstptr
 548 #define fri_srcptr      fri_mip.fi_srcptr
 549 
 550 #define FRI_NORMAL      0       /* Normal address */
 551 #define FRI_DYNAMIC     1       /* dynamic address */
 552 #define FRI_LOOKUP      2       /* address is a pool # */
 553 #define FRI_RANGE       3       /* address/mask is a range */
 554 #define FRI_NETWORK     4       /* network address from if */
 555 #define FRI_BROADCAST   5       /* broadcast address from if */
 556 #define FRI_PEERADDR    6       /* Peer address for P-to-P */
 557 #define FRI_NETMASKED   7       /* network address with netmask from if */
 558 
 559 
 560 typedef struct  frentry * (* frentfunc_t) __P((fr_info_t *));
 561 
 562 typedef struct  frentry {
 563         ipfmutex_t      fr_lock;
 564         struct  frentry *fr_next;
 565         struct  frentry **fr_grp;
 566         struct  ipscan  *fr_isc;
 567         void    *fr_ifas[4];
 568         void    *fr_ptr;        /* for use with fr_arg */
 569         char    *fr_comment;    /* text comment for rule */
 570         int     fr_ref;         /* reference count - for grouping */
 571         int     fr_statecnt;    /* state count - for limit rules */
 572         /*
 573          * These are only incremented when a packet  matches this rule and
 574          * it is the last match
 575          */
 576         U_QUAD_T        fr_hits;
 577         U_QUAD_T        fr_bytes;
 578 
 579         /*
 580          * For PPS rate limiting
 581          */
 582         struct timeval  fr_lastpkt;
 583         int             fr_curpps;
 584 
 585         union   {
 586                 void            *fru_data;
 587                 caddr_t         fru_caddr;
 588                 fripf_t         *fru_ipf;
 589                 frentfunc_t     fru_func;
 590         } fr_dun;
 591 
 592         /*
 593          * Fields after this may not change whilst in the kernel.
 594          */
 595         ipfunc_t fr_func;       /* call this function */
 596         int     fr_dsize;
 597         int     fr_pps;
 598         int     fr_statemax;    /* max reference count */
 599         int     fr_flineno;     /* line number from conf file */
 600         u_32_t  fr_type;
 601         u_32_t  fr_flags;       /* per-rule flags && options (see below) */
 602         u_32_t  fr_logtag;      /* user defined log tag # */
 603         u_32_t  fr_collect;     /* collection number */
 604         uuid_t  fr_uuid;        /* user defined uuid */
 605         u_int   fr_arg;         /* misc. numeric arg for rule */ 
 606         u_int   fr_loglevel;    /* syslog log facility + priority */
 607         u_int   fr_age[2];      /* non-TCP timeouts */
 608         u_char  fr_v;
 609         u_char  fr_icode;       /* return ICMP code */
 610         char    fr_group[FR_GROUPLEN];  /* group to which this rule belongs */
 611         char    fr_grhead[FR_GROUPLEN]; /* group # which this rule starts */
 612         ipftag_t fr_nattag;
 613         char    fr_ifnames[4][LIFNAMSIZ];
 614         char    fr_isctag[16];
 615         frdest_t fr_tifs[2];    /* "to"/"reply-to" interface */
 616         frdest_t fr_dif;        /* duplicate packet interface */
 617         /*
 618          * This must be last and will change after loaded into the kernel.
 619          */
 620         u_int   fr_cksum;       /* checksum on filter rules for performance */
 621 } frentry_t;
 622 
 623 #define fr_caddr        fr_dun.fru_caddr
 624 #define fr_data         fr_dun.fru_data
 625 #define fr_dfunc        fr_dun.fru_func
 626 #define fr_ipf          fr_dun.fru_ipf
 627 #define fr_ip           fr_ipf->fri_ip
 628 #define fr_mip          fr_ipf->fri_mip
 629 #define fr_icmpm        fr_ipf->fri_icmpm
 630 #define fr_icmp         fr_ipf->fri_icmp
 631 #define fr_tuc          fr_ipf->fri_tuc
 632 #define fr_satype       fr_ipf->fri_satype
 633 #define fr_datype       fr_ipf->fri_datype
 634 #define fr_sifpidx      fr_ipf->fri_sifpidx
 635 #define fr_difpidx      fr_ipf->fri_difpidx
 636 #define fr_proto        fr_ip.fi_p
 637 #define fr_mproto       fr_mip.fi_p
 638 #define fr_ttl          fr_ip.fi_ttl
 639 #define fr_mttl         fr_mip.fi_ttl
 640 #define fr_tos          fr_ip.fi_tos
 641 #define fr_mtos         fr_mip.fi_tos
 642 #define fr_tcpfm        fr_tuc.ftu_tcpfm
 643 #define fr_tcpf         fr_tuc.ftu_tcpf
 644 #define fr_scmp         fr_tuc.ftu_scmp
 645 #define fr_dcmp         fr_tuc.ftu_dcmp
 646 #define fr_dport        fr_tuc.ftu_dport
 647 #define fr_sport        fr_tuc.ftu_sport
 648 #define fr_stop         fr_tuc.ftu_stop
 649 #define fr_dtop         fr_tuc.ftu_dtop
 650 #define fr_dst          fr_ip.fi_dst.in4
 651 #define fr_daddr        fr_ip.fi_dst.in4.s_addr
 652 #define fr_src          fr_ip.fi_src.in4
 653 #define fr_saddr        fr_ip.fi_src.in4.s_addr
 654 #define fr_dmsk         fr_mip.fi_dst.in4
 655 #define fr_dmask        fr_mip.fi_dst.in4.s_addr
 656 #define fr_smsk         fr_mip.fi_src.in4
 657 #define fr_smask        fr_mip.fi_src.in4.s_addr
 658 #define fr_dstnum       fr_ip.fi_dstnum
 659 #define fr_srcnum       fr_ip.fi_srcnum
 660 #define fr_dsttype      fr_ip.fi_dsttype
 661 #define fr_srctype      fr_ip.fi_srctype
 662 #define fr_dstptr       fr_mip.fi_dstptr
 663 #define fr_srcptr       fr_mip.fi_srcptr
 664 #define fr_dstfunc      fr_mip.fi_dstfunc
 665 #define fr_srcfunc      fr_mip.fi_srcfunc
 666 #define fr_optbits      fr_ip.fi_optmsk
 667 #define fr_optmask      fr_mip.fi_optmsk
 668 #define fr_secbits      fr_ip.fi_secmsk
 669 #define fr_secmask      fr_mip.fi_secmsk
 670 #define fr_authbits     fr_ip.fi_auth
 671 #define fr_authmask     fr_mip.fi_auth
 672 #define fr_flx          fr_ip.fi_flx
 673 #define fr_mflx         fr_mip.fi_flx
 674 #define fr_ifname       fr_ifnames[0]
 675 #define fr_oifname      fr_ifnames[2]
 676 #define fr_ifa          fr_ifas[0]
 677 #define fr_oifa         fr_ifas[2]
 678 #define fr_tif          fr_tifs[0]
 679 #define fr_rif          fr_tifs[1]
 680 
 681 #define FR_NOLOGTAG     0
 682 
 683 #define FR_CMPSIZ       (sizeof(struct frentry) - \
 684                          offsetof(struct frentry, fr_func))
 685 
 686 /*
 687  * fr_type
 688  */
 689 #define FR_T_NONE       0
 690 #define FR_T_IPF        1       /* IPF structures */
 691 #define FR_T_BPFOPC     2       /* BPF opcode */
 692 #define FR_T_CALLFUNC   3       /* callout to function in fr_func only */
 693 #define FR_T_COMPIPF    4       /* compiled C code */
 694 #define FR_T_BUILTIN    0x80000000      /* rule is in kernel space */
 695 
 696 /*
 697  * fr_flags
 698  */
 699 #define FR_CALL         0x00000 /* call rule */
 700 #define FR_BLOCK        0x00001 /* do not allow packet to pass */
 701 #define FR_PASS         0x00002 /* allow packet to pass */
 702 #define FR_AUTH         0x00003 /* use authentication */
 703 #define FR_PREAUTH      0x00004 /* require preauthentication */
 704 #define FR_ACCOUNT      0x00005 /* Accounting rule */
 705 #define FR_SKIP         0x00006 /* skip rule */
 706 #define FR_DIVERT       0x00007 /* divert rule */
 707 #define FR_CMDMASK      0x0000f
 708 #define FR_LOG          0x00010 /* Log */
 709 #define FR_LOGB         0x00011 /* Log-fail */
 710 #define FR_LOGP         0x00012 /* Log-pass */
 711 #define FR_LOGMASK      (FR_LOG|FR_CMDMASK)
 712 #define FR_CALLNOW      0x00020 /* call another function (fr_func) if matches */
 713 #define FR_NOTSRCIP     0x00040
 714 #define FR_NOTDSTIP     0x00080
 715 #define FR_QUICK        0x00100 /* match & stop processing list */
 716 #define FR_KEEPFRAG     0x00200 /* keep fragment information */
 717 #define FR_KEEPSTATE    0x00400 /* keep `connection' state information */
 718 #define FR_FASTROUTE    0x00800 /* bypass normal routing */
 719 #define FR_RETRST       0x01000 /* Return TCP RST packet - reset connection */
 720 #define FR_RETICMP      0x02000 /* Return ICMP unreachable packet */
 721 #define FR_FAKEICMP     0x03000 /* Return ICMP unreachable with fake source */
 722 #define FR_OUTQUE       0x04000 /* outgoing packets */
 723 #define FR_INQUE        0x08000 /* ingoing packets */
 724 #define FR_LOGBODY      0x10000 /* Log the body */
 725 #define FR_LOGFIRST     0x20000 /* Log the first byte if state held */
 726 #define FR_LOGORBLOCK   0x40000 /* block the packet if it can't be logged */
 727 #define FR_DUP          0x80000 /* duplicate packet */
 728 #define FR_FRSTRICT     0x100000        /* strict frag. cache */
 729 #define FR_STSTRICT     0x200000        /* strict keep state */
 730 #define FR_NEWISN       0x400000        /* new ISN for outgoing TCP */
 731 #define FR_NOICMPERR    0x800000        /* do not match ICMP errors in state */
 732 #define FR_STATESYNC    0x1000000       /* synchronize state to slave */
 733 #define FR_CFWLOG       0x2000000       /* Global CFW logging enabled */
 734 #define FR_NOMATCH      0x8000000       /* no match occured */
 735                 /*      0x10000000      FF_LOGPASS */
 736                 /*      0x20000000      FF_LOGBLOCK */
 737                 /*      0x40000000      FF_LOGNOMATCH */
 738                 /*      0x80000000      FF_BLOCKNONIP */
 739 #define FR_COPIED       0x40000000      /* copied from user space */
 740 #define FR_INACTIVE     0x80000000      /* only used when flush'ing rules */
 741 
 742 #define FR_RETMASK      (FR_RETICMP|FR_RETRST|FR_FAKEICMP)
 743 #define FR_ISBLOCK(x)   (((x) & FR_CMDMASK) == FR_BLOCK)
 744 #define FR_ISPASS(x)    (((x) & FR_CMDMASK) == FR_PASS)
 745 #define FR_ISAUTH(x)    (((x) & FR_CMDMASK) == FR_AUTH)
 746 #define FR_ISPREAUTH(x) (((x) & FR_CMDMASK) == FR_PREAUTH)
 747 #define FR_ISACCOUNT(x) (((x) & FR_CMDMASK) == FR_ACCOUNT)
 748 #define FR_ISSKIP(x)    (((x) & FR_CMDMASK) == FR_SKIP)
 749 #define FR_ISNOMATCH(x) ((x) & FR_NOMATCH)
 750 #define FR_INOUT        (FR_INQUE|FR_OUTQUE)
 751 
 752 /*
 753  * recognized flags for SIOCGETFF and SIOCSETFF, and get put in fr_flags
 754  */
 755 #define FF_LOGPASS      0x10000000
 756 #define FF_LOGBLOCK     0x20000000
 757 #define FF_LOGNOMATCH   0x40000000
 758 #define FF_LOGGING      (FF_LOGPASS|FF_LOGBLOCK|FF_LOGNOMATCH)
 759 #define FF_BLOCKNONIP   0x80000000      /* Solaris2 Only */
 760 
 761 
 762 /*
 763  * Structure that passes information on what/how to flush to the kernel.
 764  */
 765 typedef struct  ipfflush        {
 766         int     ipflu_how;
 767         int     ipflu_arg;
 768 } ipfflush_t;
 769 
 770 
 771 /*
 772  *
 773  */
 774 typedef struct  ipfgetctl       {
 775         u_int   ipfg_min;       /* min value */
 776         u_int   ipfg_current;   /* current value */
 777         u_int   ipfg_max;       /* max value */
 778         u_int   ipfg_default;   /* default value */
 779         u_int   ipfg_steps;     /* value increments */
 780         char    ipfg_name[40];  /* tag name for this control */
 781 } ipfgetctl_t;
 782 
 783 typedef struct  ipfsetctl       {
 784         int     ipfs_which;     /* 0 = min 1 = current 2 = max 3 = default */
 785         u_int   ipfs_value;     /* min value */
 786         char    ipfs_name[40];  /* tag name for this control */
 787 } ipfsetctl_t;
 788 
 789 
 790 /*
 791  * Some of the statistics below are in their own counters, but most are kept
 792  * in this single structure so that they can all easily be collected and
 793  * copied back as required.
 794  *
 795  * NOTE: when changing, keep in sync with kstats (below).
 796  */
 797 typedef struct  filterstats {
 798         u_long  fr_pass;        /* packets allowed */
 799         u_long  fr_block;       /* packets denied */
 800         u_long  fr_nom;         /* packets which don't match any rule */
 801         u_long  fr_short;       /* packets which are short */
 802         u_long  fr_ppkl;        /* packets allowed and logged */
 803         u_long  fr_bpkl;        /* packets denied and logged */
 804         u_long  fr_npkl;        /* packets unmatched and logged */
 805         u_long  fr_pkl;         /* packets logged */
 806         u_long  fr_skip;        /* packets to be logged but buffer full */
 807         u_long  fr_ret;         /* packets for which a return is sent */
 808         u_long  fr_acct;        /* packets for which counting was performed */
 809         u_long  fr_bnfr;        /* bad attempts to allocate fragment state */
 810         u_long  fr_nfr;         /* new fragment state kept */
 811         u_long  fr_cfr;         /* add new fragment state but complete pkt */
 812         u_long  fr_bads;        /* bad attempts to allocate packet state */
 813         u_long  fr_ads;         /* new packet state kept */
 814         u_long  fr_chit;        /* cached hit */
 815         u_long  fr_tcpbad;      /* TCP checksum check failures */
 816         u_long  fr_pull[2];     /* good and bad pullup attempts */
 817         u_long  fr_badsrc;      /* source received doesn't match route */
 818         u_long  fr_badttl;      /* TTL in packet doesn't reach minimum */
 819         u_long  fr_bad;         /* bad IP packets to the filter */
 820         u_long  fr_ipv6;        /* IPv6 packets in/out */
 821         u_long  fr_ppshit;      /* dropped because of pps ceiling */
 822         u_long  fr_ipud;        /* IP id update failures */
 823 } filterstats_t;
 824 
 825 /*
 826  * kstat "copy" of the above - keep in sync!
 827  * also keep in sync with initialisation code in solaris.c, ipf_kstat_init().
 828  */
 829 typedef struct  filter_kstats {
 830         kstat_named_t   fks_pass;       /* see above for comments */
 831         kstat_named_t   fks_block;
 832         kstat_named_t   fks_nom;
 833         kstat_named_t   fks_short;
 834         kstat_named_t   fks_ppkl;
 835         kstat_named_t   fks_bpkl;
 836         kstat_named_t   fks_npkl;
 837         kstat_named_t   fks_pkl;
 838         kstat_named_t   fks_skip;
 839         kstat_named_t   fks_ret;
 840         kstat_named_t   fks_acct;
 841         kstat_named_t   fks_bnfr;
 842         kstat_named_t   fks_nfr;
 843         kstat_named_t   fks_cfr;
 844         kstat_named_t   fks_bads;
 845         kstat_named_t   fks_ads;
 846         kstat_named_t   fks_chit;
 847         kstat_named_t   fks_tcpbad;
 848         kstat_named_t   fks_pull[2];
 849         kstat_named_t   fks_badsrc;
 850         kstat_named_t   fks_badttl;
 851         kstat_named_t   fks_bad;
 852         kstat_named_t   fks_ipv6;
 853         kstat_named_t   fks_ppshit;
 854         kstat_named_t   fks_ipud;
 855 } filter_kstats_t;
 856 
 857 /*
 858  * Log structure.  Each packet header logged is prepended by one of these.
 859  * Following this in the log records read from the device will be an ipflog
 860  * structure which is then followed by any packet data.
 861  */
 862 typedef struct  iplog   {
 863         u_32_t          ipl_magic;
 864         u_int           ipl_count;
 865         struct  timeval ipl_time;
 866         size_t          ipl_dsize;
 867         struct  iplog   *ipl_next;
 868 } iplog_t;
 869 
 870 #define ipl_sec         ipl_time.tv_sec
 871 #define ipl_usec        ipl_time.tv_usec
 872 
 873 #define IPL_MAGIC       0x49504c4d      /* 'IPLM' */
 874 #define IPL_MAGIC_NAT   0x49504c4e      /* 'IPLN' */
 875 #define IPL_MAGIC_STATE 0x49504c53      /* 'IPLS' */
 876 #define IPLOG_SIZE      sizeof(iplog_t)
 877 
 878 typedef struct  ipflog  {
 879 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
 880         (defined(OpenBSD) && (OpenBSD >= 199603))
 881 #else
 882         u_int   fl_unit;
 883 #endif
 884         u_32_t  fl_rule;
 885         u_32_t  fl_flags;
 886         u_32_t  fl_lflags;
 887         u_32_t  fl_logtag;
 888         ipftag_t        fl_nattag;
 889         uuid_t  fl_uuid;
 890         u_short fl_plen;        /* extra data after hlen */
 891         u_short fl_loglevel;    /* syslog log level */
 892         char    fl_group[FR_GROUPLEN];
 893         u_char  fl_hlen;        /* length of IP headers saved */
 894         u_char  fl_dir;
 895         u_char  fl_xxx[2];      /* pad */
 896         char    fl_ifname[LIFNAMSIZ];
 897 } ipflog_t;
 898 
 899 #ifndef IPF_LOGGING
 900 # define        IPF_LOGGING     0
 901 #endif
 902 #ifndef IPF_DEFAULT_PASS
 903 # define        IPF_DEFAULT_PASS        FR_PASS
 904 #endif
 905 
 906 #define DEFAULT_IPFLOGSIZE      8192
 907 #ifndef IPFILTER_LOGSIZE
 908 # define        IPFILTER_LOGSIZE        DEFAULT_IPFLOGSIZE
 909 #else
 910 # if IPFILTER_LOGSIZE < DEFAULT_IPFLOGSIZE
 911 #  error IPFILTER_LOGSIZE too small.  Must be >= DEFAULT_IPFLOGSIZE
 912 # endif
 913 #endif
 914 
 915 #define IPF_OPTCOPY     0x07ff00        /* bit mask of copied options */
 916 
 917 /*
 918  * Device filenames for reading log information.  Use ipf on Solaris2 because
 919  * ipl is already a name used by something else.
 920  */
 921 #ifndef IPL_NAME
 922 # ifdef SOLARIS
 923 #  define       IPL_NAME        "/dev/ipf"
 924 # else
 925 #  define       IPL_NAME        "/dev/ipl"
 926 # endif
 927 #endif
 928 /*
 929  * Pathnames for various IP Filter control devices.  Used by LKM
 930  * and userland, so defined here.
 931  */
 932 #define IPNAT_NAME      "/dev/ipnat"
 933 #define IPSTATE_NAME    "/dev/ipstate"
 934 #define IPAUTH_NAME     "/dev/ipauth"
 935 #define IPSYNC_NAME     "/dev/ipsync"
 936 #define IPSCAN_NAME     "/dev/ipscan"
 937 #define IPLOOKUP_NAME   "/dev/iplookup"
 938 #define IPFEV_NAME      "/dev/ipfev"
 939 
 940 #define IPL_LOGIPF      0       /* Minor device #'s for accessing logs */
 941 #define IPL_LOGNAT      1
 942 #define IPL_LOGSTATE    2
 943 #define IPL_LOGAUTH     3
 944 #define IPL_LOGSYNC     4
 945 #define IPL_LOGSCAN     5
 946 #define IPL_LOGLOOKUP   6
 947 #define IPL_LOGEV       7
 948 #define IPL_LOGCOUNT    8
 949 #define IPL_LOGMAX      8
 950 #define IPL_LOGSIZE     (IPL_LOGMAX + 1)
 951 #define IPL_LOGALL      -1
 952 #define IPL_LOGNONE     -2
 953 
 954 /*
 955  * For SIOCGETFS
 956  */
 957 typedef struct  friostat        {
 958         struct  filterstats     f_st[2];
 959         struct  frentry         *f_ipf[2][2];
 960         struct  frentry         *f_acct[2][2];
 961         struct  frentry         *f_ipf6[2][2];
 962         struct  frentry         *f_acct6[2][2];
 963         struct  frentry         *f_auth;
 964         struct  frgroup         *f_groups[IPL_LOGSIZE][2];
 965         u_long  f_froute[2];
 966         u_long  f_ticks;
 967         int     f_locks[IPL_LOGMAX];
 968         size_t  f_kmutex_sz;
 969         size_t  f_krwlock_sz;
 970         int     f_defpass;      /* default pass - from fr_pass */
 971         int     f_active;       /* 1 or 0 - active rule set */
 972         int     f_running;      /* 1 if running, else 0 */
 973         int     f_logging;      /* 1 if enabled, else 0 */
 974         int     f_features;
 975         char    f_version[32];  /* version string */
 976 } friostat_t;
 977 
 978 #define f_fin           f_ipf[0]
 979 #define f_fin6          f_ipf6[0]
 980 #define f_fout          f_ipf[1]
 981 #define f_fout6         f_ipf6[1]
 982 #define f_acctin        f_acct[0]
 983 #define f_acctin6       f_acct6[0]
 984 #define f_acctout       f_acct[1]
 985 #define f_acctout6      f_acct6[1]
 986 
 987 #define IPF_FEAT_LKM            0x001
 988 #define IPF_FEAT_LOG            0x002
 989 #define IPF_FEAT_LOOKUP         0x004
 990 #define IPF_FEAT_BPF            0x008
 991 #define IPF_FEAT_COMPILED       0x010
 992 #define IPF_FEAT_CKSUM          0x020
 993 #define IPF_FEAT_SYNC           0x040
 994 #define IPF_FEAT_SCAN           0x080
 995 #define IPF_FEAT_IPV6           0x100
 996 
 997 typedef struct  optlist {
 998         u_short ol_val;
 999         int     ol_bit;
1000 } optlist_t;
1001 
1002 
1003 /*
1004  * Group list structure.
1005  */
1006 typedef struct frgroup {
1007         struct  frgroup *fg_next;
1008         struct  frentry *fg_head;
1009         struct  frentry *fg_start;
1010         u_32_t  fg_flags;
1011         int     fg_ref;
1012         char    fg_name[FR_GROUPLEN];
1013 } frgroup_t;
1014 
1015 #define FG_NAME(g)      (*(g)->fg_name == '\0' ? "" : (g)->fg_name)
1016 
1017 
1018 /*
1019  * Used by state and NAT tables
1020  */
1021 typedef struct icmpinfo {
1022         u_short ici_id;
1023         u_short ici_seq;
1024         u_char  ici_type;
1025 } icmpinfo_t;
1026 
1027 typedef struct udpinfo {
1028         u_short us_sport;
1029         u_short us_dport;
1030 } udpinfo_t;
1031 
1032 
1033 typedef struct  tcpdata {
1034         u_32_t  td_end;
1035         u_32_t  td_maxend;
1036         u_32_t  td_maxwin;
1037         u_32_t  td_winscale;
1038         u_32_t  td_maxseg;
1039         int     td_winflags;
1040 } tcpdata_t;
1041 
1042 #define TCP_WSCALE_MAX          14
1043 
1044 #define TCP_WSCALE_SEEN         0x00000001
1045 #define TCP_WSCALE_FIRST        0x00000002
1046 #define TCP_SACK_PERMIT         0x00000004
1047 
1048 
1049 typedef struct tcpinfo {
1050         u_short ts_sport;
1051         u_short ts_dport;
1052         tcpdata_t ts_data[2];
1053 } tcpinfo_t;
1054 
1055 
1056 /*
1057  * Structures to define a GRE header as seen in a packet.
1058  */
1059 struct  grebits {
1060         u_32_t  grb_C:1;
1061         u_32_t  grb_R:1;
1062         u_32_t  grb_K:1;
1063         u_32_t  grb_S:1;
1064         u_32_t  grb_s:1;
1065         u_32_t  grb_recur:1;
1066         u_32_t  grb_A:1;
1067         u_32_t  grb_flags:3;
1068         u_32_t  grb_ver:3;
1069         u_short grb_ptype;
1070 };
1071 
1072 typedef struct  grehdr  {
1073         union   {
1074                 struct  grebits gru_bits;
1075                 u_short gru_flags;
1076         } gr_un;
1077         u_short gr_len;
1078         u_short gr_call;
1079 } grehdr_t;
1080 
1081 #define gr_flags        gr_un.gru_flags
1082 #define gr_bits         gr_un.gru_bits
1083 #define gr_ptype        gr_bits.grb_ptype
1084 #define gr_C            gr_bits.grb_C
1085 #define gr_R            gr_bits.grb_R
1086 #define gr_K            gr_bits.grb_K
1087 #define gr_S            gr_bits.grb_S
1088 #define gr_s            gr_bits.grb_s
1089 #define gr_recur        gr_bits.grb_recur
1090 #define gr_A            gr_bits.grb_A
1091 #define gr_ver          gr_bits.grb_ver
1092 
1093 /*
1094  * GRE information tracked by "keep state"
1095  */
1096 typedef struct  greinfo {
1097         u_short gs_call[2];
1098         u_short gs_flags;
1099         u_short gs_ptype;
1100 } greinfo_t;
1101 
1102 #define GRE_REV(x)      ((ntohs(x) >> 13) & 7)
1103 
1104 
1105 /*
1106  * Format of an Authentication header
1107  */
1108 typedef struct  authhdr {
1109         u_char  ah_next;
1110         u_char  ah_plen;
1111         u_short ah_reserved;
1112         u_32_t  ah_spi;
1113         u_32_t  ah_seq;
1114         /* Following the sequence number field is 0 or more bytes of */
1115         /* authentication data, as specified by ah_plen - RFC 2402.  */
1116 } authhdr_t;
1117 
1118 
1119 /*
1120  * Timeout tail queue list member
1121  */
1122 typedef struct  ipftqent        {
1123         struct ipftqent **tqe_pnext;
1124         struct ipftqent *tqe_next;
1125         struct  ipftq   *tqe_ifq;
1126         void    *tqe_parent;            /* pointer back to NAT/state struct */
1127         u_long  tqe_die;                /* when this entriy is to die */
1128         u_long  tqe_touched;
1129         int     tqe_flags;
1130         int     tqe_state[2];           /* current state of this entry */
1131 } ipftqent_t;
1132 
1133 #define TQE_RULEBASED   0x00000001
1134 
1135 
1136 /*
1137  * Timeout tail queue head for IPFilter
1138  */
1139 typedef struct  ipftq   {
1140         ipfmutex_t      ifq_lock;
1141         u_int   ifq_ttl;
1142         ipftqent_t      *ifq_head;
1143         ipftqent_t      **ifq_tail;
1144         struct  ipftq   *ifq_next;
1145         struct  ipftq   **ifq_pnext;
1146         int     ifq_ref;
1147         u_int   ifq_flags;
1148 } ipftq_t;
1149 
1150 #define IFQF_USER       0x01            /* User defined aging */
1151 #define IFQF_DELETE     0x02            /* Marked for deletion */
1152 #define IFQF_PROXY      0x04            /* Timeout queue in use by a proxy */
1153 
1154 #define IPF_HZ_MULT     1
1155 #define IPF_HZ_DIVIDE   2               /* How many times a second ipfilter */
1156                                         /* checks its timeout queues.       */
1157 #define IPF_TTLVAL(x)   (((x) / IPF_HZ_MULT) * IPF_HZ_DIVIDE)
1158 
1159 /*
1160  * Structure to define address for pool lookups.
1161  */
1162 typedef struct  {
1163         u_char          adf_len;
1164         sa_family_t     adf_family;
1165         i6addr_t        adf_addr;
1166 } addrfamily_t;
1167 
1168 
1169 /*
1170  * Object structure description.  For passing through in ioctls.
1171  */
1172 typedef struct  ipfobj  {
1173         u_32_t  ipfo_rev;               /* IPFilter version number */
1174         u_32_t  ipfo_size;              /* size of object at ipfo_ptr */
1175         void    *ipfo_ptr;              /* pointer to object */
1176         int     ipfo_type;              /* type of object being pointed to */
1177         int     ipfo_offset;            /* bytes from ipfo_ptr where to start */
1178         u_char  ipfo_xxxpad[32];        /* reserved for future use */
1179 } ipfobj_t;
1180 
1181 /*
1182  * ioctl struct for setting what zone further ioctls will act on. ipfz_gz is a
1183  * boolean: set it to 1 to operate on the GZ-controlled stack.
1184  */
1185 typedef struct  ipfzoneobj      {
1186         u_32_t          ipfz_gz;                        /* GZ stack boolean */
1187         char            ipfz_zonename[ZONENAME_MAX];    /* zone to act on */
1188 } ipfzoneobj_t;
1189 
1190 /* ioctl to grab CFW logging parameters */
1191 typedef struct ipfcfwcfg {
1192         uint32_t ipfcfwc_maxevsize;
1193         uint32_t ipfcfwc_evringsize;
1194 } ipfcfwcfg_t;
1195 
1196 #if defined(_KERNEL)
1197 /* Set ipfs_zoneid to this if no zone has been set: */
1198 #define IPFS_ZONE_UNSET -2
1199 
1200 typedef struct  ipf_devstate    {
1201         zoneid_t        ipfs_zoneid;
1202         minor_t         ipfs_minor;
1203         boolean_t       ipfs_gz;
1204 } ipf_devstate_t;
1205 #endif
1206 
1207 #define IPFOBJ_FRENTRY          0       /* struct frentry */
1208 #define IPFOBJ_IPFSTAT          1       /* struct friostat */
1209 #define IPFOBJ_IPFINFO          2       /* struct fr_info */
1210 #define IPFOBJ_AUTHSTAT         3       /* struct fr_authstat */
1211 #define IPFOBJ_FRAGSTAT         4       /* struct ipfrstat */
1212 #define IPFOBJ_IPNAT            5       /* struct ipnat */
1213 #define IPFOBJ_NATSTAT          6       /* struct natstat */
1214 #define IPFOBJ_STATESAVE        7       /* struct ipstate_save */
1215 #define IPFOBJ_NATSAVE          8       /* struct nat_save */
1216 #define IPFOBJ_NATLOOKUP        9       /* struct natlookup */
1217 #define IPFOBJ_IPSTATE          10      /* struct ipstate */
1218 #define IPFOBJ_STATESTAT        11      /* struct ips_stat */
1219 #define IPFOBJ_FRAUTH           12      /* struct frauth */
1220 #define IPFOBJ_TUNEABLE         13      /* struct ipftune */
1221 #define IPFOBJ_NAT              14      /* struct nat */
1222 #define IPFOBJ_IPFITER          15      /* struct ipfruleiter */
1223 #define IPFOBJ_GENITER          16      /* struct ipfgeniter */
1224 #define IPFOBJ_GTABLE           17      /* struct ipftable */
1225 #define IPFOBJ_LOOKUPITER       18      /* struct ipflookupiter */
1226 #define IPFOBJ_COUNT            19      /* How many #defines are above this? */
1227 
1228 
1229 typedef union   ipftunevalptr   {
1230         void    *ipftp_void;
1231         u_long  *ipftp_long;
1232         u_int   *ipftp_int;
1233         u_short *ipftp_short;
1234         u_char  *ipftp_char;
1235 } ipftunevalptr_t;
1236 
1237 typedef struct  ipftuneable     {
1238         ipftunevalptr_t ipft_una;
1239         char            *ipft_name;
1240         u_long          ipft_min;
1241         u_long          ipft_max;
1242         int             ipft_sz;
1243         int             ipft_flags;
1244         struct ipftuneable *ipft_next;
1245 } ipftuneable_t;
1246 
1247 #define ipft_addr       ipft_una.ipftp_void
1248 #define ipft_plong      ipft_una.ipftp_long
1249 #define ipft_pint       ipft_una.ipftp_int
1250 #define ipft_pshort     ipft_una.ipftp_short
1251 #define ipft_pchar      ipft_una.ipftp_char
1252 
1253 #define IPFT_RDONLY     1       /* read-only */
1254 #define IPFT_WRDISABLED 2       /* write when disabled only */
1255 
1256 typedef union   ipftuneval      {
1257         u_long  ipftu_long;
1258         u_int   ipftu_int;
1259         u_short ipftu_short;
1260         u_char  ipftu_char;
1261 } ipftuneval_t;
1262 
1263 typedef struct  ipftune {
1264         void            *ipft_cookie;
1265         ipftuneval_t    ipft_un;
1266         u_long          ipft_min;
1267         u_long          ipft_max;
1268         int             ipft_sz;
1269         int             ipft_flags;
1270         char            ipft_name[80];
1271 } ipftune_t;
1272 
1273 #define ipft_vlong      ipft_un.ipftu_long
1274 #define ipft_vint       ipft_un.ipftu_int
1275 #define ipft_vshort     ipft_un.ipftu_short
1276 #define ipft_vchar      ipft_un.ipftu_char
1277 
1278 /*
1279  * ipfruleiter is iterator structure used for filter rules.
1280  */
1281 typedef struct  ipfruleiter {
1282         int             iri_ver;
1283         int             iri_inout;
1284         char            iri_group[FR_GROUPLEN];
1285         int             iri_active;
1286         int             iri_nrules;
1287         frentry_t       *iri_rule;
1288 } ipfruleiter_t;
1289 
1290 /* Values for iri_inout  */
1291 #define F_IN    0
1292 #define F_OUT   1
1293 #define F_ACIN  2
1294 #define F_ACOUT 3
1295 
1296 /*
1297  * ipfgeniter is generic iterator structure used for nat rules,
1298  * hostmap entries and nat table entries.
1299  */
1300 typedef struct  ipfgeniter {
1301         int     igi_type;       /* type of data we're looking at */
1302         int     igi_nitems;
1303         void    *igi_data;
1304 } ipfgeniter_t;
1305 
1306 #define IPFGENITER_IPF          0
1307 #define IPFGENITER_NAT          1
1308 #define IPFGENITER_IPNAT        2
1309 #define IPFGENITER_FRAG         3
1310 #define IPFGENITER_AUTH         4
1311 #define IPFGENITER_STATE        5
1312 #define IPFGENITER_NATFRAG      6
1313 #define IPFGENITER_HOSTMAP      7
1314 #define IPFGENITER_LOOKUP       8
1315 
1316 typedef struct  ipftable {
1317         int     ita_type;
1318         void    *ita_table;
1319 } ipftable_t;
1320 
1321 typedef struct ipftoken {
1322         struct ipftoken *ipt_next;
1323         struct ipftoken **ipt_pnext;
1324         void            *ipt_ctx;
1325         void            *ipt_data;
1326         u_long          ipt_die;
1327         int             ipt_type;
1328         int             ipt_uid;
1329         int             ipt_subtype;
1330         int             ipt_alive;
1331 } ipftoken_t;
1332 
1333 
1334 /*
1335  * sync commands
1336  */
1337 #define IPFSYNC_RESYNC  0
1338 #define IPFSYNC_NEWIFP  1
1339 #define IPFSYNC_OLDIFP  2
1340 
1341 
1342 /*
1343 ** HPUX Port
1344 */
1345 #ifdef __hpux
1346 /* HP-UX locking sequence deadlock detection module lock MAJOR ID */
1347 # define        IPF_SMAJ        0       /* temp assignment XXX, not critical */
1348 #endif
1349 
1350 #if !defined(CDEV_MAJOR) && defined (__FreeBSD_version) && \
1351     (__FreeBSD_version >= 220000)
1352 # define        CDEV_MAJOR      79
1353 #endif
1354 
1355 /*
1356  * Post NetBSD 1.2 has the PFIL interface for packet filters.  This turns
1357  * on those hooks.  We don't need any special mods in non-IP Filter code
1358  * with this!
1359  */
1360 #if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \
1361     (defined(NetBSD1_2) && NetBSD1_2 > 1) || \
1362     (defined(__FreeBSD__) && (__FreeBSD_version >= 500043))
1363 # if (NetBSD >= 199905)
1364 #  define PFIL_HOOKS
1365 # endif
1366 # ifdef PFIL_HOOKS
1367 #  define NETBSD_PF
1368 # endif
1369 #endif
1370 
1371 #ifndef _KERNEL
1372 extern  int     fr_check __P((struct ip *, int, void *, int, mb_t **, ipf_stack_t *));
1373 extern  int     (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **, ipf_stack_t *));
1374 extern  int     ipf_log __P((void));
1375 extern  struct  ifnet *get_unit __P((char *, int, ipf_stack_t *));
1376 extern  char    *get_ifname __P((struct ifnet *));
1377 # if defined(__NetBSD__) || defined(__OpenBSD__) || \
1378           (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
1379 extern  int     frrequest __P((int, u_long, caddr_t, int, int, ipf_stack_t *));
1380 # else
1381 extern  int     iplioctl __P((int, ioctlcmd_t, caddr_t, int));
1382 # endif
1383 extern  int     iplopen __P((dev_t, int));
1384 extern  int     iplclose __P((dev_t, int));
1385 extern  void    m_freem __P((mb_t *));
1386 #else /* #ifndef _KERNEL */
1387 extern  phy_if_t        get_unit __P((char *, int, ipf_stack_t *));
1388 # if defined(__NetBSD__) && defined(PFIL_HOOKS)
1389 extern  void    ipfilterattach __P((int));
1390 # endif
1391 extern  int     ipl_enable __P((void));
1392 extern  int     ipl_disable __P((void));
1393 # ifdef MENTAT
1394 extern  int     fr_check __P((struct ip *, int, void *, int, void *,
1395                               mblk_t **, ipf_stack_t *));
1396 #  if SOLARIS
1397 #   if SOLARIS2 >= 7
1398 extern  int     iplioctl __P((dev_t, int, intptr_t, int, cred_t *, int *));
1399 #   else
1400 extern  int     iplioctl __P((dev_t, int, int *, int, cred_t *, int *));
1401 #   endif
1402 #   if SOLARIS2 >= 10 && defined(_KERNEL)
1403 extern  int     fr_make_rst __P((fr_info_t *));
1404 extern  int     fr_make_icmp __P((fr_info_t *));
1405 extern  void    fr_calc_chksum __P((fr_info_t *, mb_t *));
1406 extern  ipf_stack_t *ipf_find_stack(const zoneid_t, ipf_devstate_t *);
1407 #   endif
1408 extern  int     iplopen __P((dev_t *, int, int, cred_t *));
1409 extern  int     iplclose __P((dev_t, int, int, cred_t *));
1410 extern  int     iplread __P((dev_t, uio_t *, cred_t *));
1411 extern  int     iplwrite __P((dev_t, uio_t *, cred_t *));
1412 #  endif
1413 #  ifdef __hpux
1414 extern  int     iplopen __P((dev_t, int, intptr_t, int));
1415 extern  int     iplclose __P((dev_t, int, int));
1416 extern  int     iplioctl __P((dev_t, int, caddr_t, int));
1417 extern  int     iplread __P((dev_t, uio_t *));
1418 extern  int     iplwrite __P((dev_t, uio_t *));
1419 extern  int     iplselect __P((dev_t, int));
1420 #  endif
1421 extern  int     ipfsync __P((ipf_stack_t *));
1422 extern  int     fr_qout __P((queue_t *, mblk_t *));
1423 # else /* MENTAT */
1424 extern  int     fr_check __P((struct ip *, int, void *, int, mb_t **, ipf_stack_t *));
1425 extern  int     (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **, ipf_stack_t *));
1426 extern  size_t  mbufchainlen __P((mb_t *));
1427 #  ifdef        __sgi
1428 #   include <sys/cred.h>
1429 extern  int     iplioctl __P((dev_t, int, caddr_t, int, cred_t *, int *));
1430 extern  int     iplopen __P((dev_t *, int, int, cred_t *));
1431 extern  int     iplclose __P((dev_t, int, int, cred_t *));
1432 extern  int     iplread __P((dev_t, uio_t *, cred_t *));
1433 extern  int     iplwrite __P((dev_t, uio_t *, cred_t *));
1434 extern  int     ipfsync __P((ipf_stack_t *));
1435 extern  int     ipfilter_sgi_attach __P((void));
1436 extern  void    ipfilter_sgi_detach __P((void));
1437 extern  void    ipfilter_sgi_intfsync __P((void));
1438 #  else
1439 #   ifdef       IPFILTER_LKM
1440 extern  int     iplidentify __P((char *));
1441 #   endif
1442 #   if (_BSDI_VERSION >= 199510) || (__FreeBSD_version >= 220000) || \
1443       (NetBSD >= 199511) || defined(__OpenBSD__)
1444 #    if defined(__NetBSD__) || (_BSDI_VERSION >= 199701) || \
1445        defined(__OpenBSD__) || (__FreeBSD_version >= 300000)
1446 #     if (__FreeBSD_version >= 500024)
1447 #      if (__FreeBSD_version >= 502116)
1448 extern  int     iplioctl __P((struct cdev*, u_long, caddr_t, int, struct thread *));
1449 #      else
1450 extern  int     iplioctl __P((dev_t, u_long, caddr_t, int, struct thread *));
1451 #      endif /* __FreeBSD_version >= 502116 */
1452 #     else
1453 extern  int     iplioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
1454 #     endif /* __FreeBSD_version >= 500024 */
1455 #    else
1456 extern  int     iplioctl __P((dev_t, int, caddr_t, int, struct proc *));
1457 #    endif
1458 #    if (__FreeBSD_version >= 500024)
1459 #      if (__FreeBSD_version >= 502116)
1460 extern  int     iplopen __P((struct cdev*, int, int, struct thread *));
1461 extern  int     iplclose __P((struct cdev*, int, int, struct thread *));
1462 #      else
1463 extern  int     iplopen __P((dev_t, int, int, struct thread *));
1464 extern  int     iplclose __P((dev_t, int, int, struct thread *));
1465 #      endif /* __FreeBSD_version >= 502116 */
1466 #    else
1467 extern  int     iplopen __P((dev_t, int, int, struct proc *));
1468 extern  int     iplclose __P((dev_t, int, int, struct proc *));
1469 #    endif /* __FreeBSD_version >= 500024 */
1470 #   else
1471 #    ifdef linux
1472 extern  int     iplioctl __P((struct inode *, struct file *, u_int, u_long));
1473 #    else
1474 extern  int     iplopen __P((dev_t, int));
1475 extern  int     iplclose __P((dev_t, int));
1476 extern  int     iplioctl __P((dev_t, int, caddr_t, int));
1477 #    endif
1478 #   endif /* (_BSDI_VERSION >= 199510) */
1479 #   if  BSD >= 199306
1480 #      if (__FreeBSD_version >= 502116)
1481 extern  int     iplread __P((struct cdev*, struct uio *, int));
1482 extern  int     iplwrite __P((struct cdev*, struct uio *, int));
1483 #      else
1484 extern  int     iplread __P((dev_t, struct uio *, int));
1485 extern  int     iplwrite __P((dev_t, struct uio *, int));
1486 #      endif /* __FreeBSD_version >= 502116 */
1487 #   else
1488 #    ifndef linux
1489 extern  int     iplread __P((dev_t, struct uio *));
1490 extern  int     iplwrite __P((dev_t, struct uio *));
1491 #    endif
1492 #   endif /* BSD >= 199306 */
1493 #  endif /* __ sgi */
1494 # endif /* MENTAT */
1495 
1496 #endif /* #ifndef _KERNEL */
1497 
1498 extern  char    *memstr __P((char *, char *, int, int));
1499 extern  int     count4bits __P((u_32_t));
1500 extern  int     count6bits __P((u_32_t *));
1501 extern  int     frrequest __P((int, ioctlcmd_t, caddr_t, int, int, ipf_stack_t *));
1502 extern  char    *getifname __P((struct ifnet *));
1503 extern  int     iplattach __P((ipf_stack_t *));
1504 extern  int     ipldetach __P((ipf_stack_t *));
1505 extern  u_short ipf_cksum __P((u_short *, int));
1506 extern  int     copyinptr __P((void *, void *, size_t));
1507 extern  int     copyoutptr __P((void *, void *, size_t));
1508 extern  int     fr_fastroute __P((mb_t *, mb_t **, fr_info_t *, frdest_t *));
1509 extern  int     fr_inobj __P((void *, void *, int));
1510 extern  int     fr_inobjsz __P((void *, void *, int, int));
1511 extern  int     fr_ioctlswitch __P((int, void *, ioctlcmd_t, int, int, void *,
1512                                     ipf_stack_t *));
1513 extern  int     fr_ipftune __P((ioctlcmd_t, void *, ipf_stack_t *));
1514 extern  int     fr_outobj __P((void *, void *, int));
1515 extern  int     fr_outobjsz __P((void *, void *, int, int));
1516 extern  void    *fr_pullup __P((mb_t *, fr_info_t *, int));
1517 extern  void    fr_resolvedest __P((struct frdest *, int, ipf_stack_t *));
1518 extern  int     fr_resolvefunc __P((void *));
1519 extern  void    *fr_resolvenic __P((char *, int, ipf_stack_t *));
1520 extern  int     fr_send_icmp_err __P((int, fr_info_t *, int));
1521 extern  int     fr_send_reset __P((fr_info_t *));
1522 #if  (__FreeBSD_version < 490000) || !defined(_KERNEL)
1523 extern  int     ppsratecheck __P((struct timeval *, int *, int));
1524 #endif
1525 extern  ipftq_t *fr_addtimeoutqueue __P((ipftq_t **, u_int, ipf_stack_t *));
1526 extern  void    fr_deletequeueentry __P((ipftqent_t *));
1527 extern  int     fr_deletetimeoutqueue __P((ipftq_t *));
1528 extern  void    fr_freetimeoutqueue __P((ipftq_t *, ipf_stack_t *));
1529 extern  void    fr_movequeue __P((ipftqent_t *, ipftq_t *, ipftq_t *,
1530                                   ipf_stack_t *));
1531 extern  void    fr_queueappend __P((ipftqent_t *, ipftq_t *, void *,
1532                                     ipf_stack_t *));
1533 extern  void    fr_queueback __P((ipftqent_t *, ipf_stack_t *));
1534 extern  void    fr_queuefront __P((ipftqent_t *));
1535 extern  void    fr_checkv4sum __P((fr_info_t *));
1536 extern  int     fr_checkl4sum __P((fr_info_t *));
1537 extern  int     fr_ifpfillv4addr __P((int, struct sockaddr_in *,
1538                                       struct sockaddr_in *, struct in_addr *,
1539                                       struct in_addr *));
1540 extern  int     fr_coalesce __P((fr_info_t *));
1541 #ifdef  USE_INET6
1542 extern  void    fr_checkv6sum __P((fr_info_t *));
1543 extern  int     fr_ifpfillv6addr __P((int, struct sockaddr_in6 *,
1544                                       struct sockaddr_in6 *, struct in_addr *,
1545                                       struct in_addr *));
1546 #endif
1547 
1548 #define IPFILTER_COMPAT
1549 extern  int     fr_incomptrans __P((ipfobj_t *, void *));
1550 extern  int     fr_outcomptrans __P((ipfobj_t *, void *));
1551 
1552 extern  int             fr_addipftune __P((ipftuneable_t *, ipf_stack_t *));
1553 extern  int             fr_delipftune __P((ipftuneable_t *, ipf_stack_t *));
1554 
1555 extern  int     frflush __P((minor_t, int, int, ipf_stack_t *));
1556 extern  void    frsync __P((int, int, void *, char *, ipf_stack_t *));
1557 #if SOLARIS2 >= 10
1558 extern  void    fr_ifindexsync __P((void *, void *, ipf_stack_t *));
1559 #endif
1560 extern  frgroup_t *fr_addgroup __P((char *, void *, u_32_t, minor_t, int,
1561                                     ipf_stack_t *));
1562 extern  int     fr_derefrule __P((frentry_t **, ipf_stack_t *));
1563 extern  void    fr_delgroup __P((char *, minor_t, int, ipf_stack_t *));
1564 extern  frgroup_t *fr_findgroup __P((char *, minor_t, int, frgroup_t ***,
1565                                      ipf_stack_t *));
1566 
1567 extern  int     fr_loginit __P((ipf_stack_t *));
1568 extern  int     ipflog_clear __P((minor_t, ipf_stack_t *));
1569 extern  int     ipflog_read __P((minor_t, struct uio *, ipf_stack_t *));
1570 extern  int     ipflog __P((fr_info_t *, u_int));
1571 extern  int     ipllog __P((int, fr_info_t *, void **, size_t *, int *, int,
1572                             ipf_stack_t *));
1573 extern  void    fr_logunload __P((ipf_stack_t *));
1574 
1575 /* SmartOS single-FD global-zone state accumulator (see cfw.c) */
1576 extern boolean_t ipf_cfwlog_enabled;
1577 struct ipstate; /* Ugggh. */
1578 extern void ipf_log_cfwlog __P((struct ipstate *, uint_t, ipf_stack_t *));
1579 extern void ipf_block_cfwlog __P((frentry_t *, fr_info_t *, ipf_stack_t *));
1580 #define IFS_CFWLOG(ifs, fr) ((ifs)->ifs_gz_controlled && ipf_cfwlog_enabled &&\
1581         fr != NULL && ((fr)->fr_flags & FR_CFWLOG))
1582 struct cfwev_s; /* See ipf_cfw.h */
1583 extern boolean_t ipf_cfwev_consume __P((struct cfwev_s *, boolean_t));
1584 /* See cfw.c's ipf_cfwev_consume_many() for details. */
1585 typedef uint_t (*cfwmanycb_t) __P((struct cfwev_s *, uint_t, void *));
1586 extern uint_t
1587         ipf_cfwev_consume_many __P((uint_t, boolean_t, cfwmanycb_t, void *));
1588 extern int ipf_cfwlog_read __P((dev_t, struct uio *, struct cred *));
1589 extern int ipf_cfwlog_ioctl __P((dev_t, int, intptr_t, int, cred_t *, int *));
1590 
1591 extern  frentry_t       *fr_acctpkt __P((fr_info_t *, u_32_t *));
1592 extern  int             fr_copytolog __P((int, char *, int));
1593 extern  u_short         fr_cksum __P((mb_t *, ip_t *, int, void *));
1594 extern  void            fr_deinitialise __P((ipf_stack_t *));
1595 extern  frentry_t       *fr_dolog __P((fr_info_t *, u_32_t *));
1596 extern  frentry_t       *fr_dstgrpmap __P((fr_info_t *, u_32_t *));
1597 extern  void            fr_fixskip __P((frentry_t **, frentry_t *, int));
1598 extern  void            fr_forgetifp __P((void *, ipf_stack_t *));
1599 extern  frentry_t       *fr_getrulen __P((int, char *, u_32_t, 
1600                                           ipf_stack_t *));
1601 extern  void            fr_getstat __P((struct friostat *, ipf_stack_t *));
1602 extern  int             fr_ifpaddr __P((int, int, void *,
1603                                         struct in_addr *, struct in_addr *,
1604                                         ipf_stack_t *));
1605 extern  int             fr_initialise __P((ipf_stack_t *));
1606 extern  int             fr_lock __P((caddr_t, int *));
1607 extern  int             fr_makefrip __P((int, ip_t *, fr_info_t *));
1608 extern  int             fr_matchtag __P((ipftag_t *, ipftag_t *));
1609 extern  int             fr_matchicmpqueryreply __P((int, icmpinfo_t *,
1610                                                     struct icmp *, int));
1611 extern  u_32_t          fr_newisn __P((fr_info_t *));
1612 extern  u_short         fr_nextipid __P((fr_info_t *));
1613 extern  int             fr_rulen __P((int, frentry_t *, ipf_stack_t *));
1614 extern  int             fr_scanlist __P((fr_info_t *, u_32_t));
1615 extern  frentry_t       *fr_srcgrpmap __P((fr_info_t *, u_32_t *));
1616 extern  int             fr_tcpudpchk __P((fr_info_t *, frtuc_t *));
1617 extern  int             fr_verifysrc __P((fr_info_t *fin));
1618 extern  int             fr_zerostats __P((char *, ipf_stack_t *));
1619 extern  ipftoken_t      *ipf_findtoken __P((int, int, void *, ipf_stack_t *));
1620 extern  int             ipf_getnextrule __P((ipftoken_t *, void *,
1621                                              ipf_stack_t *));
1622 extern  void            ipf_expiretokens __P((ipf_stack_t *));
1623 extern  void            ipf_freetoken __P((ipftoken_t *, ipf_stack_t *));
1624 extern  int             ipf_deltoken __P((int, int, void *, ipf_stack_t *));
1625 extern  int             ipf_genericiter __P((void *, int, void *, ipf_stack_t *));
1626 extern  int             ipf_extraflush __P((int, ipftq_t *, ipftq_t *, ipf_stack_t *));
1627 extern  int             ipf_flushclosing __P((int, int, ipftq_t *, ipftq_t *, ipf_stack_t *));
1628 extern  int             ipf_earlydrop __P((int, ipftq_t *, int, ipf_stack_t *));
1629 
1630 #ifndef ipf_random
1631 extern  u_32_t          ipf_random __P((void));
1632 #endif
1633 
1634 #if defined(_KERNEL)
1635 extern  int     fr_setzoneid __P((ipf_devstate_t *, void *));
1636 #endif
1637 
1638 extern  char    ipfilter_version[];
1639 #ifdef  USE_INET6
1640 extern  int     icmptoicmp6types[ICMP_MAXTYPE+1];
1641 extern  int     icmptoicmp6unreach[ICMP_MAX_UNREACH];
1642 extern  int     icmpreplytype6[ICMP6_MAXTYPE + 1];
1643 #endif
1644 extern  int     icmpreplytype4[ICMP_MAXTYPE + 1];
1645 extern  frentry_t *ipfrule_match __P((fr_info_t *));
1646 
1647 extern void     ipftuneable_alloc(ipf_stack_t *);
1648 extern void     ipftuneable_free(ipf_stack_t *);
1649 
1650 #endif  /* __IP_FIL_H__ */