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