[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net/pf/pf.c

Version: -  FREEBSD  -  FREEBSD8  -  FREEBSD7  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  OPENSOLARIS  -  minix-3-1-1  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

    1 /*      $FreeBSD: src/sys/contrib/pf/net/pf.c,v 1.19 2004/09/11 11:18:25 mlaier Exp $   */
    2 /*      $OpenBSD: pf.c,v 1.433.2.2 2004/07/17 03:22:34 brad Exp $ */
    3 /* add  $OpenBSD: pf.c,v 1.448 2004/05/11 07:34:11 dhartmei Exp $ */
    4 /*      $DragonFly: src/sys/net/pf/pf.c,v 1.20 2008/06/05 18:06:32 swildner Exp $ */
    5 
    6 /*
    7  * Copyright (c) 2004 The DragonFly Project.  All rights reserved.
    8  *
    9  * Copyright (c) 2001 Daniel Hartmeier
   10  * Copyright (c) 2002,2003 Henning Brauer
   11  * All rights reserved.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  *
   17  *    - Redistributions of source code must retain the above copyright
   18  *      notice, this list of conditions and the following disclaimer.
   19  *    - Redistributions in binary form must reproduce the above
   20  *      copyright notice, this list of conditions and the following
   21  *      disclaimer in the documentation and/or other materials provided
   22  *      with the distribution.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   28  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   35  * POSSIBILITY OF SUCH DAMAGE.
   36  *
   37  * Effort sponsored in part by the Defense Advanced Research Projects
   38  * Agency (DARPA) and Air Force Research Laboratory, Air Force
   39  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
   40  *
   41  */
   42 
   43 #include "opt_inet.h"
   44 #include "opt_inet6.h"
   45 #include "use_pfsync.h"
   46 
   47 #include <sys/param.h>
   48 #include <sys/systm.h>
   49 #include <sys/malloc.h>
   50 #include <sys/mbuf.h>
   51 #include <sys/filio.h>
   52 #include <sys/socket.h>
   53 #include <sys/socketvar.h>
   54 #include <sys/kernel.h>
   55 #include <sys/time.h>
   56 #include <sys/sysctl.h>
   57 #include <sys/endian.h>
   58 #include <vm/vm_zone.h>
   59 
   60 #include <machine/inttypes.h>
   61 
   62 #include <net/if.h>
   63 #include <net/if_types.h>
   64 #include <net/bpf.h>
   65 #include <net/netisr.h>
   66 #include <net/route.h>
   67 
   68 #include <netinet/in.h>
   69 #include <netinet/in_var.h>
   70 #include <netinet/in_systm.h>
   71 #include <netinet/ip.h>
   72 #include <netinet/ip_var.h>
   73 #include <netinet/tcp.h>
   74 #include <netinet/tcp_seq.h>
   75 #include <netinet/udp.h>
   76 #include <netinet/ip_icmp.h>
   77 #include <netinet/in_pcb.h>
   78 #include <netinet/tcp_timer.h>
   79 #include <netinet/tcp_var.h>
   80 #include <netinet/udp_var.h>
   81 #include <netinet/icmp_var.h>
   82 
   83 #include <net/pf/pfvar.h>
   84 #include <net/pf/if_pflog.h>
   85 
   86 #if NPFSYNC > 0
   87 #include <net/pf/if_pfsync.h>
   88 #endif /* NPFSYNC > 0 */
   89 
   90 #ifdef INET6
   91 #include <netinet/ip6.h>
   92 #include <netinet/in_pcb.h>
   93 #include <netinet/icmp6.h>
   94 #include <netinet6/nd6.h>
   95 #include <netinet6/ip6_var.h>
   96 #include <netinet6/in6_pcb.h>
   97 #endif /* INET6 */
   98 
   99 #include <sys/in_cksum.h>
  100 #include <sys/ucred.h>
  101 #include <machine/limits.h>
  102 #include <sys/msgport2.h>
  103 #include <net/netmsg2.h>
  104 
  105 extern int ip_optcopy(struct ip *, struct ip *);
  106 
  107 #define DPFPRINTF(n, x) if (pf_status.debug >= (n)) kprintf x
  108 
  109 /*
  110  * Global variables
  111  */
  112 
  113 struct pf_anchorqueue    pf_anchors;
  114 struct pf_ruleset        pf_main_ruleset;
  115 struct pf_altqqueue      pf_altqs[2];
  116 struct pf_palist         pf_pabuf;
  117 struct pf_altqqueue     *pf_altqs_active;
  118 struct pf_altqqueue     *pf_altqs_inactive;
  119 struct pf_status         pf_status;
  120 
  121 u_int32_t                ticket_altqs_active;
  122 u_int32_t                ticket_altqs_inactive;
  123 int                      altqs_inactive_open;
  124 u_int32_t                ticket_pabuf;
  125 
  126 struct callout           pf_expire_to;                  /* expire timeout */
  127 
  128 vm_zone_t                pf_src_tree_pl, pf_rule_pl;
  129 vm_zone_t                pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
  130 
  131 void                     pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
  132 void                     pf_print_state(struct pf_state *);
  133 void                     pf_print_flags(u_int8_t);
  134 
  135 u_int16_t                pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,
  136                             u_int8_t);
  137 void                     pf_change_ap(struct pf_addr *, u_int16_t *,
  138                             u_int16_t *, u_int16_t *, struct pf_addr *,
  139                             u_int16_t, u_int8_t, sa_family_t);
  140 #ifdef INET6
  141 void                     pf_change_a6(struct pf_addr *, u_int16_t *,
  142                             struct pf_addr *, u_int8_t);
  143 #endif /* INET6 */
  144 void                     pf_change_icmp(struct pf_addr *, u_int16_t *,
  145                             struct pf_addr *, struct pf_addr *, u_int16_t,
  146                             u_int16_t *, u_int16_t *, u_int16_t *,
  147                             u_int16_t *, u_int8_t, sa_family_t);
  148 void                     pf_send_tcp(const struct pf_rule *, sa_family_t,
  149                             const struct pf_addr *, const struct pf_addr *,
  150                             u_int16_t, u_int16_t, u_int32_t, u_int32_t,
  151                             u_int8_t, u_int16_t, u_int16_t, u_int8_t);
  152 void                     pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
  153                             sa_family_t, struct pf_rule *);
  154 struct pf_rule          *pf_match_translation(struct pf_pdesc *, struct mbuf *,
  155                             int, int, struct pfi_kif *,
  156                             struct pf_addr *, u_int16_t, struct pf_addr *,
  157                             u_int16_t, int);
  158 struct pf_rule          *pf_get_translation(struct pf_pdesc *, struct mbuf *,
  159                             int, int, struct pfi_kif *, struct pf_src_node **,
  160                             struct pf_addr *, u_int16_t,
  161                             struct pf_addr *, u_int16_t,
  162                             struct pf_addr *, u_int16_t *);
  163 int                      pf_test_tcp(struct pf_rule **, struct pf_state **,
  164                             int, struct pfi_kif *, struct mbuf *, int,
  165                             void *, struct pf_pdesc *, struct pf_rule **,
  166                             struct pf_ruleset **);
  167 int                      pf_test_udp(struct pf_rule **, struct pf_state **,
  168                             int, struct pfi_kif *, struct mbuf *, int,
  169                             void *, struct pf_pdesc *, struct pf_rule **,
  170                             struct pf_ruleset **);
  171 int                      pf_test_icmp(struct pf_rule **, struct pf_state **,
  172                             int, struct pfi_kif *, struct mbuf *, int,
  173                             void *, struct pf_pdesc *, struct pf_rule **,
  174                             struct pf_ruleset **);
  175 int                      pf_test_other(struct pf_rule **, struct pf_state **,
  176                             int, struct pfi_kif *, struct mbuf *, int, void *,
  177                             struct pf_pdesc *, struct pf_rule **,
  178                             struct pf_ruleset **);
  179 int                      pf_test_fragment(struct pf_rule **, int,
  180                             struct pfi_kif *, struct mbuf *, void *,
  181                             struct pf_pdesc *, struct pf_rule **,
  182                             struct pf_ruleset **);
  183 int                      pf_test_state_tcp(struct pf_state **, int,
  184                             struct pfi_kif *, struct mbuf *, int,
  185                             void *, struct pf_pdesc *, u_short *);
  186 int                      pf_test_state_udp(struct pf_state **, int,
  187                             struct pfi_kif *, struct mbuf *, int,
  188                             void *, struct pf_pdesc *);
  189 int                      pf_test_state_icmp(struct pf_state **, int,
  190                             struct pfi_kif *, struct mbuf *, int,
  191                             void *, struct pf_pdesc *);
  192 int                      pf_test_state_other(struct pf_state **, int,
  193                             struct pfi_kif *, struct pf_pdesc *);
  194 static int               pf_match_tag(struct mbuf *, struct pf_rule *,
  195                                       struct pf_rule *, int *);
  196 void                     pf_hash(struct pf_addr *, struct pf_addr *,
  197                             struct pf_poolhashkey *, sa_family_t);
  198 int                      pf_map_addr(u_int8_t, struct pf_rule *,
  199                             struct pf_addr *, struct pf_addr *,
  200                             struct pf_addr *, struct pf_src_node **);
  201 int                      pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
  202                             struct pf_addr *, struct pf_addr *, u_int16_t,
  203                             struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
  204                             struct pf_src_node **);
  205 void                     pf_route(struct mbuf **, struct pf_rule *, int,
  206                             struct ifnet *, struct pf_state *);
  207 void                     pf_route6(struct mbuf **, struct pf_rule *, int,
  208                             struct ifnet *, struct pf_state *);
  209 int                      pf_socket_lookup(uid_t *, gid_t *,
  210                             int, struct pf_pdesc *);
  211 u_int8_t                 pf_get_wscale(struct mbuf *, int, u_int16_t,
  212                             sa_family_t);
  213 u_int16_t                pf_get_mss(struct mbuf *, int, u_int16_t,
  214                             sa_family_t);
  215 u_int16_t                pf_calc_mss(struct pf_addr *, sa_family_t,
  216                                 u_int16_t);
  217 void                     pf_set_rt_ifp(struct pf_state *,
  218                             struct pf_addr *);
  219 int                      pf_check_proto_cksum(struct mbuf *, int, int,
  220                             u_int8_t, sa_family_t);
  221 int                      pf_addr_wrap_neq(struct pf_addr_wrap *,
  222                             struct pf_addr_wrap *);
  223 struct pf_state         *pf_find_state_recurse(struct pfi_kif *,
  224                             struct pf_state *, u_int8_t);
  225 
  226 struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX];
  227 
  228 #define STATE_LOOKUP()                                                  \
  229         do {                                                            \
  230                 if (direction == PF_IN)                                 \
  231                         *state = pf_find_state_recurse(         \
  232                             kif, &key, PF_EXT_GWY);                     \
  233                 else                                                    \
  234                         *state = pf_find_state_recurse(         \
  235                             kif, &key, PF_LAN_EXT);                     \
  236                 if (*state == NULL)                                     \
  237                         return (PF_DROP);                               \
  238                 if (direction == PF_OUT &&                              \
  239                     (((*state)->rule.ptr->rt == PF_ROUTETO &&           \
  240                     (*state)->rule.ptr->direction == PF_OUT) ||         \
  241                     ((*state)->rule.ptr->rt == PF_REPLYTO &&            \
  242                     (*state)->rule.ptr->direction == PF_IN)) &&         \
  243                     (*state)->rt_kif != NULL &&                         \
  244                     (*state)->rt_kif != kif)                            \
  245                         return (PF_PASS);                               \
  246         } while (0)
  247 
  248 #define STATE_TRANSLATE(s) \
  249         (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \
  250         ((s)->af == AF_INET6 && \
  251         ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \
  252         (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \
  253         (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \
  254         (s)->lan.port != (s)->gwy.port
  255 
  256 #define BOUND_IFACE(r, k) (((r)->rule_flag & PFRULE_IFBOUND) ? (k) :   \
  257         ((r)->rule_flag & PFRULE_GRBOUND) ? (k)->pfik_parent :         \
  258         (k)->pfik_parent->pfik_parent)
  259 
  260 static int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
  261 static int pf_state_compare_lan_ext(struct pf_state *,
  262         struct pf_state *);
  263 static int pf_state_compare_ext_gwy(struct pf_state *,
  264         struct pf_state *);
  265 static int pf_state_compare_id(struct pf_state *,
  266         struct pf_state *);
  267 
  268 struct pf_src_tree tree_src_tracking;
  269 
  270 struct pf_state_tree_id tree_id;
  271 struct pf_state_queue state_updates;
  272 
  273 RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
  274 RB_GENERATE(pf_state_tree_lan_ext, pf_state,
  275     u.s.entry_lan_ext, pf_state_compare_lan_ext);
  276 RB_GENERATE(pf_state_tree_ext_gwy, pf_state,
  277     u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
  278 RB_GENERATE(pf_state_tree_id, pf_state,
  279     u.s.entry_id, pf_state_compare_id);
  280 
  281 static int
  282 pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
  283 {
  284         int     diff;
  285 
  286         if (a->rule.ptr > b->rule.ptr)
  287                 return (1);
  288         if (a->rule.ptr < b->rule.ptr)
  289                 return (-1);
  290         if ((diff = a->af - b->af) != 0)
  291                 return (diff);
  292         switch (a->af) {
  293 #ifdef INET
  294         case AF_INET:
  295                 if (a->addr.addr32[0] > b->addr.addr32[0])
  296                         return (1);
  297                 if (a->addr.addr32[0] < b->addr.addr32[0])
  298                         return (-1);
  299                 break;
  300 #endif /* INET */
  301 #ifdef INET6
  302         case AF_INET6:
  303                 if (a->addr.addr32[3] > b->addr.addr32[3])
  304                         return (1);
  305                 if (a->addr.addr32[3] < b->addr.addr32[3])
  306                         return (-1);
  307                 if (a->addr.addr32[2] > b->addr.addr32[2])
  308                         return (1);
  309                 if (a->addr.addr32[2] < b->addr.addr32[2])
  310                         return (-1);
  311                 if (a->addr.addr32[1] > b->addr.addr32[1])
  312                         return (1);
  313                 if (a->addr.addr32[1] < b->addr.addr32[1])
  314                         return (-1);
  315                 if (a->addr.addr32[0] > b->addr.addr32[0])
  316                         return (1);
  317                 if (a->addr.addr32[0] < b->addr.addr32[0])
  318                         return (-1);
  319                 break;
  320 #endif /* INET6 */
  321         }
  322         return (0);
  323 }
  324 
  325 u_int32_t
  326 pf_state_hash(struct pf_state *s)
  327 {
  328         u_int32_t hv = (intptr_t)s / sizeof(*s);
  329 
  330         hv ^= crc32(&s->lan, sizeof(s->lan));
  331         hv ^= crc32(&s->gwy, sizeof(s->gwy));
  332         hv ^= crc32(&s->ext, sizeof(s->ext));
  333         if (hv == 0)    /* disallow 0 */
  334                 hv = 1;
  335         return(hv);
  336 }
  337 
  338 static int
  339 pf_state_compare_lan_ext(struct pf_state *a, struct pf_state *b)
  340 {
  341         int     diff;
  342 
  343         if ((diff = a->proto - b->proto) != 0)
  344                 return (diff);
  345         if ((diff = a->af - b->af) != 0)
  346                 return (diff);
  347         switch (a->af) {
  348 #ifdef INET
  349         case AF_INET:
  350                 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
  351                         return (1);
  352                 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
  353                         return (-1);
  354                 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
  355                         return (1);
  356                 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
  357                         return (-1);
  358                 break;
  359 #endif /* INET */
  360 #ifdef INET6
  361         case AF_INET6:
  362                 if (a->lan.addr.addr32[3] > b->lan.addr.addr32[3])
  363                         return (1);
  364                 if (a->lan.addr.addr32[3] < b->lan.addr.addr32[3])
  365                         return (-1);
  366                 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
  367                         return (1);
  368                 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
  369                         return (-1);
  370                 if (a->lan.addr.addr32[2] > b->lan.addr.addr32[2])
  371                         return (1);
  372                 if (a->lan.addr.addr32[2] < b->lan.addr.addr32[2])
  373                         return (-1);
  374                 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
  375                         return (1);
  376                 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
  377                         return (-1);
  378                 if (a->lan.addr.addr32[1] > b->lan.addr.addr32[1])
  379                         return (1);
  380                 if (a->lan.addr.addr32[1] < b->lan.addr.addr32[1])
  381                         return (-1);
  382                 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
  383                         return (1);
  384                 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
  385                         return (-1);
  386                 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
  387                         return (1);
  388                 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
  389                         return (-1);
  390                 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
  391                         return (1);
  392                 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
  393                         return (-1);
  394                 break;
  395 #endif /* INET6 */
  396         }
  397 
  398         if ((diff = a->lan.port - b->lan.port) != 0)
  399                 return (diff);
  400         if ((diff = a->ext.port - b->ext.port) != 0)
  401                 return (diff);
  402 
  403         return (0);
  404 }
  405 
  406 static int
  407 pf_state_compare_ext_gwy(struct pf_state *a, struct pf_state *b)
  408 {
  409         int     diff;
  410 
  411         if ((diff = a->proto - b->proto) != 0)
  412                 return (diff);
  413         if ((diff = a->af - b->af) != 0)
  414                 return (diff);
  415         switch (a->af) {
  416 #ifdef INET
  417         case AF_INET:
  418                 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
  419                         return (1);
  420                 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
  421                         return (-1);
  422                 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
  423                         return (1);
  424                 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
  425                         return (-1);
  426                 break;
  427 #endif /* INET */
  428 #ifdef INET6
  429         case AF_INET6:
  430                 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
  431                         return (1);
  432                 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
  433                         return (-1);
  434                 if (a->gwy.addr.addr32[3] > b->gwy.addr.addr32[3])
  435                         return (1);
  436                 if (a->gwy.addr.addr32[3] < b->gwy.addr.addr32[3])
  437                         return (-1);
  438                 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
  439                         return (1);
  440                 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
  441                         return (-1);
  442                 if (a->gwy.addr.addr32[2] > b->gwy.addr.addr32[2])
  443                         return (1);
  444                 if (a->gwy.addr.addr32[2] < b->gwy.addr.addr32[2])
  445                         return (-1);
  446                 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
  447                         return (1);
  448                 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
  449                         return (-1);
  450                 if (a->gwy.addr.addr32[1] > b->gwy.addr.addr32[1])
  451                         return (1);
  452                 if (a->gwy.addr.addr32[1] < b->gwy.addr.addr32[1])
  453                         return (-1);
  454                 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
  455                         return (1);
  456                 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
  457                         return (-1);
  458                 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
  459                         return (1);
  460                 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
  461                         return (-1);
  462                 break;
  463 #endif /* INET6 */
  464         }
  465 
  466         if ((diff = a->ext.port - b->ext.port) != 0)
  467                 return (diff);
  468         if ((diff = a->gwy.port - b->gwy.port) != 0)
  469                 return (diff);
  470 
  471         return (0);
  472 }
  473 
  474 static int
  475 pf_state_compare_id(struct pf_state *a, struct pf_state *b)
  476 {
  477         if (a->id > b->id)
  478                 return (1);
  479         if (a->id < b->id)
  480                 return (-1);
  481         if (a->creatorid > b->creatorid)
  482                 return (1);
  483         if (a->creatorid < b->creatorid)
  484                 return (-1);
  485 
  486         return (0);
  487 }
  488 
  489 #ifdef INET6
  490 void
  491 pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
  492 {
  493         switch (af) {
  494 #ifdef INET
  495         case AF_INET:
  496                 dst->addr32[0] = src->addr32[0];
  497                 break;
  498 #endif /* INET */
  499         case AF_INET6:
  500                 dst->addr32[0] = src->addr32[0];
  501                 dst->addr32[1] = src->addr32[1];
  502                 dst->addr32[2] = src->addr32[2];
  503                 dst->addr32[3] = src->addr32[3];
  504                 break;
  505         }
  506 }
  507 #endif
  508 
  509 struct pf_state *
  510 pf_find_state_byid(struct pf_state *key)
  511 {
  512         pf_status.fcounters[FCNT_STATE_SEARCH]++;
  513         return (RB_FIND(pf_state_tree_id, &tree_id, key));
  514 }
  515 
  516 struct pf_state *
  517 pf_find_state_recurse(struct pfi_kif *kif, struct pf_state *key, u_int8_t tree)
  518 {
  519         struct pf_state *s;
  520 
  521         pf_status.fcounters[FCNT_STATE_SEARCH]++;
  522 
  523         switch (tree) {
  524         case PF_LAN_EXT:
  525                 for (; kif != NULL; kif = kif->pfik_parent) {
  526                         s = RB_FIND(pf_state_tree_lan_ext,
  527                             &kif->pfik_lan_ext, key);
  528                         if (s != NULL)
  529                                 return (s);
  530                 }
  531                 return (NULL);
  532         case PF_EXT_GWY:
  533                 for (; kif != NULL; kif = kif->pfik_parent) {
  534                         s = RB_FIND(pf_state_tree_ext_gwy,
  535                             &kif->pfik_ext_gwy, key);
  536                         if (s != NULL)
  537                                 return (s);
  538                 }
  539                 return (NULL);
  540         default:
  541                 panic("pf_find_state_recurse");
  542         }
  543 }
  544 
  545 struct pf_state *
  546 pf_find_state_all(struct pf_state *key, u_int8_t tree, int *more)
  547 {
  548         struct pf_state *s, *ss = NULL;
  549         struct pfi_kif  *kif;
  550 
  551         pf_status.fcounters[FCNT_STATE_SEARCH]++;
  552 
  553         switch (tree) {
  554         case PF_LAN_EXT:
  555                 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
  556                         s = RB_FIND(pf_state_tree_lan_ext,
  557                             &kif->pfik_lan_ext, key);
  558                         if (s == NULL)
  559                                 continue;
  560                         if (more == NULL)
  561                                 return (s);
  562                         ss = s;
  563                         (*more)++;
  564                 }
  565                 return (ss);
  566         case PF_EXT_GWY:
  567                 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
  568                         s = RB_FIND(pf_state_tree_ext_gwy,
  569                             &kif->pfik_ext_gwy, key);
  570                         if (s == NULL)
  571                                 continue;
  572                         if (more == NULL)
  573                                 return (s);
  574                         ss = s;
  575                         (*more)++;
  576                 }
  577                 return (ss);
  578         default:
  579                 panic("pf_find_state_all");
  580         }
  581 }
  582 
  583 int
  584 pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
  585     struct pf_addr *src, sa_family_t af)
  586 {
  587         struct pf_src_node      k;
  588 
  589         if (*sn == NULL) {
  590                 k.af = af;
  591                 PF_ACPY(&k.addr, src, af);
  592                 if (rule->rule_flag & PFRULE_RULESRCTRACK ||
  593                     rule->rpool.opts & PF_POOL_STICKYADDR)
  594                         k.rule.ptr = rule;
  595                 else
  596                         k.rule.ptr = NULL;
  597                 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
  598                 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
  599         }
  600         if (*sn == NULL) {
  601                 if (!rule->max_src_nodes ||
  602                     rule->src_nodes < rule->max_src_nodes)
  603                         (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT);
  604                 if ((*sn) == NULL)
  605                         return (-1);
  606                 bzero(*sn, sizeof(struct pf_src_node));
  607                 (*sn)->af = af;
  608                 if (rule->rule_flag & PFRULE_RULESRCTRACK ||
  609                     rule->rpool.opts & PF_POOL_STICKYADDR)
  610                         (*sn)->rule.ptr = rule;
  611                 else
  612                         (*sn)->rule.ptr = NULL;
  613                 PF_ACPY(&(*sn)->addr, src, af);
  614                 if (RB_INSERT(pf_src_tree,
  615                     &tree_src_tracking, *sn) != NULL) {
  616                         if (pf_status.debug >= PF_DEBUG_MISC) {
  617                                 kprintf("pf: src_tree insert failed: ");
  618                                 pf_print_host(&(*sn)->addr, 0, af);
  619                                 kprintf("\n");
  620                         }
  621                         pool_put(&pf_src_tree_pl, *sn);
  622                         return (-1);
  623                 }
  624                 (*sn)->creation = time_second;
  625                 (*sn)->ruletype = rule->action;
  626                 if ((*sn)->rule.ptr != NULL)
  627                         (*sn)->rule.ptr->src_nodes++;
  628                 pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
  629                 pf_status.src_nodes++;
  630         } else {
  631                 if (rule->max_src_states &&
  632                     (*sn)->states >= rule->max_src_states)
  633                         return (-1);
  634         }
  635         return (0);
  636 }
  637 
  638 int
  639 pf_insert_state(struct pfi_kif *kif, struct pf_state *state)
  640 {
  641         /* Thou MUST NOT insert multiple duplicate keys */
  642         state->u.s.kif = kif;
  643         if (RB_INSERT(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state)) {
  644                 if (pf_status.debug >= PF_DEBUG_MISC) {
  645                         kprintf("pf: state insert failed: tree_lan_ext");
  646                         kprintf(" lan: ");
  647                         pf_print_host(&state->lan.addr, state->lan.port,
  648                             state->af);
  649                         kprintf(" gwy: ");
  650                         pf_print_host(&state->gwy.addr, state->gwy.port,
  651                             state->af);
  652                         kprintf(" ext: ");
  653                         pf_print_host(&state->ext.addr, state->ext.port,
  654                             state->af);
  655                         if (state->sync_flags & PFSTATE_FROMSYNC)
  656                                 kprintf(" (from sync)");
  657                         kprintf("\n");
  658                 }
  659                 return (-1);
  660         }
  661 
  662         if (RB_INSERT(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state)) {
  663                 if (pf_status.debug >= PF_DEBUG_MISC) {
  664                         kprintf("pf: state insert failed: tree_ext_gwy");
  665                         kprintf(" lan: ");
  666                         pf_print_host(&state->lan.addr, state->lan.port,
  667                             state->af);
  668                         kprintf(" gwy: ");
  669                         pf_print_host(&state->gwy.addr, state->gwy.port,
  670                             state->af);
  671                         kprintf(" ext: ");
  672                         pf_print_host(&state->ext.addr, state->ext.port,
  673                             state->af);
  674                         if (state->sync_flags & PFSTATE_FROMSYNC)
  675                                 kprintf(" (from sync)");
  676                         kprintf("\n");
  677                 }
  678                 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
  679                 return (-1);
  680         }
  681 
  682         if (state->id == 0 && state->creatorid == 0) {
  683                 state->id = htobe64(pf_status.stateid++);
  684                 state->creatorid = pf_status.hostid;
  685         }
  686         if (RB_INSERT(pf_state_tree_id, &tree_id, state) != NULL) {
  687                 if (pf_status.debug >= PF_DEBUG_MISC) {
  688                         kprintf("pf: state insert failed: "
  689                             "id: %016" PRIx64 " creatorid: %08" PRIx32,
  690                             be64toh(state->id), ntohl(state->creatorid));
  691                         if (state->sync_flags & PFSTATE_FROMSYNC)
  692                                 kprintf(" (from sync)");
  693                         kprintf("\n");
  694                 }
  695                 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
  696                 RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state);
  697                 return (-1);
  698         }
  699         TAILQ_INSERT_HEAD(&state_updates, state, u.s.entry_updates);
  700 
  701         pf_status.fcounters[FCNT_STATE_INSERT]++;
  702         pf_status.states++;
  703         pfi_attach_state(kif);
  704 #if NPFSYNC
  705         pfsync_insert_state(state);
  706 #endif
  707         return (0);
  708 }
  709 
  710 void
  711 pf_purge_timeout(void *arg)
  712 {
  713         struct callout  *to = arg;
  714 
  715         crit_enter();
  716         pf_purge_expired_states();
  717         pf_purge_expired_fragments();
  718         pf_purge_expired_src_nodes();
  719         crit_exit();
  720 
  721         callout_reset(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz,
  722             pf_purge_timeout, to);
  723 }
  724 
  725 u_int32_t
  726 pf_state_expires(const struct pf_state *state)
  727 {
  728         u_int32_t       timeout;
  729         u_int32_t       start;
  730         u_int32_t       end;
  731         u_int32_t       states;
  732 
  733         /* handle all PFTM_* > PFTM_MAX here */
  734         if (state->timeout == PFTM_PURGE)
  735                 return (time_second);
  736         if (state->timeout == PFTM_UNTIL_PACKET)
  737                 return (0);
  738         KASSERT((state->timeout < PFTM_MAX), 
  739             ("pf_state_expires: timeout > PFTM_MAX"));
  740         timeout = state->rule.ptr->timeout[state->timeout];
  741         if (!timeout)
  742                 timeout = pf_default_rule.timeout[state->timeout];
  743         start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
  744         if (start) {
  745                 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];
  746                 states = state->rule.ptr->states;
  747         } else {
  748                 start = pf_default_rule.timeout[PFTM_ADAPTIVE_START];
  749                 end = pf_default_rule.timeout[PFTM_ADAPTIVE_END];
  750                 states = pf_status.states;
  751         }
  752         if (end && states > start && start < end) {
  753                 if (states < end)
  754                         return (state->expire + timeout * (end - states) /
  755                             (end - start));
  756                 else
  757                         return (time_second);
  758         }
  759         return (state->expire + timeout);
  760 }
  761 
  762 void
  763 pf_purge_expired_src_nodes(void)
  764 {
  765          struct pf_src_node             *cur, *next;
  766 
  767          for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
  768                  next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
  769 
  770                  if (cur->states <= 0 && cur->expire <= time_second) {
  771                          if (cur->rule.ptr != NULL) {
  772                                  cur->rule.ptr->src_nodes--;
  773                                  if (cur->rule.ptr->states <= 0 &&
  774                                      cur->rule.ptr->max_src_nodes <= 0)
  775                                          pf_rm_rule(NULL, cur->rule.ptr);
  776                          }
  777                          RB_REMOVE(pf_src_tree, &tree_src_tracking, cur);
  778                          pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
  779                          pf_status.src_nodes--;
  780                          pool_put(&pf_src_tree_pl, cur);
  781                  }
  782          }
  783 }
  784 
  785 void
  786 pf_src_tree_remove_state(struct pf_state *s)
  787 {
  788         u_int32_t timeout;
  789 
  790         if (s->src_node != NULL) {
  791                 if (--s->src_node->states <= 0) {
  792                         timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
  793                         if (!timeout)
  794                                 timeout =
  795                                     pf_default_rule.timeout[PFTM_SRC_NODE];
  796                         s->src_node->expire = time_second + timeout;
  797                 }
  798         }
  799         if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
  800                 if (--s->nat_src_node->states <= 0) {
  801                         timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
  802                         if (!timeout)
  803                                 timeout =
  804                                     pf_default_rule.timeout[PFTM_SRC_NODE];
  805                         s->nat_src_node->expire = time_second + timeout;
  806                 }
  807         }
  808         s->src_node = s->nat_src_node = NULL;
  809 }
  810 
  811 static int
  812 pf_purge_expired_states_callback(struct pf_state *cur, void *data __unused)
  813 {
  814         if (pf_state_expires(cur) <= time_second) {
  815                 RB_REMOVE(pf_state_tree_ext_gwy,
  816                     &cur->u.s.kif->pfik_ext_gwy, cur);
  817                 RB_REMOVE(pf_state_tree_lan_ext,
  818                     &cur->u.s.kif->pfik_lan_ext, cur);
  819                 RB_REMOVE(pf_state_tree_id, &tree_id, cur);
  820                 if (cur->src.state == PF_TCPS_PROXY_DST) {
  821                         pf_send_tcp(cur->rule.ptr, cur->af,
  822                             &cur->ext.addr, &cur->lan.addr,
  823                             cur->ext.port, cur->lan.port,
  824                             cur->src.seqhi, cur->src.seqlo + 1, 0,
  825                             TH_RST|TH_ACK, 0, 0);
  826                 }
  827 #if NPFSYNC
  828                 pfsync_delete_state(cur);
  829 #endif
  830                 pf_src_tree_remove_state(cur);
  831                 if (--cur->rule.ptr->states <= 0 &&
  832                     cur->rule.ptr->src_nodes <= 0)
  833                         pf_rm_rule(NULL, cur->rule.ptr);
  834                 if (cur->nat_rule.ptr != NULL)
  835                         if (--cur->nat_rule.ptr->states <= 0 &&
  836                                 cur->nat_rule.ptr->src_nodes <= 0)
  837                                 pf_rm_rule(NULL, cur->nat_rule.ptr);
  838                 if (cur->anchor.ptr != NULL)
  839                         if (--cur->anchor.ptr->states <= 0)
  840                                 pf_rm_rule(NULL, cur->anchor.ptr);
  841                 pf_normalize_tcp_cleanup(cur);
  842                 pfi_detach_state(cur->u.s.kif);
  843                 TAILQ_REMOVE(&state_updates, cur, u.s.entry_updates);
  844                 pool_put(&pf_state_pl, cur);
  845                 pf_status.fcounters[FCNT_STATE_REMOVALS]++;
  846                 pf_status.states--;
  847         }
  848         return(0);
  849 }
  850 
  851 void
  852 pf_purge_expired_states(void)
  853 {
  854         RB_SCAN(pf_state_tree_id, &tree_id, NULL,
  855                 pf_purge_expired_states_callback, NULL);
  856 }
  857 
  858 
  859 int
  860 pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
  861 {
  862         if (aw->type != PF_ADDR_TABLE)
  863                 return (0);
  864         if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)
  865                 return (1);
  866         return (0);
  867 }
  868 
  869 void
  870 pf_tbladdr_remove(struct pf_addr_wrap *aw)
  871 {
  872         if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL)
  873                 return;
  874         pfr_detach_table(aw->p.tbl);
  875         aw->p.tbl = NULL;
  876 }
  877 
  878 void
  879 pf_tbladdr_copyout(struct pf_addr_wrap *aw)
  880 {
  881         struct pfr_ktable *kt = aw->p.tbl;
  882 
  883         if (aw->type != PF_ADDR_TABLE || kt == NULL)
  884                 return;
  885         if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
  886                 kt = kt->pfrkt_root;
  887         aw->p.tbl = NULL;
  888         aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
  889                 kt->pfrkt_cnt : -1;
  890 }
  891 
  892 void
  893 pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
  894 {
  895         switch (af) {
  896 #ifdef INET
  897         case AF_INET: {
  898                 u_int32_t a = ntohl(addr->addr32[0]);
  899                 kprintf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255,
  900                     (a>>8)&255, a&255);
  901                 if (p) {
  902                         p = ntohs(p);
  903                         kprintf(":%u", p);
  904                 }
  905                 break;
  906         }
  907 #endif /* INET */
  908 #ifdef INET6
  909         case AF_INET6: {
  910                 u_int16_t b;
  911                 u_int8_t i, curstart = 255, curend = 0,
  912                     maxstart = 0, maxend = 0;
  913                 for (i = 0; i < 8; i++) {
  914                         if (!addr->addr16[i]) {
  915                                 if (curstart == 255)
  916                                         curstart = i;
  917                                 else
  918                                         curend = i;
  919                         } else {
  920                                 if (curstart) {
  921                                         if ((curend - curstart) >
  922                                             (maxend - maxstart)) {
  923                                                 maxstart = curstart;
  924                                                 maxend = curend;
  925                                                 curstart = 255;
  926                                         }
  927                                 }
  928                         }
  929                 }
  930                 for (i = 0; i < 8; i++) {
  931                         if (i >= maxstart && i <= maxend) {
  932                                 if (maxend != 7) {
  933                                         if (i == maxstart)
  934                                                 kprintf(":");
  935                                 } else {
  936                                         if (i == maxend)
  937                                                 kprintf(":");
  938                                 }
  939                         } else {
  940                                 b = ntohs(addr->addr16[i]);
  941                                 kprintf("%x", b);
  942                                 if (i < 7)
  943                                         kprintf(":");
  944                         }
  945                 }
  946                 if (p) {
  947                         p = ntohs(p);
  948                         kprintf("[%u]", p);
  949                 }
  950                 break;
  951         }
  952 #endif /* INET6 */
  953         }
  954 }
  955 
  956 void
  957 pf_print_state(struct pf_state *s)
  958 {
  959         switch (s->proto) {
  960         case IPPROTO_TCP:
  961                 kprintf("TCP ");
  962                 break;
  963         case IPPROTO_UDP:
  964                 kprintf("UDP ");
  965                 break;
  966         case IPPROTO_ICMP:
  967                 kprintf("ICMP ");
  968                 break;
  969         case IPPROTO_ICMPV6:
  970                 kprintf("ICMPV6 ");
  971                 break;
  972         default:
  973                 kprintf("%u ", s->proto);
  974                 break;
  975         }
  976         pf_print_host(&s->lan.addr, s->lan.port, s->af);
  977         kprintf(" ");
  978         pf_print_host(&s->gwy.addr, s->gwy.port, s->af);
  979         kprintf(" ");
  980         pf_print_host(&s->ext.addr, s->ext.port, s->af);
  981         kprintf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo,
  982             s->src.seqhi, s->src.max_win, s->src.seqdiff);
  983         if (s->src.wscale && s->dst.wscale)
  984                 kprintf(" wscale=%u", s->src.wscale & PF_WSCALE_MASK);
  985         kprintf("]");
  986         kprintf(" [lo=%u high=%u win=%u modulator=%u", s->dst.seqlo,
  987             s->dst.seqhi, s->dst.max_win, s->dst.seqdiff);
  988         if (s->src.wscale && s->dst.wscale)
  989                 kprintf(" wscale=%u", s->dst.wscale & PF_WSCALE_MASK);
  990         kprintf("]");
  991         kprintf(" %u:%u", s->src.state, s->dst.state);
  992 }
  993 
  994 void
  995 pf_print_flags(u_int8_t f)
  996 {
  997         if (f)
  998                 kprintf(" ");
  999         if (f & TH_FIN)
 1000                 kprintf("F");
 1001         if (f & TH_SYN)
 1002                 kprintf("S");
 1003         if (f & TH_RST)
 1004                 kprintf("R");
 1005         if (f & TH_PUSH)
 1006                 kprintf("P");
 1007         if (f & TH_ACK)
 1008                 kprintf("A");
 1009         if (f & TH_URG)
 1010                 kprintf("U");
 1011         if (f & TH_ECE)
 1012                 kprintf("E");
 1013         if (f & TH_CWR)
 1014                 kprintf("W");
 1015 }
 1016 
 1017 #define PF_SET_SKIP_STEPS(i)                                    \
 1018         do {                                                    \
 1019                 while (head[i] != cur) {                        \
 1020                         head[i]->skip[i].ptr = cur;             \
 1021                         head[i] = TAILQ_NEXT(head[i], entries); \
 1022                 }                                               \
 1023         } while (0)
 1024 
 1025 void
 1026 pf_calc_skip_steps(struct pf_rulequeue *rules)
 1027 {
 1028         struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT];
 1029         int i;
 1030 
 1031         cur = TAILQ_FIRST(rules);
 1032         prev = cur;
 1033         for (i = 0; i < PF_SKIP_COUNT; ++i)
 1034                 head[i] = cur;
 1035         while (cur != NULL) {
 1036 
 1037                 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
 1038                         PF_SET_SKIP_STEPS(PF_SKIP_IFP);
 1039                 if (cur->direction != prev->direction)
 1040                         PF_SET_SKIP_STEPS(PF_SKIP_DIR);
 1041                 if (cur->af != prev->af)
 1042                         PF_SET_SKIP_STEPS(PF_SKIP_AF);
 1043                 if (cur->proto != prev->proto)
 1044                         PF_SET_SKIP_STEPS(PF_SKIP_PROTO);
 1045                 if (cur->src.not != prev->src.not ||
 1046                     pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr))
 1047                         PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR);
 1048                 if (cur->src.port[0] != prev->src.port[0] ||
 1049                     cur->src.port[1] != prev->src.port[1] ||
 1050                     cur->src.port_op != prev->src.port_op)
 1051                         PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
 1052                 if (cur->dst.not != prev->dst.not ||
 1053                     pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
 1054                         PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
 1055                 if (cur->dst.port[0] != prev->dst.port[0] ||
 1056                     cur->dst.port[1] != prev->dst.port[1] ||
 1057                     cur->dst.port_op != prev->dst.port_op)
 1058                         PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
 1059 
 1060                 prev = cur;
 1061                 cur = TAILQ_NEXT(cur, entries);
 1062         }
 1063         for (i = 0; i < PF_SKIP_COUNT; ++i)
 1064                 PF_SET_SKIP_STEPS(i);
 1065 }
 1066 
 1067 int
 1068 pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
 1069 {
 1070         if (aw1->type != aw2->type)
 1071                 return (1);
 1072         switch (aw1->type) {
 1073         case PF_ADDR_ADDRMASK:
 1074                 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
 1075                         return (1);
 1076                 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
 1077                         return (1);
 1078                 return (0);
 1079         case PF_ADDR_DYNIFTL:
 1080                 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
 1081         case PF_ADDR_NOROUTE:
 1082                 return (0);
 1083         case PF_ADDR_TABLE:
 1084                 return (aw1->p.tbl != aw2->p.tbl);
 1085         default:
 1086                 kprintf("invalid address type: %d\n", aw1->type);
 1087                 return (1);
 1088         }
 1089 }
 1090 
 1091 void
 1092 pf_update_anchor_rules(void)
 1093 {
 1094         struct pf_rule  *rule;
 1095         int              i;
 1096 
 1097         for (i = 0; i < PF_RULESET_MAX; ++i)
 1098                 TAILQ_FOREACH(rule, pf_main_ruleset.rules[i].active.ptr,
 1099                     entries)
 1100                         if (rule->anchorname[0])
 1101                                 rule->anchor = pf_find_anchor(rule->anchorname);
 1102                         else
 1103                                 rule->anchor = NULL;
 1104 }
 1105 
 1106 u_int16_t
 1107 pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp)
 1108 {
 1109         u_int32_t       l;
 1110 
 1111         if (udp && !cksum)
 1112                 return (0x0000);
 1113         l = cksum + old - new;
 1114         l = (l >> 16) + (l & 65535);
 1115         l = l & 65535;
 1116         if (udp && !l)
 1117                 return (0xFFFF);
 1118         return (l);
 1119 }
 1120 
 1121 void
 1122 pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc,
 1123     struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af)
 1124 {
 1125         struct pf_addr  ao;
 1126         u_int16_t       po = *p;
 1127 
 1128         PF_ACPY(&ao, a, af);
 1129         PF_ACPY(a, an, af);
 1130 
 1131         *p = pn;
 1132 
 1133         switch (af) {
 1134 #ifdef INET
 1135         case AF_INET:
 1136                 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
 1137                     ao.addr16[0], an->addr16[0], 0),
 1138                     ao.addr16[1], an->addr16[1], 0);
 1139                 *p = pn;
 1140                 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
 1141                     ao.addr16[0], an->addr16[0], u),
 1142                     ao.addr16[1], an->addr16[1], u),
 1143                     po, pn, u);
 1144                 break;
 1145 #endif /* INET */
 1146 #ifdef INET6
 1147         case AF_INET6:
 1148                 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
 1149                     pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
 1150                     pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
 1151                     ao.addr16[0], an->addr16[0], u),
 1152                     ao.addr16[1], an->addr16[1], u),
 1153                     ao.addr16[2], an->addr16[2], u),
 1154                     ao.addr16[3], an->addr16[3], u),
 1155                     ao.addr16[4], an->addr16[4], u),
 1156                     ao.addr16[5], an->addr16[5], u),
 1157                     ao.addr16[6], an->addr16[6], u),
 1158                     ao.addr16[7], an->addr16[7], u),
 1159                     po, pn, u);
 1160                 break;
 1161 #endif /* INET6 */
 1162         }
 1163 }
 1164 
 1165 
 1166 /* Changes a u_int32_t.  Uses a void * so there are no align restrictions */
 1167 void
 1168 pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u)
 1169 {
 1170         u_int32_t       ao;
 1171 
 1172         memcpy(&ao, a, sizeof(ao));
 1173         memcpy(a, &an, sizeof(u_int32_t));
 1174         *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u),
 1175             ao % 65536, an % 65536, u);
 1176 }
 1177 
 1178 #ifdef INET6
 1179 void
 1180 pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u)
 1181 {
 1182         struct pf_addr  ao;
 1183 
 1184         PF_ACPY(&ao, a, AF_INET6);
 1185         PF_ACPY(a, an, AF_INET6);
 1186 
 1187         *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
 1188             pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
 1189             pf_cksum_fixup(pf_cksum_fixup(*c,
 1190             ao.addr16[0], an->addr16[0], u),
 1191             ao.addr16[1], an->addr16[1], u),
 1192             ao.addr16[2], an->addr16[2], u),
 1193             ao.addr16[3], an->addr16[3], u),
 1194             ao.addr16[4], an->addr16[4], u),
 1195             ao.addr16[5], an->addr16[5], u),
 1196             ao.addr16[6], an->addr16[6], u),
 1197             ao.addr16[7], an->addr16[7], u);
 1198 }
 1199 #endif /* INET6 */
 1200 
 1201 void
 1202 pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa,
 1203     struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c,
 1204     u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af)
 1205 {
 1206         struct pf_addr  oia, ooa;
 1207 
 1208         PF_ACPY(&oia, ia, af);
 1209         PF_ACPY(&ooa, oa, af);
 1210 
 1211         /* Change inner protocol port, fix inner protocol checksum. */
 1212         if (ip != NULL) {
 1213                 u_int16_t       oip = *ip;
 1214                 u_int32_t       opc = 0;
 1215 
 1216                 if (pc != NULL)
 1217                         opc = *pc;
 1218                 *ip = np;
 1219                 if (pc != NULL)
 1220                         *pc = pf_cksum_fixup(*pc, oip, *ip, u);
 1221                 *ic = pf_cksum_fixup(*ic, oip, *ip, 0);
 1222                 if (pc != NULL)
 1223                         *ic = pf_cksum_fixup(*ic, opc, *pc, 0);
 1224         }
 1225         /* Change inner ip address, fix inner ip and icmp checksums. */
 1226         PF_ACPY(ia, na, af);
 1227         switch (af) {
 1228 #ifdef INET
 1229         case AF_INET: {
 1230                 u_int32_t        oh2c = *h2c;
 1231 
 1232                 *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c,
 1233                     oia.addr16[0], ia->addr16[0], 0),
 1234                     oia.addr16[1], ia->addr16[1], 0);
 1235                 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
 1236                     oia.addr16[0], ia->addr16[0], 0),
 1237                     oia.addr16[1], ia->addr16[1], 0);
 1238                 *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0);
 1239                 break;
 1240         }
 1241 #endif /* INET */
 1242 #ifdef INET6
 1243         case AF_INET6:
 1244                 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
 1245                     pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
 1246                     pf_cksum_fixup(pf_cksum_fixup(*ic,
 1247                     oia.addr16[0], ia->addr16[0], u),
 1248                     oia.addr16[1], ia->addr16[1], u),
 1249                     oia.addr16[2], ia->addr16[2], u),
 1250                     oia.addr16[3], ia->addr16[3], u),
 1251                     oia.addr16[4], ia->addr16[4], u),
 1252                     oia.addr16[5], ia->addr16[5], u),
 1253                     oia.addr16[6], ia->addr16[6], u),
 1254                     oia.addr16[7], ia->addr16[7], u);
 1255                 break;
 1256 #endif /* INET6 */
 1257         }
 1258         /* Change outer ip address, fix outer ip or icmpv6 checksum. */
 1259         PF_ACPY(oa, na, af);
 1260         switch (af) {
 1261 #ifdef INET
 1262         case AF_INET:
 1263                 *hc = pf_cksum_fixup(pf_cksum_fixup(*hc,
 1264                     ooa.addr16[0], oa->addr16[0], 0),
 1265                     ooa.addr16[1], oa->addr16[1], 0);
 1266                 break;
 1267 #endif /* INET */
 1268 #ifdef INET6
 1269         case AF_INET6:
 1270                 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
 1271                     pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
 1272                     pf_cksum_fixup(pf_cksum_fixup(*ic,
 1273                     ooa.addr16[0], oa->addr16[0], u),
 1274                     ooa.addr16[1], oa->addr16[1], u),
 1275                     ooa.addr16[2], oa->addr16[2], u),
 1276                     ooa.addr16[3], oa->addr16[3], u),
 1277                     ooa.addr16[4], oa->addr16[4], u),
 1278                     ooa.addr16[5], oa->addr16[5], u),
 1279                     ooa.addr16[6], oa->addr16[6], u),
 1280                     ooa.addr16[7], oa->addr16[7], u);
 1281                 break;
 1282 #endif /* INET6 */
 1283         }
 1284 }
 1285 
 1286 void
 1287 pf_send_tcp(const struct pf_rule *r, sa_family_t af,
 1288     const struct pf_addr *saddr, const struct pf_addr *daddr,
 1289     u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
 1290     u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl)
 1291 {
 1292         struct mbuf     *m;
 1293         int              len = 0, tlen;
 1294 #ifdef INET
 1295         struct ip       *h = NULL;
 1296 #endif /* INET */
 1297 #ifdef INET6
 1298         struct ip6_hdr  *h6 = NULL;
 1299 #endif /* INET6 */
 1300         struct tcphdr   *th = NULL;
 1301         char *opt;
 1302 
 1303         /* maximum segment size tcp option */
 1304         tlen = sizeof(struct tcphdr);
 1305         if (mss)
 1306                 tlen += 4;
 1307 
 1308         switch (af) {
 1309 #ifdef INET
 1310         case AF_INET:
 1311                 len = sizeof(struct ip) + tlen;
 1312                 break;
 1313 #endif /* INET */
 1314 #ifdef INET6
 1315         case AF_INET6:
 1316                 len = sizeof(struct ip6_hdr) + tlen;
 1317                 break;
 1318 #endif /* INET6 */
 1319         }
 1320 
 1321         /* create outgoing mbuf */
 1322         m = m_gethdr(MB_DONTWAIT, MT_HEADER);
 1323         if (m == NULL)
 1324                 return;
 1325         m->m_pkthdr.fw_flags = PF_MBUF_GENERATED;
 1326 #ifdef ALTQ
 1327         if (r != NULL && r->qid) {
 1328                 m->m_pkthdr.fw_flags |= ALTQ_MBUF_TAGGED;
 1329                 m->m_pkthdr.altq_qid = r->qid;
 1330                 m->m_pkthdr.ecn_af = af;
 1331                 m->m_pkthdr.header = mtod(m, struct ip *);
 1332         }
 1333 #endif
 1334         m->m_data += max_linkhdr;
 1335         m->m_pkthdr.len = m->m_len = len;
 1336         m->m_pkthdr.rcvif = NULL;
 1337         bzero(m->m_data, len);
 1338         switch (af) {
 1339 #ifdef INET
 1340         case AF_INET:
 1341                 h = mtod(m, struct ip *);
 1342 
 1343                 /* IP header fields included in the TCP checksum */
 1344                 h->ip_p = IPPROTO_TCP;
 1345                 h->ip_len = tlen;
 1346                 h->ip_src.s_addr = saddr->v4.s_addr;
 1347                 h->ip_dst.s_addr = daddr->v4.s_addr;
 1348 
 1349                 th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip));
 1350                 break;
 1351 #endif /* INET */
 1352 #ifdef INET6
 1353         case AF_INET6:
 1354                 h6 = mtod(m, struct ip6_hdr *);
 1355 
 1356                 /* IP header fields included in the TCP checksum */
 1357                 h6->ip6_nxt = IPPROTO_TCP;
 1358                 h6->ip6_plen = htons(tlen);
 1359                 memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr));
 1360                 memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr));
 1361 
 1362                 th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr));
 1363                 break;
 1364 #endif /* INET6 */
 1365         }
 1366 
 1367         /* TCP header */
 1368         th->th_sport = sport;
 1369         th->th_dport = dport;
 1370         th->th_seq = htonl(seq);
 1371         th->th_ack = htonl(ack);
 1372         th->th_off = tlen >> 2;
 1373         th->th_flags = flags;
 1374         th->th_win = htons(win);
 1375 
 1376         if (mss) {
 1377                 opt = (char *)(th + 1);
 1378                 opt[0] = TCPOPT_MAXSEG;
 1379                 opt[1] = 4;
 1380                 mss = htons(mss);
 1381                 bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2);
 1382         }
 1383 
 1384         switch (af) {
 1385 #ifdef INET
 1386         case AF_INET:
 1387                 /* TCP checksum */
 1388                 th->th_sum = in_cksum(m, len);
 1389 
 1390                 /* Finish the IP header */
 1391                 h->ip_v = 4;
 1392                 h->ip_hl = sizeof(*h) >> 2;
 1393                 h->ip_tos = IPTOS_LOWDELAY;
 1394                 h->ip_len = len;
 1395                 h->ip_off = path_mtu_discovery ? IP_DF : 0;
 1396                 h->ip_ttl = ttl ? ttl : ip_defttl;
 1397                 h->ip_sum = 0;
 1398                 ip_output(m, NULL, NULL, 0, NULL, NULL);
 1399                 break;
 1400 #endif /* INET */
 1401 #ifdef INET6
 1402         case AF_INET6:
 1403                 /* TCP checksum */
 1404                 th->th_sum = in6_cksum(m, IPPROTO_TCP,
 1405                     sizeof(struct ip6_hdr), tlen);
 1406 
 1407                 h6->ip6_vfc |= IPV6_VERSION;
 1408                 h6->ip6_hlim = IPV6_DEFHLIM;
 1409 
 1410                 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
 1411                 break;
 1412 #endif /* INET6 */
 1413         }
 1414 }
 1415 
 1416 void
 1417 pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
 1418     struct pf_rule *r)
 1419 {
 1420         struct mbuf     *m0;
 1421 
 1422         m0 = m_copypacket(m, MB_DONTWAIT);
 1423         if (m0 == NULL)
 1424                 return;
 1425         m0->m_pkthdr.fw_flags |= PF_MBUF_GENERATED;
 1426 
 1427 #ifdef ALTQ
 1428         if (r->qid) {
 1429                 m->m_pkthdr.fw_flags |= ALTQ_MBUF_TAGGED;
 1430                 m->m_pkthdr.altq_qid = r->qid;
 1431                 m->m_pkthdr.ecn_af = af;
 1432                 m->m_pkthdr.header = mtod(m0, struct ip *);
 1433         }
 1434 #endif
 1435 
 1436         switch (af) {
 1437 #ifdef INET
 1438         case AF_INET:
 1439                 icmp_error(m0, type, code, 0, 0);
 1440                 break;
 1441 #endif /* INET */
 1442 #ifdef INET6
 1443         case AF_INET6:
 1444                 icmp6_error(m0, type, code, 0);
 1445                 break;
 1446 #endif /* INET6 */
 1447         }
 1448 }
 1449 
 1450 /*
 1451  * Return 1 if the addresses a and b match (with mask m), otherwise return 0.
 1452  * If n is 0, they match if they are equal. If n is != 0, they match if they
 1453  * are different.
 1454  */
 1455 int
 1456 pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
 1457     struct pf_addr *b, sa_family_t af)
 1458 {
 1459         int     match = 0;
 1460 
 1461         switch (af) {
 1462 #ifdef INET
 1463         case AF_INET:
 1464                 if ((a->addr32[0] & m->addr32[0]) ==
 1465                     (b->addr32[0] & m->addr32[0]))
 1466                         match++;
 1467                 break;
 1468 #endif /* INET */
 1469 #ifdef INET6
 1470         case AF_INET6:
 1471                 if (((a->addr32[0] & m->addr32[0]) ==
 1472                      (b->addr32[0] & m->addr32[0])) &&
 1473                     ((a->addr32[1] & m->addr32[1]) ==
 1474                      (b->addr32[1] & m->addr32[1])) &&
 1475                     ((a->addr32[2] & m->addr32[2]) ==
 1476                      (b->addr32[2] & m->addr32[2])) &&
 1477                     ((a->addr32[3] & m->addr32[3]) ==
 1478                      (b->addr32[3] & m->addr32[3])))
 1479                         match++;
 1480                 break;
 1481 #endif /* INET6 */
 1482         }
 1483         if (match) {
 1484                 if (n)
 1485                         return (0);
 1486                 else
 1487                         return (1);
 1488         } else {
 1489                 if (n)
 1490                         return (1);
 1491                 else
 1492                         return (0);
 1493         }
 1494 }
 1495 
 1496 int
 1497 pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
 1498 {
 1499         switch (op) {
 1500         case PF_OP_IRG:
 1501                 return ((p > a1) && (p < a2));
 1502         case PF_OP_XRG:
 1503                 return ((p < a1) || (p > a2));
 1504         case PF_OP_RRG:
 1505                 return ((p >= a1) && (p <= a2));
 1506         case PF_OP_EQ:
 1507                 return (p == a1);
 1508         case PF_OP_NE:
 1509                 return (p != a1);
 1510         case PF_OP_LT:
 1511                 return (p < a1);
 1512         case PF_OP_LE:
 1513                 return (p <= a1);
 1514         case PF_OP_GT:
 1515                 return (p > a1);
 1516         case PF_OP_GE:
 1517                 return (p >= a1);
 1518         }
 1519         return (0); /* never reached */
 1520 }
 1521 
 1522 int
 1523 pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
 1524 {
 1525         a1 = ntohs(a1);
 1526         a2 = ntohs(a2);
 1527         p = ntohs(p);
 1528         return (pf_match(op, a1, a2, p));
 1529 }
 1530 
 1531 int
 1532 pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
 1533 {
 1534         if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
 1535                 return (0);
 1536         return (pf_match(op, a1, a2, u));
 1537 }
 1538 
 1539 int
 1540 pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
 1541 {
 1542         if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
 1543                 return (0);
 1544         return (pf_match(op, a1, a2, g));
 1545 }
 1546 
 1547 static int
 1548 pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_rule *nat_rule,
 1549              int *tag)
 1550 {
 1551         if (*tag == -1) {       /* find mbuf tag */
 1552                 if (nat_rule != NULL && nat_rule->tag)
 1553                         *tag = nat_rule->tag;
 1554                 else if (m->m_pkthdr.fw_flags & PF_MBUF_TAGGED)
 1555                         *tag = m->m_pkthdr.pf_tag;
 1556                 else
 1557                         *tag = 0;
 1558         }
 1559 
 1560         return ((!r->match_tag_not && r->match_tag == *tag) ||
 1561             (r->match_tag_not && r->match_tag != *tag));
 1562 }
 1563 
 1564 void
 1565 pf_tag_packet(struct mbuf *m, int tag)
 1566 {
 1567         if (tag <= 0)
 1568                 return;
 1569 
 1570         m->m_pkthdr.fw_flags |= PF_MBUF_TAGGED;
 1571         m->m_pkthdr.pf_tag = tag;
 1572 }
 1573 
 1574 #define PF_STEP_INTO_ANCHOR(r, a, s, n)                                 \
 1575         do {                                                            \
 1576                 if ((r) == NULL || (r)->anchor == NULL ||               \
 1577                     (s) != NULL || (a) != NULL)                         \
 1578                         panic("PF_STEP_INTO_ANCHOR");                   \
 1579                 (a) = (r);                                              \
 1580                 (s) = TAILQ_FIRST(&(r)->anchor->rulesets);              \
 1581                 (r) = NULL;                                             \
 1582                 while ((s) != NULL && ((r) =                            \
 1583                     TAILQ_FIRST((s)->rules[n].active.ptr)) == NULL)     \
 1584                         (s) = TAILQ_NEXT((s), entries);                 \
 1585                 if ((r) == NULL) {                                      \
 1586                         (r) = TAILQ_NEXT((a), entries);                 \
 1587                         (a) = NULL;                                     \
 1588                 }                                                       \
 1589         } while (0)
 1590 
 1591 #define PF_STEP_OUT_OF_ANCHOR(r, a, s, n)                               \
 1592         do {                                                            \
 1593                 if ((r) != NULL || (a) == NULL || (s) == NULL)          \
 1594                         panic("PF_STEP_OUT_OF_ANCHOR");                 \
 1595                 (s) = TAILQ_NEXT((s), entries);                         \
 1596                 while ((s) != NULL && ((r) =                            \
 1597                     TAILQ_FIRST((s)->rules[n].active.ptr)) == NULL)     \
 1598                         (s) = TAILQ_NEXT((s), entries);                 \
 1599                 if ((r) == NULL) {                                      \
 1600                         (r) = TAILQ_NEXT((a), entries);                 \
 1601                         (a) = NULL;                                     \
 1602                 }                                                       \
 1603         } while (0)
 1604 
 1605 #ifdef INET6
 1606 void
 1607 pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
 1608     struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af)
 1609 {
 1610         switch (af) {
 1611 #ifdef INET
 1612         case AF_INET:
 1613                 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
 1614                 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
 1615                 break;
 1616 #endif /* INET */
 1617         case AF_INET6:
 1618                 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
 1619                 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
 1620                 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) |
 1621                 ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]);
 1622                 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) |
 1623                 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]);
 1624                 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) |
 1625                 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]);
 1626                 break;
 1627         }
 1628 }
 1629 
 1630 void
 1631 pf_addr_inc(struct pf_addr *addr, sa_family_t af)
 1632 {
 1633         switch (af) {
 1634 #ifdef INET
 1635         case AF_INET:
 1636                 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1);
 1637                 break;
 1638 #endif /* INET */
 1639         case AF_INET6:
 1640                 if (addr->addr32[3] == 0xffffffff) {
 1641                         addr->addr32[3] = 0;
 1642                         if (addr->addr32[2] == 0xffffffff) {
 1643                                 addr->addr32[2] = 0;
 1644                                 if (addr->addr32[1] == 0xffffffff) {
 1645                                         addr->addr32[1] = 0;
 1646                                         addr->addr32[0] =
 1647                                             htonl(ntohl(addr->addr32[0]) + 1);
 1648                                 } else
 1649                                         addr->addr32[1] =
 1650                                             htonl(ntohl(addr->addr32[1]) + 1);
 1651                         } else
 1652                                 addr->addr32[2] =
 1653                                     htonl(ntohl(addr->addr32[2]) + 1);
 1654                 } else
 1655                         addr->addr32[3] =
 1656                             htonl(ntohl(addr->addr32[3]) + 1);
 1657                 break;
 1658         }
 1659 }
 1660 #endif /* INET6 */
 1661 
 1662 #define mix(a,b,c) \
 1663         do {                                    \
 1664                 a -= b; a -= c; a ^= (c >> 13); \
 1665                 b -= c; b -= a; b ^= (a << 8);  \
 1666                 c -= a; c -= b; c ^= (b >> 13); \
 1667                 a -= b; a -= c; a ^= (c >> 12); \
 1668                 b -= c; b -= a; b ^= (a << 16); \
 1669                 c -= a; c -= b; c ^= (b >> 5);  \
 1670                 a -= b; a -= c; a ^= (c >> 3);  \
 1671                 b -= c; b -= a; b ^= (a << 10); \
 1672                 c -= a; c -= b; c ^= (b >> 15); \
 1673         } while (0)
 1674 
 1675 /*
 1676  * hash function based on bridge_hash in if_bridge.c
 1677  */
 1678 void
 1679 pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
 1680     struct pf_poolhashkey *key, sa_family_t af)
 1681 {
 1682         u_int32_t       a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0];
 1683 
 1684         switch (af) {
 1685 #ifdef INET
 1686         case AF_INET:
 1687                 a += inaddr->addr32[0];
 1688                 b += key->key32[1];
 1689                 mix(a, b, c);
 1690                 hash->addr32[0] = c + key->key32[2];
 1691                 break;
 1692 #endif /* INET */
 1693 #ifdef INET6
 1694         case AF_INET6:
 1695                 a += inaddr->addr32[0];
 1696                 b += inaddr->addr32[2];
 1697                 mix(a, b, c);
 1698                 hash->addr32[0] = c;
 1699                 a += inaddr->addr32[1];
 1700                 b += inaddr->addr32[3];
 1701                 c += key->key32[1];
 1702                 mix(a, b, c);
 1703                 hash->addr32[1] = c;
 1704                 a += inaddr->addr32[2];
 1705                 b += inaddr->addr32[1];
 1706                 c += key->key32[2];
 1707                 mix(a, b, c);
 1708                 hash->addr32[2] = c;
 1709                 a += inaddr->addr32[3];
 1710                 b += inaddr->addr32[0];
 1711                 c += key->key32[3];
 1712                 mix(a, b, c);
 1713                 hash->addr32[3] = c;
 1714                 break;
 1715 #endif /* INET6 */
 1716         }
 1717 }
 1718 
 1719 int
 1720 pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
 1721     struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
 1722 {
 1723         unsigned char            hash[16];
 1724         struct pf_pool          *rpool = &r->rpool;
 1725         struct pf_addr          *raddr = &rpool->cur->addr.v.a.addr;
 1726         struct pf_addr          *rmask = &rpool->cur->addr.v.a.mask;
 1727         struct pf_pooladdr      *acur = rpool->cur;
 1728         struct pf_src_node       k;
 1729 
 1730         if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
 1731             (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
 1732                 k.af = af;
 1733                 PF_ACPY(&k.addr, saddr, af);
 1734                 if (r->rule_flag & PFRULE_RULESRCTRACK ||
 1735                     r->rpool.opts & PF_POOL_STICKYADDR)
 1736                         k.rule.ptr = r;
 1737                 else
 1738                         k.rule.ptr = NULL;
 1739                 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
 1740                 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
 1741                 if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
 1742                         PF_ACPY(naddr, &(*sn)->raddr, af);
 1743                         if (pf_status.debug >= PF_DEBUG_MISC) {
 1744                                 kprintf("pf_map_addr: src tracking maps ");
 1745                                 pf_print_host(&k.addr, 0, af);
 1746                                 kprintf(" to ");
 1747                                 pf_print_host(naddr, 0, af);
 1748                                 kprintf("\n");
 1749                         }
 1750                         return (0);
 1751                 }
 1752         }
 1753 
 1754         if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
 1755                 return (1);
 1756         if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
 1757                 if (af == AF_INET) {
 1758                         if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
 1759                             (rpool->opts & PF_POOL_TYPEMASK) !=
 1760                             PF_POOL_ROUNDROBIN)
 1761                                 return (1);
 1762                          raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
 1763                          rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
 1764                 } else {
 1765                         if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
 1766                             (rpool->opts & PF_POOL_TYPEMASK) !=
 1767                             PF_POOL_ROUNDROBIN)
 1768                                 return (1);
 1769                         raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
 1770                         rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
 1771                 }
 1772         } else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
 1773                 if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
 1774                         return (1); /* unsupported */
 1775         } else {
 1776                 raddr = &rpool->cur->addr.v.a.addr;
 1777                 rmask = &rpool->cur->addr.v.a.mask;
 1778         }
 1779 
 1780         switch (rpool->opts & PF_POOL_TYPEMASK) {
 1781         case PF_POOL_NONE:
 1782                 PF_ACPY(naddr, raddr, af);
 1783                 break;
 1784         case PF_POOL_BITMASK:
 1785                 PF_POOLMASK(naddr, raddr, rmask, saddr, af);
 1786                 break;
 1787         case PF_POOL_RANDOM:
 1788                 if (init_addr != NULL && PF_AZERO(init_addr, af)) {
 1789                         switch (af) {
 1790 #ifdef INET
 1791                         case AF_INET:
 1792                                 rpool->counter.addr32[0] = karc4random();
 1793                                 break;
 1794 #endif /* INET */
 1795 #ifdef INET6
 1796                         case AF_INET6:
 1797                                 if (rmask->addr32[3] != 0xffffffff)
 1798                                         rpool->counter.addr32[3] = karc4random();
 1799                                 else
 1800                                         break;
 1801                                 if (rmask->addr32[2] != 0xffffffff)
 1802                                         rpool->counter.addr32[2] = karc4random();
 1803                                 else
 1804                                         break;
 1805                                 if (rmask->addr32[1] != 0xffffffff)
 1806                                         rpool->counter.addr32[1] = karc4random();
 1807                                 else
 1808                                         break;
 1809                                 if (rmask->addr32[0] != 0xffffffff)
 1810                                         rpool->counter.addr32[0] = karc4random();
 1811                                 break;
 1812 #endif /* INET6 */
 1813                         }
 1814                         PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
 1815                         PF_ACPY(init_addr, naddr, af);
 1816 
 1817                 } else {
 1818                         PF_AINC(&rpool->counter, af);
 1819                         PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
 1820                 }
 1821                 break;
 1822         case PF_POOL_SRCHASH:
 1823                 pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
 1824                 PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
 1825                 break;
 1826         case PF_POOL_ROUNDROBIN:
 1827                 if (rpool->cur->addr.type == PF_ADDR_TABLE) {
 1828                         if (!pfr_pool_get(rpool->cur->addr.p.tbl,
 1829                             &rpool->tblidx, &rpool->counter,
 1830                             &raddr, &rmask, af))
 1831                                 goto get_addr;
 1832                 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
 1833                         if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
 1834                             &rpool->tblidx, &rpool->counter,
 1835                             &raddr, &rmask, af))
 1836                                 goto get_addr;
 1837                 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
 1838                         goto get_addr;
 1839 
 1840         try_next:
 1841                 if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL)
 1842                         rpool->cur = TAILQ_FIRST(&rpool->list);
 1843                 if (rpool->cur->addr.type == PF_ADDR_TABLE) {
 1844                         rpool->tblidx = -1;
 1845                         if (pfr_pool_get(rpool->cur->addr.p.tbl,
 1846                             &rpool->tblidx, &rpool->counter,
 1847                             &raddr, &rmask, af)) {
 1848                                 /* table contains no address of type 'af' */
 1849                                 if (rpool->cur != acur)
 1850                                         goto try_next;
 1851                                 return (1);
 1852                         }
 1853                 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
 1854                         rpool->tblidx = -1;
 1855                         if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
 1856                             &rpool->tblidx, &rpool->counter,
 1857                             &raddr, &rmask, af)) {
 1858                                 /* table contains no address of type 'af' */
 1859                                 if (rpool->cur != acur)
 1860                                         goto try_next;
 1861                                 return (1);
 1862                         }
 1863                 } else {
 1864                         raddr = &rpool->cur->addr.v.a.addr;
 1865                         rmask = &rpool->cur->addr.v.a.mask;
 1866                         PF_ACPY(&rpool->counter, raddr, af);
 1867                 }
 1868 
 1869         get_addr:
 1870                 PF_ACPY(naddr, &rpool->counter, af);
 1871                 PF_AINC(&rpool->counter, af);
 1872                 break;
 1873         }
 1874         if (*sn != NULL)
 1875                 PF_ACPY(&(*sn)->raddr, naddr, af);
 1876 
 1877         if (pf_status.debug >= PF_DEBUG_MISC &&
 1878             (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
 1879                 kprintf("pf_map_addr: selected address ");
 1880                 pf_print_host(naddr, 0, af);
 1881                 kprintf("\n");
 1882         }
 1883 
 1884         return (0);
 1885 }
 1886 
 1887 int
 1888 pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
 1889     struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
 1890     struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
 1891     struct pf_src_node **sn)
 1892 {
 1893         struct pf_state         key;
 1894         struct pf_addr          init_addr;
 1895         u_int16_t               cut;
 1896 
 1897         bzero(&init_addr, sizeof(init_addr));
 1898         if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
 1899                 return (1);
 1900 
 1901         do {
 1902                 key.af = af;
 1903                 key.proto = proto;
 1904                 PF_ACPY(&key.ext.addr, daddr, key.af);
 1905                 PF_ACPY(&key.gwy.addr, naddr, key.af);
 1906                 key.ext.port = dport;
 1907 
 1908                 /*
 1909                  * port search; start random, step;
 1910                  * similar 2 portloop in in_pcbbind
 1911                  */
 1912                 if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP)) {
 1913                         key.gwy.port = 0;
 1914                         if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
 1915                                 return (0);
 1916                 } else if (low == 0 && high == 0) {
 1917                         key.gwy.port = *nport;
 1918                         if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
 1919                                 return (0);
 1920                 } else if (low == high) {
 1921                         key.gwy.port = htons(low);
 1922                         if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) {
 1923                                 *nport = htons(low);
 1924                                 return (0);
 1925                         }
 1926                 } else {
 1927                         u_int16_t tmp;
 1928 
 1929                         if (low > high) {
 1930                                 tmp = low;
 1931                                 low = high;
 1932                                 high = tmp;
 1933                         }
 1934                         /* low < high */
 1935                         cut = karc4random() % (1 + high - low) + low;
 1936                         /* low <= cut <= high */
 1937                         for (tmp = cut; tmp <= high; ++(tmp)) {
 1938                                 key.gwy.port = htons(tmp);
 1939                                 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
 1940                                     NULL) {
 1941                                         *nport = htons(tmp);
 1942                                         return (0);
 1943                                 }
 1944                         }
 1945                         for (tmp = cut - 1; tmp >= low; --(tmp)) {
 1946                                 key.gwy.port = htons(tmp);
 1947                                 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
 1948                                     NULL) {
 1949                                         *nport = htons(tmp);
 1950                                         return (0);
 1951                                 }
 1952                         }
 1953                 }
 1954 
 1955                 switch (r->rpool.opts & PF_POOL_TYPEMASK) {
 1956                 case PF_POOL_RANDOM:
 1957                 case PF_POOL_ROUNDROBIN:
 1958                         if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
 1959                                 return (1);
 1960                         break;
 1961                 case PF_POOL_NONE:
 1962                 case PF_POOL_SRCHASH:
 1963                 case PF_POOL_BITMASK:
 1964                 default:
 1965                         return (1);
 1966                 }
 1967         } while (! PF_AEQ(&init_addr, naddr, af) );
 1968 
 1969         return (1);                                     /* none available */
 1970 }
 1971 
 1972 struct pf_rule *
 1973 pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
 1974     int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
 1975     struct pf_addr *daddr, u_int16_t dport, int rs_num)
 1976 {
 1977         struct pf_rule          *r, *rm = NULL, *anchorrule = NULL;
 1978         struct pf_ruleset       *ruleset = NULL;
 1979 
 1980         r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
 1981         while (r && rm == NULL) {
 1982                 struct pf_rule_addr     *src = NULL, *dst = NULL;
 1983                 struct pf_addr_wrap     *xdst = NULL;
 1984 
 1985                 if (r->action == PF_BINAT && direction == PF_IN) {
 1986                         src = &r->dst;
 1987                         if (r->rpool.cur != NULL)
 1988                                 xdst = &r->rpool.cur->addr;
 1989                 } else {
 1990                         src = &r->src;
 1991                         dst = &r->dst;
 1992                 }
 1993 
 1994                 r->evaluations++;
 1995                 if (r->kif != NULL &&
 1996                     (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
 1997                         r = r->skip[PF_SKIP_IFP].ptr;
 1998                 else if (r->direction && r->direction != direction)
 1999                         r = r->skip[PF_SKIP_DIR].ptr;
 2000                 else if (r->af && r->af != pd->af)
 2001                         r = r->skip[PF_SKIP_AF].ptr;
 2002                 else if (r->proto && r->proto != pd->proto)
 2003                         r = r->skip[PF_SKIP_PROTO].ptr;
 2004                 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, src->not))
 2005                         r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR :
 2006                             PF_SKIP_DST_ADDR].ptr;
 2007                 else if (src->port_op && !pf_match_port(src->port_op,
 2008                     src->port[0], src->port[1], sport))
 2009                         r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
 2010                             PF_SKIP_DST_PORT].ptr;
 2011                 else if (dst != NULL &&
 2012                     PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->not))
 2013                         r = r->skip[PF_SKIP_DST_ADDR].ptr;
 2014                 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, 0))
 2015                         r = TAILQ_NEXT(r, entries);
 2016                 else if (dst != NULL && dst->port_op &&
 2017                     !pf_match_port(dst->port_op, dst->port[0],
 2018                     dst->port[1], dport))
 2019                         r = r->skip[PF_SKIP_DST_PORT].ptr;
 2020                 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
 2021                     IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
 2022                     off, pd->hdr.tcp), r->os_fingerprint)))
 2023                         r = TAILQ_NEXT(r, entries);
 2024                 else if (r->anchorname[0] && r->anchor == NULL)
 2025                         r = TAILQ_NEXT(r, entries);
 2026                 else if (r->anchor == NULL)
 2027                                 rm = r;
 2028                 else
 2029                         PF_STEP_INTO_ANCHOR(r, anchorrule, ruleset, rs_num);
 2030                 if (r == NULL && anchorrule != NULL)
 2031                         PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset,
 2032                             rs_num);
 2033         }
 2034         if (rm != NULL && (rm->action == PF_NONAT ||
 2035             rm->action == PF_NORDR || rm->action == PF_NOBINAT))
 2036                 return (NULL);
 2037         return (rm);
 2038 }
 2039 
 2040 struct pf_rule *
 2041 pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
 2042     struct pfi_kif *kif, struct pf_src_node **sn,
 2043     struct pf_addr *saddr, u_int16_t sport,
 2044     struct pf_addr *daddr, u_int16_t dport,
 2045     struct pf_addr *naddr, u_int16_t *nport)
 2046 {
 2047         struct pf_rule  *r = NULL;
 2048 
 2049         if (direction == PF_OUT) {
 2050                 r = pf_match_translation(pd, m, off, direction, kif, saddr,
 2051                     sport, daddr, dport, PF_RULESET_BINAT);
 2052                 if (r == NULL)
 2053                         r = pf_match_translation(pd, m, off, direction, kif,
 2054                             saddr, sport, daddr, dport, PF_RULESET_NAT);
 2055         } else {
 2056                 r = pf_match_translation(pd, m, off, direction, kif, saddr,
 2057                     sport, daddr, dport, PF_RULESET_RDR);
 2058                 if (r == NULL)
 2059                         r = pf_match_translation(pd, m, off, direction, kif,
 2060                             saddr, sport, daddr, dport, PF_RULESET_BINAT);
 2061         }
 2062 
 2063         if (r != NULL) {
 2064                 switch (r->action) {
 2065                 case PF_NONAT:
 2066                 case PF_NOBINAT:
 2067                 case PF_NORDR:
 2068                         return (NULL);
 2069                 case PF_NAT:
 2070                         if (pf_get_sport(pd->af, pd->proto, r, saddr,
 2071                             daddr, dport, naddr, nport, r->rpool.proxy_port[0],
 2072                             r->rpool.proxy_port[1], sn)) {
 2073                                 DPFPRINTF(PF_DEBUG_MISC,
 2074                                     ("pf: NAT proxy port allocation "
 2075                                     "(%u-%u) failed\n",
 2076                                     r->rpool.proxy_port[0],
 2077                                     r->rpool.proxy_port[1]));
 2078                                 return (NULL);
 2079                         }
 2080                         break;
 2081                 case PF_BINAT:
 2082                         switch (direction) {
 2083                         case PF_OUT:
 2084                                 if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
 2085                                         if (pd->af == AF_INET) {
 2086                                                 if (r->rpool.cur->addr.p.dyn->
 2087                                                     pfid_acnt4 < 1)
 2088                                                         return (NULL);
 2089                                                 PF_POOLMASK(naddr,
 2090                                                     &r->rpool.cur->addr.p.dyn->
 2091                                                     pfid_addr4,
 2092                                                     &r->rpool.cur->addr.p.dyn->
 2093                                                     pfid_mask4,
 2094                                                     saddr, AF_INET);
 2095                                         } else {
 2096                                                 if (r->rpool.cur->addr.p.dyn->
 2097                                                     pfid_acnt6 < 1)
 2098                                                         return (NULL);
 2099                                                 PF_POOLMASK(naddr,
 2100                                                     &r->rpool.cur->addr.p.dyn->
 2101                                                     pfid_addr6,
 2102                                                     &r->rpool.cur->addr.p.dyn->
 2103                                                     pfid_mask6,
 2104                                                     saddr, AF_INET6);
 2105                                         }
 2106                                 } else
 2107                                         PF_POOLMASK(naddr,
 2108                                             &r->rpool.cur->addr.v.a.addr,
 2109                                             &r->rpool.cur->addr.v.a.mask,
 2110                                             saddr, pd->af);
 2111                                 break;
 2112                         case PF_IN:
 2113                                 if (r->src.addr.type == PF_ADDR_DYNIFTL){
 2114                                         if (pd->af == AF_INET) {
 2115                                                 if (r->src.addr.p.dyn->
 2116                                                     pfid_acnt4 < 1)
 2117                                                         return (NULL);
 2118                                                 PF_POOLMASK(naddr,
 2119                                                     &r->src.addr.p.dyn->
 2120                                                     pfid_addr4,
 2121                                                     &r->src.addr.p.dyn->
 2122                                                     pfid_mask4,
 2123                                                     daddr, AF_INET);
 2124                                         } else {
 2125                                                 if (r->src.addr.p.dyn->
 2126                                                     pfid_acnt6 < 1)
 2127                                                         return (NULL);
 2128                                                 PF_POOLMASK(naddr,
 2129                                                     &r->src.addr.p.dyn->
 2130                                                     pfid_addr6,
 2131                                                     &r->src.addr.p.dyn->
 2132                                                     pfid_mask6,
 2133                                                     daddr, AF_INET6);
 2134                                         }
 2135                                 } else
 2136                                         PF_POOLMASK(naddr,
 2137                                             &r->src.addr.v.a.addr,
 2138                                             &r->src.addr.v.a.mask, daddr,
 2139                                             pd->af);
 2140                                 break;
 2141                         }
 2142                         break;
 2143                 case PF_RDR: {
 2144                         if (pf_map_addr(r->af, r, saddr, naddr, NULL, sn))
 2145                                 return (NULL);
 2146 
 2147                         if (r->rpool.proxy_port[1]) {
 2148                                 u_int32_t       tmp_nport;
 2149 
 2150                                 tmp_nport = ((ntohs(dport) -
 2151                                     ntohs(r->dst.port[0])) %
 2152                                     (r->rpool.proxy_port[1] -
 2153                                     r->rpool.proxy_port[0] + 1)) +
 2154                                     r->rpool.proxy_port[0];
 2155 
 2156                                 /* wrap around if necessary */
 2157                                 if (tmp_nport > 65535)
 2158                                         tmp_nport -= 65535;
 2159                                 *nport = htons((u_int16_t)tmp_nport);
 2160                         } else if (r->rpool.proxy_port[0])
 2161                                 *nport = htons(r->rpool.proxy_port[0]);
 2162                         break;
 2163                 }
 2164                 default:
 2165                         return (NULL);
 2166                 }
 2167         }
 2168 
 2169         return (r);
 2170 }
 2171 
 2172 #ifdef SMP
 2173 struct netmsg_hashlookup {
 2174         struct netmsg           nm_netmsg;
 2175         struct inpcb            **nm_pinp;
 2176         struct inpcbinfo        *nm_pcbinfo;
 2177         struct pf_addr          *nm_saddr;
 2178         struct pf_addr          *nm_daddr;
 2179         uint16_t                nm_sport;
 2180         uint16_t                nm_dport;
 2181         sa_family_t             nm_af;
 2182 };
 2183 
 2184 static void
 2185 in_pcblookup_hash_handler(struct netmsg *msg0)
 2186 {
 2187         struct netmsg_hashlookup *msg = (struct netmsg_hashlookup *)msg0;
 2188 
 2189         if (msg->nm_af == AF_INET)
 2190                 *msg->nm_pinp = in_pcblookup_hash(msg->nm_pcbinfo,
 2191                     msg->nm_saddr->v4, msg->nm_sport, msg->nm_daddr->v4,
 2192                     msg->nm_dport, INPLOOKUP_WILDCARD, NULL);
 2193 #ifdef INET6
 2194         else
 2195                 *msg->nm_pinp = in6_pcblookup_hash(msg->nm_pcbinfo,
 2196                     &msg->nm_saddr->v6, msg->nm_sport, &msg->nm_daddr->v6,
 2197                     msg->nm_dport, INPLOOKUP_WILDCARD, NULL);
 2198 #endif /* INET6 */
 2199         lwkt_replymsg(&msg->nm_netmsg.nm_lmsg, 0);
 2200 }
 2201 #endif /* SMP */
 2202 
 2203 int
 2204 pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd)
 2205 {
 2206         struct pf_addr          *saddr, *daddr;
 2207         u_int16_t                sport, dport;
 2208         struct inpcbinfo        *pi;
 2209         struct inpcb            *inp;
 2210 #ifdef SMP
 2211         struct netmsg_hashlookup *msg = NULL;
 2212 #endif
 2213         int                      pi_cpu = 0;
 2214 
 2215         *uid = UID_MAX;
 2216         *gid = GID_MAX;
 2217         if (direction == PF_IN) {
 2218                 saddr = pd->src;
 2219                 daddr = pd->dst;
 2220         } else {
 2221                 saddr = pd->dst;
 2222                 daddr = pd->src;
 2223         }
 2224         switch (pd->proto) {
 2225         case IPPROTO_TCP:
 2226                 sport = pd->hdr.tcp->th_sport;
 2227                 dport = pd->hdr.tcp->th_dport;
 2228 
 2229                 pi_cpu = tcp_addrcpu(saddr->v4.s_addr, sport, daddr->v4.s_addr, dport);
 2230                 pi = &tcbinfo[pi_cpu];
 2231 #ifdef SMP
 2232                 /*
 2233                  * Our netstack runs lockless on MP systems
 2234                  * (only for TCP connections at the moment).
 2235                  * 
 2236                  * As we are not allowed to read another CPU's tcbinfo,
 2237                  * we have to ask that CPU via remote call to search the
 2238                  * table for us.
 2239                  * 
 2240                  * Prepare a msg iff data belongs to another CPU.
 2241                  */
 2242                 if (pi_cpu != mycpu->gd_cpuid) {
 2243                         msg = kmalloc(sizeof(*msg), M_LWKTMSG, M_INTWAIT);
 2244                         netmsg_init(&msg->nm_netmsg, &netisr_afree_rport, 0,
 2245                                     in_pcblookup_hash_handler);
 2246                         msg->nm_pinp = &inp;
 2247                         msg->nm_pcbinfo = pi;
 2248                         msg->nm_saddr = saddr;
 2249                         msg->nm_sport = sport;
 2250                         msg->nm_daddr = daddr;
 2251                         msg->nm_dport = dport;
 2252                         msg->nm_af = pd->af;
 2253                 }
 2254 #endif /* SMP */
 2255                 break;
 2256         case IPPROTO_UDP:
 2257                 sport = pd->hdr.udp->uh_sport;
 2258                 dport = pd->hdr.udp->uh_dport;
 2259                 pi = &udbinfo;
 2260                 break;
 2261         default:
 2262                 return (0);
 2263         }
 2264         if (direction != PF_IN) {
 2265                 u_int16_t       p;
 2266 
 2267                 p = sport;
 2268                 sport = dport;
 2269                 dport = p;
 2270         }
 2271         switch (pd->af) {
 2272 #ifdef INET6
 2273         case AF_INET6:
 2274 #ifdef SMP
 2275                 /*
 2276                  * Query other CPU, second part
 2277                  * 
 2278                  * msg only gets initialized when:
 2279                  * 1) packet is TCP
 2280                  * 2) the info belongs to another CPU
 2281                  *
 2282                  * Use some switch/case magic to avoid code duplication.
 2283                  */
 2284                 if (msg == NULL)
 2285 #endif /* SMP */
 2286                 {
 2287                         inp = in6_pcblookup_hash(pi, &saddr->v6, sport,
 2288                             &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL);
 2289 
 2290                         if (inp == NULL)
 2291                                 return (0);
 2292                         break;
 2293                 }
 2294                 /* FALLTHROUGH if SMP and on other CPU */
 2295 #endif /* INET6 */
 2296         case AF_INET:
 2297 #ifdef SMP
 2298                 if (msg != NULL) {
 2299                         lwkt_sendmsg(tcp_cport(pi_cpu),
 2300                                      &msg->nm_netmsg.nm_lmsg);
 2301                 } else
 2302 #endif /* SMP */
 2303                 {
 2304                         inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4,
 2305                             dport, INPLOOKUP_WILDCARD, NULL);
 2306                 }
 2307                 if (inp == NULL)
 2308                         return (0);
 2309                 break;
 2310 
 2311         default:
 2312                 return (0);
 2313         }
 2314         *uid = inp->inp_socket->so_cred->cr_uid;
 2315         *gid = inp->inp_socket->so_cred->cr_groups[0];
 2316         return (1);
 2317 }
 2318 
 2319 u_int8_t
 2320 pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
 2321 {
 2322         int              hlen;
 2323         u_int8_t         hdr[60];
 2324         u_int8_t        *opt, optlen;
 2325         u_int8_t         wscale = 0;
 2326 
 2327         hlen = th_off << 2;             /* hlen <= sizeof(hdr) */
 2328         if (hlen <= sizeof(struct tcphdr))
 2329                 return (0);
 2330         if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
 2331                 return (0);
 2332         opt = hdr + sizeof(struct tcphdr);
 2333         hlen -= sizeof(struct tcphdr);
 2334         while (hlen >= 3) {
 2335                 switch (*opt) {
 2336                 case TCPOPT_EOL:
 2337                 case TCPOPT_NOP:
 2338                         ++opt;
 2339                         --hlen;
 2340                         break;
 2341                 case TCPOPT_WINDOW:
 2342                         wscale = opt[2];
 2343                         if (wscale > TCP_MAX_WINSHIFT)
 2344                                 wscale = TCP_MAX_WINSHIFT;
 2345                         wscale |= PF_WSCALE_FLAG;
 2346                         /* FALLTHROUGH */
 2347                 default:
 2348                         optlen = opt[1];
 2349                         if (optlen < 2)
 2350                                 optlen = 2;
 2351                         hlen -= optlen;
 2352                         opt += optlen;
 2353                         break;
 2354                 }
 2355         }
 2356         return (wscale);
 2357 }
 2358 
 2359 u_int16_t
 2360 pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
 2361 {
 2362         int              hlen;
 2363         u_int8_t         hdr[60];
 2364         u_int8_t        *opt, optlen;
 2365         u_int16_t        mss = tcp_mssdflt;
 2366 
 2367         hlen = th_off << 2;     /* hlen <= sizeof(hdr) */
 2368         if (hlen <= sizeof(struct tcphdr))
 2369                 return (0);
 2370         if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
 2371                 return (0);
 2372         opt = hdr + sizeof(struct tcphdr);
 2373         hlen -= sizeof(struct tcphdr);
 2374         while (hlen >= TCPOLEN_MAXSEG) {
 2375                 switch (*opt) {
 2376                 case TCPOPT_EOL:
 2377                 case TCPOPT_NOP:
 2378                         ++opt;
 2379                         --hlen;
 2380                         break;
 2381                 case TCPOPT_MAXSEG:
 2382                         bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2);
 2383                         /* FALLTHROUGH */
 2384                 default:
 2385                         optlen = opt[1];
 2386                         if (optlen < 2)
 2387                                 optlen = 2;
 2388                         hlen -= optlen;
 2389                         opt += optlen;
 2390                         break;
 2391                 }
 2392         }
 2393         return (mss);
 2394 }
 2395 
 2396 u_int16_t
 2397 pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer)
 2398 {
 2399 #ifdef INET
 2400         struct sockaddr_in      *dst;
 2401         struct route             ro;
 2402 #endif /* INET */
 2403 #ifdef INET6
 2404         struct sockaddr_in6     *dst6;
 2405         struct route_in6         ro6;
 2406 #endif /* INET6 */
 2407         struct rtentry          *rt = NULL;
 2408         int                      hlen = 0;
 2409         u_int16_t                mss = tcp_mssdflt;
 2410 
 2411         switch (af) {
 2412 #ifdef INET
 2413         case AF_INET:
 2414                 hlen = sizeof(struct ip);
 2415                 bzero(&ro, sizeof(ro));
 2416                 dst = (struct sockaddr_in *)&ro.ro_dst;
 2417                 dst->sin_family = AF_INET;
 2418                 dst->sin_len = sizeof(*dst);
 2419                 dst->sin_addr = addr->v4;
 2420                 rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING));
 2421                 rt = ro.ro_rt;
 2422                 break;
 2423 #endif /* INET */
 2424 #ifdef INET6
 2425         case AF_INET6:
 2426                 hlen = sizeof(struct ip6_hdr);
 2427                 bzero(&ro6, sizeof(ro6));
 2428                 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst;
 2429                 dst6->sin6_family = AF_INET6;
 2430                 dst6->sin6_len = sizeof(*dst6);
 2431                 dst6->sin6_addr = addr->v6;
 2432                 rtalloc_ign((struct route *)&ro6, (RTF_CLONING | RTF_PRCLONING));
 2433                 rt = ro6.ro_rt;
 2434                 break;
 2435 #endif /* INET6 */
 2436         }
 2437 
 2438         if (rt && rt->rt_ifp) {
 2439                 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr);
 2440                 mss = max(tcp_mssdflt, mss);
 2441                 RTFREE(rt);
 2442         }
 2443         mss = min(mss, offer);
 2444         mss = max(mss, 64);             /* sanity - at least max opt space */
 2445         return (mss);
 2446 }
 2447 
 2448 void
 2449 pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
 2450 {
 2451         struct pf_rule *r = s->rule.ptr;
 2452 
 2453         s->rt_kif = NULL;
 2454         if (!r->rt || r->rt == PF_FASTROUTE)
 2455                 return;
 2456         switch (s->af) {
 2457 #ifdef INET
 2458         case AF_INET:
 2459                 pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL,
 2460                     &s->nat_src_node);
 2461                 s->rt_kif = r->rpool.cur->kif;
 2462                 break;
 2463 #endif /* INET */
 2464 #ifdef INET6
 2465         case AF_INET6:
 2466                 pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL,
 2467                     &s->nat_src_node);
 2468                 s->rt_kif = r->rpool.cur->kif;
 2469                 break;
 2470 #endif /* INET6 */
 2471         }
 2472 }
 2473 
 2474 int
 2475 pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
 2476     struct pfi_kif *kif, struct mbuf *m, int off, void *h,
 2477     struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm)
 2478 {
 2479         struct pf_rule          *nr = NULL;
 2480         struct pf_addr          *saddr = pd->src, *daddr = pd->dst;
 2481         struct tcphdr           *th = pd->hdr.tcp;
 2482         u_int16_t                bport, nport = 0;
 2483         sa_family_t              af = pd->af;
 2484         int                      lookup = -1;
 2485         uid_t                    uid;
 2486         gid_t                    gid;
 2487         struct pf_rule          *r, *a = NULL;
 2488         struct pf_ruleset       *ruleset = NULL;
 2489         struct pf_src_node      *nsn = NULL;
 2490         u_short                  reason;
 2491         int                      rewrite = 0;
 2492         int                      tag = -1;
 2493 
 2494         r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
 2495 
 2496         if (direction == PF_OUT) {
 2497                 bport = nport = th->th_sport;
 2498                 /* check outgoing packet for BINAT/NAT */
 2499                 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
 2500                     saddr, th->th_sport, daddr, th->th_dport,
 2501                     &pd->naddr, &nport)) != NULL) {
 2502                         PF_ACPY(&pd->baddr, saddr, af);
 2503                         pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
 2504                             &th->th_sum, &pd->naddr, nport, 0, af);
 2505                         rewrite++;
 2506                         if (nr->natpass)
 2507                                 r = NULL;
 2508                         pd->nat_rule = nr;
 2509                 }
 2510         } else {
 2511                 bport = nport = th->th_dport;
 2512                 /* check incoming packet for BINAT/RDR */
 2513                 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
 2514                     saddr, th->th_sport, daddr, th->th_dport,
 2515                     &pd->naddr, &nport)) != NULL) {
 2516                         PF_ACPY(&pd->baddr, daddr, af);
 2517                         pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
 2518                             &th->th_sum, &pd->naddr, nport, 0, af);
 2519                         rewrite++;
 2520                         if (nr->natpass)
 2521                                 r = NULL;
 2522                         pd->nat_rule = nr;
 2523                 }
 2524         }
 2525 
 2526         while (r != NULL) {
 2527                 r->evaluations++;
 2528                 if (r->kif != NULL &&
 2529                     (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
 2530                         r = r->skip[PF_SKIP_IFP].ptr;
 2531                 else if (r->direction && r->direction != direction)
 2532                         r = r->skip[PF_SKIP_DIR].ptr;
 2533                 else if (r->af && r->af != af)
 2534                         r = r->skip[PF_SKIP_AF].ptr;
 2535                 else if (r->proto && r->proto != IPPROTO_TCP)
 2536                         r = r->skip[PF_SKIP_PROTO].ptr;
 2537                 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not))
 2538                         r = r->skip[PF_SKIP_SRC_ADDR].ptr;
 2539                 else if (r->src.port_op && !pf_match_port(r->src.port_op,
 2540                     r->src.port[0], r->src.port[1], th->th_sport))
 2541                         r = r->skip[PF_SKIP_SRC_PORT].ptr;
 2542                 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not))
 2543                         r = r->skip[PF_SKIP_DST_ADDR].ptr;
 2544                 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
 2545                     r->dst.port[0], r->dst.port[1], th->th_dport))
 2546                         r = r->skip[PF_SKIP_DST_PORT].ptr;
 2547                 else if (r->tos && !(r->tos & pd->tos))
 2548                         r = TAILQ_NEXT(r, entries);
 2549                 else if (r->rule_flag & PFRULE_FRAGMENT)
 2550                         r = TAILQ_NEXT(r, entries);
 2551                 else if ((r->flagset & th->th_flags) != r->flags)
 2552                         r = TAILQ_NEXT(r, entries);
 2553                 else if (r->uid.op && (lookup != -1 || (lookup =
 2554                     pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
 2555                     !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
 2556                     uid))
 2557                         r = TAILQ_NEXT(r, entries);
 2558                 else if (r->gid.op && (lookup != -1 || (lookup =
 2559                     pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
 2560                     !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
 2561                     gid))
 2562                         r = TAILQ_NEXT(r, entries);
 2563                 else if (r->prob && r->prob <= karc4random())
 2564                         r = TAILQ_NEXT(r, entries);
 2565                 else if (r->match_tag && !pf_match_tag(m, r, nr, &tag))
 2566                         r = TAILQ_NEXT(r, entries);
 2567                 else if (r->anchorname[0] && r->anchor == NULL)
 2568                         r = TAILQ_NEXT(r, entries);
 2569                 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
 2570                     pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint))
 2571                         r = TAILQ_NEXT(r, entries);
 2572                 else {
 2573                         if (r->tag)
 2574                                 tag = r->tag;
 2575                         if (r->anchor == NULL) {
 2576                                 *rm = r;
 2577                                 *am = a;
 2578                                 *rsm = ruleset;
 2579                                 if ((*rm)->quick)
 2580                                         break;
 2581                                 r = TAILQ_NEXT(r, entries);
 2582                         } else
 2583                                 PF_STEP_INTO_ANCHOR(r, a, ruleset,
 2584                                     PF_RULESET_FILTER);
 2585                 }
 2586                 if (r == NULL && a != NULL)
 2587                         PF_STEP_OUT_OF_ANCHOR(r, a, ruleset,
 2588                             PF_RULESET_FILTER);
 2589         }
 2590         r = *rm;
 2591         a = *am;
 2592         ruleset = *rsm;
 2593 
 2594         REASON_SET(&reason, PFRES_MATCH);
 2595 
 2596         if (r->log) {
 2597                 if (rewrite)
 2598                         m_copyback(m, off, sizeof(*th), (caddr_t)th);
 2599                 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
 2600         }
 2601 
 2602         if ((r->action == PF_DROP) &&
 2603             ((r->rule_flag & PFRULE_RETURNRST) ||
 2604             (r->rule_flag & PFRULE_RETURNICMP) ||
 2605             (r->rule_flag & PFRULE_RETURN))) {
 2606                 /* undo NAT changes, if they have taken place */
 2607                 if (nr != NULL) {
 2608                         if (direction == PF_OUT) {
 2609                                 pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
 2610                                     &th->th_sum, &pd->baddr, bport, 0, af);
 2611                                 rewrite++;
 2612                         } else {
 2613                                 pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
 2614                                     &th->th_sum, &pd->baddr, bport, 0, af);
 2615                                 rewrite++;
 2616                         }
 2617                 }
 2618                 if (((r->rule_flag & PFRULE_RETURNRST) ||
 2619                     (r->rule_flag & PFRULE_RETURN)) &&
 2620                     !(th->th_flags & TH_RST)) {
 2621                         u_int32_t ack = ntohl(th->th_seq) + pd->p_len;
 2622 
 2623                         if (th->th_flags & TH_SYN)
 2624                                 ack++;
 2625                         if (th->th_flags & TH_FIN)
 2626                                 ack++;
 2627                         pf_send_tcp(r, af, pd->dst,
 2628                             pd->src, th->th_dport, th->th_sport,
 2629                             ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
 2630                             r->return_ttl);
 2631                 } else if ((af == AF_INET) && r->return_icmp)
 2632                         pf_send_icmp(m, r->return_icmp >> 8,
 2633                             r->return_icmp & 255, af, r);
 2634                 else if ((af == AF_INET6) && r->return_icmp6)
 2635                         pf_send_icmp(m, r->return_icmp6 >> 8,
 2636                             r->return_icmp6 & 255, af, r);
 2637         }
 2638 
 2639         if (r->action == PF_DROP)
 2640                 return (PF_DROP);
 2641 
 2642         pf_tag_packet(m, tag);
 2643 
 2644         if (r->keep_state || nr != NULL ||
 2645             (pd->flags & PFDESC_TCP_NORM)) {
 2646                 /* create new state */
 2647                 u_int16_t        len;
 2648                 struct pf_state *s = NULL;
 2649                 struct pf_src_node *sn = NULL;
 2650 
 2651                 len = pd->tot_len - off - (th->th_off << 2);
 2652 
 2653                 /* check maximums */
 2654                 if (r->max_states && (r->states >= r->max_states))
 2655                         goto cleanup;
 2656                 /* src node for flter rule */
 2657                 if ((r->rule_flag & PFRULE_SRCTRACK ||
 2658                     r->rpool.opts & PF_POOL_STICKYADDR) &&
 2659                     pf_insert_src_node(&sn, r, saddr, af) != 0)
 2660                         goto cleanup;
 2661                 /* src node for translation rule */
 2662                 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
 2663                     ((direction == PF_OUT &&
 2664                     pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
 2665                     (pf_insert_src_node(&nsn, nr, saddr, af) != 0)))
 2666                         goto cleanup;
 2667                 s = pool_get(&pf_state_pl, PR_NOWAIT);
 2668                 if (s == NULL) {
 2669 cleanup:
 2670                         if (sn != NULL && sn->states == 0 && sn->expire == 0) {
 2671                                 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
 2672                                 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
 2673                                 pf_status.src_nodes--;
 2674                                 pool_put(&pf_src_tree_pl, sn);
 2675                         }
 2676                         if (nsn != sn && nsn != NULL && nsn->states == 0 &&
 2677                             nsn->expire == 0) {
 2678                                 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
 2679                                 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
 2680                                 pf_status.src_nodes--;
 2681                                 pool_put(&pf_src_tree_pl, nsn);
 2682                         }
 2683                         REASON_SET(&reason, PFRES_MEMORY);
 2684                         return (PF_DROP);
 2685                 }
 2686                 bzero(s, sizeof(*s));
 2687                 r->states++;
 2688                 if (a != NULL)
 2689                         a->states++;
 2690                 s->rule.ptr = r;
 2691                 s->nat_rule.ptr = nr;
 2692                 if (s->nat_rule.ptr != NULL)
 2693                         s->nat_rule.ptr->states++;
 2694                 s->anchor.ptr = a;
 2695                 s->allow_opts = r->allow_opts;
 2696                 s->log = r->log & 2;
 2697                 s->proto = IPPROTO_TCP;
 2698                 s->direction = direction;
 2699                 s->af = af;
 2700                 if (direction == PF_OUT) {
 2701                         PF_ACPY(&s->gwy.addr, saddr, af);
 2702                         s->gwy.port = th->th_sport;             /* sport */
 2703                         PF_ACPY(&s->ext.addr, daddr, af);
 2704                         s->ext.port = th->th_dport;
 2705                         if (nr != NULL) {
 2706                                 PF_ACPY(&s->lan.addr, &pd->baddr, af);
 2707                                 s->lan.port = bport;
 2708                         } else {
 2709                                 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
 2710                                 s->lan.port = s->gwy.port;
 2711                         }
 2712                 } else {
 2713                         PF_ACPY(&s->lan.addr, daddr, af);
 2714                         s->lan.port = th->th_dport;
 2715                         PF_ACPY(&s->ext.addr, saddr, af);
 2716                         s->ext.port = th->th_sport;
 2717                         if (nr != NULL) {
 2718                                 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
 2719                                 s->gwy.port = bport;
 2720                         } else {
 2721                                 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
 2722                                 s->gwy.port = s->lan.port;
 2723                         }
 2724                 }
 2725 
 2726                 s->hash = pf_state_hash(s);
 2727                 s->src.seqlo = ntohl(th->th_seq);
 2728                 s->src.seqhi = s->src.seqlo + len + 1;
 2729                 s->pickup_mode = r->pickup_mode;
 2730 
 2731                 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
 2732                     r->keep_state == PF_STATE_MODULATE) {
 2733                         /* Generate sequence number modulator */
 2734                         while ((s->src.seqdiff = karc4random()) == 0)
 2735                                 ;
 2736                         pf_change_a(&th->th_seq, &th->th_sum,
 2737                             htonl(s->src.seqlo + s->src.seqdiff), 0);
 2738                         rewrite = 1;
 2739                 } else
 2740                         s->src.seqdiff = 0;
 2741 
 2742                 /*
 2743                  * WARNING!  NetBSD patched this to not scale max_win up
 2744                  * on the initial SYN, but they failed to correct the code
 2745                  * in pf_test_state_tcp() that 'undid' the scaling, and they
 2746                  * failed to remove the scale factor on successful window
 2747                  * scale negotiation (and doing so would be difficult in the
 2748                  * face of retransmission, without adding more flags to the
 2749                  * state structure).
 2750                  * 
 2751                  * After discussions with Daniel Hartmeier and Max Laier
 2752                  * I've decided not to apply the NetBSD patch.
 2753                  * 
 2754                  * The worst that happens is that the undo code on window
 2755                  * scale negotiation failures will produce a larger
 2756                  * max_win then actual.
 2757                  */
 2758                 if (th->th_flags & TH_SYN) {
 2759                         s->src.seqhi++;
 2760                         s->src.wscale = pf_get_wscale(m, off, th->th_off, af);
 2761                         s->sync_flags |= PFSTATE_GOT_SYN1;
 2762                 }
 2763                 s->src.max_win = MAX(ntohs(th->th_win), 1);
 2764                 if (s->src.wscale & PF_WSCALE_MASK) {
 2765                         /* Remove scale factor from initial window */
 2766                         u_int win = s->src.max_win;
 2767                         win += 1 << (s->src.wscale & PF_WSCALE_MASK);
 2768                         s->src.max_win = (win - 1) >>
 2769                             (s->src.wscale & PF_WSCALE_MASK);
 2770                 }
 2771                 if (th->th_flags & TH_FIN)
 2772                         s->src.seqhi++;
 2773                 s->dst.seqhi = 1;
 2774                 s->dst.max_win = 1;
 2775                 s->src.state = TCPS_SYN_SENT;
 2776                 s->dst.state = TCPS_CLOSED;
 2777                 s->creation = time_second;
 2778                 s->expire = time_second;
 2779                 s->timeout = PFTM_TCP_FIRST_PACKET;
 2780                 pf_set_rt_ifp(s, saddr);
 2781                 if (sn != NULL) {
 2782                         s->src_node = sn;
 2783                         s->src_node->states++;
 2784                 }
 2785                 if (nsn != NULL) {
 2786                         PF_ACPY(&nsn->raddr, &pd->naddr, af);
 2787                         s->nat_src_node = nsn;
 2788                         s->nat_src_node->states++;
 2789                 }
 2790                 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m,
 2791                     off, pd, th, &s->src, &s->dst)) {
 2792                         REASON_SET(&reason, PFRES_MEMORY);
 2793                         pf_src_tree_remove_state(s);
 2794                         pool_put(&pf_state_pl, s);
 2795                         return (PF_DROP);
 2796                 }
 2797                 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub &&
 2798                     pf_normalize_tcp_stateful(m, off, pd, &reason, th, &s->src,
 2799                     &s->dst, &rewrite)) {
 2800                         pf_normalize_tcp_cleanup(s);
 2801                         pf_src_tree_remove_state(s);
 2802                         pool_put(&pf_state_pl, s);
 2803                         return (PF_DROP);
 2804                 }
 2805                 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
 2806                         pf_normalize_tcp_cleanup(s);
 2807                         REASON_SET(&reason, PFRES_MEMORY);
 2808                         pf_src_tree_remove_state(s);
 2809                         pool_put(&pf_state_pl, s);
 2810                         return (PF_DROP);
 2811                 } else
 2812                         *sm = s;
 2813                 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
 2814                     r->keep_state == PF_STATE_SYNPROXY) {
 2815                         u_int16_t mss;
 2816 
 2817                         s->src.state = PF_TCPS_PROXY_SRC;
 2818                         if (nr != NULL) {
 2819                                 if (direction == PF_OUT) {
 2820                                         pf_change_ap(saddr, &th->th_sport,
 2821                                             pd->ip_sum, &th->th_sum, &pd->baddr,
 2822                                             bport, 0, af);
 2823                                 } else {
 2824                                         pf_change_ap(daddr, &th->th_dport,
 2825                                             pd->ip_sum, &th->th_sum, &pd->baddr,
 2826                                             bport, 0, af);
 2827                                 }
 2828                         }
 2829                         s->src.seqhi = karc4random();
 2830                         /* Find mss option */
 2831                         mss = pf_get_mss(m, off, th->th_off, af);
 2832                         mss = pf_calc_mss(saddr, af, mss);
 2833                         mss = pf_calc_mss(daddr, af, mss);
 2834                         s->src.mss = mss;
 2835                         pf_send_tcp(r, af, daddr, saddr, th->th_dport,
 2836                             th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
 2837                             TH_SYN|TH_ACK, 0, s->src.mss, 0);
 2838                         return (PF_SYNPROXY_DROP);
 2839                 }
 2840         }
 2841 
 2842         /* copy back packet headers if we performed NAT operations */
 2843         if (rewrite)
 2844                 m_copyback(m, off, sizeof(*th), (caddr_t)th);
 2845 
 2846         return (PF_PASS);
 2847 }
 2848 
 2849 int
 2850 pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
 2851     struct pfi_kif *kif, struct mbuf *m, int off, void *h,
 2852     struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm)
 2853 {
 2854         struct pf_rule          *nr = NULL;
 2855         struct pf_addr          *saddr = pd->src, *daddr = pd->dst;
 2856         struct udphdr           *uh = pd->hdr.udp;
 2857         u_int16_t                bport, nport = 0;
 2858         sa_family_t              af = pd->af;
 2859         int                      lookup = -1;
 2860         uid_t                    uid;
 2861         gid_t                    gid;
 2862         struct pf_rule          *r, *a = NULL;
 2863         struct pf_ruleset       *ruleset = NULL;
 2864         struct pf_src_node      *nsn = NULL;
 2865         u_short                  reason;
 2866         int                      rewrite = 0;
 2867         int                      tag = -1;
 2868 
 2869         r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
 2870 
 2871         if (direction == PF_OUT) {
 2872                 bport = nport = uh->uh_sport;
 2873                 /* check outgoing packet for BINAT/NAT */
 2874                 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
 2875                     saddr, uh->uh_sport, daddr, uh->uh_dport,
 2876                     &pd->naddr, &nport)) != NULL) {
 2877                         PF_ACPY(&pd->baddr, saddr, af);
 2878                         pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum,
 2879                             &uh->uh_sum, &pd->naddr, nport, 1, af);
 2880                         rewrite++;
 2881                         if (nr->natpass)
 2882                                 r = NULL;
 2883                         pd->nat_rule = nr;
 2884                 }
 2885         } else {
 2886                 bport = nport = uh->uh_dport;
 2887                 /* check incoming packet for BINAT/RDR */
 2888                 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
 2889                     saddr, uh->uh_sport, daddr, uh->uh_dport, &pd->naddr,
 2890                     &nport)) != NULL) {
 2891                         PF_ACPY(&pd->baddr, daddr, af);
 2892                         pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum,
 2893                             &uh->uh_sum, &pd->naddr, nport, 1, af);
 2894                         rewrite++;
 2895                         if (nr->natpass)
 2896                                 r = NULL;
 2897                         pd->nat_rule = nr;
 2898                 }
 2899         }
 2900 
 2901         while (r != NULL) {
 2902                 r->evaluations++;
 2903                 if (r->kif != NULL &&
 2904                     (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
 2905                         r = r->skip[PF_SKIP_IFP].ptr;
 2906                 else if (r->direction && r->direction != direction)
 2907                         r = r->skip[PF_SKIP_DIR].ptr;
 2908                 else if (r->af && r->af != af)
 2909                         r = r->skip[PF_SKIP_AF].ptr;
 2910                 else if (r->proto && r->proto != IPPROTO_UDP)
 2911                         r = r->skip[PF_SKIP_PROTO].ptr;
 2912                 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not))
 2913                         r = r->skip[PF_SKIP_SRC_ADDR].ptr;
 2914                 else if (r->src.port_op && !pf_match_port(r->src.port_op,
 2915                     r->src.port[0], r->src.port[1], uh->uh_sport))
 2916                         r = r->skip[PF_SKIP_SRC_PORT].ptr;
 2917                 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not))
 2918                         r = r->skip[PF_SKIP_DST_ADDR].ptr;
 2919                 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
 2920                     r->dst.port[0], r->dst.port[1], uh->uh_dport))
 2921                         r = r->skip[PF_SKIP_DST_PORT].ptr;
 2922                 else if (r->tos && !(r->tos & pd->tos))
 2923                         r = TAILQ_NEXT(r, entries);
 2924                 else if (r->rule_flag & PFRULE_FRAGMENT)
 2925                         r = TAILQ_NEXT(r, entries);
 2926                 else if (r->uid.op && (lookup != -1 || (lookup =
 2927                     pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
 2928                     !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
 2929                     uid))
 2930                         r = TAILQ_NEXT(r, entries);
 2931                 else if (r->gid.op && (lookup != -1 || (lookup =
 2932                     pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
 2933                     !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
 2934                     gid))
 2935                         r = TAILQ_NEXT(r, entries);
 2936                 else if (r->prob && r->prob <= karc4random())
 2937                         r = TAILQ_NEXT(r, entries);
 2938                 else if (r->match_tag && !pf_match_tag(m, r, nr, &tag))
 2939                         r = TAILQ_NEXT(r, entries);
 2940                 else if (r->anchorname[0] && r->anchor == NULL)
 2941                         r = TAILQ_NEXT(r, entries);
 2942                 else if (r->os_fingerprint != PF_OSFP_ANY)
 2943                         r = TAILQ_NEXT(r, entries);
 2944                 else {
 2945                         if (r->tag)
 2946                                 tag = r->tag;
 2947                         if (r->anchor == NULL) {
 2948                                 *rm = r;
 2949                                 *am = a;
 2950                                 *rsm = ruleset;
 2951                                 if ((*rm)->quick)
 2952                                         break;
 2953                                 r = TAILQ_NEXT(r, entries);
 2954                         } else
 2955                                 PF_STEP_INTO_ANCHOR(r, a, ruleset,
 2956                                     PF_RULESET_FILTER);
 2957                 }
 2958                 if (r == NULL && a != NULL)
 2959                         PF_STEP_OUT_OF_ANCHOR(r, a, ruleset,
 2960                             PF_RULESET_FILTER);
 2961         }
 2962         r = *rm;
 2963         a = *am;
 2964         ruleset = *rsm;
 2965 
 2966         REASON_SET(&reason, PFRES_MATCH);
 2967 
 2968         if (r->log) {
 2969                 if (rewrite)
 2970                         m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
 2971                 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
 2972         }
 2973 
 2974         if ((r->action == PF_DROP) &&
 2975             ((r->rule_flag & PFRULE_RETURNICMP) ||
 2976             (r->rule_flag & PFRULE_RETURN))) {
 2977                 /* undo NAT changes, if they have taken place */
 2978                 if (nr != NULL) {
 2979                         if (direction == PF_OUT) {
 2980                                 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum,
 2981                                     &uh->uh_sum, &pd->baddr, bport, 1, af);
 2982                                 rewrite++;
 2983                         } else {
 2984                                 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum,
 2985                                     &uh->uh_sum, &pd->baddr, bport, 1, af);
 2986                                 rewrite++;
 2987                         }
 2988                 }
 2989                 if ((af == AF_INET) && r->return_icmp)
 2990                         pf_send_icmp(m, r->return_icmp >> 8,
 2991                             r->return_icmp & 255, af, r);
 2992                 else if ((af == AF_INET6) && r->return_icmp6)
 2993                         pf_send_icmp(m, r->return_icmp6 >> 8,
 2994                             r->return_icmp6 & 255, af, r);
 2995         }
 2996 
 2997         if (r->action == PF_DROP)
 2998                 return (PF_DROP);
 2999 
 3000         pf_tag_packet(m, tag);
 3001 
 3002         if (r->keep_state || nr != NULL) {
 3003                 /* create new state */
 3004                 struct pf_state *s = NULL;
 3005                 struct pf_src_node *sn = NULL;
 3006 
 3007                 /* check maximums */
 3008                 if (r->max_states && (r->states >= r->max_states))
 3009                         goto cleanup;
 3010                 /* src node for flter rule */
 3011                 if ((r->rule_flag & PFRULE_SRCTRACK ||
 3012                     r->rpool.opts & PF_POOL_STICKYADDR) &&
 3013                     pf_insert_src_node(&sn, r, saddr, af) != 0)
 3014                         goto cleanup;
 3015                 /* src node for translation rule */
 3016                 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
 3017                     ((direction == PF_OUT &&
 3018                     pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
 3019                     (pf_insert_src_node(&nsn, nr, saddr, af) != 0)))
 3020                         goto cleanup;
 3021                 s = pool_get(&pf_state_pl, PR_NOWAIT);
 3022                 if (s == NULL) {
 3023 cleanup:
 3024                         if (sn != NULL && sn->states == 0 && sn->expire == 0) {
 3025                                 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
 3026                                 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
 3027                                 pf_status.src_nodes--;
 3028                                 pool_put(&pf_src_tree_pl, sn);
 3029                         }
 3030                         if (nsn != sn && nsn != NULL && nsn->states == 0 &&
 3031                             nsn->expire == 0) {
 3032                                 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
 3033                                 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
 3034                                 pf_status.src_nodes--;
 3035                                 pool_put(&pf_src_tree_pl, nsn);
 3036                         }
 3037                         REASON_SET(&reason, PFRES_MEMORY);
 3038                         return (PF_DROP);
 3039                 }
 3040                 bzero(s, sizeof(*s));
 3041                 r->states++;
 3042                 if (a != NULL)
 3043                         a->states++;
 3044                 s->rule.ptr = r;
 3045                 s->nat_rule.ptr = nr;
 3046                 if (s->nat_rule.ptr != NULL)
 3047                         s->nat_rule.ptr->states++;
 3048                 s->anchor.ptr = a;
 3049                 s->allow_opts = r->allow_opts;
 3050                 s->log = r->log & 2;
 3051                 s->proto = IPPROTO_UDP;
 3052                 s->direction = direction;
 3053                 s->af = af;
 3054                 if (direction == PF_OUT) {
 3055                         PF_ACPY(&s->gwy.addr, saddr, af);
 3056                         s->gwy.port = uh->uh_sport;
 3057                         PF_ACPY(&s->ext.addr, daddr, af);
 3058                         s->ext.port = uh->uh_dport;
 3059                         if (nr != NULL) {
 3060                                 PF_ACPY(&s->lan.addr, &pd->baddr, af);
 3061                                 s->lan.port = bport;
 3062                         } else {
 3063                                 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
 3064                                 s->lan.port = s->gwy.port;
 3065                         }
 3066                 } else {
 3067                         PF_ACPY(&s->lan.addr, daddr, af);
 3068                         s->lan.port = uh->uh_dport;
 3069                         PF_ACPY(&s->ext.addr, saddr, af);
 3070                         s->ext.port = uh->uh_sport;
 3071                         if (nr != NULL) {
 3072                                 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
 3073                                 s->gwy.port = bport;
 3074                         } else {
 3075                                 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
 3076                                 s->gwy.port = s->lan.port;
 3077                         }
 3078                 }
 3079                 s->hash = pf_state_hash(s);
 3080                 s->src.state = PFUDPS_SINGLE;
 3081                 s->dst.state = PFUDPS_NO_TRAFFIC;
 3082                 s->creation = time_second;
 3083                 s->expire = time_second;
 3084                 s->timeout = PFTM_UDP_FIRST_PACKET;
 3085                 pf_set_rt_ifp(s, saddr);
 3086                 if (sn != NULL) {
 3087                         s->src_node = sn;
 3088                         s->src_node->states++;
 3089                 }
 3090                 if (nsn != NULL) {
 3091                         PF_ACPY(&nsn->raddr, &pd->naddr, af);
 3092                         s->nat_src_node = nsn;
 3093                         s->nat_src_node->states++;
 3094                 }
 3095                 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
 3096                         REASON_SET(&reason, PFRES_MEMORY);
 3097                         pf_src_tree_remove_state(s);
 3098                         pool_put(&pf_state_pl, s);
 3099                         return (PF_DROP);
 3100                 } else
 3101                         *sm = s;
 3102         }
 3103 
 3104         /* copy back packet headers if we performed NAT operations */
 3105         if (rewrite)
 3106                 m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
 3107 
 3108         return (PF_PASS);
 3109 }
 3110 
 3111 int
 3112 pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
 3113     struct pfi_kif *kif, struct mbuf *m, int off, void *h,
 3114     struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm)
 3115 {
 3116         struct pf_rule          *nr = NULL;
 3117         struct pf_addr          *saddr = pd->src, *daddr = pd->dst;
 3118         struct pf_rule          *r, *a = NULL;
 3119         struct pf_ruleset       *ruleset = NULL;
 3120         struct pf_src_node      *nsn = NULL;
 3121         u_short                  reason;
 3122         u_int16_t                icmpid = 0;
 3123         sa_family_t              af = pd->af;
 3124         u_int8_t                 icmptype = 0, icmpcode = 0;
 3125         int                      state_icmp = 0;
 3126         int                      tag = -1;
 3127 #ifdef INET6
 3128         int                      rewrite = 0;
 3129 #endif /* INET6 */
 3130 
 3131         switch (pd->proto) {
 3132 #ifdef INET
 3133         case IPPROTO_ICMP:
 3134                 icmptype = pd->hdr.icmp->icmp_type;
 3135                 icmpcode = pd->hdr.icmp->icmp_code;
 3136                 icmpid = pd->hdr.icmp->icmp_id;
 3137 
 3138                 if (icmptype == ICMP_UNREACH ||
 3139                     icmptype == ICMP_SOURCEQUENCH ||
 3140                     icmptype == ICMP_REDIRECT ||
 3141                     icmptype == ICMP_TIMXCEED ||
 3142                     icmptype == ICMP_PARAMPROB)
 3143                         state_icmp++;
 3144                 break;
 3145 #endif /* INET */
 3146 #ifdef INET6
 3147         case IPPROTO_ICMPV6:
 3148                 icmptype = pd->hdr.icmp6->icmp6_type;
 3149                 icmpcode = pd->hdr.icmp6->icmp6_code;
 3150                 icmpid = pd->hdr.icmp6->icmp6_id;
 3151 
 3152                 if (icmptype == ICMP6_DST_UNREACH ||
 3153                     icmptype == ICMP6_PACKET_TOO_BIG ||
 3154                     icmptype == ICMP6_TIME_EXCEEDED ||
 3155                     icmptype == ICMP6_PARAM_PROB)
 3156                         state_icmp++;
 3157                 break;
 3158 #endif /* INET6 */
 3159         }
 3160 
 3161         r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
 3162 
 3163         if (direction == PF_OUT) {
 3164                 /* check outgoing packet for BINAT/NAT */
 3165                 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
 3166                     saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) {
 3167                         PF_ACPY(&pd->baddr, saddr, af);
 3168                         switch (af) {
 3169 #ifdef INET
 3170                         case AF_INET:
 3171                                 pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
 3172                                     pd->naddr.v4.s_addr, 0);
 3173                                 break;
 3174 #endif /* INET */
 3175 #ifdef INET6
 3176                         case AF_INET6:
 3177                                 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum,
 3178                                     &pd->naddr, 0);
 3179                                 rewrite++;
 3180                                 break;
 3181 #endif /* INET6 */
 3182                         }
 3183                         if (nr->natpass)
 3184                                 r = NULL;
 3185                         pd->nat_rule = nr;
 3186                 }
 3187         } else {
 3188                 /* check incoming packet for BINAT/RDR */
 3189                 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
 3190                     saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) {
 3191                         PF_ACPY(&pd->baddr, daddr, af);
 3192                         switch (af) {
 3193 #ifdef INET
 3194                         case AF_INET:
 3195                                 pf_change_a(&daddr->v4.s_addr,
 3196                                     pd->ip_sum, pd->naddr.v4.s_addr, 0);
 3197                                 break;
 3198 #endif /* INET */
 3199 #ifdef INET6
 3200                         case AF_INET6:
 3201                                 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum,
 3202                                     &pd->naddr, 0);
 3203                                 rewrite++;
 3204                                 break;
 3205 #endif /* INET6 */
 3206                         }
 3207                         if (nr->natpass)
 3208                                 r = NULL;
 3209                         pd->nat_rule = nr;
 3210                 }
 3211         }
 3212 
 3213         while (r != NULL) {
 3214                 r->evaluations++;
 3215                 if (r->kif != NULL &&
 3216                     (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
 3217                         r = r->skip[PF_SKIP_IFP].ptr;
 3218                 else if (r->direction && r->direction != direction)
 3219                         r = r->skip[PF_SKIP_DIR].ptr;
 3220                 else if (r->af && r->af != af)
 3221                         r = r->skip[PF_SKIP_AF].ptr;
 3222                 else if (r->proto && r->proto != pd->proto)
 3223                         r = r->skip[PF_SKIP_PROTO].ptr;
 3224                 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not))
 3225                         r = r->skip[PF_SKIP_SRC_ADDR].ptr;
 3226                 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not))
 3227                         r = r->skip[PF_SKIP_DST_ADDR].ptr;
 3228                 else if (r->type && r->type != icmptype + 1)
 3229                         r = TAILQ_NEXT(r, entries);
 3230                 else if (r->code && r->code != icmpcode + 1)
 3231                         r = TAILQ_NEXT(r, entries);
 3232                 else if (r->tos && !(r->tos & pd->tos))
 3233                         r = TAILQ_NEXT(r, entries);
 3234                 else if (r->rule_flag & PFRULE_FRAGMENT)
 3235                         r = TAILQ_NEXT(r, entries);
 3236                 else if (r->prob && r->prob <= karc4random())
 3237                         r = TAILQ_NEXT(r, entries);
 3238                 else if (r->match_tag && !pf_match_tag(m, r, nr, &tag))
 3239                         r = TAILQ_NEXT(r, entries);
 3240                 else if (r->anchorname[0] && r->anchor == NULL)
 3241                         r = TAILQ_NEXT(r, entries);
 3242                 else if (r->os_fingerprint != PF_OSFP_ANY)
 3243                         r = TAILQ_NEXT(r, entries);
 3244                 else {
 3245                         if (r->tag)
 3246                                 tag = r->tag;
 3247                         if (r->anchor == NULL) {
 3248                                 *rm = r;
 3249                                 *am = a;
 3250                                 *rsm = ruleset;
 3251                                 if ((*rm)->quick)
 3252                                         break;
 3253                                 r = TAILQ_NEXT(r, entries);
 3254                         } else
 3255                                 PF_STEP_INTO_ANCHOR(r, a, ruleset,
 3256                                     PF_RULESET_FILTER);
 3257                 }
 3258                 if (r == NULL && a != NULL)
 3259                         PF_STEP_OUT_OF_ANCHOR(r, a, ruleset,
 3260                             PF_RULESET_FILTER);
 3261         }
 3262         r = *rm;
 3263         a = *am;
 3264         ruleset = *rsm;
 3265 
 3266         REASON_SET(&reason, PFRES_MATCH);
 3267 
 3268         if (r->log) {
 3269 #ifdef INET6
 3270                 if (rewrite)
 3271                         m_copyback(m, off, sizeof(struct icmp6_hdr),
 3272                             (caddr_t)pd->hdr.icmp6);
 3273 #endif /* INET6 */
 3274                 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
 3275         }
 3276 
 3277         if (r->action != PF_PASS)
 3278                 return (PF_DROP);
 3279 
 3280         pf_tag_packet(m, tag);
 3281 
 3282         if (!state_icmp && (r->keep_state || nr != NULL)) {
 3283                 /* create new state */
 3284                 struct pf_state *s = NULL;
 3285                 struct pf_src_node *sn = NULL;
 3286 
 3287                 /* check maximums */
 3288                 if (r->max_states && (r->states >= r->max_states))
 3289                         goto cleanup;
 3290                 /* src node for flter rule */
 3291                 if ((r->rule_flag & PFRULE_SRCTRACK ||
 3292                     r->rpool.opts & PF_POOL_STICKYADDR) &&
 3293                     pf_insert_src_node(&sn, r, saddr, af) != 0)
 3294                         goto cleanup;
 3295                 /* src node for translation rule */
 3296                 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
 3297                     ((direction == PF_OUT &&
 3298                     pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
 3299                     (pf_insert_src_node(&nsn, nr, saddr, af) != 0)))
 3300                         goto cleanup;
 3301                 s = pool_get(&pf_state_pl, PR_NOWAIT);
 3302                 if (s == NULL) {
 3303 cleanup:
 3304                         if (sn != NULL && sn->states == 0 && sn->expire == 0) {
 3305                                 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
 3306                                 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
 3307                                 pf_status.src_nodes--;
 3308                                 pool_put(&pf_src_tree_pl, sn);
 3309                         }
 3310                         if (nsn != sn && nsn != NULL && nsn->states == 0 &&
 3311                             nsn->expire == 0) {
 3312                                 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
 3313                                 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
 3314                                 pf_status.src_nodes--;
 3315                                 pool_put(&pf_src_tree_pl, nsn);
 3316                         }
 3317                         REASON_SET(&reason, PFRES_MEMORY);
 3318                         return (PF_DROP);
 3319                 }
 3320                 bzero(s, sizeof(*s));
 3321                 r->states++;
 3322                 if (a != NULL)
 3323                         a->states++;
 3324                 s->rule.ptr = r;
 3325                 s->nat_rule.ptr = nr;
 3326                 if (s->nat_rule.ptr != NULL)
 3327                         s->nat_rule.ptr->states++;
 3328                 s->anchor.ptr = a;
 3329                 s->allow_opts = r->allow_opts;
 3330                 s->log = r->log & 2;
 3331                 s->proto = pd->proto;
 3332                 s->direction = direction;
 3333                 s->af = af;
 3334                 if (direction == PF_OUT) {
 3335                         PF_ACPY(&s->gwy.addr, saddr, af);
 3336                         s->gwy.port = icmpid;
 3337                         PF_ACPY(&s->ext.addr, daddr, af);
 3338                         s->ext.port = icmpid;
 3339                         if (nr != NULL)
 3340                                 PF_ACPY(&s->lan.addr, &pd->baddr, af);
 3341                         else
 3342                                 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
 3343                         s->lan.port = icmpid;
 3344                 } else {
 3345                         PF_ACPY(&s->lan.addr, daddr, af);
 3346                         s->lan.port = icmpid;
 3347                         PF_ACPY(&s->ext.addr, saddr, af);
 3348                         s->ext.port = icmpid;
 3349                         if (nr != NULL)
 3350                                 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
 3351                         else
 3352                                 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
 3353                         s->gwy.port = icmpid;
 3354                 }
 3355                 s->hash = pf_state_hash(s);
 3356                 s->creation = time_second;
 3357                 s->expire = time_second;
 3358                 s->timeout = PFTM_ICMP_FIRST_PACKET;
 3359                 pf_set_rt_ifp(s, saddr);
 3360                 if (sn != NULL) {
 3361                         s->src_node = sn;
 3362                         s->src_node->states++;
 3363                 }
 3364                 if (nsn != NULL) {
 3365                         PF_ACPY(&nsn->raddr, &pd->naddr, af);
 3366                         s->nat_src_node = nsn;
 3367                         s->nat_src_node->states++;
 3368                 }
 3369                 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
 3370                         REASON_SET(&reason, PFRES_MEMORY);
 3371                         pf_src_tree_remove_state(s);
 3372                         pool_put(&pf_state_pl, s);
 3373                         return (PF_DROP);
 3374                 } else
 3375                         *sm = s;
 3376         }
 3377 
 3378 #ifdef INET6
 3379         /* copy back packet headers if we performed IPv6 NAT operations */
 3380         if (rewrite)
 3381                 m_copyback(m, off, sizeof(struct icmp6_hdr),
 3382                     (caddr_t)pd->hdr.icmp6);
 3383 #endif /* INET6 */
 3384 
 3385         return (PF_PASS);
 3386 }
 3387 
 3388 int
 3389 pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction,
 3390     struct pfi_kif *kif, struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
 3391     struct pf_rule **am, struct pf_ruleset **rsm)
 3392 {
 3393         struct pf_rule          *nr = NULL;
 3394         struct pf_rule          *r, *a = NULL;
 3395         struct pf_ruleset       *ruleset = NULL;
 3396         struct pf_src_node      *nsn = NULL;
 3397         struct pf_addr          *saddr = pd->src, *daddr = pd->dst;
 3398         sa_family_t              af = pd->af;
 3399         u_short                  reason;
 3400         int                      tag = -1;
 3401 
 3402         r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
 3403 
 3404         if (direction == PF_OUT) {
 3405                 /* check outgoing packet for BINAT/NAT */
 3406                 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
 3407                     saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) {
 3408                         PF_ACPY(&pd->baddr, saddr, af);
 3409                         switch (af) {
 3410 #ifdef INET
 3411                         case AF_INET:
 3412                                 pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
 3413                                     pd->naddr.v4.s_addr, 0);
 3414                                 break;
 3415 #endif /* INET */
 3416 #ifdef INET6
 3417                         case AF_INET6:
 3418                                 PF_ACPY(saddr, &pd->naddr, af);
 3419                                 break;
 3420 #endif /* INET6 */
 3421                         }
 3422                         if (nr->natpass)
 3423                                 r = NULL;
 3424                         pd->nat_rule = nr;
 3425                 }
 3426         } else {
 3427                 /* check incoming packet for BINAT/RDR */
 3428                 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
 3429                     saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) {
 3430                         PF_ACPY(&pd->baddr, daddr, af);
 3431                         switch (af) {
 3432 #ifdef INET
 3433                         case AF_INET:
 3434                                 pf_change_a(&daddr->v4.s_addr,
 3435                                     pd->ip_sum, pd->naddr.v4.s_addr, 0);
 3436                                 break;
 3437 #endif /* INET */
 3438 #ifdef INET6
 3439                         case AF_INET6:
 3440                                 PF_ACPY(daddr, &pd->naddr, af);
 3441                                 break;
 3442 #endif /* INET6 */
 3443                         }
 3444                         if (nr->natpass)
 3445                                 r = NULL;
 3446                         pd->nat_rule = nr;
 3447                 }
 3448         }
 3449 
 3450         while (r != NULL) {
 3451                 r->evaluations++;
 3452                 if (r->kif != NULL &&
 3453                     (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
 3454                         r = r->skip[PF_SKIP_IFP].ptr;
 3455                 else if (r->direction && r->direction != direction)
 3456                         r = r->skip[PF_SKIP_DIR].ptr;
 3457                 else if (r->af && r->af != af)
 3458                         r = r->skip[PF_SKIP_AF].ptr;
 3459                 else if (r->proto && r->proto != pd->proto)
 3460                         r = r->skip[PF_SKIP_PROTO].ptr;
 3461                 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not))
 3462                         r = r->skip[PF_SKIP_SRC_ADDR].ptr;
 3463                 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not))
 3464                         r = r->skip[PF_SKIP_DST_ADDR].ptr;
 3465                 else if (r->tos && !(r->tos & pd->tos))
 3466                         r = TAILQ_NEXT(r, entries);
 3467                 else if (r->rule_flag & PFRULE_FRAGMENT)
 3468                         r = TAILQ_NEXT(r, entries);
 3469                 else if (r->prob && r->prob <= karc4random())
 3470                         r = TAILQ_NEXT(r, entries);
 3471                 else if (r->match_tag && !pf_match_tag(m, r, nr, &tag))
 3472                         r = TAILQ_NEXT(r, entries);
 3473                 else if (r->anchorname[0] && r->anchor == NULL)
 3474                         r = TAILQ_NEXT(r, entries);
 3475                 else if (r->os_fingerprint != PF_OSFP_ANY)
 3476                         r = TAILQ_NEXT(r, entries);
 3477                 else {
 3478                         if (r->tag)
 3479                                 tag = r->tag;
 3480                         if (r->anchor == NULL) {
 3481                                 *rm = r;
 3482                                 *am = a;
 3483                                 *rsm = ruleset;
 3484                                 if ((*rm)->quick)
 3485                                         break;
 3486                                 r = TAILQ_NEXT(r, entries);
 3487                         } else
 3488                                 PF_STEP_INTO_ANCHOR(r, a, ruleset,
 3489                                     PF_RULESET_FILTER);
 3490                 }
 3491                 if (r == NULL && a != NULL)
 3492                         PF_STEP_OUT_OF_ANCHOR(r, a, ruleset,
 3493                             PF_RULESET_FILTER);
 3494         }
 3495         r = *rm;
 3496         a = *am;
 3497         ruleset = *rsm;
 3498 
 3499         REASON_SET(&reason, PFRES_MATCH);
 3500 
 3501         if (r->log)
 3502                 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
 3503 
 3504         if ((r->action == PF_DROP) &&
 3505             ((r->rule_flag & PFRULE_RETURNICMP) ||
 3506             (r->rule_flag & PFRULE_RETURN))) {
 3507                 struct pf_addr *a = NULL;
 3508 
 3509                 if (nr != NULL) {
 3510                         if (direction == PF_OUT)
 3511                                 a = saddr;
 3512                         else
 3513                                 a = daddr;
 3514                 }
 3515                 if (a != NULL) {
 3516                         switch (af) {
 3517 #ifdef INET
 3518                         case AF_INET:
 3519                                 pf_change_a(&a->v4.s_addr, pd->ip_sum,
 3520                                     pd->baddr.v4.s_addr, 0);
 3521                                 break;
 3522 #endif /* INET */
 3523 #ifdef INET6
 3524                         case AF_INET6:
 3525                                 PF_ACPY(a, &pd->baddr, af);
 3526                                 break;
 3527 #endif /* INET6 */
 3528                         }
 3529                 }
 3530                 if ((af == AF_INET) && r->return_icmp)
 3531                         pf_send_icmp(m, r->return_icmp >> 8,
 3532                             r->return_icmp & 255, af, r);
 3533                 else if ((af == AF_INET6) && r->return_icmp6)
 3534                         pf_send_icmp(m, r->return_icmp6 >> 8,
 3535                             r->return_icmp6 & 255, af, r);
 3536         }
 3537 
 3538         if (r->action != PF_PASS)
 3539                 return (PF_DROP);
 3540 
 3541         pf_tag_packet(m, tag);
 3542 
 3543         if (r->keep_state || nr != NULL) {
 3544                 /* create new state */
 3545                 struct pf_state *s = NULL;
 3546                 struct pf_src_node *sn = NULL;
 3547 
 3548                 /* check maximums */
 3549                 if (r->max_states && (r->states >= r->max_states))
 3550                         goto cleanup;
 3551                 /* src node for flter rule */
 3552                 if ((r->rule_flag & PFRULE_SRCTRACK ||
 3553                     r->rpool.opts & PF_POOL_STICKYADDR) &&
 3554                     pf_insert_src_node(&sn, r, saddr, af) != 0)
 3555                         goto cleanup;
 3556                 /* src node for translation rule */
 3557                 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
 3558                     ((direction == PF_OUT &&
 3559                     pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
 3560                     (pf_insert_src_node(&nsn, nr, saddr, af) != 0)))
 3561                         goto cleanup;
 3562                 s = pool_get(&pf_state_pl, PR_NOWAIT);
 3563                 if (s == NULL) {
 3564 cleanup:
 3565                         if (sn != NULL && sn->states == 0 && sn->expire == 0) {
 3566                                 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
 3567                                 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
 3568                                 pf_status.src_nodes--;
 3569                                 pool_put(&pf_src_tree_pl, sn);
 3570                         }
 3571                         if (nsn != sn && nsn != NULL && nsn->states == 0 &&
 3572                             nsn->expire == 0) {
 3573                                 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
 3574                                 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
 3575                                 pf_status.src_nodes--;
 3576                                 pool_put(&pf_src_tree_pl, nsn);
 3577                         }
 3578                         REASON_SET(&reason, PFRES_MEMORY);
 3579                         return (PF_DROP);
 3580                 }
 3581                 bzero(s, sizeof(*s));
 3582                 r->states++;
 3583                 if (a != NULL)
 3584                         a->states++;
 3585                 s->rule.ptr = r;
 3586                 s->nat_rule.ptr = nr;
 3587                 if (s->nat_rule.ptr != NULL)
 3588                         s->nat_rule.ptr->states++;
 3589                 s->anchor.ptr = a;
 3590                 s->allow_opts = r->allow_opts;
 3591                 s->log = r->log & 2;
 3592                 s->proto = pd->proto;
 3593                 s->direction = direction;
 3594                 s->af = af;
 3595                 if (direction == PF_OUT) {
 3596                         PF_ACPY(&s->gwy.addr, saddr, af);
 3597                         PF_ACPY(&s->ext.addr, daddr, af);
 3598                         if (nr != NULL)
 3599                                 PF_ACPY(&s->lan.addr, &pd->baddr, af);
 3600                         else
 3601                                 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
 3602                 } else {
 3603                         PF_ACPY(&s->lan.addr, daddr, af);
 3604                         PF_ACPY(&s->ext.addr, saddr, af);
 3605                         if (nr != NULL)
 3606                                 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
 3607                         else
 3608                                 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
 3609                 }
 3610                 s->hash = pf_state_hash(s);
 3611                 s->src.state = PFOTHERS_SINGLE;
 3612                 s->dst.state = PFOTHERS_NO_TRAFFIC;
 3613                 s->creation = time_second;
 3614                 s->expire = time_second;
 3615                 s->timeout = PFTM_OTHER_FIRST_PACKET;
 3616                 pf_set_rt_ifp(s, saddr);
 3617                 if (sn != NULL) {
 3618                         s->src_node = sn;
 3619                         s->src_node->states++;
 3620                 }
 3621                 if (nsn != NULL) {
 3622                         PF_ACPY(&nsn->raddr, &pd->naddr, af);
 3623                         s->nat_src_node = nsn;
 3624                         s->nat_src_node->states++;
 3625                 }
 3626                 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
 3627                         REASON_SET(&reason, PFRES_MEMORY);
 3628                         pf_src_tree_remove_state(s);
 3629                         pool_put(&pf_state_pl, s);
 3630                         return (PF_DROP);
 3631                 } else
 3632                         *sm = s;
 3633         }
 3634 
 3635         return (PF_PASS);
 3636 }
 3637 
 3638 int
 3639 pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
 3640     struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am,
 3641     struct pf_ruleset **rsm)
 3642 {
 3643         struct pf_rule          *r, *a = NULL;
 3644         struct pf_ruleset       *ruleset = NULL;
 3645         sa_family_t              af = pd->af;
 3646         u_short                  reason;
 3647         int                      tag = -1;
 3648 
 3649         r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
 3650         while (r != NULL) {
 3651                 r->evaluations++;
 3652                 if (r->kif != NULL &&
 3653                     (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
 3654                         r = r->skip[PF_SKIP_IFP].ptr;
 3655                 else if (r->direction && r->direction != direction)
 3656                         r = r->skip[PF_SKIP_DIR].ptr;
 3657                 else if (r->af && r->af != af)
 3658                         r = r->skip[PF_SKIP_AF].ptr;
 3659                 else if (r->proto && r->proto != pd->proto)
 3660                         r = r->skip[PF_SKIP_PROTO].ptr;
 3661                 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not))
 3662                         r = r->skip[PF_SKIP_SRC_ADDR].ptr;
 3663                 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not))
 3664                         r = r->skip[PF_SKIP_DST_ADDR].ptr;
 3665                 else if (r->tos && !(r->tos & pd->tos))
 3666                         r = TAILQ_NEXT(r, entries);
 3667                 else if (r->os_fingerprint != PF_OSFP_ANY)
 3668                         r = TAILQ_NEXT(r, entries);
 3669                 else if (pd->proto == IPPROTO_UDP &&
 3670                     (r->src.port_op || r->dst.port_op))
 3671                         r = TAILQ_NEXT(r, entries);
 3672                 else if (pd->proto == IPPROTO_TCP &&
 3673                     (r->src.port_op || r->dst.port_op || r->flagset))
 3674                         r = TAILQ_NEXT(r, entries);
 3675                 else if ((pd->proto == IPPROTO_ICMP ||
 3676                     pd->proto == IPPROTO_ICMPV6) &&
 3677                     (r->type || r->code))
 3678                         r = TAILQ_NEXT(r, entries);
 3679                 else if (r->prob && r->prob <= karc4random())
 3680                         r = TAILQ_NEXT(r, entries);
 3681                 else if (r->match_tag && !pf_match_tag(m, r, NULL, &tag))
 3682                         r = TAILQ_NEXT(r, entries);
 3683                 else if (r->anchorname[0] && r->anchor == NULL)
 3684                         r = TAILQ_NEXT(r, entries);
 3685                 else {
 3686                         if (r->anchor == NULL) {
 3687                                 *rm = r;
 3688                                 *am = a;
 3689                                 *rsm = ruleset;
 3690                                 if ((*rm)->quick)
 3691                                         break;
 3692                                 r = TAILQ_NEXT(r, entries);
 3693                         } else
 3694                                 PF_STEP_INTO_ANCHOR(r, a, ruleset,
 3695                                     PF_RULESET_FILTER);
 3696                 }
 3697                 if (r == NULL && a != NULL)
 3698                         PF_STEP_OUT_OF_ANCHOR(r, a, ruleset,
 3699                             PF_RULESET_FILTER);
 3700         }
 3701         r = *rm;
 3702         a = *am;
 3703         ruleset = *rsm;
 3704 
 3705         REASON_SET(&reason, PFRES_MATCH);
 3706 
 3707         if (r->log)
 3708                 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
 3709 
 3710         if (r->action != PF_PASS)
 3711                 return (PF_DROP);
 3712 
 3713         pf_tag_packet(m, tag);
 3714 
 3715         return (PF_PASS);
 3716 }
 3717 
 3718 int
 3719 pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
 3720     struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
 3721     u_short *reason)
 3722 {
 3723         struct pf_state          key;
 3724         struct tcphdr           *th = pd->hdr.tcp;
 3725         u_int16_t                win = ntohs(th->th_win);
 3726         u_int32_t                ack, end, seq;
 3727         u_int8_t                 sws, dws;
 3728         int                      ackskew;
 3729         int                      copyback = 0;
 3730         struct pf_state_peer    *src, *dst;
 3731 
 3732         key.af = pd->af;
 3733         key.proto = IPPROTO_TCP;
 3734         if (direction == PF_IN) {
 3735                 PF_ACPY(&key.ext.addr, pd->src, key.af);
 3736                 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
 3737                 key.ext.port = th->th_sport;
 3738                 key.gwy.port = th->th_dport;
 3739         } else {
 3740                 PF_ACPY(&key.lan.addr, pd->src, key.af);
 3741                 PF_ACPY(&key.ext.addr, pd->dst, key.af);
 3742                 key.lan.port = th->th_sport;
 3743                 key.ext.port = th->th_dport;
 3744         }
 3745 
 3746         STATE_LOOKUP();
 3747 
 3748         if (direction == (*state)->direction) {
 3749                 src = &(*state)->src;
 3750                 dst = &(*state)->dst;
 3751         } else {
 3752                 src = &(*state)->dst;
 3753                 dst = &(*state)->src;
 3754         }
 3755 
 3756         if ((*state)->src.state == PF_TCPS_PROXY_SRC) {
 3757                 if (direction != (*state)->direction)
 3758                         return (PF_SYNPROXY_DROP);
 3759                 if (th->th_flags & TH_SYN) {
 3760                         if (ntohl(th->th_seq) != (*state)->src.seqlo)
 3761                                 return (PF_DROP);
 3762                         pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
 3763                             pd->src, th->th_dport, th->th_sport,
 3764                             (*state)->src.seqhi, ntohl(th->th_seq) + 1,
 3765                             TH_SYN|TH_ACK, 0, (*state)->src.mss, 0);
 3766                         return (PF_SYNPROXY_DROP);
 3767                 } else if (!(th->th_flags & TH_ACK) ||
 3768                     (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
 3769                     (ntohl(th->th_seq) != (*state)->src.seqlo + 1))
 3770                         return (PF_DROP);
 3771                 else
 3772                         (*state)->src.state = PF_TCPS_PROXY_DST;
 3773         }
 3774         if ((*state)->src.state == PF_TCPS_PROXY_DST) {
 3775                 struct pf_state_host *src, *dst;
 3776 
 3777                 if (direction == PF_OUT) {
 3778                         src = &(*state)->gwy;
 3779                         dst = &(*state)->ext;
 3780                 } else {
 3781                         src = &(*state)->ext;
 3782                         dst = &(*state)->lan;
 3783                 }
 3784                 if (direction == (*state)->direction) {
 3785                         if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) ||
 3786                             (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
 3787                             (ntohl(th->th_seq) != (*state)->src.seqlo + 1))
 3788                                 return (PF_DROP);
 3789                         (*state)->src.max_win = MAX(ntohs(th->th_win), 1);
 3790                         if ((*state)->dst.seqhi == 1)
 3791                                 (*state)->dst.seqhi = karc4random();
 3792                         pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
 3793                             &dst->addr, src->port, dst->port,
 3794                             (*state)->dst.seqhi, 0, TH_SYN, 0,
 3795                             (*state)->src.mss, 0);
 3796                         return (PF_SYNPROXY_DROP);
 3797                 } else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
 3798                     (TH_SYN|TH_ACK)) ||
 3799                     (ntohl(th->th_ack) != (*state)->dst.seqhi + 1))
 3800                         return (PF_DROP);
 3801                 else {
 3802                         (*state)->dst.max_win = MAX(ntohs(th->th_win), 1);
 3803                         (*state)->dst.seqlo = ntohl(th->th_seq);
 3804                         pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
 3805                             pd->src, th->th_dport, th->th_sport,
 3806                             ntohl(th->th_ack), ntohl(th->th_seq) + 1,
 3807                             TH_ACK, (*state)->src.max_win, 0, 0);
 3808                         pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
 3809                             &dst->addr, src->port, dst->port,
 3810                             (*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
 3811                             TH_ACK, (*state)->dst.max_win, 0, 0);
 3812                         (*state)->src.seqdiff = (*state)->dst.seqhi -
 3813                             (*state)->src.seqlo;
 3814                         (*state)->dst.seqdiff = (*state)->src.seqhi -
 3815                             (*state)->dst.seqlo;
 3816                         (*state)->src.seqhi = (*state)->src.seqlo +
 3817                             (*state)->dst.max_win;
 3818                         (*state)->dst.seqhi = (*state)->dst.seqlo +
 3819                             (*state)->src.max_win;
 3820                         (*state)->src.wscale = (*state)->dst.wscale = 0;
 3821                         (*state)->src.state = (*state)->dst.state =
 3822                             TCPS_ESTABLISHED;
 3823                         return (PF_SYNPROXY_DROP);
 3824                 }
 3825         }
 3826 
 3827         if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
 3828                 sws = src->wscale & PF_WSCALE_MASK;
 3829                 dws = dst->wscale & PF_WSCALE_MASK;
 3830         } else
 3831                 sws = dws = 0;
 3832 
 3833         /*
 3834          * Sequence tracking algorithm from Guido van Rooij's paper:
 3835          *   http://www.madison-gurkha.com/publications/tcp_filtering/
 3836          *      tcp_filtering.ps
 3837          */
 3838 
 3839         seq = ntohl(th->th_seq);
 3840         if (src->seqlo == 0) {
 3841                 /*
 3842                  * First packet from this end.  The other end has already set
 3843                  * the seqlo field.  Set its state.
 3844                  */
 3845                 if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) &&
 3846                     src->scrub == NULL) {
 3847                         if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) {
 3848                                 REASON_SET(reason, PFRES_MEMORY);
 3849                                 return (PF_DROP);
 3850                         }
 3851                 }
 3852 
 3853                 /* Deferred generation of sequence number modulator */
 3854                 if (dst->seqdiff && !src->seqdiff) {
 3855                         while ((src->seqdiff = karc4random()) == 0)
 3856                                 ;
 3857                         ack = ntohl(th->th_ack) - dst->seqdiff;
 3858                         pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
 3859                             src->seqdiff), 0);
 3860                         pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
 3861                         copyback = 1;
 3862                 } else {
 3863                         ack = ntohl(th->th_ack);
 3864                 }
 3865 
 3866                 end = seq + pd->p_len;
 3867                 if (th->th_flags & TH_SYN) {
 3868                         end++;
 3869                         (*state)->sync_flags |= PFSTATE_GOT_SYN2;
 3870                         if (dst->wscale & PF_WSCALE_FLAG) {
 3871                                 src->wscale = pf_get_wscale(m, off, th->th_off,
 3872                                     pd->af);
 3873                                 if (src->wscale & PF_WSCALE_FLAG) {
 3874                                         /* Remove scale factor from initial
 3875                                          * window */
 3876                                         sws = src->wscale & PF_WSCALE_MASK;
 3877                                         win = ((u_int32_t)win + (1 << sws) - 1)
 3878                                             >> sws;
 3879                                         dws = dst->wscale & PF_WSCALE_MASK;
 3880                                 } else {
 3881                                         /*
 3882                                          * Fixup other window.  Undo the
 3883                                          * normalization that was done on
 3884                                          * the initial SYN.  This can result
 3885                                          * in max_win being larger then
 3886                                          * actual but we don't really have
 3887                                          * much of a choice.
 3888                                          */
 3889                                         dst->max_win <<= dst->wscale &
 3890                                             PF_WSCALE_MASK;
 3891                                         /* in case of a retrans SYN|ACK */
 3892                                         dst->wscale = 0;
 3893                                 }
 3894                         }
 3895                 }
 3896                 if (th->th_flags & TH_FIN)
 3897                         end++;
 3898 
 3899                 src->seqlo = seq;
 3900                 if (src->state < TCPS_SYN_SENT)
 3901                         src->state = TCPS_SYN_SENT;
 3902 
 3903                 /*
 3904                  * May need to slide the window (seqhi may have been set by
 3905                  * the crappy stack check or if we picked up the connection
 3906                  * after establishment)
 3907                  */
 3908                 if (src->seqhi == 1 ||
 3909                     SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi))
 3910                         src->seqhi = end + MAX(1, dst->max_win << dws);
 3911                 if (win > src->max_win)
 3912                         src->max_win = win;
 3913 
 3914         } else {
 3915                 ack = ntohl(th->th_ack) - dst->seqdiff;
 3916                 if (src->seqdiff) {
 3917                         /* Modulate sequence numbers */
 3918                         pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
 3919                             src->seqdiff), 0);
 3920                         pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
 3921                         copyback = 1;
 3922                 }
 3923                 end = seq + pd->p_len;
 3924                 if (th->th_flags & TH_SYN)
 3925                         end++;
 3926                 if (th->th_flags & TH_FIN)
 3927                         end++;
 3928         }
 3929 
 3930         if ((th->th_flags & TH_ACK) == 0) {
 3931                 /* Let it pass through the ack skew check */
 3932                 ack = dst->seqlo;
 3933         } else if ((ack == 0 &&
 3934             (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) ||
 3935             /* broken tcp stacks do not set ack */
 3936             (dst->state < TCPS_SYN_SENT)) {
 3937                 /*
 3938                  * Many stacks (ours included) will set the ACK number in an
 3939                  * FIN|ACK if the SYN times out -- no sequence to ACK.
 3940                  */
 3941                 ack = dst->seqlo;
 3942         }
 3943 
 3944         if (seq == end) {
 3945                 /* Ease sequencing restrictions on no data packets */
 3946                 seq = src->seqlo;
 3947                 end = seq;
 3948         }
 3949 
 3950         ackskew = dst->seqlo - ack;
 3951 
 3952 #define MAXACKWINDOW (0xffff + 1500)    /* 1500 is an arbitrary fudge factor */
 3953 
 3954         if (SEQ_GEQ(src->seqhi, end) &&
 3955             /* Last octet inside other's window space */
 3956             SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
 3957             /* Retrans: not more than one window back */
 3958             (ackskew >= -MAXACKWINDOW) &&
 3959             /* Acking not more than one reassembled fragment backwards */
 3960             (ackskew <= (MAXACKWINDOW << sws))) {
 3961             /* Acking not more than one window forward */
 3962 
 3963                 /* update max window */
 3964                 if (src->max_win < win)
 3965                         src->max_win = win;
 3966                 /* synchronize sequencing */
 3967                 if (SEQ_GT(end, src->seqlo))
 3968                         src->seqlo = end;
 3969                 /* slide the window of what the other end can send */
 3970                 if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
 3971                         dst->seqhi = ack + MAX((win << sws), 1);
 3972 
 3973 
 3974                 /* update states */
 3975                 if (th->th_flags & TH_SYN)
 3976                         if (src->state < TCPS_SYN_SENT)
 3977                                 src->state = TCPS_SYN_SENT;
 3978                 if (th->th_flags & TH_FIN)
 3979                         if (src->state < TCPS_CLOSING)
 3980                                 src->state = TCPS_CLOSING;
 3981                 if (th->th_flags & TH_ACK) {
 3982                         if (dst->state == TCPS_SYN_SENT)
 3983                                 dst->state = TCPS_ESTABLISHED;
 3984                         else if (dst->state == TCPS_CLOSING)
 3985                                 dst->state = TCPS_FIN_WAIT_2;
 3986                 }
 3987                 if (th->th_flags & TH_RST)
 3988                         src->state = dst->state = TCPS_TIME_WAIT;
 3989 
 3990                 /* update expire time */
 3991                 (*state)->expire = time_second;
 3992                 if (src->state >= TCPS_FIN_WAIT_2 &&
 3993                     dst->state >= TCPS_FIN_WAIT_2)
 3994                         (*state)->timeout = PFTM_TCP_CLOSED;
 3995                 else if (src->state >= TCPS_FIN_WAIT_2 ||
 3996                     dst->state >= TCPS_FIN_WAIT_2)
 3997                         (*state)->timeout = PFTM_TCP_FIN_WAIT;
 3998                 else if (src->state < TCPS_ESTABLISHED ||
 3999                     dst->state < TCPS_ESTABLISHED)
 4000                         (*state)->timeout = PFTM_TCP_OPENING;
 4001                 else if (src->state >= TCPS_CLOSING ||
 4002                     dst->state >= TCPS_CLOSING)
 4003                         (*state)->timeout = PFTM_TCP_CLOSING;
 4004                 else
 4005                         (*state)->timeout = PFTM_TCP_ESTABLISHED;
 4006 
 4007                 /* Fall through to PASS packet */
 4008 
 4009         } else if ((dst->state < TCPS_SYN_SENT ||
 4010                 dst->state >= TCPS_FIN_WAIT_2 ||
 4011                 src->state >= TCPS_FIN_WAIT_2) &&
 4012             SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) &&
 4013             /* Within a window forward of the originating packet */
 4014             SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) {
 4015             /* Within a window backward of the originating packet */
 4016 
 4017                 /*
 4018                  * This currently handles three situations:
 4019                  *  1) Stupid stacks will shotgun SYNs before their peer
 4020                  *     replies.
 4021                  *  2) When PF catches an already established stream (the
 4022                  *     firewall rebooted, the state table was flushed, routes
 4023                  *     changed...)
 4024                  *  3) Packets get funky immediately after the connection
 4025                  *     closes (this should catch Solaris spurious ACK|FINs
 4026                  *     that web servers like to spew after a close)
 4027                  *
 4028                  * This must be a little more careful than the above code
 4029                  * since packet floods will also be caught here. We don't
 4030                  * update the TTL here to mitigate the damage of a packet
 4031                  * flood and so the same code can handle awkward establishment
 4032                  * and a loosened connection close.
 4033                  * In the establishment case, a correct peer response will
 4034                  * validate the connection, go through the normal state code
 4035                  * and keep updating the state TTL.
 4036                  */
 4037 
 4038                 if (pf_status.debug >= PF_DEBUG_MISC) {
 4039                         kprintf("pf: loose state match: ");
 4040                         pf_print_state(*state);
 4041                         pf_print_flags(th->th_flags);
 4042                         kprintf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d\n",
 4043                             seq, ack, pd->p_len, ackskew,
 4044                             (*state)->packets[0], (*state)->packets[1]);
 4045                 }
 4046 
 4047                 /* update max window */
 4048                 if (src->max_win < win)
 4049                         src->max_win = win;
 4050                 /* synchronize sequencing */
 4051                 if (SEQ_GT(end, src->seqlo))
 4052                         src->seqlo = end;
 4053                 /* slide the window of what the other end can send */
 4054                 if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
 4055                         dst->seqhi = ack + MAX((win << sws), 1);
 4056 
 4057                 /*
 4058                  * Cannot set dst->seqhi here since this could be a shotgunned
 4059                  * SYN and not an already established connection.
 4060                  */
 4061 
 4062                 if (th->th_flags & TH_FIN)
 4063                         if (src->state < TCPS_CLOSING)
 4064                                 src->state = TCPS_CLOSING;
 4065                 if (th->th_flags & TH_RST)
 4066                         src->state = dst->state = TCPS_TIME_WAIT;
 4067 
 4068                 /* Fall through to PASS packet */
 4069 
 4070         } else if ((*state)->pickup_mode == PF_PICKUPS_HASHONLY ||
 4071                     ((*state)->pickup_mode == PF_PICKUPS_ENABLED &&
 4072                      ((*state)->sync_flags & PFSTATE_GOT_SYN_MASK) !=
 4073                       PFSTATE_GOT_SYN_MASK)) {
 4074                 /*
 4075                  * If pickup mode is hash only, do not fail on sequence checks.
 4076                  *
 4077                  * If pickup mode is enabled and we did not see the SYN in
 4078                  * both direction, do not fail on sequence checks because
 4079                  * we do not have complete information on window scale.
 4080                  *
 4081                  * Adjust expiration and fall through to PASS packet.
 4082                  * XXX Add a FIN check to reduce timeout?
 4083                  */
 4084                 (*state)->expire = time_second;
 4085         } else  {
 4086                 /*
 4087                  * Failure processing
 4088                  */
 4089                 if ((*state)->dst.state == TCPS_SYN_SENT &&
 4090                     (*state)->src.state == TCPS_SYN_SENT) {
 4091                         /* Send RST for state mismatches during handshake */
 4092                         if (!(th->th_flags & TH_RST)) {
 4093                                 u_int32_t ack = ntohl(th->th_seq) + pd->p_len;
 4094 
 4095                                 if (th->th_flags & TH_SYN)
 4096                                         ack++;
 4097                                 if (th->th_flags & TH_FIN)
 4098                                         ack++;
 4099                                 pf_send_tcp((*state)->rule.ptr, pd->af,
 4100                                     pd->dst, pd->src, th->th_dport,
 4101                                     th->th_sport, ntohl(th->th_ack), ack,
 4102                                     TH_RST|TH_ACK, 0, 0,
 4103                                     (*state)->rule.ptr->return_ttl);
 4104                         }
 4105                         src->seqlo = 0;
 4106                         src->seqhi = 1;
 4107                         src->max_win = 1;
 4108                 } else if (pf_status.debug >= PF_DEBUG_MISC) {
 4109                         kprintf("pf: BAD state: ");
 4110                         pf_print_state(*state);
 4111                         pf_print_flags(th->th_flags);
 4112                         kprintf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d "
 4113                             "dir=%s,%s\n", seq, ack, pd->p_len, ackskew,
 4114                             (*state)->packets[0], (*state)->packets[1],
 4115                             direction == PF_IN ? "in" : "out",
 4116                             direction == (*state)->direction ? "fwd" : "rev");
 4117                         kprintf("pf: State failure on: %c %c %c %c | %c %c\n",
 4118                             SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
 4119                             SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
 4120                             ' ': '2',
 4121                             (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
 4122                             (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',
 4123                             SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5',
 4124                             SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6');
 4125                 }
 4126                 return (PF_DROP);
 4127         }
 4128 
 4129         if (dst->scrub || src->scrub) {
 4130                 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
 4131                     src, dst, &copyback))
 4132                         return (PF_DROP);
 4133         }
 4134 
 4135         /* Any packets which have gotten here are to be passed */
 4136 
 4137         /* translate source/destination address, if necessary */
 4138         if (STATE_TRANSLATE(*state)) {
 4139                 if (direction == PF_OUT)
 4140                         pf_change_ap(pd->src, &th->th_sport, pd->ip_sum,
 4141                             &th->th_sum, &(*state)->gwy.addr,
 4142                             (*state)->gwy.port, 0, pd->af);
 4143                 else
 4144                         pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum,
 4145                             &th->th_sum, &(*state)->lan.addr,
 4146                             (*state)->lan.port, 0, pd->af);
 4147                 m_copyback(m, off, sizeof(*th), (caddr_t)th);
 4148         } else if (copyback) {
 4149                 /* Copyback sequence modulation or stateful scrub changes */
 4150                 m_copyback(m, off, sizeof(*th), (caddr_t)th);
 4151         }
 4152 
 4153         return (PF_PASS);
 4154 }
 4155 
 4156 int
 4157 pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
 4158     struct mbuf *m, int off, void *h, struct pf_pdesc *pd)
 4159 {
 4160         struct pf_state_peer    *src, *dst;
 4161         struct pf_state          key;
 4162         struct udphdr           *uh = pd->hdr.udp;
 4163 
 4164         key.af = pd->af;
 4165         key.proto = IPPROTO_UDP;
 4166         if (direction == PF_IN) {
 4167                 PF_ACPY(&key.ext.addr, pd->src, key.af);
 4168                 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
 4169                 key.ext.port = uh->uh_sport;
 4170                 key.gwy.port = uh->uh_dport;
 4171         } else {
 4172                 PF_ACPY(&key.lan.addr, pd->src, key.af);
 4173                 PF_ACPY(&key.ext.addr, pd->dst, key.af);
 4174                 key.lan.port = uh->uh_sport;
 4175                 key.ext.port = uh->uh_dport;
 4176         }
 4177 
 4178         STATE_LOOKUP();
 4179 
 4180         if (direction == (*state)->direction) {
 4181                 src = &(*state)->src;
 4182                 dst = &(*state)->dst;
 4183         } else {
 4184                 src = &(*state)->dst;
 4185                 dst = &(*state)->src;
 4186         }
 4187 
 4188         /* update states */
 4189         if (src->state < PFUDPS_SINGLE)
 4190                 src->state = PFUDPS_SINGLE;
 4191         if (dst->state == PFUDPS_SINGLE)
 4192                 dst->state = PFUDPS_MULTIPLE;
 4193 
 4194         /* update expire time */
 4195         (*state)->expire = time_second;
 4196         if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE)
 4197                 (*state)->timeout = PFTM_UDP_MULTIPLE;
 4198         else
 4199                 (*state)->timeout = PFTM_UDP_SINGLE;
 4200 
 4201         /* translate source/destination address, if necessary */
 4202         if (STATE_TRANSLATE(*state)) {
 4203                 if (direction == PF_OUT)
 4204                         pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum,
 4205                             &uh->uh_sum, &(*state)->gwy.addr,
 4206                             (*state)->gwy.port, 1, pd->af);
 4207                 else
 4208                         pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum,
 4209                             &uh->uh_sum, &(*state)->lan.addr,
 4210                             (*state)->lan.port, 1, pd->af);
 4211                 m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
 4212         }
 4213 
 4214         return (PF_PASS);
 4215 }
 4216 
 4217 int
 4218 pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
 4219     struct mbuf *m, int off, void *h, struct pf_pdesc *pd)
 4220 {
 4221         struct pf_addr  *saddr = pd->src, *daddr = pd->dst;
 4222         u_int16_t        icmpid = 0;
 4223         u_int16_t       *icmpsum = NULL;
 4224         u_int8_t         icmptype = 0;
 4225         int              state_icmp = 0;
 4226 
 4227         switch (pd->proto) {
 4228 #ifdef INET
 4229         case IPPROTO_ICMP:
 4230                 icmptype = pd->hdr.icmp->icmp_type;
 4231                 icmpid = pd->hdr.icmp->icmp_id;
 4232                 icmpsum = &pd->hdr.icmp->icmp_cksum;
 4233 
 4234                 if (icmptype == ICMP_UNREACH ||
 4235                     icmptype == ICMP_SOURCEQUENCH ||
 4236                     icmptype == ICMP_REDIRECT ||
 4237                     icmptype == ICMP_TIMXCEED ||
 4238                     icmptype == ICMP_PARAMPROB)
 4239                         state_icmp++;
 4240                 break;
 4241 #endif /* INET */
 4242 #ifdef INET6
 4243         case IPPROTO_ICMPV6:
 4244                 icmptype = pd->hdr.icmp6->icmp6_type;
 4245                 icmpid = pd->hdr.icmp6->icmp6_id;
 4246                 icmpsum = &pd->hdr.icmp6->icmp6_cksum;
 4247 
 4248                 if (icmptype == ICMP6_DST_UNREACH ||
 4249                     icmptype == ICMP6_PACKET_TOO_BIG ||
 4250                     icmptype == ICMP6_TIME_EXCEEDED ||
 4251                     icmptype == ICMP6_PARAM_PROB)
 4252                         state_icmp++;
 4253                 break;
 4254 #endif /* INET6 */
 4255         }
 4256 
 4257         if (!state_icmp) {
 4258 
 4259                 /*
 4260                  * ICMP query/reply message not related to a TCP/UDP packet.
 4261                  * Search for an ICMP state.
 4262                  */
 4263                 struct pf_state         key;
 4264 
 4265                 key.af = pd->af;
 4266                 key.proto = pd->proto;
 4267                 if (direction == PF_IN) {
 4268                         PF_ACPY(&key.ext.addr, pd->src, key.af);
 4269                         PF_ACPY(&key.gwy.addr, pd->dst, key.af);
 4270                         key.ext.port = icmpid;
 4271                         key.gwy.port = icmpid;
 4272                 } else {
 4273                         PF_ACPY(&key.lan.addr, pd->src, key.af);
 4274                         PF_ACPY(&key.ext.addr, pd->dst, key.af);
 4275                         key.lan.port = icmpid;
 4276                         key.ext.port = icmpid;
 4277                 }
 4278 
 4279                 STATE_LOOKUP();
 4280 
 4281                 (*state)->expire = time_second;
 4282                 (*state)->timeout = PFTM_ICMP_ERROR_REPLY;
 4283 
 4284                 /* translate source/destination address, if necessary */
 4285                 if (PF_ANEQ(&(*state)->lan.addr, &(*state)->gwy.addr, pd->af)) {
 4286                         if (direction == PF_OUT) {
 4287                                 switch (pd->af) {
 4288 #ifdef INET
 4289                                 case AF_INET:
 4290                                         pf_change_a(&saddr->v4.s_addr,
 4291                                             pd->ip_sum,
 4292                                             (*state)->gwy.addr.v4.s_addr, 0);
 4293                                         break;
 4294 #endif /* INET */
 4295 #ifdef INET6
 4296                                 case AF_INET6:
 4297                                         pf_change_a6(saddr,
 4298                                             &pd->hdr.icmp6->icmp6_cksum,
 4299                                             &(*state)->gwy.addr, 0);
 4300                                         m_copyback(m, off,
 4301                                             sizeof(struct icmp6_hdr),
 4302                                             (caddr_t)pd->hdr.icmp6);
 4303                                         break;
 4304 #endif /* INET6 */
 4305                                 }
 4306                         } else {
 4307                                 switch (pd->af) {
 4308 #ifdef INET
 4309                                 case AF_INET:
 4310                                         pf_change_a(&daddr->v4.s_addr,
 4311                                             pd->ip_sum,
 4312                                             (*state)->lan.addr.v4.s_addr, 0);
 4313                                         break;
 4314 #endif /* INET */
 4315 #ifdef INET6
 4316                                 case AF_INET6:
 4317                                         pf_change_a6(daddr,
 4318                                             &pd->hdr.icmp6->icmp6_cksum,
 4319                                             &(*state)->lan.addr, 0);
 4320                                         m_copyback(m, off,
 4321                                             sizeof(struct icmp6_hdr),
 4322                                             (caddr_t)pd->hdr.icmp6);
 4323                                         break;
 4324 #endif /* INET6 */
 4325                                 }
 4326                         }
 4327                 }
 4328 
 4329                 return (PF_PASS);
 4330 
 4331         } else {
 4332                 /*
 4333                  * ICMP error message in response to a TCP/UDP packet.
 4334                  * Extract the inner TCP/UDP header and search for that state.
 4335                  */
 4336 
 4337                 struct pf_pdesc pd2;
 4338 #ifdef INET
 4339                 struct ip       h2;
 4340 #endif /* INET */
 4341 #ifdef INET6
 4342                 struct ip6_hdr  h2_6;
 4343                 int             terminal = 0;
 4344 #endif /* INET6 */
 4345                 int             ipoff2 = 0;
 4346                 int             off2 = 0;
 4347 
 4348                 pd2.af = pd->af;
 4349                 switch (pd->af) {
 4350 #ifdef INET
 4351                 case AF_INET:
 4352                         /* offset of h2 in mbuf chain */
 4353                         ipoff2 = off + ICMP_MINLEN;
 4354 
 4355                         if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2),
 4356                             NULL, NULL, pd2.af)) {
 4357                                 DPFPRINTF(PF_DEBUG_MISC,
 4358                                     ("pf: ICMP error message too short "
 4359                                     "(ip)\n"));
 4360                                 return (PF_DROP);
 4361                         }
 4362                         /*
 4363                          * ICMP error messages don't refer to non-first
 4364                          * fragments
 4365                          */
 4366                         /* 
 4367                          * Note: We are dealing with an encapsulated
 4368                          * header. This means ip_off/ip_len are not
 4369                          * in host byte order!
 4370                          */
 4371                         if (h2.ip_off & htons(IP_OFFMASK))
 4372                                 return (PF_DROP);
 4373 
 4374                         /* offset of protocol header that follows h2 */
 4375                         off2 = ipoff2 + (h2.ip_hl << 2);
 4376 
 4377                         pd2.proto = h2.ip_p;
 4378                         pd2.src = (struct pf_addr *)&h2.ip_src;
 4379                         pd2.dst = (struct pf_addr *)&h2.ip_dst;
 4380                         pd2.ip_sum = &h2.ip_sum;
 4381                         break;
 4382 #endif /* INET */
 4383 #ifdef INET6
 4384                 case AF_INET6:
 4385                         ipoff2 = off + sizeof(struct icmp6_hdr);
 4386 
 4387                         if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6),
 4388                             NULL, NULL, pd2.af)) {
 4389                                 DPFPRINTF(PF_DEBUG_MISC,
 4390                                     ("pf: ICMP error message too short "
 4391                                     "(ip6)\n"));
 4392                                 return (PF_DROP);
 4393                         }
 4394                         pd2.proto = h2_6.ip6_nxt;
 4395                         pd2.src = (struct pf_addr *)&h2_6.ip6_src;
 4396                         pd2.dst = (struct pf_addr *)&h2_6.ip6_dst;
 4397                         pd2.ip_sum = NULL;
 4398                         off2 = ipoff2 + sizeof(h2_6);
 4399                         do {
 4400                                 switch (pd2.proto) {
 4401                                 case IPPROTO_FRAGMENT:
 4402                                         /*
 4403                                          * ICMPv6 error messages for
 4404                                          * non-first fragments
 4405                                          */
 4406                                         return (PF_DROP);
 4407                                 case IPPROTO_AH:
 4408                                 case IPPROTO_HOPOPTS:
 4409                                 case IPPROTO_ROUTING:
 4410                                 case IPPROTO_DSTOPTS: {
 4411                                         /* get next header and header length */
 4412                                         struct ip6_ext opt6;
 4413 
 4414                                         if (!pf_pull_hdr(m, off2, &opt6,
 4415                                             sizeof(opt6), NULL, NULL, pd2.af)) {
 4416                                                 DPFPRINTF(PF_DEBUG_MISC,
 4417                                                     ("pf: ICMPv6 short opt\n"));
 4418                                                 return (PF_DROP);
 4419                                         }
 4420                                         if (pd2.proto == IPPROTO_AH)
 4421                                                 off2 += (opt6.ip6e_len + 2) * 4;
 4422                                         else
 4423                                                 off2 += (opt6.ip6e_len + 1) * 8;
 4424                                         pd2.proto = opt6.ip6e_nxt;
 4425                                         /* goto the next header */
 4426                                         break;
 4427                                 }
 4428                                 default:
 4429                                         terminal++;
 4430                                         break;
 4431                                 }
 4432                         } while (!terminal);
 4433                         break;
 4434 #endif /* INET6 */
 4435                 }
 4436 
 4437                 switch (pd2.proto) {
 4438                 case IPPROTO_TCP: {
 4439                         struct tcphdr            th;
 4440                         u_int32_t                seq;
 4441                         struct pf_state          key;
 4442                         struct pf_state_peer    *src, *dst;
 4443                         u_int8_t                 dws;
 4444                         int                      copyback = 0;
 4445 
 4446                         /*
 4447                          * Only the first 8 bytes of the TCP header can be
 4448                          * expected. Don't access any TCP header fields after
 4449                          * th_seq, an ackskew test is not possible.
 4450                          */
 4451                         if (!pf_pull_hdr(m, off2, &th, 8, NULL, NULL, pd2.af)) {
 4452                                 DPFPRINTF(PF_DEBUG_MISC,
 4453                                     ("pf: ICMP error message too short "
 4454                                     "(tcp)\n"));
 4455                                 return (PF_DROP);
 4456                         }
 4457 
 4458                         key.af = pd2.af;
 4459                         key.proto = IPPROTO_TCP;
 4460                         if (direction == PF_IN) {
 4461                                 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
 4462                                 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
 4463                                 key.ext.port = th.th_dport;
 4464                                 key.gwy.port = th.th_sport;
 4465                         } else {
 4466                                 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
 4467                                 PF_ACPY(&key.ext.addr, pd2.src, key.af);
 4468                                 key.lan.port = th.th_dport;
 4469                                 key.ext.port = th.th_sport;
 4470                         }
 4471 
 4472                         STATE_LOOKUP();
 4473 
 4474                         if (direction == (*state)->direction) {
 4475                                 src = &(*state)->dst;
 4476                                 dst = &(*state)->src;
 4477                         } else {
 4478                                 src = &(*state)->src;
 4479                                 dst = &(*state)->dst;
 4480                         }
 4481 
 4482                         if (src->wscale && dst->wscale &&
 4483                             !(th.th_flags & TH_SYN))
 4484                                 dws = dst->wscale & PF_WSCALE_MASK;
 4485                         else
 4486                                 dws = 0;
 4487 
 4488                         /* Demodulate sequence number */
 4489                         seq = ntohl(th.th_seq) - src->seqdiff;
 4490                         if (src->seqdiff) {
 4491                                 pf_change_a(&th.th_seq, icmpsum,
 4492                                     htonl(seq), 0);
 4493                                 copyback = 1;
 4494                         }
 4495 
 4496                         if (!SEQ_GEQ(src->seqhi, seq) ||
 4497                             !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws))) {
 4498                                 if (pf_status.debug >= PF_DEBUG_MISC) {
 4499                                         kprintf("pf: BAD ICMP %d:%d ",
 4500                                             icmptype, pd->hdr.icmp->icmp_code);
 4501                                         pf_print_host(pd->src, 0, pd->af);
 4502                                         kprintf(" -> ");
 4503                                         pf_print_host(pd->dst, 0, pd->af);
 4504                                         kprintf(" state: ");
 4505                                         pf_print_state(*state);
 4506                                         kprintf(" seq=%u\n", seq);
 4507                                 }
 4508                                 return (PF_DROP);
 4509                         }
 4510 
 4511                         if (STATE_TRANSLATE(*state)) {
 4512                                 if (direction == PF_IN) {
 4513                                         pf_change_icmp(pd2.src, &th.th_sport,
 4514                                             daddr, &(*state)->lan.addr,
 4515                                             (*state)->lan.port, NULL,
 4516                                             pd2.ip_sum, icmpsum,
 4517                                             pd->ip_sum, 0, pd2.af);
 4518                                 } else {
 4519                                         pf_change_icmp(pd2.dst, &th.th_dport,
 4520                                             saddr, &(*state)->gwy.addr,
 4521                                             (*state)->gwy.port, NULL,
 4522                                             pd2.ip_sum, icmpsum,
 4523                                             pd->ip_sum, 0, pd2.af);
 4524                                 }
 4525                                 copyback = 1;
 4526                         }
 4527 
 4528                         if (copyback) {
 4529                                 switch (pd2.af) {
 4530 #ifdef INET
 4531                                 case AF_INET:
 4532                                         m_copyback(m, off, ICMP_MINLEN,
 4533                                             (caddr_t)pd->hdr.icmp);
 4534                                         m_copyback(m, ipoff2, sizeof(h2),
 4535                                             (caddr_t)&h2);
 4536                                         break;
 4537 #endif /* INET */
 4538 #ifdef INET6
 4539                                 case AF_INET6:
 4540                                         m_copyback(m, off,
 4541                                             sizeof(struct icmp6_hdr),
 4542                                             (caddr_t)pd->hdr.icmp6);
 4543                                         m_copyback(m, ipoff2, sizeof(h2_6),
 4544                                             (caddr_t)&h2_6);
 4545                                         break;
 4546 #endif /* INET6 */
 4547                                 }
 4548                                 m_copyback(m, off2, 8, (caddr_t)&th);
 4549                         }
 4550 
 4551                         return (PF_PASS);
 4552                         break;
 4553                 }
 4554                 case IPPROTO_UDP: {
 4555                         struct udphdr           uh;
 4556                         struct pf_state         key;
 4557 
 4558                         if (!pf_pull_hdr(m, off2, &uh, sizeof(uh),
 4559                             NULL, NULL, pd2.af)) {
 4560                                 DPFPRINTF(PF_DEBUG_MISC,
 4561                                     ("pf: ICMP error message too short "
 4562                                     "(udp)\n"));
 4563                                 return (PF_DROP);
 4564                         }
 4565 
 4566                         key.af = pd2.af;
 4567                         key.proto = IPPROTO_UDP;
 4568                         if (direction == PF_IN) {
 4569                                 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
 4570                                 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
 4571                                 key.ext.port = uh.uh_dport;
 4572                                 key.gwy.port = uh.uh_sport;
 4573                         } else {
 4574                                 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
 4575                                 PF_ACPY(&key.ext.addr, pd2.src, key.af);
 4576                                 key.lan.port = uh.uh_dport;
 4577                                 key.ext.port = uh.uh_sport;
 4578                         }
 4579 
 4580                         STATE_LOOKUP();
 4581 
 4582                         if (STATE_TRANSLATE(*state)) {
 4583                                 if (direction == PF_IN) {
 4584                                         pf_change_icmp(pd2.src, &uh.uh_sport,
 4585                                             daddr, &(*state)->lan.addr,
 4586                                             (*state)->lan.port, &uh.uh_sum,
 4587                                             pd2.ip_sum, icmpsum,
 4588                                             pd->ip_sum, 1, pd2.af);
 4589                                 } else {
 4590                                         pf_change_icmp(pd2.dst, &uh.uh_dport,
 4591                                             saddr, &(*state)->gwy.addr,
 4592                                             (*state)->gwy.port, &uh.uh_sum,
 4593                                             pd2.ip_sum, icmpsum,
 4594                                             pd->ip_sum, 1, pd2.af);
 4595                                 }
 4596                                 switch (pd2.af) {
 4597 #ifdef INET
 4598                                 case AF_INET:
 4599                                         m_copyback(m, off, ICMP_MINLEN,
 4600                                             (caddr_t)pd->hdr.icmp);
 4601                                         m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2);
 4602                                         break;
 4603 #endif /* INET */
 4604 #ifdef INET6
 4605                                 case AF_INET6:
 4606                                         m_copyback(m, off,
 4607                                             sizeof(struct icmp6_hdr),
 4608                                             (caddr_t)pd->hdr.icmp6);
 4609                                         m_copyback(m, ipoff2, sizeof(h2_6),
 4610                                             (caddr_t)&h2_6);
 4611                                         break;
 4612 #endif /* INET6 */
 4613                                 }
 4614                                 m_copyback(m, off2, sizeof(uh), (caddr_t)&uh);
 4615                         }
 4616 
 4617                         return (PF_PASS);
 4618                         break;
 4619                 }
 4620 #ifdef INET
 4621                 case IPPROTO_ICMP: {
 4622                         struct icmp             iih;
 4623                         struct pf_state         key;
 4624 
 4625                         if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN,
 4626                             NULL, NULL, pd2.af)) {
 4627                                 DPFPRINTF(PF_DEBUG_MISC,
 4628                                     ("pf: ICMP error message too short i"
 4629                                     "(icmp)\n"));
 4630                                 return (PF_DROP);
 4631                         }
 4632 
 4633                         key.af = pd2.af;
 4634                         key.proto = IPPROTO_ICMP;
 4635                         if (direction == PF_IN) {
 4636                                 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
 4637                                 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
 4638                                 key.ext.port = iih.icmp_id;
 4639                                 key.gwy.port = iih.icmp_id;
 4640                         } else {
 4641                                 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
 4642                                 PF_ACPY(&key.ext.addr, pd2.src, key.af);
 4643                                 key.lan.port = iih.icmp_id;
 4644                                 key.ext.port = iih.icmp_id;
 4645                         }
 4646 
 4647                         STATE_LOOKUP();
 4648 
 4649                         if (STATE_TRANSLATE(*state)) {
 4650                                 if (direction == PF_IN) {
 4651                                         pf_change_icmp(pd2.src, &iih.icmp_id,
 4652                                             daddr, &(*state)->lan.addr,
 4653                                             (*state)->lan.port, NULL,
 4654                                             pd2.ip_sum, icmpsum,
 4655                                             pd->ip_sum, 0, AF_INET);
 4656                                 } else {
 4657                                         pf_change_icmp(pd2.dst, &iih.icmp_id,
 4658                                             saddr, &(*state)->gwy.addr,
 4659                                             (*state)->gwy.port, NULL,
 4660                                             pd2.ip_sum, icmpsum,
 4661                                             pd->ip_sum, 0, AF_INET);
 4662                                 }
 4663                                 m_copyback(m, off, ICMP_MINLEN, (caddr_t)pd->hdr.icmp);
 4664                                 m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2);
 4665                                 m_copyback(m, off2, ICMP_MINLEN, (caddr_t)&iih);
 4666                         }
 4667 
 4668                         return (PF_PASS);
 4669                         break;
 4670                 }
 4671 #endif /* INET */
 4672 #ifdef INET6
 4673                 case IPPROTO_ICMPV6: {
 4674                         struct icmp6_hdr        iih;
 4675                         struct pf_state         key;
 4676 
 4677                         if (!pf_pull_hdr(m, off2, &iih,
 4678                             sizeof(struct icmp6_hdr), NULL, NULL, pd2.af)) {
 4679                                 DPFPRINTF(PF_DEBUG_MISC,
 4680                                     ("pf: ICMP error message too short "
 4681                                     "(icmp6)\n"));
 4682                                 return (PF_DROP);
 4683                         }
 4684 
 4685                         key.af = pd2.af;
 4686                         key.proto = IPPROTO_ICMPV6;
 4687                         if (direction == PF_IN) {
 4688                                 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
 4689                                 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
 4690                                 key.ext.port = iih.icmp6_id;
 4691                                 key.gwy.port = iih.icmp6_id;
 4692                         } else {
 4693                                 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
 4694                                 PF_ACPY(&key.ext.addr, pd2.src, key.af);
 4695                                 key.lan.port = iih.icmp6_id;
 4696                                 key.ext.port = iih.icmp6_id;
 4697                         }
 4698 
 4699                         STATE_LOOKUP();
 4700 
 4701                         if (STATE_TRANSLATE(*state)) {
 4702                                 if (direction == PF_IN) {
 4703                                         pf_change_icmp(pd2.src, &iih.icmp6_id,
 4704                                             daddr, &(*state)->lan.addr,
 4705                                             (*state)->lan.port, NULL,
 4706                                             pd2.ip_sum, icmpsum,
 4707                                             pd->ip_sum, 0, AF_INET6);
 4708                                 } else {
 4709                                         pf_change_icmp(pd2.dst, &iih.icmp6_id,
 4710                                             saddr, &(*state)->gwy.addr,
 4711                                             (*state)->gwy.port, NULL,
 4712                                             pd2.ip_sum, icmpsum,
 4713                                             pd->ip_sum, 0, AF_INET6);
 4714                                 }
 4715                                 m_copyback(m, off, sizeof(struct icmp6_hdr),
 4716                                     (caddr_t)pd->hdr.icmp6);
 4717                                 m_copyback(m, ipoff2, sizeof(h2_6), (caddr_t)&h2_6);
 4718                                 m_copyback(m, off2, sizeof(struct icmp6_hdr),
 4719                                     (caddr_t)&iih);
 4720                         }
 4721 
 4722                         return (PF_PASS);
 4723                         break;
 4724                 }
 4725 #endif /* INET6 */
 4726                 default: {
 4727                         struct pf_state         key;
 4728 
 4729                         key.af = pd2.af;
 4730                         key.proto = pd2.proto;
 4731                         if (direction == PF_IN) {
 4732                                 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
 4733                                 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
 4734                                 key.ext.port = 0;
 4735                                 key.gwy.port = 0;
 4736                         } else {
 4737                                 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
 4738                                 PF_ACPY(&key.ext.addr, pd2.src, key.af);
 4739                                 key.lan.port = 0;
 4740                                 key.ext.port = 0;
 4741                         }
 4742 
 4743                         STATE_LOOKUP();
 4744 
 4745                         if (STATE_TRANSLATE(*state)) {
 4746                                 if (direction == PF_IN) {
 4747                                         pf_change_icmp(pd2.src, NULL,
 4748                                             daddr, &(*state)->lan.addr,
 4749                                             0, NULL,
 4750                                             pd2.ip_sum, icmpsum,
 4751                                             pd->ip_sum, 0, pd2.af);
 4752                                 } else {
 4753                                         pf_change_icmp(pd2.dst, NULL,
 4754                                             saddr, &(*state)->gwy.addr,
 4755                                             0, NULL,
 4756                                             pd2.ip_sum, icmpsum,
 4757                                             pd->ip_sum, 0, pd2.af);
 4758                                 }
 4759                                 switch (pd2.af) {
 4760 #ifdef INET
 4761                                 case AF_INET:
 4762                                         m_copyback(m, off, ICMP_MINLEN,
 4763                                             (caddr_t)pd->hdr.icmp);
 4764                                         m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2);
 4765                                         break;
 4766 #endif /* INET */
 4767 #ifdef INET6
 4768                                 case AF_INET6:
 4769                                         m_copyback(m, off,
 4770                                             sizeof(struct icmp6_hdr),
 4771                                             (caddr_t)pd->hdr.icmp6);
 4772                                         m_copyback(m, ipoff2, sizeof(h2_6),
 4773                                             (caddr_t)&h2_6);
 4774                                         break;
 4775 #endif /* INET6 */
 4776                                 }
 4777                         }
 4778 
 4779                         return (PF_PASS);
 4780                         break;
 4781                 }
 4782                 }
 4783         }
 4784 }
 4785 
 4786 int
 4787 pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
 4788     struct pf_pdesc *pd)
 4789 {
 4790         struct pf_state_peer    *src, *dst;
 4791         struct pf_state          key;
 4792 
 4793         key.af = pd->af;
 4794         key.proto = pd->proto;
 4795         if (direction == PF_IN) {
 4796                 PF_ACPY(&key.ext.addr, pd->src, key.af);
 4797                 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
 4798                 key.ext.port = 0;
 4799                 key.gwy.port = 0;
 4800         } else {
 4801                 PF_ACPY(&key.lan.addr, pd->src, key.af);
 4802                 PF_ACPY(&key.ext.addr, pd->dst, key.af);
 4803                 key.lan.port = 0;
 4804                 key.ext.port = 0;
 4805         }
 4806 
 4807         STATE_LOOKUP();
 4808 
 4809         if (direction == (*state)->direction) {
 4810                 src = &(*state)->src;
 4811                 dst = &(*state)->dst;
 4812         } else {
 4813                 src = &(*state)->dst;
 4814                 dst = &(*state)->src;
 4815         }
 4816 
 4817         /* update states */
 4818         if (src->state < PFOTHERS_SINGLE)
 4819                 src->state = PFOTHERS_SINGLE;
 4820         if (dst->state == PFOTHERS_SINGLE)
 4821                 dst->state = PFOTHERS_MULTIPLE;
 4822 
 4823         /* update expire time */
 4824         (*state)->expire = time_second;
 4825         if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE)
 4826                 (*state)->timeout = PFTM_OTHER_MULTIPLE;
 4827         else
 4828                 (*state)->timeout = PFTM_OTHER_SINGLE;
 4829 
 4830         /* translate source/destination address, if necessary */
 4831         if (STATE_TRANSLATE(*state)) {
 4832                 if (direction == PF_OUT)
 4833                         switch (pd->af) {
 4834 #ifdef INET
 4835                         case AF_INET:
 4836                                 pf_change_a(&pd->src->v4.s_addr,
 4837                                     pd->ip_sum, (*state)->gwy.addr.v4.s_addr,
 4838                                     0);
 4839                                 break;
 4840 #endif /* INET */
 4841 #ifdef INET6
 4842                         case AF_INET6:
 4843                                 PF_ACPY(pd->src, &(*state)->gwy.addr, pd->af);
 4844                                 break;
 4845 #endif /* INET6 */
 4846                         }
 4847                 else
 4848                         switch (pd->af) {
 4849 #ifdef INET
 4850                         case AF_INET:
 4851                                 pf_change_a(&pd->dst->v4.s_addr,
 4852                                     pd->ip_sum, (*state)->lan.addr.v4.s_addr,
 4853                                     0);
 4854                                 break;
 4855 #endif /* INET */
 4856 #ifdef INET6
 4857                         case AF_INET6:
 4858                                 PF_ACPY(pd->dst, &(*state)->lan.addr, pd->af);
 4859                                 break;
 4860 #endif /* INET6 */
 4861                         }
 4862         }
 4863 
 4864         return (PF_PASS);
 4865 }
 4866 
 4867 /*
 4868  * ipoff and off are measured from the start of the mbuf chain.
 4869  * h must be at "ipoff" on the mbuf chain.
 4870  */
 4871 void *
 4872 pf_pull_hdr(struct mbuf *m, int off, void *p, int len,
 4873     u_short *actionp, u_short *reasonp, sa_family_t af)
 4874 {
 4875         switch (af) {
 4876 #ifdef INET
 4877         case AF_INET: {
 4878                 struct ip       *h = mtod(m, struct ip *);
 4879                 u_int16_t        fragoff = (h->ip_off & IP_OFFMASK) << 3;
 4880 
 4881                 if (fragoff) {
 4882                         if (fragoff >= len)
 4883                                 ACTION_SET(actionp, PF_PASS);
 4884                         else {
 4885                                 ACTION_SET(actionp, PF_DROP);
 4886                                 REASON_SET(reasonp, PFRES_FRAG);
 4887                         }
 4888                         return (NULL);
 4889                 }
 4890                 if (m->m_pkthdr.len < off + len ||
 4891                     h->ip_len < off + len) {
 4892                         ACTION_SET(actionp, PF_DROP);
 4893                         REASON_SET(reasonp, PFRES_SHORT);
 4894                         return (NULL);
 4895                 }
 4896                 break;
 4897         }
 4898 #endif /* INET */
 4899 #ifdef INET6
 4900         case AF_INET6: {
 4901                 struct ip6_hdr  *h = mtod(m, struct ip6_hdr *);
 4902 
 4903                 if (m->m_pkthdr.len < off + len ||
 4904                     (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) <
 4905                     (unsigned)(off + len)) {
 4906                         ACTION_SET(actionp, PF_DROP);
 4907                         REASON_SET(reasonp, PFRES_SHORT);
 4908                         return (NULL);
 4909                 }
 4910                 break;
 4911         }
 4912 #endif /* INET6 */
 4913         }
 4914         m_copydata(m, off, len, p);
 4915         return (p);
 4916 }
 4917 
 4918 int
 4919 pf_routable(struct pf_addr *addr, sa_family_t af)
 4920 {
 4921         struct sockaddr_in      *dst;
 4922         struct route             ro;
 4923         int                      ret = 0;
 4924 
 4925         bzero(&ro, sizeof(ro));
 4926         dst = satosin(&ro.ro_dst);
 4927         dst->sin_family = af;
 4928         dst->sin_len = sizeof(*dst);
 4929         dst->sin_addr = addr->v4;
 4930         rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING));
 4931 
 4932         if (ro.ro_rt != NULL) {
 4933                 ret = 1;
 4934                 RTFREE(ro.ro_rt);
 4935         }
 4936 
 4937         return (ret);
 4938 }
 4939 
 4940 #ifdef INET
 4941 void
 4942 pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
 4943     struct pf_state *s)
 4944 {
 4945         struct mbuf             *m0, *m1;
 4946         struct route             iproute;
 4947         struct route            *ro = NULL;
 4948         struct sockaddr_in      *dst;
 4949         struct ip               *ip;
 4950         struct ifnet            *ifp = NULL;
 4951         struct pf_addr           naddr;
 4952         struct pf_src_node      *sn = NULL;
 4953         int                      error = 0;
 4954         int sw_csum;
 4955 
 4956         if (m == NULL || *m == NULL || r == NULL ||
 4957             (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
 4958                 panic("pf_route: invalid parameters");
 4959 
 4960         if (((*m)->m_pkthdr.fw_flags & PF_MBUF_ROUTED) == 0) {
 4961                 (*m)->m_pkthdr.fw_flags |= PF_MBUF_ROUTED;
 4962                 (*m)->m_pkthdr.pf_routed = 1;
 4963         } else {
 4964                 if ((*m)->m_pkthdr.pf_routed > 3) {
 4965                         m0 = *m;
 4966                         *m = NULL;
 4967                         goto bad;
 4968                 }
 4969                 (*m)->m_pkthdr.pf_routed++;
 4970         }
 4971 
 4972         if (r->rt == PF_DUPTO) {
 4973                 if ((m0 = m_dup(*m, MB_DONTWAIT)) == NULL)
 4974                         return;
 4975         } else {
 4976                 if ((r->rt == PF_REPLYTO) == (r->direction == dir))
 4977                         return;
 4978                 m0 = *m;
 4979         }
 4980 
 4981         if (m0->m_len < sizeof(struct ip))
 4982                 panic("pf_route: m0->m_len < sizeof(struct ip)");
 4983         ip = mtod(m0, struct ip *);
 4984 
 4985         ro = &iproute;
 4986         bzero((caddr_t)ro, sizeof(*ro));
 4987         dst = satosin(&ro->ro_dst);
 4988         dst->sin_family = AF_INET;
 4989         dst->sin_len = sizeof(*dst);
 4990         dst->sin_addr = ip->ip_dst;
 4991 
 4992         if (r->rt == PF_FASTROUTE) {
 4993                 rtalloc(ro);
 4994                 if (ro->ro_rt == 0) {
 4995                         ipstat.ips_noroute++;
 4996                         goto bad;
 4997                 }
 4998 
 4999                 ifp = ro->ro_rt->rt_ifp;
 5000                 ro->ro_rt->rt_use++;
 5001 
 5002                 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
 5003                         dst = satosin(ro->ro_rt->rt_gateway);
 5004         } else {
 5005                 if (TAILQ_EMPTY(&r->rpool.list))
 5006                         panic("pf_route: TAILQ_EMPTY(&r->rpool.list)");
 5007                 if (s == NULL) {
 5008                         pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
 5009                             &naddr, NULL, &sn);
 5010                         if (!PF_AZERO(&naddr, AF_INET))
 5011                                 dst->sin_addr.s_addr = naddr.v4.s_addr;
 5012                         ifp = r->rpool.cur->kif ?
 5013                             r->rpool.cur->kif->pfik_ifp : NULL;
 5014                 } else {
 5015                         if (!PF_AZERO(&s->rt_addr, AF_INET))
 5016                                 dst->sin_addr.s_addr =
 5017                                     s->rt_addr.v4.s_addr;
 5018                         ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
 5019                 }
 5020         }
 5021         if (ifp == NULL)
 5022                 goto bad;
 5023 
 5024         if (oifp != ifp) {
 5025                 if (pf_test(PF_OUT, ifp, &m0) != PF_PASS)
 5026                         goto bad;
 5027                 else if (m0 == NULL)
 5028                         goto done;
 5029                 if (m0->m_len < sizeof(struct ip))
 5030                         panic("pf_route: m0->m_len < sizeof(struct ip)");
 5031                 ip = mtod(m0, struct ip *);
 5032         }
 5033 
 5034         /* Copied from ip_output. */
 5035         m0->m_pkthdr.csum_flags |= CSUM_IP;
 5036         sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist;
 5037         if (sw_csum & CSUM_DELAY_DATA) {
 5038                 in_delayed_cksum(m0);
 5039                 sw_csum &= ~CSUM_DELAY_DATA;
 5040         }
 5041         m0->m_pkthdr.csum_flags &= ifp->if_hwassist;
 5042 
 5043         /*
 5044          * If small enough for interface, or the interface will take
 5045          * care of the fragmentation for us, can just send directly.
 5046          */
 5047         if (ip->ip_len <= ifp->if_mtu || ((ifp->if_hwassist & CSUM_FRAGMENT) &&
 5048                 (ip->ip_off & IP_DF) == 0)) {
 5049                 ip->ip_len = htons(ip->ip_len);
 5050                 ip->ip_off = htons(ip->ip_off);
 5051                 ip->ip_sum = 0;
 5052                 if (sw_csum & CSUM_DELAY_IP) {
 5053                         /* From KAME */
 5054                         if (ip->ip_v == IPVERSION &&
 5055                             (ip->ip_hl << 2) == sizeof(*ip)) {
 5056                                 ip->ip_sum = in_cksum_hdr(ip);
 5057                         } else {
 5058                                 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
 5059                         }
 5060                 }
 5061 
 5062                 error = ifp->if_output(ifp, m0, sintosa(dst), ro->ro_rt);
 5063                 goto done;
 5064         }
 5065 
 5066         /*
 5067          * Too large for interface; fragment if possible.
 5068          * Must be able to put at least 8 bytes per fragment.
 5069          */
 5070         if (ip->ip_off & IP_DF) {
 5071                 ipstat.ips_cantfrag++;
 5072                 if (r->rt != PF_DUPTO) {
 5073                         icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
 5074                             ifp->if_mtu);
 5075                         goto done;
 5076                 } else
 5077                         goto bad;
 5078         }
 5079 
 5080         m1 = m0;
 5081         error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum);
 5082         if (error)
 5083                 goto bad;
 5084 
 5085         for (m0 = m1; m0; m0 = m1) {
 5086                 m1 = m0->m_nextpkt;
 5087                 m0->m_nextpkt = 0;
 5088                 if (error == 0) {
 5089                         error = ifp->if_output(ifp, m0, sintosa(dst), NULL);
 5090                 } else {
 5091                         m_freem(m0);
 5092                 }
 5093         }
 5094 
 5095         if (error == 0)
 5096                 ipstat.ips_fragmented++;
 5097 
 5098 done:
 5099         if (r->rt != PF_DUPTO)
 5100                 *m = NULL;
 5101         if (ro == &iproute && ro->ro_rt)
 5102                 RTFREE(ro->ro_rt);
 5103         return;
 5104 
 5105 bad:
 5106         m_freem(m0);
 5107         goto done;
 5108 }
 5109 #endif /* INET */
 5110 
 5111 #ifdef INET6
 5112 void
 5113 pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
 5114     struct pf_state *s)
 5115 {
 5116         struct mbuf             *m0;
 5117         struct route_in6         ip6route;
 5118         struct route_in6        *ro;
 5119         struct sockaddr_in6     *dst;
 5120         struct ip6_hdr          *ip6;
 5121         struct ifnet            *ifp = NULL;
 5122         struct pf_addr           naddr;
 5123         struct pf_src_node      *sn = NULL;
 5124         int                      error = 0;
 5125 
 5126         if (m == NULL || *m == NULL || r == NULL ||
 5127             (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
 5128                 panic("pf_route6: invalid parameters");
 5129 
 5130         if (((*m)->m_pkthdr.fw_flags & PF_MBUF_ROUTED) == 0) {
 5131                 (*m)->m_pkthdr.fw_flags |= PF_MBUF_ROUTED;
 5132                 (*m)->m_pkthdr.pf_routed = 1;
 5133         } else {
 5134                 if ((*m)->m_pkthdr.pf_routed > 3) {
 5135                         m0 = *m;
 5136                         *m = NULL;
 5137                         goto bad;
 5138                 }
 5139                 (*m)->m_pkthdr.pf_routed++;
 5140         }
 5141 
 5142         if (r->rt == PF_DUPTO) {
 5143                 if ((m0 = m_dup(*m, MB_DONTWAIT)) == NULL)
 5144                         return;
 5145         } else {
 5146                 if ((r->rt == PF_REPLYTO) == (r->direction == dir))
 5147                         return;
 5148                 m0 = *m;
 5149         }
 5150 
 5151         if (m0->m_len < sizeof(struct ip6_hdr))
 5152                 panic("pf_route6: m0->m_len < sizeof(struct ip6_hdr)");
 5153         ip6 = mtod(m0, struct ip6_hdr *);
 5154 
 5155         ro = &ip6route;
 5156         bzero((caddr_t)ro, sizeof(*ro));
 5157         dst = (struct sockaddr_in6 *)&ro->ro_dst;
 5158         dst->sin6_family = AF_INET6;
 5159         dst->sin6_len = sizeof(*dst);
 5160         dst->sin6_addr = ip6->ip6_dst;
 5161 
 5162         /* Cheat. */
 5163         if (r->rt == PF_FASTROUTE) {
 5164                 m0->m_pkthdr.fw_flags |= PF_MBUF_GENERATED;
 5165                 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
 5166                 return;
 5167         }
 5168 
 5169         if (TAILQ_EMPTY(&r->rpool.list))
 5170                 panic("pf_route6: TAILQ_EMPTY(&r->rpool.list)");
 5171         if (s == NULL) {
 5172                 pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
 5173                     &naddr, NULL, &sn);
 5174                 if (!PF_AZERO(&naddr, AF_INET6))
 5175                         PF_ACPY((struct pf_addr *)&dst->sin6_addr,
 5176                             &naddr, AF_INET6);
 5177                 ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
 5178         } else {
 5179                 if (!PF_AZERO(&s->rt_addr, AF_INET6))
 5180                         PF_ACPY((struct pf_addr *)&dst->sin6_addr,
 5181                             &s->rt_addr, AF_INET6);
 5182                 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
 5183         }
 5184         if (ifp == NULL)
 5185                 goto bad;
 5186 
 5187         if (oifp != ifp) {
 5188                 if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS)
 5189                         goto bad;
 5190                 else if (m0 == NULL)
 5191                         goto done;
 5192                 if (m0->m_len < sizeof(struct ip6_hdr))
 5193                         panic("pf_route6: m0->m_len < sizeof(struct ip6_hdr)");
 5194                 ip6 = mtod(m0, struct ip6_hdr *);
 5195         }
 5196 
 5197         /*
 5198          * If the packet is too large for the outgoing interface,
 5199          * send back an icmp6 error.
 5200          */
 5201         if (IN6_IS_ADDR_LINKLOCAL(&dst->sin6_addr))
 5202                 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
 5203         if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
 5204                 error = nd6_output(ifp, ifp, m0, dst, NULL);
 5205         } else {
 5206                 in6_ifstat_inc(ifp, ifs6_in_toobig);
 5207                 if (r->rt != PF_DUPTO)
 5208                         icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
 5209                 else
 5210                         goto bad;
 5211         }
 5212 
 5213 done:
 5214         if (r->rt != PF_DUPTO)
 5215                 *m = NULL;
 5216         return;
 5217 
 5218 bad:
 5219         m_freem(m0);
 5220         goto done;
 5221 }
 5222 #endif /* INET6 */
 5223 
 5224 
 5225 /*
 5226  * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag
 5227  *   off is the offset where the protocol header starts
 5228  *   len is the total length of protocol header plus payload
 5229  * returns 0 when the checksum is valid, otherwise returns 1.
 5230  */
 5231 /*
 5232  * XXX
 5233  * FreeBSD supports cksum offload for the following drivers.
 5234  * em(4), gx(4), lge(4), nge(4), ti(4), xl(4)
 5235  * If we can make full use of it we would outperform ipfw/ipfilter in
 5236  * very heavy traffic. 
 5237  * I have not tested 'cause I don't have NICs that supports cksum offload.
 5238  * (There might be problems. Typical phenomena would be
 5239  *   1. No route message for UDP packet.
 5240  *   2. No connection acceptance from external hosts regardless of rule set.)
 5241  */
 5242 int
 5243 pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,
 5244     sa_family_t af)
 5245 {
 5246         u_int16_t sum = 0;
 5247         int hw_assist = 0;
 5248         struct ip *ip;
 5249 
 5250         if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
 5251                 return (1);
 5252         if (m->m_pkthdr.len < off + len)
 5253                 return (1);
 5254 
 5255         switch (p) {
 5256         case IPPROTO_TCP:
 5257         case IPPROTO_UDP:
 5258                 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
 5259                         if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) {
 5260                                 sum = m->m_pkthdr.csum_data;
 5261                         } else {
 5262                                 ip = mtod(m, struct ip *);      
 5263                                 sum = in_pseudo(ip->ip_src.s_addr,
 5264                                         ip->ip_dst.s_addr, htonl((u_short)len +
 5265                                         m->m_pkthdr.csum_data + p));
 5266                         }
 5267                         sum ^= 0xffff;
 5268                         ++hw_assist;
 5269                 }
 5270                 break;
 5271         case IPPROTO_ICMP:
 5272 #ifdef INET6
 5273         case IPPROTO_ICMPV6:
 5274 #endif /* INET6 */
 5275                 break;
 5276         default:
 5277                 return (1);
 5278         }
 5279 
 5280         if (!hw_assist) {
 5281                 switch (af) {
 5282                 case AF_INET:
 5283                         if (p == IPPROTO_ICMP) {
 5284                                 if (m->m_len < off)
 5285                                         return (1);
 5286                                 m->m_data += off;
 5287                                 m->m_len -= off;
 5288                                 sum = in_cksum(m, len);
 5289                                 m->m_data -= off;
 5290                                 m->m_len += off;
 5291                         } else {
 5292                                 if (m->m_len < sizeof(struct ip))
 5293                                         return (1);
 5294                                 sum = in_cksum_range(m, p, off, len);
 5295                                 if (sum == 0) {
 5296                                         m->m_pkthdr.csum_flags |=
 5297                                             (CSUM_DATA_VALID |
 5298                                              CSUM_PSEUDO_HDR);
 5299                                         m->m_pkthdr.csum_data = 0xffff;
 5300                                 }
 5301                         }
 5302                         break;
 5303 #ifdef INET6
 5304                 case AF_INET6:
 5305                         if (m->m_len < sizeof(struct ip6_hdr))
 5306                                 return (1);
 5307                         sum = in6_cksum(m, p, off, len);
 5308                         /*
 5309                          * XXX
 5310                          * IPv6 H/W cksum off-load not supported yet!
 5311                          *
 5312                          * if (sum == 0) {
 5313                          *      m->m_pkthdr.csum_flags |=
 5314                          *          (CSUM_DATA_VALID|CSUM_PSEUDO_HDR);
 5315                          *      m->m_pkthdr.csum_data = 0xffff;
 5316                          *}
 5317                          */
 5318                         break;
 5319 #endif /* INET6 */
 5320                 default:
 5321                         return (1);
 5322                 }
 5323         }
 5324         if (sum) {
 5325                 switch (p) {
 5326                 case IPPROTO_TCP:
 5327                         tcpstat.tcps_rcvbadsum++;
 5328                         break;
 5329                 case IPPROTO_UDP:
 5330                         udpstat.udps_badsum++;
 5331                         break;
 5332                 case IPPROTO_ICMP:
 5333                         icmpstat.icps_checksum++;
 5334                         break;
 5335 #ifdef INET6
 5336                 case IPPROTO_ICMPV6:
 5337                         icmp6stat.icp6s_checksum++;
 5338                         break;
 5339 #endif /* INET6 */
 5340                 }
 5341                 return (1);
 5342         }
 5343         return (0);
 5344 }
 5345 
 5346 #ifdef INET
 5347 int
 5348 pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
 5349 {
 5350         struct pfi_kif          *kif;
 5351         u_short                  action, reason = 0, log = 0;
 5352         struct mbuf             *m = *m0;
 5353         struct ip               *h = NULL;
 5354         struct pf_rule          *a = NULL, *r = &pf_default_rule, *tr, *nr;
 5355         struct pf_state         *s = NULL;
 5356         struct pf_ruleset       *ruleset = NULL;
 5357         struct pf_pdesc          pd;
 5358         int                      off, dirndx, pqid = 0;
 5359 
 5360         if (!pf_status.running || (m->m_pkthdr.fw_flags & PF_MBUF_GENERATED))
 5361                 return (PF_PASS);
 5362 
 5363         kif = pfi_index2kif[ifp->if_index];
 5364         if (kif == NULL)
 5365                 return (PF_DROP);
 5366 
 5367 #ifdef DIAGNOSTIC
 5368         if ((m->m_flags & M_PKTHDR) == 0)
 5369                 panic("non-M_PKTHDR is passed to pf_test");
 5370 #endif
 5371 
 5372         memset(&pd, 0, sizeof(pd));
 5373         if (m->m_pkthdr.len < (int)sizeof(*h)) {
 5374                 action = PF_DROP;
 5375                 REASON_SET(&reason, PFRES_SHORT);
 5376                 log = 1;
 5377                 goto done;
 5378         }
 5379 
 5380         /* We do IP header normalization and packet reassembly here */
 5381         if (pf_normalize_ip(m0, dir, kif, &reason) != PF_PASS) {
 5382                 action = PF_DROP;
 5383                 goto done;
 5384         }
 5385         m = *m0;
 5386         h = mtod(m, struct ip *);
 5387 
 5388         off = h->ip_hl << 2;
 5389         if (off < (int)sizeof(*h)) {
 5390                 action = PF_DROP;
 5391                 REASON_SET(&reason, PFRES_SHORT);
 5392                 log = 1;
 5393                 goto done;
 5394         }
 5395 
 5396         pd.src = (struct pf_addr *)&h->ip_src;
 5397         pd.dst = (struct pf_addr *)&h->ip_dst;
 5398         PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET);
 5399         pd.ip_sum = &h->ip_sum;
 5400         pd.proto = h->ip_p;
 5401         pd.af = AF_INET;
 5402         pd.tos = h->ip_tos;
 5403         pd.tot_len = h->ip_len;
 5404 
 5405         /* handle fragments that didn't get reassembled by normalization */
 5406         if (h->ip_off & (IP_MF | IP_OFFMASK)) {
 5407                 action = pf_test_fragment(&r, dir, kif, m, h,
 5408                     &pd, &a, &ruleset);
 5409                 goto done;
 5410         }
 5411 
 5412         switch (h->ip_p) {
 5413 
 5414         case IPPROTO_TCP: {
 5415                 struct tcphdr   th;
 5416 
 5417                 pd.hdr.tcp = &th;
 5418                 if (!pf_pull_hdr(m, off, &th, sizeof(th),
 5419                     &action, &reason, AF_INET)) {
 5420                         log = action != PF_PASS;
 5421                         goto done;
 5422                 }
 5423                 if (dir == PF_IN && pf_check_proto_cksum(m, off,
 5424                     h->ip_len - off, IPPROTO_TCP, AF_INET)) {
 5425                         action = PF_DROP;
 5426                         goto done;
 5427                 }
 5428                 pd.p_len = pd.tot_len - off - (th.th_off << 2);
 5429                 if ((th.th_flags & TH_ACK) && pd.p_len == 0)
 5430                         pqid = 1;
 5431                 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
 5432                 if (action == PF_DROP)
 5433                         goto done;
 5434                 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
 5435                     &reason);
 5436                 if (action == PF_PASS) {
 5437 #if NPFSYNC
 5438                         pfsync_update_state(s);
 5439 #endif
 5440                         r = s->rule.ptr;
 5441                         a = s->anchor.ptr;
 5442                         log = s->log;
 5443                 } else if (s == NULL)
 5444                         action = pf_test_tcp(&r, &s, dir, kif,
 5445                             m, off, h, &pd, &a, &ruleset);
 5446                 break;
 5447         }
 5448 
 5449         case IPPROTO_UDP: {
 5450                 struct udphdr   uh;
 5451 
 5452                 pd.hdr.udp = &uh;
 5453                 if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
 5454                     &action, &reason, AF_INET)) {
 5455                         log = action != PF_PASS;
 5456                         goto done;
 5457                 }
 5458                 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m,
 5459                     off, h->ip_len - off, IPPROTO_UDP, AF_INET)) {
 5460                         action = PF_DROP;
 5461                         goto done;
 5462                 }
 5463                 if (uh.uh_dport == 0 ||
 5464                     ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
 5465                     ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
 5466                         action = PF_DROP;
 5467                         goto done;
 5468                 }
 5469                 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
 5470                 if (action == PF_PASS) {
 5471 #if NPFSYNC
 5472                         pfsync_update_state(s);
 5473 #endif
 5474                         r = s->rule.ptr;
 5475                         a = s->anchor.ptr;
 5476                         log = s->log;
 5477                 } else if (s == NULL)
 5478                         action = pf_test_udp(&r, &s, dir, kif,
 5479                             m, off, h, &pd, &a, &ruleset);
 5480                 break;
 5481         }
 5482 
 5483         case IPPROTO_ICMP: {
 5484                 struct icmp     ih;
 5485 
 5486                 pd.hdr.icmp = &ih;
 5487                 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN,
 5488                     &action, &reason, AF_INET)) {
 5489                         log = action != PF_PASS;
 5490                         goto done;
 5491                 }
 5492                 if (dir == PF_IN && pf_check_proto_cksum(m, off,
 5493                     h->ip_len - off, IPPROTO_ICMP, AF_INET)) {
 5494                         action = PF_DROP;
 5495                         goto done;
 5496                 }
 5497                 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd);
 5498                 if (action == PF_PASS) {
 5499 #if NPFSYNC
 5500                         pfsync_update_state(s);
 5501 #endif
 5502                         r = s->rule.ptr;
 5503                         a = s->anchor.ptr;
 5504                         log = s->log;
 5505                 } else if (s == NULL)
 5506                         action = pf_test_icmp(&r, &s, dir, kif,
 5507                             m, off, h, &pd, &a, &ruleset);
 5508                 break;
 5509         }
 5510 
 5511         default:
 5512                 action = pf_test_state_other(&s, dir, kif, &pd);
 5513                 if (action == PF_PASS) {
 5514 #if NPFSYNC
 5515                         pfsync_update_state(s);
 5516 #endif
 5517                         r = s->rule.ptr;
 5518                         a = s->anchor.ptr;
 5519                         log = s->log;
 5520                 } else if (s == NULL)
 5521                         action = pf_test_other(&r, &s, dir, kif, m, off, h,
 5522                             &pd, &a, &ruleset);
 5523                 break;
 5524         }
 5525 
 5526 done:
 5527         if (action == PF_PASS && h->ip_hl > 5 &&
 5528             !((s && s->allow_opts) || r->allow_opts)) {
 5529                 action = PF_DROP;
 5530                 REASON_SET(&reason, PFRES_SHORT);
 5531                 log = 1;
 5532                 DPFPRINTF(PF_DEBUG_MISC,
 5533                     ("pf: dropping packet with ip options\n"));
 5534         }
 5535 
 5536 #ifdef ALTQ
 5537         if (action == PF_PASS && r->qid) {
 5538                 m->m_pkthdr.fw_flags |= ALTQ_MBUF_TAGGED;
 5539                 if (pd.tos == IPTOS_LOWDELAY)
 5540                         m->m_pkthdr.altq_qid = r->pqid;
 5541                 else
 5542                         m->m_pkthdr.altq_qid = r->qid;
 5543                 if (s) {
 5544                         KKASSERT(s->hash != 0);
 5545                         m->m_pkthdr.fw_flags |= ALTQ_MBUF_STATE_HASHED;
 5546                         m->m_pkthdr.altq_state_hash = s->hash;
 5547                 }
 5548                 m->m_pkthdr.ecn_af = AF_INET;
 5549                 m->m_pkthdr.header = h;
 5550         }
 5551 #endif
 5552 
 5553         /*
 5554          * connections redirected to loopback should not match sockets
 5555          * bound specifically to loopback due to security implications,
 5556          * see tcp_input() and in_pcblookup_listen().
 5557          */
 5558         if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
 5559             pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
 5560             (s->nat_rule.ptr->action == PF_RDR ||
 5561             s->nat_rule.ptr->action == PF_BINAT) &&
 5562             (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
 5563                 action = PF_DROP;
 5564                 REASON_SET(&reason, PFRES_MEMORY);
 5565         }
 5566 
 5567         m->m_pkthdr.fw_flags |= PF_MBUF_TRANSLATE_LOCALHOST;
 5568 
 5569         if (log)
 5570                 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, a, ruleset);
 5571 
 5572         kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
 5573         kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++;
 5574 
 5575         if (action == PF_PASS || r->action == PF_DROP) {
 5576                 r->packets++;
 5577                 r->bytes += pd.tot_len;
 5578                 if (a != NULL) {
 5579                         a->packets++;
 5580                         a->bytes += pd.tot_len;
 5581                 }
 5582                 if (s != NULL) {
 5583                         dirndx = (dir == s->direction) ? 0 : 1;
 5584                         s->packets[dirndx]++;
 5585                         s->bytes[dirndx] += pd.tot_len;
 5586                         if (s->nat_rule.ptr != NULL) {
 5587                                 s->nat_rule.ptr->packets++;
 5588                                 s->nat_rule.ptr->bytes += pd.tot_len;
 5589                         }
 5590                         if (s->src_node != NULL) {
 5591                                 s->src_node->packets++;
 5592                                 s->src_node->bytes += pd.tot_len;
 5593                         }
 5594                         if (s->nat_src_node != NULL) {
 5595                                 s->nat_src_node->packets++;
 5596                                 s->nat_src_node->bytes += pd.tot_len;
 5597                         }
 5598                 }
 5599                 tr = r;
 5600                 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
 5601                 if (nr != NULL) {
 5602                         struct pf_addr *x;
 5603                         /*
 5604                          * XXX: we need to make sure that the addresses
 5605                          * passed to pfr_update_stats() are the same than
 5606                          * the addresses used during matching (pfr_match)
 5607                          */
 5608                         if (r == &pf_default_rule) {
 5609                                 tr = nr;
 5610                                 x = (s == NULL || s->direction == dir) ?
 5611                                     &pd.baddr : &pd.naddr;
 5612                         } else
 5613                                 x = (s == NULL || s->direction == dir) ?
 5614                                     &pd.naddr : &pd.baddr;
 5615                         if (x == &pd.baddr || s == NULL) {
 5616                                 /* we need to change the address */
 5617                                 if (dir == PF_OUT)
 5618                                         pd.src = x;
 5619                                 else
 5620                                         pd.dst = x;
 5621                         }
 5622                 }
 5623                 if (tr->src.addr.type == PF_ADDR_TABLE)
 5624                         pfr_update_stats(tr->src.addr.p.tbl, (s == NULL ||
 5625                             s->direction == dir) ? pd.src : pd.dst, pd.af,
 5626                             pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
 5627                             tr->src.not);
 5628                 if (tr->dst.addr.type == PF_ADDR_TABLE)
 5629                         pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL ||
 5630                             s->direction == dir) ? pd.dst : pd.src, pd.af,
 5631                             pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
 5632                             tr->dst.not);
 5633         }
 5634 
 5635 
 5636         if (action == PF_SYNPROXY_DROP) {
 5637                 m_freem(*m0);
 5638                 *m0 = NULL;
 5639                 action = PF_PASS;
 5640         } else if (r->rt)
 5641                 /* pf_route can free the mbuf causing *m0 to become NULL */
 5642                 pf_route(m0, r, dir, ifp, s);
 5643 
 5644         return (action);
 5645 }
 5646 #endif /* INET */
 5647 
 5648 #ifdef INET6
 5649 int
 5650 pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
 5651 {
 5652         struct pfi_kif          *kif;
 5653         u_short                  action, reason = 0, log = 0;
 5654         struct mbuf             *m = *m0;
 5655         struct ip6_hdr          *h = NULL;
 5656         struct pf_rule          *a = NULL, *r = &pf_default_rule, *tr, *nr;
 5657         struct pf_state         *s = NULL;
 5658         struct pf_ruleset       *ruleset = NULL;
 5659         struct pf_pdesc          pd;
 5660         int                      off, terminal = 0, dirndx;
 5661 
 5662         if (!pf_status.running || (m->m_pkthdr.fw_flags & PF_MBUF_GENERATED))
 5663                 return (PF_PASS);
 5664 
 5665         kif = pfi_index2kif[ifp->if_index];
 5666         if (kif == NULL)
 5667                 return (PF_DROP);
 5668 
 5669 #ifdef DIAGNOSTIC
 5670         if ((m->m_flags & M_PKTHDR) == 0)
 5671                 panic("non-M_PKTHDR is passed to pf_test");
 5672 #endif
 5673 
 5674         memset(&pd, 0, sizeof(pd));
 5675         if (m->m_pkthdr.len < (int)sizeof(*h)) {
 5676                 action = PF_DROP;
 5677                 REASON_SET(&reason, PFRES_SHORT);
 5678                 log = 1;
 5679                 goto done;
 5680         }
 5681 
 5682         /* We do IP header normalization and packet reassembly here */
 5683         if (pf_normalize_ip6(m0, dir, kif, &reason) != PF_PASS) {
 5684                 action = PF_DROP;
 5685                 goto done;
 5686         }
 5687         m = *m0;
 5688         h = mtod(m, struct ip6_hdr *);
 5689 
 5690         pd.src = (struct pf_addr *)&h->ip6_src;
 5691         pd.dst = (struct pf_addr *)&h->ip6_dst;
 5692         PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET6);
 5693         pd.ip_sum = NULL;
 5694         pd.af = AF_INET6;
 5695         pd.tos = 0;
 5696         pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
 5697 
 5698         off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr);
 5699         pd.proto = h->ip6_nxt;
 5700         do {
 5701                 switch (pd.proto) {
 5702                 case IPPROTO_FRAGMENT:
 5703                         action = pf_test_fragment(&r, dir, kif, m, h,
 5704                             &pd, &a, &ruleset);
 5705                         if (action == PF_DROP)
 5706                                 REASON_SET(&reason, PFRES_FRAG);
 5707                         goto done;
 5708                 case IPPROTO_AH:
 5709                 case IPPROTO_HOPOPTS:
 5710                 case IPPROTO_ROUTING:
 5711                 case IPPROTO_DSTOPTS: {
 5712                         /* get next header and header length */
 5713                         struct ip6_ext  opt6;
 5714 
 5715                         if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6),
 5716                             NULL, NULL, pd.af)) {
 5717                                 DPFPRINTF(PF_DEBUG_MISC,
 5718                                     ("pf: IPv6 short opt\n"));
 5719                                 action = PF_DROP;
 5720                                 REASON_SET(&reason, PFRES_SHORT);
 5721                                 log = 1;
 5722                                 goto done;
 5723                         }
 5724                         if (pd.proto == IPPROTO_AH)
 5725                                 off += (opt6.ip6e_len + 2) * 4;
 5726                         else
 5727                                 off += (opt6.ip6e_len + 1) * 8;
 5728                         pd.proto = opt6.ip6e_nxt;
 5729                         /* goto the next header */
 5730                         break;
 5731                 }
 5732                 default:
 5733                         terminal++;
 5734                         break;
 5735                 }
 5736         } while (!terminal);
 5737 
 5738         switch (pd.proto) {
 5739 
 5740         case IPPROTO_TCP: {
 5741                 struct tcphdr   th;
 5742 
 5743                 pd.hdr.tcp = &th;
 5744                 if (!pf_pull_hdr(m, off, &th, sizeof(th),
 5745                     &action, &reason, AF_INET6)) {
 5746                         log = action != PF_PASS;
 5747                         goto done;
 5748                 }
 5749                 if (dir == PF_IN && pf_check_proto_cksum(m, off,
 5750                     ntohs(h->ip6_plen), IPPROTO_TCP, AF_INET6)) {
 5751                         action = PF_DROP;
 5752                         goto done;
 5753                 }
 5754                 pd.p_len = pd.tot_len - off - (th.th_off << 2);
 5755                 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
 5756                 if (action == PF_DROP)
 5757                         goto done;
 5758                 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
 5759                     &reason);
 5760                 if (action == PF_PASS) {
 5761 #if NPFSYNC
 5762                         pfsync_update_state(s);
 5763 #endif
 5764                         r = s->rule.ptr;
 5765                         a = s->anchor.ptr;
 5766                         log = s->log;
 5767                 } else if (s == NULL)
 5768                         action = pf_test_tcp(&r, &s, dir, kif,
 5769                             m, off, h, &pd, &a, &ruleset);
 5770                 break;
 5771         }
 5772 
 5773         case IPPROTO_UDP: {
 5774                 struct udphdr   uh;
 5775 
 5776                 pd.hdr.udp = &uh;
 5777                 if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
 5778                     &action, &reason, AF_INET6)) {
 5779                         log = action != PF_PASS;
 5780                         goto done;
 5781                 }
 5782                 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m,
 5783                     off, ntohs(h->ip6_plen), IPPROTO_UDP, AF_INET6)) {
 5784                         action = PF_DROP;
 5785                         goto done;
 5786                 }
 5787                 if (uh.uh_dport == 0 ||
 5788                     ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
 5789                     ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
 5790                         action = PF_DROP;
 5791                         goto done;
 5792                 }
 5793                 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
 5794                 if (action == PF_PASS) {
 5795 #if NPFSYNC
 5796                         pfsync_update_state(s);
 5797 #endif
 5798                         r = s->rule.ptr;
 5799                         a = s->anchor.ptr;
 5800                         log = s->log;
 5801                 } else if (s == NULL)
 5802                         action = pf_test_udp(&r, &s, dir, kif,
 5803                             m, off, h, &pd, &a, &ruleset);
 5804                 break;
 5805         }
 5806 
 5807         case IPPROTO_ICMPV6: {
 5808                 struct icmp6_hdr        ih;
 5809 
 5810                 pd.hdr.icmp6 = &ih;
 5811                 if (!pf_pull_hdr(m, off, &ih, sizeof(ih),
 5812                     &action, &reason, AF_INET6)) {
 5813                         log = action != PF_PASS;
 5814                         goto done;
 5815                 }
 5816                 if (dir == PF_IN && pf_check_proto_cksum(m, off,
 5817                     ntohs(h->ip6_plen), IPPROTO_ICMPV6, AF_INET6)) {
 5818                         action = PF_DROP;
 5819                         goto done;
 5820                 }
 5821                 action = pf_test_state_icmp(&s, dir, kif,
 5822                     m, off, h, &pd);
 5823                 if (action == PF_PASS) {
 5824 #if NPFSYNC
 5825                         pfsync_update_state(s);
 5826 #endif
 5827                         r = s->rule.ptr;
 5828                         a = s->anchor.ptr;
 5829                         log = s->log;
 5830                 } else if (s == NULL)
 5831                         action = pf_test_icmp(&r, &s, dir, kif,
 5832                             m, off, h, &pd, &a, &ruleset);
 5833                 break;
 5834         }
 5835 
 5836         default:
 5837                 action = pf_test_state_other(&s, dir, kif, &pd);
 5838                 if (action == PF_PASS) {
 5839                         r = s->rule.ptr;
 5840                         a = s->anchor.ptr;
 5841                         log = s->log;
 5842                 } else if (s == NULL)
 5843                         action = pf_test_other(&r, &s, dir, kif, m, off, h,
 5844                             &pd, &a, &ruleset);
 5845                 break;
 5846         }
 5847 
 5848 done:
 5849         /* XXX handle IPv6 options, if not allowed. not implemented. */
 5850 
 5851 #ifdef ALTQ
 5852         if (action == PF_PASS && r->qid) {
 5853                 m->m_pkthdr.fw_flags |= ALTQ_MBUF_TAGGED;
 5854                 if (pd.tos == IPTOS_LOWDELAY)
 5855                         m->m_pkthdr.altq_qid = r->pqid;
 5856                 else
 5857                         m->m_pkthdr.altq_qid = r->qid;
 5858                 if (s) {
 5859                         KKASSERT(s->hash != 0);
 5860                         m->m_pkthdr.fw_flags |= ALTQ_MBUF_STATE_HASHED;
 5861                         m->m_pkthdr.altq_state_hash = s->hash;
 5862                 }
 5863                 m->m_pkthdr.ecn_af = AF_INET6;
 5864                 m->m_pkthdr.header = h;
 5865         }
 5866 #endif
 5867 
 5868         if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
 5869             pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
 5870             (s->nat_rule.ptr->action == PF_RDR ||
 5871             s->nat_rule.ptr->action == PF_BINAT) &&
 5872             IN6_IS_ADDR_LOOPBACK(&pd.dst->v6)) {
 5873                 action = PF_DROP;
 5874                 REASON_SET(&reason, PFRES_MEMORY);
 5875         }
 5876 
 5877         m->m_pkthdr.fw_flags |= PF_MBUF_TRANSLATE_LOCALHOST;
 5878 
 5879         if (log)
 5880                 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, r, a, ruleset);
 5881 
 5882         kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
 5883         kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++;
 5884 
 5885         if (action == PF_PASS || r->action == PF_DROP) {
 5886                 r->packets++;
 5887                 r->bytes += pd.tot_len;
 5888                 if (a != NULL) {
 5889                         a->packets++;
 5890                         a->bytes += pd.tot_len;
 5891                 }
 5892                 if (s != NULL) {
 5893                         dirndx = (dir == s->direction) ? 0 : 1;
 5894                         s->packets[dirndx]++;
 5895                         s->bytes[dirndx] += pd.tot_len;
 5896                         if (s->nat_rule.ptr != NULL) {
 5897                                 s->nat_rule.ptr->packets++;
 5898                                 s->nat_rule.ptr->bytes += pd.tot_len;
 5899                         }
 5900                         if (s->src_node != NULL) {
 5901                                 s->src_node->packets++;
 5902                                 s->src_node->bytes += pd.tot_len;
 5903                         }
 5904                         if (s->nat_src_node != NULL) {
 5905                                 s->nat_src_node->packets++;
 5906                                 s->nat_src_node->bytes += pd.tot_len;
 5907                         }
 5908                 }
 5909                 tr = r;
 5910                 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
 5911                 if (nr != NULL) {
 5912                         struct pf_addr *x;
 5913                         /*
 5914                          * XXX: we need to make sure that the addresses
 5915                          * passed to pfr_update_stats() are the same than
 5916                          * the addresses used during matching (pfr_match)
 5917                          */
 5918                         if (r == &pf_default_rule) {
 5919                                 tr = nr;
 5920                                 x = (s == NULL || s->direction == dir) ?
 5921                                     &pd.baddr : &pd.naddr;
 5922                         } else {
 5923                                 x = (s == NULL || s->direction == dir) ?
 5924                                     &pd.naddr : &pd.baddr;
 5925                         }
 5926                         if (x == &pd.baddr || s == NULL) {
 5927                                 if (dir == PF_OUT)
 5928                                         pd.src = x;
 5929                                 else
 5930                                         pd.dst = x;
 5931                         }
 5932                 }
 5933                 if (tr->src.addr.type == PF_ADDR_TABLE)
 5934                         pfr_update_stats(tr->src.addr.p.tbl, (s == NULL ||
 5935                             s->direction == dir) ? pd.src : pd.dst, pd.af,
 5936                             pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
 5937                             tr->src.not);
 5938                 if (tr->dst.addr.type == PF_ADDR_TABLE)
 5939                         pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL ||
 5940                             s->direction == dir) ? pd.dst : pd.src, pd.af,
 5941                             pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
 5942                             tr->dst.not);
 5943         }
 5944 
 5945 
 5946         if (action == PF_SYNPROXY_DROP) {
 5947                 m_freem(*m0);
 5948                 *m0 = NULL;
 5949                 action = PF_PASS;
 5950         } else if (r->rt)
 5951                 /* pf_route6 can free the mbuf causing *m0 to become NULL */
 5952                 pf_route6(m0, r, dir, ifp, s);
 5953 
 5954         return (action);
 5955 }
 5956 #endif /* INET6 */

Cache object: eb129ba4f4ccd5127d30c76c1b487901


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.