LCOV - code coverage report
Current view: top level - net - pf.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 4121 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 158 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: pf.c,v 1.1075 2018/09/13 19:53:58 bluhm Exp $ */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2001 Daniel Hartmeier
       5             :  * Copyright (c) 2002 - 2013 Henning Brauer <henning@openbsd.org>
       6             :  * All rights reserved.
       7             :  *
       8             :  * Redistribution and use in source and binary forms, with or without
       9             :  * modification, are permitted provided that the following conditions
      10             :  * are met:
      11             :  *
      12             :  *    - Redistributions of source code must retain the above copyright
      13             :  *      notice, this list of conditions and the following disclaimer.
      14             :  *    - Redistributions in binary form must reproduce the above
      15             :  *      copyright notice, this list of conditions and the following
      16             :  *      disclaimer in the documentation and/or other materials provided
      17             :  *      with the distribution.
      18             :  *
      19             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      20             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      21             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
      22             :  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
      23             :  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
      24             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
      25             :  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      26             :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
      27             :  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      28             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
      29             :  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      30             :  * POSSIBILITY OF SUCH DAMAGE.
      31             :  *
      32             :  * Effort sponsored in part by the Defense Advanced Research Projects
      33             :  * Agency (DARPA) and Air Force Research Laboratory, Air Force
      34             :  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
      35             :  *
      36             :  */
      37             : 
      38             : #include "bpfilter.h"
      39             : #include "carp.h"
      40             : #include "pflog.h"
      41             : #include "pfsync.h"
      42             : #include "pflow.h"
      43             : 
      44             : #include <sys/param.h>
      45             : #include <sys/systm.h>
      46             : #include <sys/mbuf.h>
      47             : #include <sys/filio.h>
      48             : #include <sys/socket.h>
      49             : #include <sys/socketvar.h>
      50             : #include <sys/kernel.h>
      51             : #include <sys/time.h>
      52             : #include <sys/pool.h>
      53             : #include <sys/proc.h>
      54             : #include <sys/rwlock.h>
      55             : #include <sys/syslog.h>
      56             : 
      57             : #include <crypto/sha2.h>
      58             : 
      59             : #include <net/if.h>
      60             : #include <net/if_var.h>
      61             : #include <net/if_types.h>
      62             : #include <net/route.h>
      63             : 
      64             : #include <netinet/in.h>
      65             : #include <netinet/in_var.h>
      66             : #include <netinet/ip.h>
      67             : #include <netinet/in_pcb.h>
      68             : #include <netinet/ip_var.h>
      69             : #include <netinet/ip_icmp.h>
      70             : #include <netinet/icmp_var.h>
      71             : #include <netinet/tcp.h>
      72             : #include <netinet/tcp_seq.h>
      73             : #include <netinet/tcp_timer.h>
      74             : #include <netinet/tcp_var.h>
      75             : #include <netinet/tcp_fsm.h>
      76             : #include <netinet/udp.h>
      77             : #include <netinet/udp_var.h>
      78             : #include <netinet/ip_divert.h>
      79             : 
      80             : #ifdef INET6
      81             : #include <netinet6/in6_var.h>
      82             : #include <netinet/ip6.h>
      83             : #include <netinet6/ip6_var.h>
      84             : #include <netinet/icmp6.h>
      85             : #include <netinet6/nd6.h>
      86             : #include <netinet6/ip6_divert.h>
      87             : #endif /* INET6 */
      88             : 
      89             : #include <net/pfvar.h>
      90             : #include <net/pfvar_priv.h>
      91             : 
      92             : #if NPFLOG > 0
      93             : #include <net/if_pflog.h>
      94             : #endif  /* NPFLOG > 0 */
      95             : 
      96             : #if NPFLOW > 0
      97             : #include <net/if_pflow.h>
      98             : #endif  /* NPFLOW > 0 */
      99             : 
     100             : #if NPFSYNC > 0
     101             : #include <net/if_pfsync.h>
     102             : #endif /* NPFSYNC > 0 */
     103             : 
     104             : #ifdef DDB
     105             : #include <machine/db_machdep.h>
     106             : #include <ddb/db_interface.h>
     107             : #endif
     108             : 
     109             : /*
     110             :  * Global variables
     111             :  */
     112             : struct pf_state_tree     pf_statetbl;
     113             : struct pf_queuehead      pf_queues[2];
     114             : struct pf_queuehead     *pf_queues_active;
     115             : struct pf_queuehead     *pf_queues_inactive;
     116             : 
     117             : struct pf_status         pf_status;
     118             : 
     119             : int                      pf_hdr_limit = 20;  /* arbitrary limit, tune in ddb */
     120             : 
     121             : SHA2_CTX                 pf_tcp_secret_ctx;
     122             : u_char                   pf_tcp_secret[16];
     123             : int                      pf_tcp_secret_init;
     124             : int                      pf_tcp_iss_off;
     125             : 
     126             : int              pf_npurge;
     127             : struct task      pf_purge_task = TASK_INITIALIZER(pf_purge, &pf_npurge);
     128             : struct timeout   pf_purge_to = TIMEOUT_INITIALIZER(pf_purge_timeout, NULL);
     129             : 
     130             : enum pf_test_status {
     131             :         PF_TEST_FAIL = -1,
     132             :         PF_TEST_OK,
     133             :         PF_TEST_QUICK
     134             : };
     135             : 
     136             : struct pf_test_ctx {
     137             :         enum pf_test_status       test_status;
     138             :         struct pf_pdesc          *pd;
     139             :         struct pf_rule_actions    act;
     140             :         u_int8_t                  icmpcode;
     141             :         u_int8_t                  icmptype;
     142             :         int                       icmp_dir;
     143             :         int                       state_icmp;
     144             :         int                       tag;
     145             :         u_short                   reason;
     146             :         struct pf_rule_item      *ri;
     147             :         struct pf_src_node       *sns[PF_SN_MAX];
     148             :         struct pf_rule_slist      rules;
     149             :         struct pf_rule           *nr;
     150             :         struct pf_rule          **rm;
     151             :         struct pf_rule           *a;
     152             :         struct pf_rule          **am;
     153             :         struct pf_ruleset       **rsm;
     154             :         struct pf_ruleset        *arsm;
     155             :         struct pf_ruleset        *aruleset;
     156             :         struct tcphdr            *th;
     157             :         int                       depth;
     158             : };
     159             : 
     160             : #define PF_ANCHOR_STACK_MAX     64
     161             : 
     162             : struct pool              pf_src_tree_pl, pf_rule_pl, pf_queue_pl;
     163             : struct pool              pf_state_pl, pf_state_key_pl, pf_state_item_pl;
     164             : struct pool              pf_rule_item_pl, pf_sn_item_pl, pf_pktdelay_pl;
     165             : 
     166             : void                     pf_add_threshold(struct pf_threshold *);
     167             : int                      pf_check_threshold(struct pf_threshold *);
     168             : int                      pf_check_tcp_cksum(struct mbuf *, int, int,
     169             :                             sa_family_t);
     170             : static __inline void     pf_cksum_fixup(u_int16_t *, u_int16_t, u_int16_t,
     171             :                             u_int8_t);
     172             : void                     pf_cksum_fixup_a(u_int16_t *, const struct pf_addr *,
     173             :                             const struct pf_addr *, sa_family_t, u_int8_t);
     174             : int                      pf_modulate_sack(struct pf_pdesc *,
     175             :                             struct pf_state_peer *);
     176             : int                      pf_icmp_mapping(struct pf_pdesc *, u_int8_t, int *,
     177             :                             u_int16_t *, u_int16_t *);
     178             : int                      pf_change_icmp_af(struct mbuf *, int,
     179             :                             struct pf_pdesc *, struct pf_pdesc *,
     180             :                             struct pf_addr *, struct pf_addr *, sa_family_t,
     181             :                             sa_family_t);
     182             : int                      pf_translate_a(struct pf_pdesc *, struct pf_addr *,
     183             :                             struct pf_addr *);
     184             : void                     pf_translate_icmp(struct pf_pdesc *, struct pf_addr *,
     185             :                             u_int16_t *, struct pf_addr *, struct pf_addr *,
     186             :                             u_int16_t);
     187             : int                      pf_translate_icmp_af(struct pf_pdesc*, int, void *);
     188             : void                     pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t, int,
     189             :                             sa_family_t, struct pf_rule *, u_int);
     190             : void                     pf_detach_state(struct pf_state *);
     191             : void                     pf_state_key_detach(struct pf_state *, int);
     192             : u_int32_t                pf_tcp_iss(struct pf_pdesc *);
     193             : void                     pf_rule_to_actions(struct pf_rule *,
     194             :                             struct pf_rule_actions *);
     195             : int                      pf_test_rule(struct pf_pdesc *, struct pf_rule **,
     196             :                             struct pf_state **, struct pf_rule **,
     197             :                             struct pf_ruleset **, u_short *);
     198             : static __inline int      pf_create_state(struct pf_pdesc *, struct pf_rule *,
     199             :                             struct pf_rule *, struct pf_rule *,
     200             :                             struct pf_state_key **, struct pf_state_key **,
     201             :                             int *, struct pf_state **, int,
     202             :                             struct pf_rule_slist *, struct pf_rule_actions *,
     203             :                             struct pf_src_node *[]);
     204             : static __inline int      pf_state_key_addr_setup(struct pf_pdesc *, void *,
     205             :                             int, struct pf_addr *, int, struct pf_addr *,
     206             :                             int, int);
     207             : int                      pf_state_key_setup(struct pf_pdesc *, struct
     208             :                             pf_state_key **, struct pf_state_key **, int);
     209             : int                      pf_tcp_track_full(struct pf_pdesc *,
     210             :                             struct pf_state **, u_short *, int *, int);
     211             : int                      pf_tcp_track_sloppy(struct pf_pdesc *,
     212             :                             struct pf_state **, u_short *);
     213             : static __inline int      pf_synproxy(struct pf_pdesc *, struct pf_state **,
     214             :                             u_short *);
     215             : int                      pf_test_state(struct pf_pdesc *, struct pf_state **,
     216             :                             u_short *, int);
     217             : int                      pf_icmp_state_lookup(struct pf_pdesc *,
     218             :                             struct pf_state_key_cmp *, struct pf_state **,
     219             :                             u_int16_t, u_int16_t, int, int *, int, int);
     220             : int                      pf_test_state_icmp(struct pf_pdesc *,
     221             :                             struct pf_state **, u_short *);
     222             : u_int16_t                pf_calc_mss(struct pf_addr *, sa_family_t, int,
     223             :                             u_int16_t);
     224             : static __inline int      pf_set_rt_ifp(struct pf_state *, struct pf_addr *,
     225             :                             sa_family_t);
     226             : struct pf_divert        *pf_get_divert(struct mbuf *);
     227             : int                      pf_walk_header(struct pf_pdesc *, struct ip *,
     228             :                             u_short *);
     229             : int                      pf_walk_option6(struct pf_pdesc *, struct ip6_hdr *,
     230             :                             int, int, u_short *);
     231             : int                      pf_walk_header6(struct pf_pdesc *, struct ip6_hdr *,
     232             :                             u_short *);
     233             : void                     pf_print_state_parts(struct pf_state *,
     234             :                             struct pf_state_key *, struct pf_state_key *);
     235             : int                      pf_addr_wrap_neq(struct pf_addr_wrap *,
     236             :                             struct pf_addr_wrap *);
     237             : int                      pf_compare_state_keys(struct pf_state_key *,
     238             :                             struct pf_state_key *, struct pfi_kif *, u_int);
     239             : int                      pf_find_state(struct pf_pdesc *,
     240             :                             struct pf_state_key_cmp *, struct pf_state **);
     241             : int                      pf_src_connlimit(struct pf_state **);
     242             : int                      pf_match_rcvif(struct mbuf *, struct pf_rule *);
     243             : int                      pf_step_into_anchor(struct pf_test_ctx *,
     244             :                             struct pf_rule *);
     245             : int                      pf_match_rule(struct pf_test_ctx *,
     246             :                             struct pf_ruleset *);
     247             : void                     pf_counters_inc(int, struct pf_pdesc *,
     248             :                             struct pf_state *, struct pf_rule *,
     249             :                             struct pf_rule *);
     250             : 
     251             : int                      pf_state_key_isvalid(struct pf_state_key *);
     252             : struct pf_state_key     *pf_state_key_ref(struct pf_state_key *);
     253             : void                     pf_state_key_unref(struct pf_state_key *);
     254             : void                     pf_state_key_link_reverse(struct pf_state_key *,
     255             :                             struct pf_state_key *);
     256             : void                     pf_state_key_unlink_reverse(struct pf_state_key *);
     257             : void                     pf_state_key_link_inpcb(struct pf_state_key *,
     258             :                             struct inpcb *);
     259             : void                     pf_state_key_unlink_inpcb(struct pf_state_key *);
     260             : void                     pf_inpcb_unlink_state_key(struct inpcb *);
     261             : void                     pf_pktenqueue_delayed(void *);
     262             : 
     263             : #if NPFLOG > 0
     264             : void                     pf_log_matches(struct pf_pdesc *, struct pf_rule *,
     265             :                             struct pf_rule *, struct pf_ruleset *,
     266             :                             struct pf_rule_slist *);
     267             : #endif  /* NPFLOG > 0 */
     268             : 
     269             : extern struct pool pfr_ktable_pl;
     270             : extern struct pool pfr_kentry_pl;
     271             : 
     272             : struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
     273             :         { &pf_state_pl, PFSTATE_HIWAT, PFSTATE_HIWAT },
     274             :         { &pf_src_tree_pl, PFSNODE_HIWAT, PFSNODE_HIWAT },
     275             :         { &pf_frent_pl, PFFRAG_FRENT_HIWAT, PFFRAG_FRENT_HIWAT },
     276             :         { &pfr_ktable_pl, PFR_KTABLE_HIWAT, PFR_KTABLE_HIWAT },
     277             :         { &pfr_kentry_pl, PFR_KENTRY_HIWAT, PFR_KENTRY_HIWAT },
     278             :         { &pf_pktdelay_pl, PF_PKTDELAY_MAXPKTS, PF_PKTDELAY_MAXPKTS }
     279             : };
     280             : 
     281             : #define BOUND_IFACE(r, k) \
     282             :         ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all
     283             : 
     284             : #define STATE_INC_COUNTERS(s)                                   \
     285             :         do {                                                    \
     286             :                 struct pf_rule_item *mrm;                       \
     287             :                 s->rule.ptr->states_cur++;                        \
     288             :                 s->rule.ptr->states_tot++;                        \
     289             :                 if (s->anchor.ptr != NULL) {                 \
     290             :                         s->anchor.ptr->states_cur++;              \
     291             :                         s->anchor.ptr->states_tot++;              \
     292             :                 }                                               \
     293             :                 SLIST_FOREACH(mrm, &s->match_rules, entry)       \
     294             :                         mrm->r->states_cur++;                     \
     295             :         } while (0)
     296             : 
     297             : static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
     298             : static __inline int pf_state_compare_key(struct pf_state_key *,
     299             :         struct pf_state_key *);
     300             : static __inline int pf_state_compare_id(struct pf_state *,
     301             :         struct pf_state *);
     302             : #ifdef INET6
     303             : static __inline void pf_cksum_uncover(u_int16_t *, u_int16_t, u_int8_t);
     304             : static __inline void pf_cksum_cover(u_int16_t *, u_int16_t, u_int8_t);
     305             : #endif /* INET6 */
     306             : static __inline void pf_set_protostate(struct pf_state *, int, u_int8_t);
     307             : 
     308             : struct pf_src_tree tree_src_tracking;
     309             : 
     310             : struct pf_state_tree_id tree_id;
     311             : struct pf_state_queue state_list;
     312             : 
     313           0 : RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
     314           0 : RB_GENERATE(pf_state_tree, pf_state_key, entry, pf_state_compare_key);
     315           0 : RB_GENERATE(pf_state_tree_id, pf_state,
     316             :     entry_id, pf_state_compare_id);
     317             : 
     318             : SLIST_HEAD(pf_rule_gcl, pf_rule)        pf_rule_gcl =
     319             :         SLIST_HEAD_INITIALIZER(pf_rule_gcl);
     320             : 
     321             : __inline int
     322           0 : pf_addr_compare(struct pf_addr *a, struct pf_addr *b, sa_family_t af)
     323             : {
     324           0 :         switch (af) {
     325             :         case AF_INET:
     326           0 :                 if (a->addr32[0] > b->addr32[0])
     327           0 :                         return (1);
     328           0 :                 if (a->addr32[0] < b->addr32[0])
     329           0 :                         return (-1);
     330             :                 break;
     331             : #ifdef INET6
     332             :         case AF_INET6:
     333           0 :                 if (a->addr32[3] > b->addr32[3])
     334           0 :                         return (1);
     335           0 :                 if (a->addr32[3] < b->addr32[3])
     336           0 :                         return (-1);
     337           0 :                 if (a->addr32[2] > b->addr32[2])
     338           0 :                         return (1);
     339           0 :                 if (a->addr32[2] < b->addr32[2])
     340           0 :                         return (-1);
     341           0 :                 if (a->addr32[1] > b->addr32[1])
     342           0 :                         return (1);
     343           0 :                 if (a->addr32[1] < b->addr32[1])
     344           0 :                         return (-1);
     345           0 :                 if (a->addr32[0] > b->addr32[0])
     346           0 :                         return (1);
     347           0 :                 if (a->addr32[0] < b->addr32[0])
     348           0 :                         return (-1);
     349             :                 break;
     350             : #endif /* INET6 */
     351             :         }
     352           0 :         return (0);
     353           0 : }
     354             : 
     355             : static __inline int
     356           0 : pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
     357             : {
     358             :         int     diff;
     359             : 
     360           0 :         if (a->rule.ptr > b->rule.ptr)
     361           0 :                 return (1);
     362           0 :         if (a->rule.ptr < b->rule.ptr)
     363           0 :                 return (-1);
     364           0 :         if ((diff = a->type - b->type) != 0)
     365           0 :                 return (diff);
     366           0 :         if ((diff = a->af - b->af) != 0)
     367           0 :                 return (diff);
     368           0 :         if ((diff = pf_addr_compare(&a->addr, &b->addr, a->af)) != 0)
     369           0 :                 return (diff);
     370           0 :         return (0);
     371           0 : }
     372             : 
     373             : static __inline void
     374           0 : pf_set_protostate(struct pf_state *s, int which, u_int8_t newstate)
     375             : {
     376           0 :         if (which == PF_PEER_DST || which == PF_PEER_BOTH)
     377           0 :                 s->dst.state = newstate;
     378           0 :         if (which == PF_PEER_DST)
     379             :                 return;
     380             : 
     381           0 :         if (s->src.state == newstate)
     382             :                 return;
     383           0 :         if (s->creatorid == pf_status.hostid && s->key[PF_SK_STACK] != NULL &&
     384           0 :             s->key[PF_SK_STACK]->proto == IPPROTO_TCP &&
     385           0 :             !(TCPS_HAVEESTABLISHED(s->src.state) ||
     386           0 :             s->src.state == TCPS_CLOSED) &&
     387           0 :             (TCPS_HAVEESTABLISHED(newstate) || newstate == TCPS_CLOSED))
     388           0 :                 pf_status.states_halfopen--;
     389             : 
     390           0 :         s->src.state = newstate;
     391           0 : }
     392             : 
     393             : void
     394           0 : pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
     395             : {
     396           0 :         switch (af) {
     397             :         case AF_INET:
     398           0 :                 dst->addr32[0] = src->addr32[0];
     399           0 :                 break;
     400             : #ifdef INET6
     401             :         case AF_INET6:
     402           0 :                 dst->addr32[0] = src->addr32[0];
     403           0 :                 dst->addr32[1] = src->addr32[1];
     404           0 :                 dst->addr32[2] = src->addr32[2];
     405           0 :                 dst->addr32[3] = src->addr32[3];
     406           0 :                 break;
     407             : #endif /* INET6 */
     408             :         default:
     409           0 :                 unhandled_af(af);
     410             :         }
     411           0 : }
     412             : 
     413             : void
     414           0 : pf_init_threshold(struct pf_threshold *threshold,
     415             :     u_int32_t limit, u_int32_t seconds)
     416             : {
     417           0 :         threshold->limit = limit * PF_THRESHOLD_MULT;
     418           0 :         threshold->seconds = seconds;
     419           0 :         threshold->count = 0;
     420           0 :         threshold->last = time_uptime;
     421           0 : }
     422             : 
     423             : void
     424           0 : pf_add_threshold(struct pf_threshold *threshold)
     425             : {
     426           0 :         u_int32_t t = time_uptime, diff = t - threshold->last;
     427             : 
     428           0 :         if (diff >= threshold->seconds)
     429           0 :                 threshold->count = 0;
     430             :         else
     431           0 :                 threshold->count -= threshold->count * diff /
     432             :                     threshold->seconds;
     433           0 :         threshold->count += PF_THRESHOLD_MULT;
     434           0 :         threshold->last = t;
     435           0 : }
     436             : 
     437             : int
     438           0 : pf_check_threshold(struct pf_threshold *threshold)
     439             : {
     440           0 :         return (threshold->count > threshold->limit);
     441             : }
     442             : 
     443             : int
     444           0 : pf_src_connlimit(struct pf_state **state)
     445             : {
     446             :         int                      bad = 0;
     447             :         struct pf_src_node      *sn;
     448             : 
     449           0 :         if ((sn = pf_get_src_node((*state), PF_SN_NONE)) == NULL)
     450           0 :                 return (0);
     451             : 
     452           0 :         sn->conn++;
     453           0 :         (*state)->src.tcp_est = 1;
     454           0 :         pf_add_threshold(&sn->conn_rate);
     455             : 
     456           0 :         if ((*state)->rule.ptr->max_src_conn &&
     457           0 :             (*state)->rule.ptr->max_src_conn < sn->conn) {
     458           0 :                 pf_status.lcounters[LCNT_SRCCONN]++;
     459             :                 bad++;
     460           0 :         }
     461             : 
     462           0 :         if ((*state)->rule.ptr->max_src_conn_rate.limit &&
     463           0 :             pf_check_threshold(&sn->conn_rate)) {
     464           0 :                 pf_status.lcounters[LCNT_SRCCONNRATE]++;
     465           0 :                 bad++;
     466           0 :         }
     467             : 
     468           0 :         if (!bad)
     469           0 :                 return (0);
     470             : 
     471           0 :         if ((*state)->rule.ptr->overload_tbl) {
     472           0 :                 struct pfr_addr p;
     473             :                 u_int32_t       killed = 0;
     474             : 
     475           0 :                 pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
     476           0 :                 if (pf_status.debug >= LOG_NOTICE) {
     477           0 :                         log(LOG_NOTICE,
     478             :                             "pf: pf_src_connlimit: blocking address ");
     479           0 :                         pf_print_host(&sn->addr, 0,
     480           0 :                             (*state)->key[PF_SK_WIRE]->af);
     481           0 :                 }
     482             : 
     483           0 :                 memset(&p, 0, sizeof(p));
     484           0 :                 p.pfra_af = (*state)->key[PF_SK_WIRE]->af;
     485           0 :                 switch ((*state)->key[PF_SK_WIRE]->af) {
     486             :                 case AF_INET:
     487           0 :                         p.pfra_net = 32;
     488           0 :                         p.pfra_ip4addr = sn->addr.v4;
     489           0 :                         break;
     490             : #ifdef INET6
     491             :                 case AF_INET6:
     492           0 :                         p.pfra_net = 128;
     493           0 :                         p.pfra_ip6addr = sn->addr.v6;
     494           0 :                         break;
     495             : #endif /* INET6 */
     496             :                 }
     497             : 
     498           0 :                 pfr_insert_kentry((*state)->rule.ptr->overload_tbl,
     499           0 :                     &p, time_second);
     500             : 
     501             :                 /* kill existing states if that's required. */
     502           0 :                 if ((*state)->rule.ptr->flush) {
     503             :                         struct pf_state_key *sk;
     504             :                         struct pf_state *st;
     505             : 
     506           0 :                         pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
     507           0 :                         RB_FOREACH(st, pf_state_tree_id, &tree_id) {
     508           0 :                                 sk = st->key[PF_SK_WIRE];
     509             :                                 /*
     510             :                                  * Kill states from this source.  (Only those
     511             :                                  * from the same rule if PF_FLUSH_GLOBAL is not
     512             :                                  * set)
     513             :                                  */
     514           0 :                                 if (sk->af ==
     515           0 :                                     (*state)->key[PF_SK_WIRE]->af &&
     516           0 :                                     (((*state)->direction == PF_OUT &&
     517           0 :                                     PF_AEQ(&sn->addr, &sk->addr[1], sk->af)) ||
     518           0 :                                     ((*state)->direction == PF_IN &&
     519           0 :                                     PF_AEQ(&sn->addr, &sk->addr[0], sk->af))) &&
     520           0 :                                     ((*state)->rule.ptr->flush &
     521           0 :                                     PF_FLUSH_GLOBAL ||
     522           0 :                                     (*state)->rule.ptr == st->rule.ptr)) {
     523           0 :                                         st->timeout = PFTM_PURGE;
     524           0 :                                         pf_set_protostate(st, PF_PEER_BOTH,
     525             :                                             TCPS_CLOSED);
     526           0 :                                         killed++;
     527           0 :                                 }
     528             :                         }
     529           0 :                         if (pf_status.debug >= LOG_NOTICE)
     530           0 :                                 addlog(", %u states killed", killed);
     531           0 :                 }
     532           0 :                 if (pf_status.debug >= LOG_NOTICE)
     533           0 :                         addlog("\n");
     534           0 :         }
     535             : 
     536             :         /* kill this state */
     537           0 :         (*state)->timeout = PFTM_PURGE;
     538           0 :         pf_set_protostate(*state, PF_PEER_BOTH, TCPS_CLOSED);
     539           0 :         return (1);
     540           0 : }
     541             : 
     542             : int
     543           0 : pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
     544             :     enum pf_sn_types type, sa_family_t af, struct pf_addr *src,
     545             :     struct pf_addr *raddr)
     546             : {
     547           0 :         struct pf_src_node      k;
     548             : 
     549           0 :         if (*sn == NULL) {
     550           0 :                 k.af = af;
     551           0 :                 k.type = type;
     552           0 :                 PF_ACPY(&k.addr, src, af);
     553           0 :                 k.rule.ptr = rule;
     554           0 :                 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
     555           0 :                 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
     556           0 :         }
     557           0 :         if (*sn == NULL) {
     558           0 :                 if (!rule->max_src_nodes ||
     559           0 :                     rule->src_nodes < rule->max_src_nodes)
     560           0 :                         (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT | PR_ZERO);
     561             :                 else
     562           0 :                         pf_status.lcounters[LCNT_SRCNODES]++;
     563           0 :                 if ((*sn) == NULL)
     564           0 :                         return (-1);
     565             : 
     566           0 :                 pf_init_threshold(&(*sn)->conn_rate,
     567           0 :                     rule->max_src_conn_rate.limit,
     568           0 :                     rule->max_src_conn_rate.seconds);
     569             : 
     570           0 :                 (*sn)->type = type;
     571           0 :                 (*sn)->af = af;
     572           0 :                 (*sn)->rule.ptr = rule;
     573           0 :                 PF_ACPY(&(*sn)->addr, src, af);
     574           0 :                 if (raddr)
     575           0 :                         PF_ACPY(&(*sn)->raddr, raddr, af);
     576           0 :                 if (RB_INSERT(pf_src_tree,
     577           0 :                     &tree_src_tracking, *sn) != NULL) {
     578           0 :                         if (pf_status.debug >= LOG_NOTICE) {
     579           0 :                                 log(LOG_NOTICE,
     580             :                                     "pf: src_tree insert failed: ");
     581           0 :                                 pf_print_host(&(*sn)->addr, 0, af);
     582           0 :                                 addlog("\n");
     583           0 :                         }
     584           0 :                         pool_put(&pf_src_tree_pl, *sn);
     585           0 :                         return (-1);
     586             :                 }
     587           0 :                 (*sn)->creation = time_uptime;
     588           0 :                 (*sn)->rule.ptr->src_nodes++;
     589           0 :                 pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
     590           0 :                 pf_status.src_nodes++;
     591           0 :         } else {
     592           0 :                 if (rule->max_src_states &&
     593           0 :                     (*sn)->states >= rule->max_src_states) {
     594           0 :                         pf_status.lcounters[LCNT_SRCSTATES]++;
     595           0 :                         return (-1);
     596             :                 }
     597             :         }
     598           0 :         return (0);
     599           0 : }
     600             : 
     601             : void
     602           0 : pf_remove_src_node(struct pf_src_node *sn)
     603             : {
     604           0 :         if (sn->states > 0 || sn->expire > time_uptime)
     605             :                 return;
     606             : 
     607           0 :         sn->rule.ptr->src_nodes--;
     608           0 :         if (sn->rule.ptr->states_cur == 0 &&
     609           0 :             sn->rule.ptr->src_nodes == 0)
     610           0 :                 pf_rm_rule(NULL, sn->rule.ptr);
     611           0 :         RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
     612           0 :         pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
     613           0 :         pf_status.src_nodes--;
     614           0 :         pool_put(&pf_src_tree_pl, sn);
     615           0 : }
     616             : 
     617             : struct pf_src_node *
     618           0 : pf_get_src_node(struct pf_state *s, enum pf_sn_types type)
     619             : {
     620             :         struct pf_sn_item       *sni;
     621             : 
     622           0 :         SLIST_FOREACH(sni, &s->src_nodes, next)
     623           0 :                 if (sni->sn->type == type)
     624           0 :                         return (sni->sn);
     625           0 :         return (NULL);
     626           0 : }
     627             : 
     628             : void
     629           0 : pf_state_rm_src_node(struct pf_state *s, struct pf_src_node *sn)
     630             : {
     631             :         struct pf_sn_item       *sni, *snin, *snip = NULL;
     632             : 
     633           0 :         for (sni = SLIST_FIRST(&s->src_nodes); sni; sni = snin) {
     634           0 :                 snin = SLIST_NEXT(sni, next);
     635           0 :                 if (sni->sn == sn) {
     636           0 :                         if (snip)
     637           0 :                                 SLIST_REMOVE_AFTER(snip, next);
     638             :                         else
     639           0 :                                 SLIST_REMOVE_HEAD(&s->src_nodes, next);
     640           0 :                         pool_put(&pf_sn_item_pl, sni);
     641             :                         sni = NULL;
     642           0 :                         sn->states--;
     643           0 :                 }
     644           0 :                 if (sni != NULL)
     645           0 :                         snip = sni;
     646             :         }
     647           0 : }
     648             : 
     649             : /* state table stuff */
     650             : 
     651             : static __inline int
     652           0 : pf_state_compare_key(struct pf_state_key *a, struct pf_state_key *b)
     653             : {
     654             :         int     diff;
     655             : 
     656           0 :         if ((diff = a->proto - b->proto) != 0)
     657           0 :                 return (diff);
     658           0 :         if ((diff = a->af - b->af) != 0)
     659           0 :                 return (diff);
     660           0 :         if ((diff = pf_addr_compare(&a->addr[0], &b->addr[0], a->af)) != 0)
     661           0 :                 return (diff);
     662           0 :         if ((diff = pf_addr_compare(&a->addr[1], &b->addr[1], a->af)) != 0)
     663           0 :                 return (diff);
     664           0 :         if ((diff = a->port[0] - b->port[0]) != 0)
     665           0 :                 return (diff);
     666           0 :         if ((diff = a->port[1] - b->port[1]) != 0)
     667           0 :                 return (diff);
     668           0 :         if ((diff = a->rdomain - b->rdomain) != 0)
     669           0 :                 return (diff);
     670           0 :         return (0);
     671           0 : }
     672             : 
     673             : static __inline int
     674           0 : pf_state_compare_id(struct pf_state *a, struct pf_state *b)
     675             : {
     676           0 :         if (a->id > b->id)
     677           0 :                 return (1);
     678           0 :         if (a->id < b->id)
     679           0 :                 return (-1);
     680           0 :         if (a->creatorid > b->creatorid)
     681           0 :                 return (1);
     682           0 :         if (a->creatorid < b->creatorid)
     683           0 :                 return (-1);
     684             : 
     685           0 :         return (0);
     686           0 : }
     687             : 
     688             : int
     689           0 : pf_state_key_attach(struct pf_state_key *sk, struct pf_state *s, int idx)
     690             : {
     691             :         struct pf_state_item    *si;
     692             :         struct pf_state_key     *cur;
     693             :         struct pf_state         *olds = NULL;
     694             : 
     695           0 :         KASSERT(s->key[idx] == NULL);
     696           0 :         if ((cur = RB_INSERT(pf_state_tree, &pf_statetbl, sk)) != NULL) {
     697             :                 /* key exists. check for same kif, if none, add to key */
     698           0 :                 TAILQ_FOREACH(si, &cur->states, entry)
     699           0 :                         if (si->s->kif == s->kif &&
     700           0 :                             ((si->s->key[PF_SK_WIRE]->af == sk->af &&
     701           0 :                              si->s->direction == s->direction) ||
     702           0 :                             (si->s->key[PF_SK_WIRE]->af !=
     703           0 :                              si->s->key[PF_SK_STACK]->af &&
     704           0 :                              sk->af == si->s->key[PF_SK_STACK]->af &&
     705           0 :                              si->s->direction != s->direction))) {
     706             :                                 int reuse = 0;
     707             : 
     708           0 :                                 if (sk->proto == IPPROTO_TCP &&
     709           0 :                                     si->s->src.state >= TCPS_FIN_WAIT_2 &&
     710           0 :                                     si->s->dst.state >= TCPS_FIN_WAIT_2)
     711           0 :                                         reuse = 1;
     712           0 :                                 if (pf_status.debug >= LOG_NOTICE) {
     713           0 :                                         log(LOG_NOTICE,
     714             :                                             "pf: %s key attach %s on %s: ",
     715           0 :                                             (idx == PF_SK_WIRE) ?
     716             :                                             "wire" : "stack",
     717           0 :                                             reuse ? "reuse" : "failed",
     718           0 :                                             s->kif->pfik_name);
     719           0 :                                         pf_print_state_parts(s,
     720           0 :                                             (idx == PF_SK_WIRE) ?  sk : NULL,
     721           0 :                                             (idx == PF_SK_STACK) ?  sk : NULL);
     722           0 :                                         addlog(", existing: ");
     723           0 :                                         pf_print_state_parts(si->s,
     724             :                                             (idx == PF_SK_WIRE) ?  sk : NULL,
     725             :                                             (idx == PF_SK_STACK) ?  sk : NULL);
     726           0 :                                         addlog("\n");
     727           0 :                                 }
     728           0 :                                 if (reuse) {
     729           0 :                                         pf_set_protostate(si->s, PF_PEER_BOTH,
     730             :                                             TCPS_CLOSED);
     731             :                                         /* remove late or sks can go away */
     732           0 :                                         olds = si->s;
     733             :                                 } else {
     734           0 :                                         pool_put(&pf_state_key_pl, sk);
     735           0 :                                         return (-1);    /* collision! */
     736             :                                 }
     737           0 :                         }
     738           0 :                 pool_put(&pf_state_key_pl, sk);
     739           0 :                 s->key[idx] = cur;
     740           0 :         } else
     741           0 :                 s->key[idx] = sk;
     742             : 
     743           0 :         if ((si = pool_get(&pf_state_item_pl, PR_NOWAIT)) == NULL) {
     744           0 :                 pf_state_key_detach(s, idx);
     745           0 :                 return (-1);
     746             :         }
     747           0 :         si->s = s;
     748             : 
     749             :         /* list is sorted, if-bound states before floating */
     750           0 :         if (s->kif == pfi_all)
     751           0 :                 TAILQ_INSERT_TAIL(&s->key[idx]->states, si, entry);
     752             :         else
     753           0 :                 TAILQ_INSERT_HEAD(&s->key[idx]->states, si, entry);
     754             : 
     755           0 :         if (olds)
     756           0 :                 pf_remove_state(olds);
     757             : 
     758           0 :         return (0);
     759           0 : }
     760             : 
     761             : void
     762           0 : pf_detach_state(struct pf_state *s)
     763             : {
     764           0 :         if (s->key[PF_SK_WIRE] == s->key[PF_SK_STACK])
     765           0 :                 s->key[PF_SK_WIRE] = NULL;
     766             : 
     767           0 :         if (s->key[PF_SK_STACK] != NULL)
     768           0 :                 pf_state_key_detach(s, PF_SK_STACK);
     769             : 
     770           0 :         if (s->key[PF_SK_WIRE] != NULL)
     771           0 :                 pf_state_key_detach(s, PF_SK_WIRE);
     772           0 : }
     773             : 
     774             : void
     775           0 : pf_state_key_detach(struct pf_state *s, int idx)
     776             : {
     777             :         struct pf_state_item    *si;
     778             :         struct pf_state_key     *sk;
     779             : 
     780           0 :         if (s->key[idx] == NULL)
     781           0 :                 return;
     782             : 
     783           0 :         si = TAILQ_FIRST(&s->key[idx]->states);
     784           0 :         while (si && si->s != s)
     785           0 :             si = TAILQ_NEXT(si, entry);
     786             : 
     787           0 :         if (si) {
     788           0 :                 TAILQ_REMOVE(&s->key[idx]->states, si, entry);
     789           0 :                 pool_put(&pf_state_item_pl, si);
     790           0 :         }
     791             : 
     792           0 :         sk = s->key[idx];
     793           0 :         s->key[idx] = NULL;
     794           0 :         if (TAILQ_EMPTY(&sk->states)) {
     795           0 :                 RB_REMOVE(pf_state_tree, &pf_statetbl, sk);
     796           0 :                 sk->removed = 1;
     797           0 :                 pf_state_key_unlink_reverse(sk);
     798           0 :                 pf_state_key_unlink_inpcb(sk);
     799           0 :                 pf_state_key_unref(sk);
     800           0 :         }
     801           0 : }
     802             : 
     803             : struct pf_state_key *
     804           0 : pf_alloc_state_key(int pool_flags)
     805             : {
     806             :         struct pf_state_key     *sk;
     807             : 
     808           0 :         if ((sk = pool_get(&pf_state_key_pl, pool_flags)) == NULL)
     809           0 :                 return (NULL);
     810           0 :         TAILQ_INIT(&sk->states);
     811             : 
     812           0 :         return (sk);
     813           0 : }
     814             : 
     815             : static __inline int
     816           0 : pf_state_key_addr_setup(struct pf_pdesc *pd, void *arg, int sidx,
     817             :     struct pf_addr *saddr, int didx, struct pf_addr *daddr, int af, int multi)
     818             : {
     819           0 :         struct pf_state_key_cmp *key = arg;
     820             : #ifdef INET6
     821             :         struct pf_addr *target;
     822             : 
     823           0 :         if (af == AF_INET || pd->proto != IPPROTO_ICMPV6)
     824             :                 goto copy;
     825             : 
     826           0 :         switch (pd->hdr.icmp6.icmp6_type) {
     827             :         case ND_NEIGHBOR_SOLICIT:
     828           0 :                 if (multi)
     829           0 :                         return (-1);
     830           0 :                 target = (struct pf_addr *)&pd->hdr.nd_ns.nd_ns_target;
     831             :                 daddr = target;
     832           0 :                 break;
     833             :         case ND_NEIGHBOR_ADVERT:
     834           0 :                 if (multi)
     835           0 :                         return (-1);
     836           0 :                 target = (struct pf_addr *)&pd->hdr.nd_ns.nd_ns_target;
     837             :                 saddr = target;
     838           0 :                 if (IN6_IS_ADDR_MULTICAST(&pd->dst->v6)) {
     839           0 :                         key->addr[didx].addr32[0] = 0;
     840           0 :                         key->addr[didx].addr32[1] = 0;
     841           0 :                         key->addr[didx].addr32[2] = 0;
     842           0 :                         key->addr[didx].addr32[3] = 0;
     843             :                         daddr = NULL; /* overwritten */
     844           0 :                 }
     845             :                 break;
     846             :         default:
     847           0 :                 if (multi) {
     848           0 :                         key->addr[sidx].addr32[0] = __IPV6_ADDR_INT32_MLL;
     849           0 :                         key->addr[sidx].addr32[1] = 0;
     850           0 :                         key->addr[sidx].addr32[2] = 0;
     851           0 :                         key->addr[sidx].addr32[3] = __IPV6_ADDR_INT32_ONE;
     852             :                         saddr = NULL; /* overwritten */
     853           0 :                 }
     854             :         }
     855             :  copy:
     856             : #endif  /* INET6 */
     857           0 :         if (saddr)
     858           0 :                 PF_ACPY(&key->addr[sidx], saddr, af);
     859           0 :         if (daddr)
     860           0 :                 PF_ACPY(&key->addr[didx], daddr, af);
     861             : 
     862           0 :         return (0);
     863           0 : }
     864             : 
     865             : int
     866           0 : pf_state_key_setup(struct pf_pdesc *pd, struct pf_state_key **skw,
     867             :     struct pf_state_key **sks, int rtableid)
     868             : {
     869             :         /* if returning error we MUST pool_put state keys ourselves */
     870             :         struct pf_state_key *sk1, *sk2;
     871           0 :         u_int wrdom = pd->rdomain;
     872           0 :         int afto = pd->af != pd->naf;
     873             : 
     874           0 :         if ((sk1 = pf_alloc_state_key(PR_NOWAIT | PR_ZERO)) == NULL)
     875           0 :                 return (ENOMEM);
     876             : 
     877           0 :         pf_state_key_addr_setup(pd, sk1, pd->sidx, pd->src, pd->didx, pd->dst,
     878           0 :             pd->af, 0);
     879           0 :         sk1->port[pd->sidx] = pd->osport;
     880           0 :         sk1->port[pd->didx] = pd->odport;
     881           0 :         sk1->proto = pd->proto;
     882           0 :         sk1->af = pd->af;
     883           0 :         sk1->rdomain = pd->rdomain;
     884           0 :         PF_REF_INIT(sk1->refcnt);
     885           0 :         sk1->removed = 0;
     886           0 :         if (rtableid >= 0)
     887           0 :                 wrdom = rtable_l2(rtableid);
     888             : 
     889           0 :         if (PF_ANEQ(&pd->nsaddr, pd->src, pd->af) ||
     890           0 :             PF_ANEQ(&pd->ndaddr, pd->dst, pd->af) ||
     891           0 :             pd->nsport != pd->osport || pd->ndport != pd->odport ||
     892           0 :             wrdom != pd->rdomain || afto) {  /* NAT/NAT64 */
     893           0 :                 if ((sk2 = pf_alloc_state_key(PR_NOWAIT | PR_ZERO)) == NULL) {
     894           0 :                         pool_put(&pf_state_key_pl, sk1);
     895           0 :                         return (ENOMEM);
     896             :                 }
     897           0 :                 pf_state_key_addr_setup(pd, sk2, afto ? pd->didx : pd->sidx,
     898           0 :                     &pd->nsaddr, afto ? pd->sidx : pd->didx, &pd->ndaddr,
     899           0 :                     pd->naf, 0);
     900           0 :                 sk2->port[afto ? pd->didx : pd->sidx] = pd->nsport;
     901           0 :                 sk2->port[afto ? pd->sidx : pd->didx] = pd->ndport;
     902           0 :                 if (afto) {
     903           0 :                         switch (pd->proto) {
     904             :                         case IPPROTO_ICMP:
     905           0 :                                 sk2->proto = IPPROTO_ICMPV6;
     906           0 :                                 break;
     907             :                         case IPPROTO_ICMPV6:
     908           0 :                                 sk2->proto = IPPROTO_ICMP;
     909           0 :                                 break;
     910             :                         default:
     911           0 :                                 sk2->proto = pd->proto;
     912           0 :                         }
     913             :                 } else
     914           0 :                         sk2->proto = pd->proto;
     915           0 :                 sk2->af = pd->naf;
     916           0 :                 sk2->rdomain = wrdom;
     917           0 :                 PF_REF_INIT(sk2->refcnt);
     918           0 :                 sk2->removed = 0;
     919           0 :         } else
     920             :                 sk2 = sk1;
     921             : 
     922           0 :         if (pd->dir == PF_IN) {
     923           0 :                 *skw = sk1;
     924           0 :                 *sks = sk2;
     925           0 :         } else {
     926           0 :                 *sks = sk1;
     927           0 :                 *skw = sk2;
     928             :         }
     929             : 
     930           0 :         if (pf_status.debug >= LOG_DEBUG) {
     931           0 :                 log(LOG_DEBUG, "pf: key setup: ");
     932           0 :                 pf_print_state_parts(NULL, *skw, *sks);
     933           0 :                 addlog("\n");
     934           0 :         }
     935             : 
     936           0 :         return (0);
     937           0 : }
     938             : 
     939             : int
     940           0 : pf_state_insert(struct pfi_kif *kif, struct pf_state_key **skw,
     941             :     struct pf_state_key **sks, struct pf_state *s)
     942             : {
     943             :         PF_ASSERT_LOCKED();
     944             : 
     945           0 :         s->kif = kif;
     946           0 :         if (*skw == *sks) {
     947           0 :                 if (pf_state_key_attach(*skw, s, PF_SK_WIRE))
     948           0 :                         return (-1);
     949           0 :                 *skw = *sks = s->key[PF_SK_WIRE];
     950           0 :                 s->key[PF_SK_STACK] = s->key[PF_SK_WIRE];
     951           0 :         } else {
     952           0 :                 if (pf_state_key_attach(*skw, s, PF_SK_WIRE)) {
     953           0 :                         pool_put(&pf_state_key_pl, *sks);
     954           0 :                         return (-1);
     955             :                 }
     956           0 :                 *skw = s->key[PF_SK_WIRE];
     957           0 :                 if (pf_state_key_attach(*sks, s, PF_SK_STACK)) {
     958           0 :                         pf_state_key_detach(s, PF_SK_WIRE);
     959           0 :                         return (-1);
     960             :                 }
     961           0 :                 *sks = s->key[PF_SK_STACK];
     962             :         }
     963             : 
     964           0 :         if (s->id == 0 && s->creatorid == 0) {
     965           0 :                 s->id = htobe64(pf_status.stateid++);
     966           0 :                 s->creatorid = pf_status.hostid;
     967           0 :         }
     968           0 :         if (RB_INSERT(pf_state_tree_id, &tree_id, s) != NULL) {
     969           0 :                 if (pf_status.debug >= LOG_NOTICE) {
     970           0 :                         log(LOG_NOTICE, "pf: state insert failed: "
     971             :                             "id: %016llx creatorid: %08x",
     972           0 :                             betoh64(s->id), ntohl(s->creatorid));
     973           0 :                         addlog("\n");
     974           0 :                 }
     975           0 :                 pf_detach_state(s);
     976           0 :                 return (-1);
     977             :         }
     978           0 :         TAILQ_INSERT_TAIL(&state_list, s, entry_list);
     979           0 :         pf_status.fcounters[FCNT_STATE_INSERT]++;
     980           0 :         pf_status.states++;
     981           0 :         pfi_kif_ref(kif, PFI_KIF_REF_STATE);
     982             : #if NPFSYNC > 0
     983           0 :         pfsync_insert_state(s);
     984             : #endif  /* NPFSYNC > 0 */
     985           0 :         return (0);
     986           0 : }
     987             : 
     988             : struct pf_state *
     989           0 : pf_find_state_byid(struct pf_state_cmp *key)
     990             : {
     991           0 :         pf_status.fcounters[FCNT_STATE_SEARCH]++;
     992             : 
     993           0 :         return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key));
     994             : }
     995             : 
     996             : int
     997           0 : pf_compare_state_keys(struct pf_state_key *a, struct pf_state_key *b,
     998             :     struct pfi_kif *kif, u_int dir)
     999             : {
    1000             :         /* a (from hdr) and b (new) must be exact opposites of each other */
    1001           0 :         if (a->af == b->af && a->proto == b->proto &&
    1002           0 :             PF_AEQ(&a->addr[0], &b->addr[1], a->af) &&
    1003           0 :             PF_AEQ(&a->addr[1], &b->addr[0], a->af) &&
    1004           0 :             a->port[0] == b->port[1] &&
    1005           0 :             a->port[1] == b->port[0] && a->rdomain == b->rdomain)
    1006           0 :                 return (0);
    1007             :         else {
    1008             :                 /* mismatch. must not happen. */
    1009           0 :                 if (pf_status.debug >= LOG_ERR) {
    1010           0 :                         log(LOG_ERR,
    1011             :                             "pf: state key linking mismatch! dir=%s, "
    1012             :                             "if=%s, stored af=%u, a0: ",
    1013           0 :                             dir == PF_OUT ? "OUT" : "IN",
    1014           0 :                             kif->pfik_name, a->af);
    1015           0 :                         pf_print_host(&a->addr[0], a->port[0], a->af);
    1016           0 :                         addlog(", a1: ");
    1017           0 :                         pf_print_host(&a->addr[1], a->port[1], a->af);
    1018           0 :                         addlog(", proto=%u", a->proto);
    1019           0 :                         addlog(", found af=%u, a0: ", b->af);
    1020           0 :                         pf_print_host(&b->addr[0], b->port[0], b->af);
    1021           0 :                         addlog(", a1: ");
    1022           0 :                         pf_print_host(&b->addr[1], b->port[1], b->af);
    1023           0 :                         addlog(", proto=%u", b->proto);
    1024           0 :                         addlog("\n");
    1025           0 :                 }
    1026           0 :                 return (-1);
    1027             :         }
    1028           0 : }
    1029             : 
    1030             : int
    1031           0 : pf_find_state(struct pf_pdesc *pd, struct pf_state_key_cmp *key,
    1032             :     struct pf_state **state)
    1033             : {
    1034             :         struct pf_state_key     *sk, *pkt_sk, *inp_sk;
    1035             :         struct pf_state_item    *si;
    1036             :         struct pf_state         *s = NULL;
    1037             : 
    1038           0 :         pf_status.fcounters[FCNT_STATE_SEARCH]++;
    1039           0 :         if (pf_status.debug >= LOG_DEBUG) {
    1040           0 :                 log(LOG_DEBUG, "pf: key search, if=%s: ", pd->kif->pfik_name);
    1041           0 :                 pf_print_state_parts(NULL, (struct pf_state_key *)key, NULL);
    1042           0 :                 addlog("\n");
    1043           0 :         }
    1044             : 
    1045             :         inp_sk = NULL;
    1046             :         pkt_sk = NULL;
    1047             :         sk = NULL;
    1048           0 :         if (pd->dir == PF_OUT) {
    1049             :                 /* first if block deals with outbound forwarded packet */
    1050           0 :                 pkt_sk = pd->m->m_pkthdr.pf.statekey;
    1051             : 
    1052           0 :                 if (!pf_state_key_isvalid(pkt_sk)) {
    1053           0 :                         pf_mbuf_unlink_state_key(pd->m);
    1054             :                         pkt_sk = NULL;
    1055           0 :                 }
    1056             : 
    1057           0 :                 if (pkt_sk && pf_state_key_isvalid(pkt_sk->reverse))
    1058           0 :                         sk = pkt_sk->reverse;
    1059             : 
    1060           0 :                 if (pkt_sk == NULL) {
    1061             :                         /* here we deal with local outbound packet */
    1062           0 :                         if (pd->m->m_pkthdr.pf.inp != NULL) {
    1063           0 :                                 inp_sk = pd->m->m_pkthdr.pf.inp->inp_pf_sk;
    1064           0 :                                 if (pf_state_key_isvalid(inp_sk))
    1065           0 :                                         sk = inp_sk;
    1066             :                                 else
    1067           0 :                                         pf_inpcb_unlink_state_key(
    1068           0 :                                             pd->m->m_pkthdr.pf.inp);
    1069             :                         }
    1070             :                 }
    1071             :         }
    1072             : 
    1073           0 :         if (sk == NULL) {
    1074           0 :                 if ((sk = RB_FIND(pf_state_tree, &pf_statetbl,
    1075           0 :                     (struct pf_state_key *)key)) == NULL)
    1076           0 :                         return (PF_DROP);
    1077           0 :                 if (pd->dir == PF_OUT && pkt_sk &&
    1078           0 :                     pf_compare_state_keys(pkt_sk, sk, pd->kif, pd->dir) == 0)
    1079           0 :                         pf_state_key_link_reverse(sk, pkt_sk);
    1080           0 :                 else if (pd->dir == PF_OUT && pd->m->m_pkthdr.pf.inp &&
    1081           0 :                     !pd->m->m_pkthdr.pf.inp->inp_pf_sk && !sk->inp)
    1082           0 :                         pf_state_key_link_inpcb(sk, pd->m->m_pkthdr.pf.inp);
    1083             :         }
    1084             : 
    1085             :         /* remove firewall data from outbound packet */
    1086           0 :         if (pd->dir == PF_OUT)
    1087           0 :                 pf_pkt_addr_changed(pd->m);
    1088             : 
    1089             :         /* list is sorted, if-bound states before floating ones */
    1090           0 :         TAILQ_FOREACH(si, &sk->states, entry)
    1091           0 :                 if ((si->s->kif == pfi_all || si->s->kif == pd->kif) &&
    1092           0 :                     ((si->s->key[PF_SK_WIRE]->af == si->s->key[PF_SK_STACK]->af
    1093           0 :                     && sk == (pd->dir == PF_IN ? si->s->key[PF_SK_WIRE] :
    1094           0 :                     si->s->key[PF_SK_STACK])) ||
    1095           0 :                     (si->s->key[PF_SK_WIRE]->af != si->s->key[PF_SK_STACK]->af
    1096           0 :                     && pd->dir == PF_IN && (sk == si->s->key[PF_SK_STACK] ||
    1097           0 :                     sk == si->s->key[PF_SK_WIRE])))) {
    1098           0 :                         s = si->s;
    1099           0 :                         break;
    1100             :         }
    1101             : 
    1102           0 :         if (s == NULL || s->timeout == PFTM_PURGE)
    1103           0 :                 return (PF_DROP);
    1104             : 
    1105           0 :         if (s->rule.ptr->pktrate.limit && pd->dir == s->direction) {
    1106           0 :                 pf_add_threshold(&s->rule.ptr->pktrate);
    1107           0 :                 if (pf_check_threshold(&s->rule.ptr->pktrate))
    1108           0 :                         return (PF_DROP);
    1109             :         }
    1110             : 
    1111           0 :         *state = s;
    1112           0 :         if (pd->dir == PF_OUT && s->rt_kif != NULL && s->rt_kif != pd->kif &&
    1113           0 :             ((s->rule.ptr->rt == PF_ROUTETO &&
    1114           0 :             s->rule.ptr->direction == PF_OUT) ||
    1115           0 :             (s->rule.ptr->rt == PF_REPLYTO &&
    1116           0 :             s->rule.ptr->direction == PF_IN)))
    1117           0 :                 return (PF_PASS);
    1118             : 
    1119           0 :         return (PF_MATCH);
    1120           0 : }
    1121             : 
    1122             : struct pf_state *
    1123           0 : pf_find_state_all(struct pf_state_key_cmp *key, u_int dir, int *more)
    1124             : {
    1125             :         struct pf_state_key     *sk;
    1126             :         struct pf_state_item    *si, *ret = NULL;
    1127             : 
    1128           0 :         pf_status.fcounters[FCNT_STATE_SEARCH]++;
    1129             : 
    1130           0 :         sk = RB_FIND(pf_state_tree, &pf_statetbl, (struct pf_state_key *)key);
    1131             : 
    1132           0 :         if (sk != NULL) {
    1133           0 :                 TAILQ_FOREACH(si, &sk->states, entry)
    1134           0 :                         if (dir == PF_INOUT ||
    1135           0 :                             (sk == (dir == PF_IN ? si->s->key[PF_SK_WIRE] :
    1136           0 :                             si->s->key[PF_SK_STACK]))) {
    1137           0 :                                 if (more == NULL)
    1138           0 :                                         return (si->s);
    1139             : 
    1140           0 :                                 if (ret)
    1141           0 :                                         (*more)++;
    1142             :                                 else
    1143             :                                         ret = si;
    1144             :                         }
    1145             :         }
    1146           0 :         return (ret ? ret->s : NULL);
    1147           0 : }
    1148             : 
    1149             : void
    1150           0 : pf_state_export(struct pfsync_state *sp, struct pf_state *st)
    1151             : {
    1152             :         int32_t expire;
    1153             : 
    1154           0 :         memset(sp, 0, sizeof(struct pfsync_state));
    1155             : 
    1156             :         /* copy from state key */
    1157           0 :         sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
    1158           0 :         sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
    1159           0 :         sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
    1160           0 :         sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
    1161           0 :         sp->key[PF_SK_WIRE].rdomain = htons(st->key[PF_SK_WIRE]->rdomain);
    1162           0 :         sp->key[PF_SK_WIRE].af = st->key[PF_SK_WIRE]->af;
    1163           0 :         sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
    1164           0 :         sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
    1165           0 :         sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
    1166           0 :         sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
    1167           0 :         sp->key[PF_SK_STACK].rdomain = htons(st->key[PF_SK_STACK]->rdomain);
    1168           0 :         sp->key[PF_SK_STACK].af = st->key[PF_SK_STACK]->af;
    1169           0 :         sp->rtableid[PF_SK_WIRE] = htonl(st->rtableid[PF_SK_WIRE]);
    1170           0 :         sp->rtableid[PF_SK_STACK] = htonl(st->rtableid[PF_SK_STACK]);
    1171           0 :         sp->proto = st->key[PF_SK_WIRE]->proto;
    1172           0 :         sp->af = st->key[PF_SK_WIRE]->af;
    1173             : 
    1174             :         /* copy from state */
    1175           0 :         strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
    1176           0 :         memcpy(&sp->rt_addr, &st->rt_addr, sizeof(sp->rt_addr));
    1177           0 :         sp->creation = htonl(time_uptime - st->creation);
    1178           0 :         expire = pf_state_expires(st);
    1179           0 :         if (expire <= time_uptime)
    1180           0 :                 sp->expire = htonl(0);
    1181             :         else
    1182           0 :                 sp->expire = htonl(expire - time_uptime);
    1183             : 
    1184           0 :         sp->direction = st->direction;
    1185             : #if NPFLOG > 0
    1186           0 :         sp->log = st->log;
    1187             : #endif  /* NPFLOG > 0 */
    1188           0 :         sp->timeout = st->timeout;
    1189           0 :         sp->state_flags = htons(st->state_flags);
    1190           0 :         if (!SLIST_EMPTY(&st->src_nodes))
    1191           0 :                 sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
    1192             : 
    1193           0 :         sp->id = st->id;
    1194           0 :         sp->creatorid = st->creatorid;
    1195           0 :         pf_state_peer_hton(&st->src, &sp->src);
    1196           0 :         pf_state_peer_hton(&st->dst, &sp->dst);
    1197             : 
    1198           0 :         if (st->rule.ptr == NULL)
    1199           0 :                 sp->rule = htonl(-1);
    1200             :         else
    1201           0 :                 sp->rule = htonl(st->rule.ptr->nr);
    1202           0 :         if (st->anchor.ptr == NULL)
    1203           0 :                 sp->anchor = htonl(-1);
    1204             :         else
    1205           0 :                 sp->anchor = htonl(st->anchor.ptr->nr);
    1206           0 :         sp->nat_rule = htonl(-1);    /* left for compat, nat_rule is gone */
    1207             : 
    1208           0 :         pf_state_counter_hton(st->packets[0], sp->packets[0]);
    1209           0 :         pf_state_counter_hton(st->packets[1], sp->packets[1]);
    1210           0 :         pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
    1211           0 :         pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
    1212             : 
    1213           0 :         sp->max_mss = htons(st->max_mss);
    1214           0 :         sp->min_ttl = st->min_ttl;
    1215           0 :         sp->set_tos = st->set_tos;
    1216           0 :         sp->set_prio[0] = st->set_prio[0];
    1217           0 :         sp->set_prio[1] = st->set_prio[1];
    1218           0 : }
    1219             : 
    1220             : /* END state table stuff */
    1221             : 
    1222             : void
    1223           0 : pf_purge_expired_rules(void)
    1224             : {
    1225             :         struct pf_rule  *r;
    1226             : 
    1227             :         PF_ASSERT_LOCKED();
    1228             : 
    1229           0 :         if (SLIST_EMPTY(&pf_rule_gcl))
    1230           0 :                 return;
    1231             : 
    1232           0 :         while ((r = SLIST_FIRST(&pf_rule_gcl)) != NULL) {
    1233           0 :                 SLIST_REMOVE(&pf_rule_gcl, r, pf_rule, gcle);
    1234           0 :                 KASSERT(r->rule_flag & PFRULE_EXPIRED);
    1235           0 :                 pf_purge_rule(r);
    1236             :         }
    1237           0 : }
    1238             : 
    1239             : void
    1240           0 : pf_purge_timeout(void *unused)
    1241             : {
    1242           0 :         task_add(net_tq(0), &pf_purge_task);
    1243           0 : }
    1244             : 
    1245             : void
    1246           0 : pf_purge(void *xnloops)
    1247             : {
    1248           0 :         int *nloops = xnloops;
    1249             : 
    1250           0 :         KERNEL_LOCK();
    1251           0 :         NET_LOCK();
    1252             : 
    1253             :         /*
    1254             :          * process a fraction of the state table every second
    1255             :          * Note:
    1256             :          *      we no longer need PF_LOCK() here, because
    1257             :          *      pf_purge_expired_states() uses pf_state_lock to maintain
    1258             :          *      consistency.
    1259             :          */
    1260           0 :         pf_purge_expired_states(1 + (pf_status.states
    1261           0 :             / pf_default_rule.timeout[PFTM_INTERVAL]));
    1262             : 
    1263             :         PF_LOCK();
    1264             :         /* purge other expired types every PFTM_INTERVAL seconds */
    1265           0 :         if (++(*nloops) >= pf_default_rule.timeout[PFTM_INTERVAL]) {
    1266           0 :                 pf_purge_expired_src_nodes();
    1267           0 :                 pf_purge_expired_rules();
    1268           0 :         }
    1269             :         PF_UNLOCK();
    1270             : 
    1271             :         /*
    1272             :          * Fragments don't require PF_LOCK(), they use their own lock.
    1273             :          */
    1274           0 :         if ((*nloops) >= pf_default_rule.timeout[PFTM_INTERVAL]) {
    1275           0 :                 pf_purge_expired_fragments();
    1276           0 :                 *nloops = 0;
    1277           0 :         }
    1278           0 :         NET_UNLOCK();
    1279           0 :         KERNEL_UNLOCK();
    1280             : 
    1281           0 :         timeout_add(&pf_purge_to, 1 * hz);
    1282           0 : }
    1283             : 
    1284             : int32_t
    1285           0 : pf_state_expires(const struct pf_state *state)
    1286             : {
    1287             :         u_int32_t       timeout;
    1288             :         u_int32_t       start;
    1289             :         u_int32_t       end;
    1290             :         u_int32_t       states;
    1291             : 
    1292             :         /* handle all PFTM_* > PFTM_MAX here */
    1293           0 :         if (state->timeout == PFTM_PURGE)
    1294           0 :                 return (0);
    1295             : 
    1296           0 :         KASSERT(state->timeout != PFTM_UNLINKED);
    1297           0 :         KASSERT(state->timeout < PFTM_MAX);
    1298             : 
    1299           0 :         timeout = state->rule.ptr->timeout[state->timeout];
    1300           0 :         if (!timeout)
    1301           0 :                 timeout = pf_default_rule.timeout[state->timeout];
    1302             : 
    1303           0 :         start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
    1304           0 :         if (start) {
    1305           0 :                 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];
    1306           0 :                 states = state->rule.ptr->states_cur;
    1307           0 :         } else {
    1308           0 :                 start = pf_default_rule.timeout[PFTM_ADAPTIVE_START];
    1309           0 :                 end = pf_default_rule.timeout[PFTM_ADAPTIVE_END];
    1310           0 :                 states = pf_status.states;
    1311             :         }
    1312           0 :         if (end && states > start && start < end) {
    1313           0 :                 if (states >= end)
    1314           0 :                         return (0);
    1315             : 
    1316           0 :                 timeout = (u_int64_t)timeout * (end - states) / (end - start);
    1317           0 :         }
    1318             : 
    1319           0 :         return (state->expire + timeout);
    1320           0 : }
    1321             : 
    1322             : void
    1323           0 : pf_purge_expired_src_nodes(void)
    1324             : {
    1325             :         struct pf_src_node              *cur, *next;
    1326             : 
    1327             :         PF_ASSERT_LOCKED();
    1328             : 
    1329           0 :         for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
    1330           0 :         next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
    1331             : 
    1332           0 :                 if (cur->states == 0 && cur->expire <= time_uptime) {
    1333           0 :                         next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
    1334           0 :                         pf_remove_src_node(cur);
    1335           0 :                 }
    1336             :         }
    1337           0 : }
    1338             : 
    1339             : void
    1340           0 : pf_src_tree_remove_state(struct pf_state *s)
    1341             : {
    1342             :         u_int32_t                timeout;
    1343             :         struct pf_sn_item       *sni;
    1344             : 
    1345           0 :         while ((sni = SLIST_FIRST(&s->src_nodes)) != NULL) {
    1346           0 :                 SLIST_REMOVE_HEAD(&s->src_nodes, next);
    1347           0 :                 if (s->src.tcp_est)
    1348           0 :                         --sni->sn->conn;
    1349           0 :                 if (--sni->sn->states == 0) {
    1350           0 :                         timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
    1351           0 :                         if (!timeout)
    1352           0 :                                 timeout =
    1353           0 :                                     pf_default_rule.timeout[PFTM_SRC_NODE];
    1354           0 :                         sni->sn->expire = time_uptime + timeout;
    1355           0 :                 }
    1356           0 :                 pool_put(&pf_sn_item_pl, sni);
    1357             :         }
    1358           0 : }
    1359             : 
    1360             : void
    1361           0 : pf_remove_state(struct pf_state *cur)
    1362             : {
    1363             :         PF_ASSERT_LOCKED();
    1364             : 
    1365             :         /* handle load balancing related tasks */
    1366           0 :         pf_postprocess_addr(cur);
    1367             : 
    1368           0 :         if (cur->src.state == PF_TCPS_PROXY_DST) {
    1369           0 :                 pf_send_tcp(cur->rule.ptr, cur->key[PF_SK_WIRE]->af,
    1370           0 :                     &cur->key[PF_SK_WIRE]->addr[1],
    1371           0 :                     &cur->key[PF_SK_WIRE]->addr[0],
    1372           0 :                     cur->key[PF_SK_WIRE]->port[1],
    1373           0 :                     cur->key[PF_SK_WIRE]->port[0],
    1374           0 :                     cur->src.seqhi, cur->src.seqlo + 1,
    1375           0 :                     TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag,
    1376           0 :                     cur->key[PF_SK_WIRE]->rdomain);
    1377           0 :         }
    1378           0 :         if (cur->key[PF_SK_STACK]->proto == IPPROTO_TCP)
    1379           0 :                 pf_set_protostate(cur, PF_PEER_BOTH, TCPS_CLOSED);
    1380             : 
    1381           0 :         RB_REMOVE(pf_state_tree_id, &tree_id, cur);
    1382             : #if NPFLOW > 0
    1383           0 :         if (cur->state_flags & PFSTATE_PFLOW)
    1384           0 :                 export_pflow(cur);
    1385             : #endif  /* NPFLOW > 0 */
    1386             : #if NPFSYNC > 0
    1387           0 :         pfsync_delete_state(cur);
    1388             : #endif  /* NPFSYNC > 0 */
    1389           0 :         cur->timeout = PFTM_UNLINKED;
    1390           0 :         pf_src_tree_remove_state(cur);
    1391           0 :         pf_detach_state(cur);
    1392           0 : }
    1393             : 
    1394             : void
    1395           0 : pf_remove_divert_state(struct pf_state_key *sk)
    1396             : {
    1397             :         struct pf_state_item    *si;
    1398             : 
    1399           0 :         TAILQ_FOREACH(si, &sk->states, entry) {
    1400           0 :                 if (sk == si->s->key[PF_SK_STACK] && si->s->rule.ptr &&
    1401           0 :                     (si->s->rule.ptr->divert.type == PF_DIVERT_TO ||
    1402           0 :                     si->s->rule.ptr->divert.type == PF_DIVERT_REPLY)) {
    1403           0 :                         pf_remove_state(si->s);
    1404           0 :                         break;
    1405             :                 }
    1406             :         }
    1407           0 : }
    1408             : 
    1409             : void
    1410           0 : pf_free_state(struct pf_state *cur)
    1411             : {
    1412             :         struct pf_rule_item *ri;
    1413             : 
    1414             :         PF_ASSERT_LOCKED();
    1415             : 
    1416             : #if NPFSYNC > 0
    1417           0 :         if (pfsync_state_in_use(cur))
    1418           0 :                 return;
    1419             : #endif  /* NPFSYNC > 0 */
    1420           0 :         KASSERT(cur->timeout == PFTM_UNLINKED);
    1421           0 :         if (--cur->rule.ptr->states_cur == 0 &&
    1422           0 :             cur->rule.ptr->src_nodes == 0)
    1423           0 :                 pf_rm_rule(NULL, cur->rule.ptr);
    1424           0 :         if (cur->anchor.ptr != NULL)
    1425           0 :                 if (--cur->anchor.ptr->states_cur == 0)
    1426           0 :                         pf_rm_rule(NULL, cur->anchor.ptr);
    1427           0 :         while ((ri = SLIST_FIRST(&cur->match_rules))) {
    1428           0 :                 SLIST_REMOVE_HEAD(&cur->match_rules, entry);
    1429           0 :                 if (--ri->r->states_cur == 0 &&
    1430           0 :                     ri->r->src_nodes == 0)
    1431           0 :                         pf_rm_rule(NULL, ri->r);
    1432           0 :                 pool_put(&pf_rule_item_pl, ri);
    1433             :         }
    1434           0 :         pf_normalize_tcp_cleanup(cur);
    1435           0 :         pfi_kif_unref(cur->kif, PFI_KIF_REF_STATE);
    1436           0 :         TAILQ_REMOVE(&state_list, cur, entry_list);
    1437           0 :         if (cur->tag)
    1438           0 :                 pf_tag_unref(cur->tag);
    1439           0 :         pf_state_unref(cur);
    1440           0 :         pf_status.fcounters[FCNT_STATE_REMOVALS]++;
    1441           0 :         pf_status.states--;
    1442           0 : }
    1443             : 
    1444             : void
    1445           0 : pf_purge_expired_states(u_int32_t maxcheck)
    1446             : {
    1447             :         static struct pf_state  *cur = NULL;
    1448             :         struct pf_state         *next;
    1449             :         SLIST_HEAD(pf_state_gcl, pf_state) gcl;
    1450             : 
    1451             :         PF_ASSERT_UNLOCKED();
    1452             :         SLIST_INIT(&gcl);
    1453             : 
    1454             :         PF_STATE_ENTER_READ();
    1455           0 :         while (maxcheck--) {
    1456             :                 /* wrap to start of list when we hit the end */
    1457           0 :                 if (cur == NULL) {
    1458           0 :                         cur = pf_state_ref(TAILQ_FIRST(&state_list));
    1459           0 :                         if (cur == NULL)
    1460             :                                 break;  /* list empty */
    1461             :                 }
    1462             : 
    1463             :                 /* get next state, as cur may get deleted */
    1464           0 :                 next = TAILQ_NEXT(cur, entry_list);
    1465             : 
    1466           0 :                 if ((cur->timeout == PFTM_UNLINKED) ||
    1467           0 :                     (pf_state_expires(cur) <= time_uptime))
    1468           0 :                         SLIST_INSERT_HEAD(&gcl, cur, gc_list);
    1469             :                 else
    1470           0 :                         pf_state_unref(cur);
    1471             : 
    1472           0 :                 cur = pf_state_ref(next);
    1473             :         }
    1474             :         PF_STATE_EXIT_READ();
    1475             : 
    1476             :         PF_LOCK();
    1477             :         PF_STATE_ENTER_WRITE();
    1478           0 :         while ((next = SLIST_FIRST(&gcl)) != NULL) {
    1479           0 :                 SLIST_REMOVE_HEAD(&gcl, gc_list);
    1480           0 :                 if (next->timeout == PFTM_UNLINKED)
    1481           0 :                         pf_free_state(next);
    1482           0 :                 else if (pf_state_expires(next) <= time_uptime) {
    1483           0 :                         pf_remove_state(next);
    1484           0 :                         pf_free_state(next);
    1485           0 :                 }
    1486             : 
    1487           0 :                 pf_state_unref(next);
    1488             :         }
    1489             :         PF_STATE_EXIT_WRITE();
    1490             :         PF_UNLOCK();
    1491           0 : }
    1492             : 
    1493             : int
    1494           0 : pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
    1495             : {
    1496           0 :         if (aw->type != PF_ADDR_TABLE)
    1497           0 :                 return (0);
    1498           0 :         if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname, 1)) == NULL)
    1499           0 :                 return (1);
    1500           0 :         return (0);
    1501           0 : }
    1502             : 
    1503             : void
    1504           0 : pf_tbladdr_remove(struct pf_addr_wrap *aw)
    1505             : {
    1506           0 :         if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL)
    1507             :                 return;
    1508           0 :         pfr_detach_table(aw->p.tbl);
    1509           0 :         aw->p.tbl = NULL;
    1510           0 : }
    1511             : 
    1512             : void
    1513           0 : pf_tbladdr_copyout(struct pf_addr_wrap *aw)
    1514             : {
    1515           0 :         struct pfr_ktable *kt = aw->p.tbl;
    1516             : 
    1517           0 :         if (aw->type != PF_ADDR_TABLE || kt == NULL)
    1518           0 :                 return;
    1519           0 :         if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
    1520           0 :                 kt = kt->pfrkt_root;
    1521           0 :         aw->p.tbl = NULL;
    1522           0 :         aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
    1523           0 :                 kt->pfrkt_cnt : -1;
    1524           0 : }
    1525             : 
    1526             : void
    1527           0 : pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
    1528             : {
    1529           0 :         switch (af) {
    1530             :         case AF_INET: {
    1531           0 :                 u_int32_t a = ntohl(addr->addr32[0]);
    1532           0 :                 addlog("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255,
    1533           0 :                     (a>>8)&255, a&255);
    1534           0 :                 if (p) {
    1535           0 :                         p = ntohs(p);
    1536           0 :                         addlog(":%u", p);
    1537           0 :                 }
    1538             :                 break;
    1539             :         }
    1540             : #ifdef INET6
    1541             :         case AF_INET6: {
    1542             :                 u_int16_t b;
    1543             :                 u_int8_t i, curstart, curend, maxstart, maxend;
    1544             :                 curstart = curend = maxstart = maxend = 255;
    1545           0 :                 for (i = 0; i < 8; i++) {
    1546           0 :                         if (!addr->addr16[i]) {
    1547           0 :                                 if (curstart == 255)
    1548           0 :                                         curstart = i;
    1549             :                                 curend = i;
    1550           0 :                         } else {
    1551           0 :                                 if ((curend - curstart) >
    1552           0 :                                     (maxend - maxstart)) {
    1553             :                                         maxstart = curstart;
    1554             :                                         maxend = curend;
    1555           0 :                                 }
    1556             :                                 curstart = curend = 255;
    1557             :                         }
    1558             :                 }
    1559           0 :                 if ((curend - curstart) >
    1560           0 :                     (maxend - maxstart)) {
    1561             :                         maxstart = curstart;
    1562             :                         maxend = curend;
    1563           0 :                 }
    1564           0 :                 for (i = 0; i < 8; i++) {
    1565           0 :                         if (i >= maxstart && i <= maxend) {
    1566           0 :                                 if (i == 0)
    1567           0 :                                         addlog(":");
    1568           0 :                                 if (i == maxend)
    1569           0 :                                         addlog(":");
    1570             :                         } else {
    1571           0 :                                 b = ntohs(addr->addr16[i]);
    1572           0 :                                 addlog("%x", b);
    1573           0 :                                 if (i < 7)
    1574           0 :                                         addlog(":");
    1575             :                         }
    1576             :                 }
    1577           0 :                 if (p) {
    1578           0 :                         p = ntohs(p);
    1579           0 :                         addlog("[%u]", p);
    1580           0 :                 }
    1581             :                 break;
    1582             :         }
    1583             : #endif /* INET6 */
    1584             :         }
    1585           0 : }
    1586             : 
    1587             : void
    1588           0 : pf_print_state(struct pf_state *s)
    1589             : {
    1590           0 :         pf_print_state_parts(s, NULL, NULL);
    1591           0 : }
    1592             : 
    1593             : void
    1594           0 : pf_print_state_parts(struct pf_state *s,
    1595             :     struct pf_state_key *skwp, struct pf_state_key *sksp)
    1596             : {
    1597             :         struct pf_state_key *skw, *sks;
    1598             :         u_int8_t proto, dir;
    1599             : 
    1600             :         /* Do our best to fill these, but they're skipped if NULL */
    1601           0 :         skw = skwp ? skwp : (s ? s->key[PF_SK_WIRE] : NULL);
    1602           0 :         sks = sksp ? sksp : (s ? s->key[PF_SK_STACK] : NULL);
    1603           0 :         proto = skw ? skw->proto : (sks ? sks->proto : 0);
    1604           0 :         dir = s ? s->direction : 0;
    1605             : 
    1606           0 :         switch (proto) {
    1607             :         case IPPROTO_IPV4:
    1608           0 :                 addlog("IPv4");
    1609           0 :                 break;
    1610             :         case IPPROTO_IPV6:
    1611           0 :                 addlog("IPv6");
    1612           0 :                 break;
    1613             :         case IPPROTO_TCP:
    1614           0 :                 addlog("TCP");
    1615           0 :                 break;
    1616             :         case IPPROTO_UDP:
    1617           0 :                 addlog("UDP");
    1618           0 :                 break;
    1619             :         case IPPROTO_ICMP:
    1620           0 :                 addlog("ICMP");
    1621           0 :                 break;
    1622             :         case IPPROTO_ICMPV6:
    1623           0 :                 addlog("ICMPv6");
    1624           0 :                 break;
    1625             :         default:
    1626           0 :                 addlog("%u", proto);
    1627           0 :                 break;
    1628             :         }
    1629           0 :         switch (dir) {
    1630             :         case PF_IN:
    1631           0 :                 addlog(" in");
    1632           0 :                 break;
    1633             :         case PF_OUT:
    1634           0 :                 addlog(" out");
    1635           0 :                 break;
    1636             :         }
    1637           0 :         if (skw) {
    1638           0 :                 addlog(" wire: (%d) ", skw->rdomain);
    1639           0 :                 pf_print_host(&skw->addr[0], skw->port[0], skw->af);
    1640           0 :                 addlog(" ");
    1641           0 :                 pf_print_host(&skw->addr[1], skw->port[1], skw->af);
    1642           0 :         }
    1643           0 :         if (sks) {
    1644           0 :                 addlog(" stack: (%d) ", sks->rdomain);
    1645           0 :                 if (sks != skw) {
    1646           0 :                         pf_print_host(&sks->addr[0], sks->port[0], sks->af);
    1647           0 :                         addlog(" ");
    1648           0 :                         pf_print_host(&sks->addr[1], sks->port[1], sks->af);
    1649           0 :                 } else
    1650           0 :                         addlog("-");
    1651             :         }
    1652           0 :         if (s) {
    1653           0 :                 if (proto == IPPROTO_TCP) {
    1654           0 :                         addlog(" [lo=%u high=%u win=%u modulator=%u",
    1655           0 :                             s->src.seqlo, s->src.seqhi,
    1656           0 :                             s->src.max_win, s->src.seqdiff);
    1657           0 :                         if (s->src.wscale && s->dst.wscale)
    1658           0 :                                 addlog(" wscale=%u",
    1659           0 :                                     s->src.wscale & PF_WSCALE_MASK);
    1660           0 :                         addlog("]");
    1661           0 :                         addlog(" [lo=%u high=%u win=%u modulator=%u",
    1662           0 :                             s->dst.seqlo, s->dst.seqhi,
    1663           0 :                             s->dst.max_win, s->dst.seqdiff);
    1664           0 :                         if (s->src.wscale && s->dst.wscale)
    1665           0 :                                 addlog(" wscale=%u",
    1666           0 :                                 s->dst.wscale & PF_WSCALE_MASK);
    1667           0 :                         addlog("]");
    1668           0 :                 }
    1669           0 :                 addlog(" %u:%u", s->src.state, s->dst.state);
    1670           0 :                 if (s->rule.ptr)
    1671           0 :                         addlog(" @%d", s->rule.ptr->nr);
    1672             :         }
    1673           0 : }
    1674             : 
    1675             : void
    1676           0 : pf_print_flags(u_int8_t f)
    1677             : {
    1678           0 :         if (f)
    1679           0 :                 addlog(" ");
    1680           0 :         if (f & TH_FIN)
    1681           0 :                 addlog("F");
    1682           0 :         if (f & TH_SYN)
    1683           0 :                 addlog("S");
    1684           0 :         if (f & TH_RST)
    1685           0 :                 addlog("R");
    1686           0 :         if (f & TH_PUSH)
    1687           0 :                 addlog("P");
    1688           0 :         if (f & TH_ACK)
    1689           0 :                 addlog("A");
    1690           0 :         if (f & TH_URG)
    1691           0 :                 addlog("U");
    1692           0 :         if (f & TH_ECE)
    1693           0 :                 addlog("E");
    1694           0 :         if (f & TH_CWR)
    1695           0 :                 addlog("W");
    1696           0 : }
    1697             : 
    1698             : #define PF_SET_SKIP_STEPS(i)                                    \
    1699             :         do {                                                    \
    1700             :                 while (head[i] != cur) {                        \
    1701             :                         head[i]->skip[i].ptr = cur;          \
    1702             :                         head[i] = TAILQ_NEXT(head[i], entries); \
    1703             :                 }                                               \
    1704             :         } while (0)
    1705             : 
    1706             : void
    1707           0 : pf_calc_skip_steps(struct pf_rulequeue *rules)
    1708             : {
    1709           0 :         struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT];
    1710             :         int i;
    1711             : 
    1712           0 :         cur = TAILQ_FIRST(rules);
    1713             :         prev = cur;
    1714           0 :         for (i = 0; i < PF_SKIP_COUNT; ++i)
    1715           0 :                 head[i] = cur;
    1716           0 :         while (cur != NULL) {
    1717           0 :                 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
    1718           0 :                         PF_SET_SKIP_STEPS(PF_SKIP_IFP);
    1719           0 :                 if (cur->direction != prev->direction)
    1720           0 :                         PF_SET_SKIP_STEPS(PF_SKIP_DIR);
    1721           0 :                 if (cur->onrdomain != prev->onrdomain ||
    1722           0 :                     cur->ifnot != prev->ifnot)
    1723           0 :                         PF_SET_SKIP_STEPS(PF_SKIP_RDOM);
    1724           0 :                 if (cur->af != prev->af)
    1725           0 :                         PF_SET_SKIP_STEPS(PF_SKIP_AF);
    1726           0 :                 if (cur->proto != prev->proto)
    1727           0 :                         PF_SET_SKIP_STEPS(PF_SKIP_PROTO);
    1728           0 :                 if (cur->src.neg != prev->src.neg ||
    1729           0 :                     pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr))
    1730           0 :                         PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR);
    1731           0 :                 if (cur->dst.neg != prev->dst.neg ||
    1732           0 :                     pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
    1733           0 :                         PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
    1734           0 :                 if (cur->src.port[0] != prev->src.port[0] ||
    1735           0 :                     cur->src.port[1] != prev->src.port[1] ||
    1736           0 :                     cur->src.port_op != prev->src.port_op)
    1737           0 :                         PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
    1738           0 :                 if (cur->dst.port[0] != prev->dst.port[0] ||
    1739           0 :                     cur->dst.port[1] != prev->dst.port[1] ||
    1740           0 :                     cur->dst.port_op != prev->dst.port_op)
    1741           0 :                         PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
    1742             : 
    1743             :                 prev = cur;
    1744           0 :                 cur = TAILQ_NEXT(cur, entries);
    1745             :         }
    1746           0 :         for (i = 0; i < PF_SKIP_COUNT; ++i)
    1747           0 :                 PF_SET_SKIP_STEPS(i);
    1748           0 : }
    1749             : 
    1750             : int
    1751           0 : pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
    1752             : {
    1753           0 :         if (aw1->type != aw2->type)
    1754           0 :                 return (1);
    1755           0 :         switch (aw1->type) {
    1756             :         case PF_ADDR_ADDRMASK:
    1757             :         case PF_ADDR_RANGE:
    1758           0 :                 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, AF_INET6))
    1759           0 :                         return (1);
    1760           0 :                 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, AF_INET6))
    1761           0 :                         return (1);
    1762           0 :                 return (0);
    1763             :         case PF_ADDR_DYNIFTL:
    1764           0 :                 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
    1765             :         case PF_ADDR_NONE:
    1766             :         case PF_ADDR_NOROUTE:
    1767             :         case PF_ADDR_URPFFAILED:
    1768           0 :                 return (0);
    1769             :         case PF_ADDR_TABLE:
    1770           0 :                 return (aw1->p.tbl != aw2->p.tbl);
    1771             :         case PF_ADDR_RTLABEL:
    1772           0 :                 return (aw1->v.rtlabel != aw2->v.rtlabel);
    1773             :         default:
    1774           0 :                 addlog("invalid address type: %d\n", aw1->type);
    1775           0 :                 return (1);
    1776             :         }
    1777           0 : }
    1778             : 
    1779             : /* This algorithm computes 'a + b - c' in ones-complement using a trick to
    1780             :  * emulate at most one ones-complement subtraction. This thereby limits net
    1781             :  * carries/borrows to at most one, eliminating a reduction step and saving one
    1782             :  * each of +, >>, & and ~.
    1783             :  *
    1784             :  * def. x mod y = x - (x//y)*y for integer x,y
    1785             :  * def. sum = x mod 2^16
    1786             :  * def. accumulator = (x >> 16) mod 2^16
    1787             :  *
    1788             :  * The trick works as follows: subtracting exactly one u_int16_t from the
    1789             :  * u_int32_t x incurs at most one underflow, wrapping its upper 16-bits, the
    1790             :  * accumulator, to 2^16 - 1. Adding this to the 16-bit sum preserves the
    1791             :  * ones-complement borrow:
    1792             :  *
    1793             :  *  (sum + accumulator) mod 2^16
    1794             :  * =    { assume underflow: accumulator := 2^16 - 1 }
    1795             :  *  (sum + 2^16 - 1) mod 2^16
    1796             :  * =    { mod }
    1797             :  *  (sum - 1) mod 2^16
    1798             :  *
    1799             :  * Although this breaks for sum = 0, giving 0xffff, which is ones-complement's
    1800             :  * other zero, not -1, that cannot occur: the 16-bit sum cannot be underflown
    1801             :  * to zero as that requires subtraction of at least 2^16, which exceeds a
    1802             :  * single u_int16_t's range.
    1803             :  *
    1804             :  * We use the following theorem to derive the implementation:
    1805             :  *
    1806             :  * th. (x + (y mod z)) mod z  =  (x + y) mod z   (0)
    1807             :  * proof.
    1808             :  *     (x + (y mod z)) mod z
    1809             :  *    =  { def mod }
    1810             :  *     (x + y - (y//z)*z) mod z
    1811             :  *    =  { (a + b*c) mod c = a mod c }
    1812             :  *     (x + y) mod z                    [end of proof]
    1813             :  *
    1814             :  * ... and thereby obtain:
    1815             :  *
    1816             :  *  (sum + accumulator) mod 2^16
    1817             :  * =    { def. accumulator, def. sum }
    1818             :  *  (x mod 2^16 + (x >> 16) mod 2^16) mod 2^16
    1819             :  * =    { (0), twice }
    1820             :  *  (x + (x >> 16)) mod 2^16
    1821             :  * =    { x mod 2^n = x & (2^n - 1) }
    1822             :  *  (x + (x >> 16)) & 0xffff
    1823             :  *
    1824             :  * Note: this serves also as a reduction step for at most one add (as the
    1825             :  * trailing mod 2^16 prevents further reductions by destroying carries).
    1826             :  */
    1827             : static __inline void
    1828           0 : pf_cksum_fixup(u_int16_t *cksum, u_int16_t was, u_int16_t now,
    1829             :     u_int8_t proto)
    1830             : {
    1831             :         u_int32_t x;
    1832           0 :         const int udp = proto == IPPROTO_UDP;
    1833             : 
    1834           0 :         x = *cksum + was - now;
    1835           0 :         x = (x + (x >> 16)) & 0xffff;
    1836             : 
    1837             :         /* optimise: eliminate a branch when not udp */
    1838           0 :         if (udp && *cksum == 0x0000)
    1839           0 :                 return;
    1840           0 :         if (udp && x == 0x0000)
    1841           0 :                 x = 0xffff;
    1842             : 
    1843           0 :         *cksum = (u_int16_t)(x);
    1844           0 : }
    1845             : 
    1846             : #ifdef INET6
    1847             : /* pre: coverage(cksum) is superset of coverage(covered_cksum) */
    1848             : static __inline void
    1849           0 : pf_cksum_uncover(u_int16_t *cksum, u_int16_t covered_cksum, u_int8_t proto)
    1850             : {
    1851           0 :         pf_cksum_fixup(cksum, ~covered_cksum, 0x0, proto);
    1852           0 : }
    1853             : 
    1854             : /* pre: disjoint(coverage(cksum), coverage(uncovered_cksum)) */
    1855             : static __inline void
    1856           0 : pf_cksum_cover(u_int16_t *cksum, u_int16_t uncovered_cksum, u_int8_t proto)
    1857             : {
    1858           0 :         pf_cksum_fixup(cksum, 0x0, ~uncovered_cksum, proto);
    1859           0 : }
    1860             : #endif /* INET6 */
    1861             : 
    1862             : /* pre: *a is 16-bit aligned within its packet
    1863             :  *
    1864             :  * This algorithm emulates 16-bit ones-complement sums on a twos-complement
    1865             :  * machine by conserving ones-complement's otherwise discarded carries in the
    1866             :  * upper bits of x. These accumulated carries when added to the lower 16-bits
    1867             :  * over at least zero 'reduction' steps then complete the ones-complement sum.
    1868             :  *
    1869             :  * def. sum = x mod 2^16
    1870             :  * def. accumulator = (x >> 16)
    1871             :  *
    1872             :  * At most two reduction steps
    1873             :  *
    1874             :  *   x := sum + accumulator
    1875             :  * =    { def sum, def accumulator }
    1876             :  *   x := x mod 2^16 + (x >> 16)
    1877             :  * =    { x mod 2^n = x & (2^n - 1) }
    1878             :  *   x := (x & 0xffff) + (x >> 16)
    1879             :  *
    1880             :  * are necessary to incorporate the accumulated carries (at most one per add)
    1881             :  * i.e. to reduce x < 2^16 from at most 16 carries in the upper 16 bits.
    1882             :  *
    1883             :  * The function is also invariant over the endian of the host. Why?
    1884             :  *
    1885             :  * Define the unary transpose operator ~ on a bitstring in python slice
    1886             :  * notation as lambda m: m[P:] + m[:P] , for some constant pivot P.
    1887             :  *
    1888             :  * th. ~ distributes over ones-complement addition, denoted by +_1, i.e.
    1889             :  *
    1890             :  *     ~m +_1 ~n  =  ~(m +_1 n)    (for all bitstrings m,n of equal length)
    1891             :  *
    1892             :  * proof. Regard the bitstrings in m +_1 n as split at P, forming at most two
    1893             :  * 'half-adds'. Under ones-complement addition, each half-add carries to the
    1894             :  * other, so the sum of each half-add is unaffected by their relative
    1895             :  * order. Therefore:
    1896             :  *
    1897             :  *     ~m +_1 ~n
    1898             :  *   =    { half-adds invariant under transposition }
    1899             :  *     ~s
    1900             :  *   =    { substitute }
    1901             :  *     ~(m +_1 n)                   [end of proof]
    1902             :  *
    1903             :  * th. Summing two in-memory ones-complement 16-bit variables m,n on a machine
    1904             :  * with the converse endian does not alter the result.
    1905             :  *
    1906             :  * proof.
    1907             :  *        { converse machine endian: load/store transposes, P := 8 }
    1908             :  *     ~(~m +_1 ~n)
    1909             :  *   =    { ~ over +_1 }
    1910             :  *     ~~m +_1 ~~n
    1911             :  *   =    { ~ is an involution }
    1912             :  *      m +_1 n                     [end of proof]
    1913             :  *
    1914             :  */
    1915             : #define NEG(x) ((u_int16_t)~(x))
    1916             : void
    1917           0 : pf_cksum_fixup_a(u_int16_t *cksum, const struct pf_addr *a,
    1918             :     const struct pf_addr *an, sa_family_t af, u_int8_t proto)
    1919             : {
    1920             :         u_int32_t        x;
    1921           0 :         const u_int16_t *n = an->addr16;
    1922           0 :         const u_int16_t *o = a->addr16;
    1923           0 :         const int        udp = proto == IPPROTO_UDP;
    1924             : 
    1925           0 :         switch (af) {
    1926             :         case AF_INET:
    1927           0 :                 x = *cksum + o[0] + NEG(n[0]) + o[1] + NEG(n[1]);
    1928           0 :                 break;
    1929             : #ifdef INET6
    1930             :         case AF_INET6:
    1931           0 :                 x = *cksum + o[0] + NEG(n[0]) + o[1] + NEG(n[1]) +\
    1932           0 :                              o[2] + NEG(n[2]) + o[3] + NEG(n[3]) +\
    1933           0 :                              o[4] + NEG(n[4]) + o[5] + NEG(n[5]) +\
    1934           0 :                              o[6] + NEG(n[6]) + o[7] + NEG(n[7]);
    1935           0 :                 break;
    1936             : #endif /* INET6 */
    1937             :         default:
    1938           0 :                 unhandled_af(af);
    1939             :         }
    1940             : 
    1941           0 :         x = (x & 0xffff) + (x >> 16);
    1942           0 :         x = (x & 0xffff) + (x >> 16);
    1943             : 
    1944             :         /* optimise: eliminate a branch when not udp */
    1945           0 :         if (udp && *cksum == 0x0000)
    1946           0 :                 return;
    1947           0 :         if (udp && x == 0x0000)
    1948           0 :                 x = 0xffff;
    1949             : 
    1950           0 :         *cksum = (u_int16_t)(x);
    1951           0 : }
    1952             : 
    1953             : int
    1954           0 : pf_patch_8(struct pf_pdesc *pd, u_int8_t *f, u_int8_t v, bool hi)
    1955             : {
    1956             :         int     rewrite = 0;
    1957             : 
    1958           0 :         if (*f != v) {
    1959           0 :                 u_int16_t old = htons(hi ? (*f << 8) : *f);
    1960           0 :                 u_int16_t new = htons(hi ? ( v << 8) :  v);
    1961             : 
    1962           0 :                 pf_cksum_fixup(pd->pcksum, old, new, pd->proto);
    1963           0 :                 *f = v;
    1964             :                 rewrite = 1;
    1965           0 :         }
    1966             : 
    1967           0 :         return (rewrite);
    1968             : }
    1969             : 
    1970             : /* pre: *f is 16-bit aligned within its packet */
    1971             : int
    1972           0 : pf_patch_16(struct pf_pdesc *pd, u_int16_t *f, u_int16_t v)
    1973             : {
    1974             :         int     rewrite = 0;
    1975             : 
    1976           0 :         if (*f != v) {
    1977           0 :                 pf_cksum_fixup(pd->pcksum, *f, v, pd->proto);
    1978           0 :                 *f = v;
    1979             :                 rewrite = 1;
    1980           0 :         }
    1981             : 
    1982           0 :         return (rewrite);
    1983             : }
    1984             : 
    1985             : int
    1986           0 : pf_patch_16_unaligned(struct pf_pdesc *pd, void *f, u_int16_t v, bool hi)
    1987             : {
    1988             :         int             rewrite = 0;
    1989             :         u_int8_t       *fb = (u_int8_t*)f;
    1990             :         u_int8_t       *vb = (u_int8_t*)&v;
    1991             : 
    1992           0 :         if (hi && ALIGNED_POINTER(f, u_int16_t)) {
    1993           0 :                 return (pf_patch_16(pd, f, v)); /* optimise */
    1994             :         }
    1995             : 
    1996           0 :         rewrite += pf_patch_8(pd, fb++, *vb++, hi);
    1997           0 :         rewrite += pf_patch_8(pd, fb++, *vb++,!hi);
    1998             : 
    1999           0 :         return (rewrite);
    2000           0 : }
    2001             : 
    2002             : /* pre: *f is 16-bit aligned within its packet */
    2003             : /* pre: pd->proto != IPPROTO_UDP */
    2004             : int
    2005           0 : pf_patch_32(struct pf_pdesc *pd, u_int32_t *f, u_int32_t v)
    2006             : {
    2007             :         int             rewrite = 0;
    2008           0 :         u_int16_t      *pc = pd->pcksum;
    2009           0 :         u_int8_t        proto = pd->proto;
    2010             : 
    2011             :         /* optimise: inline udp fixup code is unused; let compiler scrub it */
    2012           0 :         if (proto == IPPROTO_UDP)
    2013           0 :                 panic("%s: udp", __func__);
    2014             : 
    2015             :         /* optimise: skip *f != v guard; true for all use-cases */
    2016           0 :         pf_cksum_fixup(pc, *f / (1 << 16), v / (1 << 16), proto);
    2017           0 :         pf_cksum_fixup(pc, *f % (1 << 16), v % (1 << 16), proto);
    2018             : 
    2019           0 :         *f = v;
    2020             :         rewrite = 1;
    2021             : 
    2022           0 :         return (rewrite);
    2023             : }
    2024             : 
    2025             : int
    2026           0 : pf_patch_32_unaligned(struct pf_pdesc *pd, void *f, u_int32_t v, bool hi)
    2027             : {
    2028             :         int             rewrite = 0;
    2029             :         u_int8_t       *fb = (u_int8_t*)f;
    2030             :         u_int8_t       *vb = (u_int8_t*)&v;
    2031             : 
    2032           0 :         if (hi && ALIGNED_POINTER(f, u_int32_t)) {
    2033           0 :                 return (pf_patch_32(pd, f, v)); /* optimise */
    2034             :         }
    2035             : 
    2036           0 :         rewrite += pf_patch_8(pd, fb++, *vb++, hi);
    2037           0 :         rewrite += pf_patch_8(pd, fb++, *vb++,!hi);
    2038           0 :         rewrite += pf_patch_8(pd, fb++, *vb++, hi);
    2039           0 :         rewrite += pf_patch_8(pd, fb++, *vb++,!hi);
    2040             : 
    2041           0 :         return (rewrite);
    2042           0 : }
    2043             : 
    2044             : int
    2045           0 : pf_icmp_mapping(struct pf_pdesc *pd, u_int8_t type, int *icmp_dir,
    2046             :     u_int16_t *virtual_id, u_int16_t *virtual_type)
    2047             : {
    2048             :         /*
    2049             :          * ICMP types marked with PF_OUT are typically responses to
    2050             :          * PF_IN, and will match states in the opposite direction.
    2051             :          * PF_IN ICMP types need to match a state with that type.
    2052             :          */
    2053           0 :         *icmp_dir = PF_OUT;
    2054             : 
    2055             :         /* Queries (and responses) */
    2056           0 :         switch (pd->af) {
    2057             :         case AF_INET:
    2058           0 :                 switch (type) {
    2059             :                 case ICMP_ECHO:
    2060           0 :                         *icmp_dir = PF_IN;
    2061             :                         /* FALLTHROUGH */
    2062             :                 case ICMP_ECHOREPLY:
    2063           0 :                         *virtual_type = ICMP_ECHO;
    2064           0 :                         *virtual_id = pd->hdr.icmp.icmp_id;
    2065           0 :                         break;
    2066             : 
    2067             :                 case ICMP_TSTAMP:
    2068           0 :                         *icmp_dir = PF_IN;
    2069             :                         /* FALLTHROUGH */
    2070             :                 case ICMP_TSTAMPREPLY:
    2071           0 :                         *virtual_type = ICMP_TSTAMP;
    2072           0 :                         *virtual_id = pd->hdr.icmp.icmp_id;
    2073           0 :                         break;
    2074             : 
    2075             :                 case ICMP_IREQ:
    2076           0 :                         *icmp_dir = PF_IN;
    2077             :                         /* FALLTHROUGH */
    2078             :                 case ICMP_IREQREPLY:
    2079           0 :                         *virtual_type = ICMP_IREQ;
    2080           0 :                         *virtual_id = pd->hdr.icmp.icmp_id;
    2081           0 :                         break;
    2082             : 
    2083             :                 case ICMP_MASKREQ:
    2084           0 :                         *icmp_dir = PF_IN;
    2085             :                         /* FALLTHROUGH */
    2086             :                 case ICMP_MASKREPLY:
    2087           0 :                         *virtual_type = ICMP_MASKREQ;
    2088           0 :                         *virtual_id = pd->hdr.icmp.icmp_id;
    2089           0 :                         break;
    2090             : 
    2091             :                 case ICMP_IPV6_WHEREAREYOU:
    2092           0 :                         *icmp_dir = PF_IN;
    2093             :                         /* FALLTHROUGH */
    2094             :                 case ICMP_IPV6_IAMHERE:
    2095           0 :                         *virtual_type = ICMP_IPV6_WHEREAREYOU;
    2096           0 :                         *virtual_id = 0; /* Nothing sane to match on! */
    2097           0 :                         break;
    2098             : 
    2099             :                 case ICMP_MOBILE_REGREQUEST:
    2100           0 :                         *icmp_dir = PF_IN;
    2101             :                         /* FALLTHROUGH */
    2102             :                 case ICMP_MOBILE_REGREPLY:
    2103           0 :                         *virtual_type = ICMP_MOBILE_REGREQUEST;
    2104           0 :                         *virtual_id = 0; /* Nothing sane to match on! */
    2105           0 :                         break;
    2106             : 
    2107             :                 case ICMP_ROUTERSOLICIT:
    2108           0 :                         *icmp_dir = PF_IN;
    2109             :                         /* FALLTHROUGH */
    2110             :                 case ICMP_ROUTERADVERT:
    2111           0 :                         *virtual_type = ICMP_ROUTERSOLICIT;
    2112           0 :                         *virtual_id = 0; /* Nothing sane to match on! */
    2113           0 :                         break;
    2114             : 
    2115             :                 /* These ICMP types map to other connections */
    2116             :                 case ICMP_UNREACH:
    2117             :                 case ICMP_SOURCEQUENCH:
    2118             :                 case ICMP_REDIRECT:
    2119             :                 case ICMP_TIMXCEED:
    2120             :                 case ICMP_PARAMPROB:
    2121             :                         /* These will not be used, but set them anyway */
    2122           0 :                         *icmp_dir = PF_IN;
    2123           0 :                         *virtual_type = htons(type);
    2124           0 :                         *virtual_id = 0;
    2125           0 :                         return (1);  /* These types match to another state */
    2126             : 
    2127             :                 /*
    2128             :                  * All remaining ICMP types get their own states,
    2129             :                  * and will only match in one direction.
    2130             :                  */
    2131             :                 default:
    2132           0 :                         *icmp_dir = PF_IN;
    2133           0 :                         *virtual_type = type;
    2134           0 :                         *virtual_id = 0;
    2135           0 :                         break;
    2136             :                 }
    2137             :                 break;
    2138             : #ifdef INET6
    2139             :         case AF_INET6:
    2140           0 :                 switch (type) {
    2141             :                 case ICMP6_ECHO_REQUEST:
    2142           0 :                         *icmp_dir = PF_IN;
    2143             :                         /* FALLTHROUGH */
    2144             :                 case ICMP6_ECHO_REPLY:
    2145           0 :                         *virtual_type = ICMP6_ECHO_REQUEST;
    2146           0 :                         *virtual_id = pd->hdr.icmp6.icmp6_id;
    2147           0 :                         break;
    2148             : 
    2149             :                 case MLD_LISTENER_QUERY:
    2150             :                 case MLD_LISTENER_REPORT: {
    2151           0 :                         struct mld_hdr *mld = &pd->hdr.mld;
    2152             :                         u_int32_t h;
    2153             : 
    2154             :                         /*
    2155             :                          * Listener Report can be sent by clients
    2156             :                          * without an associated Listener Query.
    2157             :                          * In addition to that, when Report is sent as a
    2158             :                          * reply to a Query its source and destination
    2159             :                          * address are different.
    2160             :                          */
    2161           0 :                         *icmp_dir = PF_IN;
    2162           0 :                         *virtual_type = MLD_LISTENER_QUERY;
    2163             :                         /* generate fake id for these messages */
    2164           0 :                         h = mld->mld_addr.s6_addr32[0] ^
    2165           0 :                             mld->mld_addr.s6_addr32[1] ^
    2166           0 :                             mld->mld_addr.s6_addr32[2] ^
    2167           0 :                             mld->mld_addr.s6_addr32[3];
    2168           0 :                         *virtual_id = (h >> 16) ^ (h & 0xffff);
    2169             :                         break;
    2170             :                 }
    2171             : 
    2172             :                 /*
    2173             :                  * ICMP6_FQDN and ICMP6_NI query/reply are the same type as
    2174             :                  * ICMP6_WRU
    2175             :                  */
    2176             :                 case ICMP6_WRUREQUEST:
    2177           0 :                         *icmp_dir = PF_IN;
    2178             :                         /* FALLTHROUGH */
    2179             :                 case ICMP6_WRUREPLY:
    2180           0 :                         *virtual_type = ICMP6_WRUREQUEST;
    2181           0 :                         *virtual_id = 0; /* Nothing sane to match on! */
    2182           0 :                         break;
    2183             : 
    2184             :                 case MLD_MTRACE:
    2185           0 :                         *icmp_dir = PF_IN;
    2186             :                         /* FALLTHROUGH */
    2187             :                 case MLD_MTRACE_RESP:
    2188           0 :                         *virtual_type = MLD_MTRACE;
    2189           0 :                         *virtual_id = 0; /* Nothing sane to match on! */
    2190           0 :                         break;
    2191             : 
    2192             :                 case ND_NEIGHBOR_SOLICIT:
    2193           0 :                         *icmp_dir = PF_IN;
    2194             :                         /* FALLTHROUGH */
    2195             :                 case ND_NEIGHBOR_ADVERT: {
    2196           0 :                         struct nd_neighbor_solicit *nd = &pd->hdr.nd_ns;
    2197             :                         u_int32_t h;
    2198             : 
    2199           0 :                         *virtual_type = ND_NEIGHBOR_SOLICIT;
    2200             :                         /* generate fake id for these messages */
    2201           0 :                         h = nd->nd_ns_target.s6_addr32[0] ^
    2202           0 :                             nd->nd_ns_target.s6_addr32[1] ^
    2203           0 :                             nd->nd_ns_target.s6_addr32[2] ^
    2204           0 :                             nd->nd_ns_target.s6_addr32[3];
    2205           0 :                         *virtual_id = (h >> 16) ^ (h & 0xffff);
    2206             :                         break;
    2207             :                 }
    2208             : 
    2209             :                 /*
    2210             :                  * These ICMP types map to other connections.
    2211             :                  * ND_REDIRECT can't be in this list because the triggering
    2212             :                  * packet header is optional.
    2213             :                  */
    2214             :                 case ICMP6_DST_UNREACH:
    2215             :                 case ICMP6_PACKET_TOO_BIG:
    2216             :                 case ICMP6_TIME_EXCEEDED:
    2217             :                 case ICMP6_PARAM_PROB:
    2218             :                         /* These will not be used, but set them anyway */
    2219           0 :                         *icmp_dir = PF_IN;
    2220           0 :                         *virtual_type = htons(type);
    2221           0 :                         *virtual_id = 0;
    2222           0 :                         return (1);  /* These types match to another state */
    2223             :                 /*
    2224             :                  * All remaining ICMP6 types get their own states,
    2225             :                  * and will only match in one direction.
    2226             :                  */
    2227             :                 default:
    2228           0 :                         *icmp_dir = PF_IN;
    2229           0 :                         *virtual_type = type;
    2230           0 :                         *virtual_id = 0;
    2231           0 :                         break;
    2232             :                 }
    2233             :                 break;
    2234             : #endif /* INET6 */
    2235             :         }
    2236           0 :         *virtual_type = htons(*virtual_type);
    2237           0 :         return (0);  /* These types match to their own state */
    2238           0 : }
    2239             : 
    2240             : void
    2241           0 : pf_translate_icmp(struct pf_pdesc *pd, struct pf_addr *qa, u_int16_t *qp,
    2242             :     struct pf_addr *oa, struct pf_addr *na, u_int16_t np)
    2243             : {
    2244             :         /* note: doesn't trouble to fixup quoted checksums, if any */
    2245             : 
    2246             :         /* change quoted protocol port */
    2247           0 :         if (qp != NULL)
    2248           0 :                 pf_patch_16(pd, qp, np);
    2249             : 
    2250             :         /* change quoted ip address */
    2251           0 :         pf_cksum_fixup_a(pd->pcksum, qa, na, pd->af, pd->proto);
    2252           0 :         PF_ACPY(qa, na, pd->af);
    2253             : 
    2254             :         /* change network-header's ip address */
    2255           0 :         if (oa)
    2256           0 :                 pf_translate_a(pd, oa, na);
    2257           0 : }
    2258             : 
    2259             : /* pre: *a is 16-bit aligned within its packet */
    2260             : /*      *a is a network header src/dst address */
    2261             : int
    2262           0 : pf_translate_a(struct pf_pdesc *pd, struct pf_addr *a, struct pf_addr *an)
    2263             : {
    2264             :         int     rewrite = 0;
    2265             : 
    2266             :         /* warning: !PF_ANEQ != PF_AEQ */
    2267           0 :         if (!PF_ANEQ(a, an, pd->af))
    2268           0 :                 return (0);
    2269             : 
    2270             :         /* fixup transport pseudo-header, if any */
    2271           0 :         switch (pd->proto) {
    2272             :         case IPPROTO_TCP:       /* FALLTHROUGH */
    2273             :         case IPPROTO_UDP:       /* FALLTHROUGH */
    2274             :         case IPPROTO_ICMPV6:
    2275           0 :                 pf_cksum_fixup_a(pd->pcksum, a, an, pd->af, pd->proto);
    2276           0 :                 break;
    2277             :         default:
    2278             :                 break;  /* assume no pseudo-header */
    2279             :         }
    2280             : 
    2281           0 :         PF_ACPY(a, an, pd->af);
    2282             :         rewrite = 1;
    2283             : 
    2284           0 :         return (rewrite);
    2285           0 : }
    2286             : 
    2287             : #if INET6
    2288             : /* pf_translate_af() may change pd->m, adjust local copies after calling */
    2289             : int
    2290           0 : pf_translate_af(struct pf_pdesc *pd)
    2291             : {
    2292             :         static const struct pf_addr     zero;
    2293             :         struct ip                      *ip4;
    2294             :         struct ip6_hdr                 *ip6;
    2295             :         int                             copyback = 0;
    2296             :         u_int                           hlen, ohlen, dlen;
    2297             :         u_int16_t                      *pc;
    2298             :         u_int8_t                        af_proto, naf_proto;
    2299             : 
    2300           0 :         hlen = (pd->naf == AF_INET) ? sizeof(*ip4) : sizeof(*ip6);
    2301           0 :         ohlen = pd->off;
    2302           0 :         dlen = pd->tot_len - pd->off;
    2303           0 :         pc = pd->pcksum;
    2304             : 
    2305           0 :         af_proto = naf_proto = pd->proto;
    2306           0 :         if (naf_proto == IPPROTO_ICMP)
    2307             :                 af_proto = IPPROTO_ICMPV6;
    2308           0 :         if (naf_proto == IPPROTO_ICMPV6)
    2309             :                 af_proto = IPPROTO_ICMP;
    2310             : 
    2311             :         /* uncover stale pseudo-header */
    2312           0 :         switch (af_proto) {
    2313             :         case IPPROTO_ICMPV6:
    2314             :                 /* optimise: unchanged for TCP/UDP */
    2315           0 :                 pf_cksum_fixup(pc, htons(af_proto), 0x0, af_proto);
    2316           0 :                 pf_cksum_fixup(pc, htons(dlen),     0x0, af_proto);
    2317             :                                 /* FALLTHROUGH */
    2318             :         case IPPROTO_UDP:       /* FALLTHROUGH */
    2319             :         case IPPROTO_TCP:
    2320           0 :                 pf_cksum_fixup_a(pc, pd->src, &zero, pd->af, af_proto);
    2321           0 :                 pf_cksum_fixup_a(pc, pd->dst, &zero, pd->af, af_proto);
    2322             :                 copyback = 1;
    2323           0 :                 break;
    2324             :         default:
    2325             :                 break;  /* assume no pseudo-header */
    2326             :         }
    2327             : 
    2328             :         /* replace the network header */
    2329           0 :         m_adj(pd->m, pd->off);
    2330           0 :         pd->src = NULL;
    2331           0 :         pd->dst = NULL;
    2332             : 
    2333           0 :         if ((M_PREPEND(pd->m, hlen, M_DONTWAIT)) == NULL) {
    2334           0 :                 pd->m = NULL;
    2335           0 :                 return (-1);
    2336             :         }
    2337             : 
    2338           0 :         pd->off = hlen;
    2339           0 :         pd->tot_len += hlen - ohlen;
    2340             : 
    2341           0 :         switch (pd->naf) {
    2342             :         case AF_INET:
    2343           0 :                 ip4 = mtod(pd->m, struct ip *);
    2344           0 :                 memset(ip4, 0, hlen);
    2345           0 :                 ip4->ip_v   = IPVERSION;
    2346           0 :                 ip4->ip_hl  = hlen >> 2;
    2347           0 :                 ip4->ip_tos = pd->tos;
    2348           0 :                 ip4->ip_len = htons(hlen + dlen);
    2349           0 :                 ip4->ip_id  = htons(ip_randomid());
    2350           0 :                 ip4->ip_off = htons(IP_DF);
    2351           0 :                 ip4->ip_ttl = pd->ttl;
    2352           0 :                 ip4->ip_p   = pd->proto;
    2353           0 :                 ip4->ip_src = pd->nsaddr.v4;
    2354           0 :                 ip4->ip_dst = pd->ndaddr.v4;
    2355           0 :                 break;
    2356             :         case AF_INET6:
    2357           0 :                 ip6 = mtod(pd->m, struct ip6_hdr *);
    2358           0 :                 memset(ip6, 0, hlen);
    2359           0 :                 ip6->ip6_vfc  = IPV6_VERSION;
    2360           0 :                 ip6->ip6_flow |= htonl((u_int32_t)pd->tos << 20);
    2361           0 :                 ip6->ip6_plen = htons(dlen);
    2362           0 :                 ip6->ip6_nxt  = pd->proto;
    2363           0 :                 if (!pd->ttl || pd->ttl > IPV6_DEFHLIM)
    2364           0 :                         ip6->ip6_hlim = IPV6_DEFHLIM;
    2365             :                 else
    2366           0 :                         ip6->ip6_hlim = pd->ttl;
    2367           0 :                 ip6->ip6_src  = pd->nsaddr.v6;
    2368           0 :                 ip6->ip6_dst  = pd->ndaddr.v6;
    2369           0 :                 break;
    2370             :         default:
    2371           0 :                 unhandled_af(pd->naf);
    2372             :         }
    2373             : 
    2374             :         /* UDP over IPv6 must be checksummed per rfc2460 p27 */
    2375           0 :         if (naf_proto == IPPROTO_UDP && *pc == 0x0000 &&
    2376           0 :             pd->naf == AF_INET6) {
    2377           0 :                 pd->m->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
    2378           0 :         }
    2379             : 
    2380             :         /* cover fresh pseudo-header */
    2381           0 :         switch (naf_proto) {
    2382             :         case IPPROTO_ICMPV6:
    2383             :                 /* optimise: unchanged for TCP/UDP */
    2384           0 :                 pf_cksum_fixup(pc, 0x0, htons(naf_proto), naf_proto);
    2385           0 :                 pf_cksum_fixup(pc, 0x0, htons(dlen),      naf_proto);
    2386             :                                 /* FALLTHROUGH */
    2387             :         case IPPROTO_UDP:       /* FALLTHROUGH */
    2388             :         case IPPROTO_TCP:
    2389           0 :                 pf_cksum_fixup_a(pc, &zero, &pd->nsaddr, pd->naf, naf_proto);
    2390           0 :                 pf_cksum_fixup_a(pc, &zero, &pd->ndaddr, pd->naf, naf_proto);
    2391             :                 copyback = 1;
    2392           0 :                 break;
    2393             :         default:
    2394             :                 break;  /* assume no pseudo-header */
    2395             :         }
    2396             : 
    2397             :         /* flush pd->pcksum */
    2398           0 :         if (copyback)
    2399           0 :                 m_copyback(pd->m, pd->off, pd->hdrlen, &pd->hdr, M_NOWAIT);
    2400             : 
    2401           0 :         return (0);
    2402           0 : }
    2403             : 
    2404             : int
    2405           0 : pf_change_icmp_af(struct mbuf *m, int ipoff2, struct pf_pdesc *pd,
    2406             :     struct pf_pdesc *pd2, struct pf_addr *src, struct pf_addr *dst,
    2407             :     sa_family_t af, sa_family_t naf)
    2408             : {
    2409             :         struct mbuf             *n = NULL;
    2410             :         struct ip               *ip4;
    2411             :         struct ip6_hdr          *ip6;
    2412             :         u_int                    hlen, ohlen, dlen;
    2413             :         int                      d;
    2414             : 
    2415           0 :         if (af == naf || (af != AF_INET && af != AF_INET6) ||
    2416           0 :             (naf != AF_INET && naf != AF_INET6))
    2417           0 :                 return (-1);
    2418             : 
    2419             :         /* split the mbuf chain on the quoted ip/ip6 header boundary */
    2420           0 :         if ((n = m_split(m, ipoff2, M_DONTWAIT)) == NULL)
    2421           0 :                 return (-1);
    2422             : 
    2423             :         /* new quoted header */
    2424           0 :         hlen = naf == AF_INET ? sizeof(*ip4) : sizeof(*ip6);
    2425             :         /* old quoted header */
    2426           0 :         ohlen = pd2->off - ipoff2;
    2427             : 
    2428             :         /* trim old quoted header */
    2429           0 :         pf_cksum_uncover(pd->pcksum, in_cksum(n, ohlen), pd->proto);
    2430           0 :         m_adj(n, ohlen);
    2431             : 
    2432             :         /* prepend a new, translated, quoted header */
    2433           0 :         if ((M_PREPEND(n, hlen, M_DONTWAIT)) == NULL)
    2434           0 :                 return (-1);
    2435             : 
    2436           0 :         switch (naf) {
    2437             :         case AF_INET:
    2438           0 :                 ip4 = mtod(n, struct ip *);
    2439           0 :                 memset(ip4, 0, sizeof(*ip4));
    2440           0 :                 ip4->ip_v   = IPVERSION;
    2441           0 :                 ip4->ip_hl  = sizeof(*ip4) >> 2;
    2442           0 :                 ip4->ip_len = htons(sizeof(*ip4) + pd2->tot_len - ohlen);
    2443           0 :                 ip4->ip_id  = htons(ip_randomid());
    2444           0 :                 ip4->ip_off = htons(IP_DF);
    2445           0 :                 ip4->ip_ttl = pd2->ttl;
    2446           0 :                 if (pd2->proto == IPPROTO_ICMPV6)
    2447           0 :                         ip4->ip_p = IPPROTO_ICMP;
    2448             :                 else
    2449           0 :                         ip4->ip_p = pd2->proto;
    2450           0 :                 ip4->ip_src = src->v4;
    2451           0 :                 ip4->ip_dst = dst->v4;
    2452           0 :                 ip4->ip_sum = in_cksum(n, ip4->ip_hl << 2);
    2453           0 :                 break;
    2454             :         case AF_INET6:
    2455           0 :                 ip6 = mtod(n, struct ip6_hdr *);
    2456           0 :                 memset(ip6, 0, sizeof(*ip6));
    2457           0 :                 ip6->ip6_vfc  = IPV6_VERSION;
    2458           0 :                 ip6->ip6_plen = htons(pd2->tot_len - ohlen);
    2459           0 :                 if (pd2->proto == IPPROTO_ICMP)
    2460           0 :                         ip6->ip6_nxt = IPPROTO_ICMPV6;
    2461             :                 else
    2462           0 :                         ip6->ip6_nxt = pd2->proto;
    2463           0 :                 if (!pd2->ttl || pd2->ttl > IPV6_DEFHLIM)
    2464           0 :                         ip6->ip6_hlim = IPV6_DEFHLIM;
    2465             :                 else
    2466           0 :                         ip6->ip6_hlim = pd2->ttl;
    2467           0 :                 ip6->ip6_src  = src->v6;
    2468           0 :                 ip6->ip6_dst  = dst->v6;
    2469           0 :                 break;
    2470             :         }
    2471             : 
    2472             :         /* cover new quoted header */
    2473             :         /* optimise: any new AF_INET header of ours sums to zero */
    2474           0 :         if (naf != AF_INET) {
    2475           0 :                 pf_cksum_cover(pd->pcksum, in_cksum(n, hlen), pd->proto);
    2476           0 :         }
    2477             : 
    2478             :         /* reattach modified quoted packet to outer header */
    2479             :         {
    2480           0 :                 int nlen = n->m_pkthdr.len;
    2481           0 :                 m_cat(m, n);
    2482           0 :                 m->m_pkthdr.len += nlen;
    2483             :         }
    2484             : 
    2485             :         /* account for altered length */
    2486           0 :         d = hlen - ohlen;
    2487             : 
    2488           0 :         if (pd->proto == IPPROTO_ICMPV6) {
    2489             :                 /* fixup pseudo-header */
    2490           0 :                 dlen = pd->tot_len - pd->off;
    2491           0 :                 pf_cksum_fixup(pd->pcksum,
    2492           0 :                     htons(dlen), htons(dlen + d), pd->proto);
    2493           0 :         }
    2494             : 
    2495           0 :         pd->tot_len  += d;
    2496           0 :         pd2->tot_len += d;
    2497           0 :         pd2->off     += d;
    2498             : 
    2499             :         /* note: not bothering to update network headers as
    2500             :            these due for rewrite by pf_translate_af() */
    2501             : 
    2502           0 :         return (0);
    2503           0 : }
    2504             : 
    2505             : 
    2506             : #define PTR_IP(field)   (offsetof(struct ip, field))
    2507             : #define PTR_IP6(field)  (offsetof(struct ip6_hdr, field))
    2508             : 
    2509             : int
    2510           0 : pf_translate_icmp_af(struct pf_pdesc *pd, int af, void *arg)
    2511             : {
    2512             :         struct icmp             *icmp4;
    2513             :         struct icmp6_hdr        *icmp6;
    2514             :         u_int32_t                mtu;
    2515             :         int32_t                  ptr = -1;
    2516             :         u_int8_t                 type;
    2517             :         u_int8_t                 code;
    2518             : 
    2519           0 :         switch (af) {
    2520             :         case AF_INET:
    2521           0 :                 icmp6 = arg;
    2522           0 :                 type  = icmp6->icmp6_type;
    2523           0 :                 code  = icmp6->icmp6_code;
    2524           0 :                 mtu   = ntohl(icmp6->icmp6_mtu);
    2525             : 
    2526           0 :                 switch (type) {
    2527             :                 case ICMP6_ECHO_REQUEST:
    2528             :                         type = ICMP_ECHO;
    2529           0 :                         break;
    2530             :                 case ICMP6_ECHO_REPLY:
    2531             :                         type = ICMP_ECHOREPLY;
    2532           0 :                         break;
    2533             :                 case ICMP6_DST_UNREACH:
    2534             :                         type = ICMP_UNREACH;
    2535           0 :                         switch (code) {
    2536             :                         case ICMP6_DST_UNREACH_NOROUTE:
    2537             :                         case ICMP6_DST_UNREACH_BEYONDSCOPE:
    2538             :                         case ICMP6_DST_UNREACH_ADDR:
    2539             :                                 code = ICMP_UNREACH_HOST;
    2540           0 :                                 break;
    2541             :                         case ICMP6_DST_UNREACH_ADMIN:
    2542             :                                 code = ICMP_UNREACH_HOST_PROHIB;
    2543           0 :                                 break;
    2544             :                         case ICMP6_DST_UNREACH_NOPORT:
    2545             :                                 code = ICMP_UNREACH_PORT;
    2546           0 :                                 break;
    2547             :                         default:
    2548           0 :                                 return (-1);
    2549             :                         }
    2550             :                         break;
    2551             :                 case ICMP6_PACKET_TOO_BIG:
    2552             :                         type = ICMP_UNREACH;
    2553             :                         code = ICMP_UNREACH_NEEDFRAG;
    2554           0 :                         mtu -= 20;
    2555           0 :                         break;
    2556             :                 case ICMP6_TIME_EXCEEDED:
    2557             :                         type = ICMP_TIMXCEED;
    2558           0 :                         break;
    2559             :                 case ICMP6_PARAM_PROB:
    2560           0 :                         switch (code) {
    2561             :                         case ICMP6_PARAMPROB_HEADER:
    2562             :                                 type = ICMP_PARAMPROB;
    2563             :                                 code = ICMP_PARAMPROB_ERRATPTR;
    2564             :                                 ptr  = ntohl(icmp6->icmp6_pptr);
    2565             : 
    2566           0 :                                 if (ptr == PTR_IP6(ip6_vfc))
    2567             :                                         ; /* preserve */
    2568           0 :                                 else if (ptr == PTR_IP6(ip6_vfc) + 1)
    2569           0 :                                         ptr = PTR_IP(ip_tos);
    2570           0 :                                 else if (ptr == PTR_IP6(ip6_plen) ||
    2571           0 :                                     ptr == PTR_IP6(ip6_plen) + 1)
    2572           0 :                                         ptr = PTR_IP(ip_len);
    2573           0 :                                 else if (ptr == PTR_IP6(ip6_nxt))
    2574           0 :                                         ptr = PTR_IP(ip_p);
    2575           0 :                                 else if (ptr == PTR_IP6(ip6_hlim))
    2576           0 :                                         ptr = PTR_IP(ip_ttl);
    2577           0 :                                 else if (ptr >= PTR_IP6(ip6_src) &&
    2578           0 :                                     ptr < PTR_IP6(ip6_dst))
    2579           0 :                                         ptr = PTR_IP(ip_src);
    2580           0 :                                 else if (ptr >= PTR_IP6(ip6_dst) &&
    2581           0 :                                     ptr < sizeof(struct ip6_hdr))
    2582             :                                         ptr = PTR_IP(ip_dst);
    2583             :                                 else {
    2584           0 :                                         return (-1);
    2585             :                                 }
    2586             :                                 break;
    2587             :                         case ICMP6_PARAMPROB_NEXTHEADER:
    2588             :                                 type = ICMP_UNREACH;
    2589             :                                 code = ICMP_UNREACH_PROTOCOL;
    2590           0 :                                 break;
    2591             :                         default:
    2592           0 :                                 return (-1);
    2593             :                         }
    2594             :                         break;
    2595             :                 default:
    2596           0 :                         return (-1);
    2597             :                 }
    2598             : 
    2599           0 :                 pf_patch_8(pd, &icmp6->icmp6_type, type, PF_HI);
    2600           0 :                 pf_patch_8(pd, &icmp6->icmp6_code, code, PF_LO);
    2601             : 
    2602             :                 /* aligns well with a icmpv4 nextmtu */
    2603           0 :                 pf_patch_32(pd, &icmp6->icmp6_mtu, htonl(mtu));
    2604             : 
    2605             :                 /* icmpv4 pptr is a one most significant byte */
    2606           0 :                 if (ptr >= 0)
    2607           0 :                         pf_patch_32(pd, &icmp6->icmp6_pptr, htonl(ptr << 24));
    2608             :                 break;
    2609             :         case AF_INET6:
    2610           0 :                 icmp4 = arg;
    2611           0 :                 type  = icmp4->icmp_type;
    2612           0 :                 code  = icmp4->icmp_code;
    2613           0 :                 mtu   = ntohs(icmp4->icmp_nextmtu);
    2614             : 
    2615           0 :                 switch (type) {
    2616             :                 case ICMP_ECHO:
    2617             :                         type = ICMP6_ECHO_REQUEST;
    2618           0 :                         break;
    2619             :                 case ICMP_ECHOREPLY:
    2620             :                         type = ICMP6_ECHO_REPLY;
    2621           0 :                         break;
    2622             :                 case ICMP_UNREACH:
    2623             :                         type = ICMP6_DST_UNREACH;
    2624           0 :                         switch (code) {
    2625             :                         case ICMP_UNREACH_NET:
    2626             :                         case ICMP_UNREACH_HOST:
    2627             :                         case ICMP_UNREACH_NET_UNKNOWN:
    2628             :                         case ICMP_UNREACH_HOST_UNKNOWN:
    2629             :                         case ICMP_UNREACH_ISOLATED:
    2630             :                         case ICMP_UNREACH_TOSNET:
    2631             :                         case ICMP_UNREACH_TOSHOST:
    2632             :                                 code = ICMP6_DST_UNREACH_NOROUTE;
    2633           0 :                                 break;
    2634             :                         case ICMP_UNREACH_PORT:
    2635             :                                 code = ICMP6_DST_UNREACH_NOPORT;
    2636           0 :                                 break;
    2637             :                         case ICMP_UNREACH_NET_PROHIB:
    2638             :                         case ICMP_UNREACH_HOST_PROHIB:
    2639             :                         case ICMP_UNREACH_FILTER_PROHIB:
    2640             :                         case ICMP_UNREACH_PRECEDENCE_CUTOFF:
    2641             :                                 code = ICMP6_DST_UNREACH_ADMIN;
    2642           0 :                                 break;
    2643             :                         case ICMP_UNREACH_PROTOCOL:
    2644             :                                 type = ICMP6_PARAM_PROB;
    2645             :                                 code = ICMP6_PARAMPROB_NEXTHEADER;
    2646             :                                 ptr  = offsetof(struct ip6_hdr, ip6_nxt);
    2647           0 :                                 break;
    2648             :                         case ICMP_UNREACH_NEEDFRAG:
    2649             :                                 type = ICMP6_PACKET_TOO_BIG;
    2650             :                                 code = 0;
    2651           0 :                                 mtu += 20;
    2652           0 :                                 break;
    2653             :                         default:
    2654           0 :                                 return (-1);
    2655             :                         }
    2656             :                         break;
    2657             :                 case ICMP_TIMXCEED:
    2658             :                         type = ICMP6_TIME_EXCEEDED;
    2659           0 :                         break;
    2660             :                 case ICMP_PARAMPROB:
    2661             :                         type = ICMP6_PARAM_PROB;
    2662           0 :                         switch (code) {
    2663             :                         case ICMP_PARAMPROB_ERRATPTR:
    2664             :                                 code = ICMP6_PARAMPROB_HEADER;
    2665           0 :                                 break;
    2666             :                         case ICMP_PARAMPROB_LENGTH:
    2667             :                                 code = ICMP6_PARAMPROB_HEADER;
    2668           0 :                                 break;
    2669             :                         default:
    2670           0 :                                 return (-1);
    2671             :                         }
    2672             : 
    2673           0 :                         ptr = icmp4->icmp_pptr;
    2674           0 :                         if (ptr == 0 || ptr == PTR_IP(ip_tos))
    2675             :                                 ; /* preserve */
    2676           0 :                         else if (ptr == PTR_IP(ip_len) ||
    2677           0 :                             ptr == PTR_IP(ip_len) + 1)
    2678           0 :                                 ptr = PTR_IP6(ip6_plen);
    2679           0 :                         else if (ptr == PTR_IP(ip_ttl))
    2680           0 :                                 ptr = PTR_IP6(ip6_hlim);
    2681           0 :                         else if (ptr == PTR_IP(ip_p))
    2682           0 :                                 ptr = PTR_IP6(ip6_nxt);
    2683           0 :                         else if (ptr >= PTR_IP(ip_src) &&
    2684           0 :                             ptr < PTR_IP(ip_dst))
    2685           0 :                                 ptr = PTR_IP6(ip6_src);
    2686           0 :                         else if (ptr >= PTR_IP(ip_dst) &&
    2687           0 :                             ptr < sizeof(struct ip))
    2688             :                                 ptr = PTR_IP6(ip6_dst);
    2689             :                         else {
    2690           0 :                                 return (-1);
    2691             :                         }
    2692             :                         break;
    2693             :                 default:
    2694           0 :                         return (-1);
    2695             :                 }
    2696             : 
    2697           0 :                 pf_patch_8(pd, &icmp4->icmp_type, type, PF_HI);
    2698           0 :                 pf_patch_8(pd, &icmp4->icmp_code, code, PF_LO);
    2699           0 :                 pf_patch_16(pd, &icmp4->icmp_nextmtu, htons(mtu));
    2700           0 :                 if (ptr >= 0)
    2701           0 :                         pf_patch_32(pd, &icmp4->icmp_void, htonl(ptr));
    2702             :                 break;
    2703             :         }
    2704             : 
    2705           0 :         return (0);
    2706           0 : }
    2707             : #endif /* INET6 */
    2708             : 
    2709             : /*
    2710             :  * Need to modulate the sequence numbers in the TCP SACK option
    2711             :  * (credits to Krzysztof Pfaff for report and patch)
    2712             :  */
    2713             : int
    2714           0 : pf_modulate_sack(struct pf_pdesc *pd, struct pf_state_peer *dst)
    2715             : {
    2716           0 :         struct sackblk   sack;
    2717             :         int              copyback = 0, i;
    2718             :         int              olen, optsoff;
    2719           0 :         u_int8_t         opts[MAX_TCPOPTLEN], *opt, *eoh;
    2720             : 
    2721           0 :         olen = (pd->hdr.tcp.th_off << 2) - sizeof(struct tcphdr);
    2722           0 :         optsoff = pd->off + sizeof(struct tcphdr);
    2723             : #define TCPOLEN_MINSACK (TCPOLEN_SACK + 2)
    2724           0 :         if (olen < TCPOLEN_MINSACK ||
    2725           0 :             !pf_pull_hdr(pd->m, optsoff, opts, olen, NULL, NULL, pd->af))
    2726           0 :                 return (0);
    2727             : 
    2728           0 :         eoh = opts + olen;
    2729             :         opt = opts;
    2730           0 :         while ((opt = pf_find_tcpopt(opt, opts, olen,
    2731           0 :                     TCPOPT_SACK, TCPOLEN_MINSACK)) != NULL)
    2732             :         {
    2733           0 :                 size_t safelen = MIN(opt[1], (eoh - opt));
    2734           0 :                 for (i = 2; i + TCPOLEN_SACK <= safelen; i += TCPOLEN_SACK) {
    2735           0 :                         size_t startoff = (opt + i) - opts;
    2736           0 :                         memcpy(&sack, &opt[i], sizeof(sack));
    2737           0 :                         pf_patch_32_unaligned(pd, &sack.start,
    2738           0 :                             htonl(ntohl(sack.start) - dst->seqdiff),
    2739           0 :                             PF_ALGNMNT(startoff));
    2740           0 :                         pf_patch_32_unaligned(pd, &sack.end,
    2741           0 :                             htonl(ntohl(sack.end) - dst->seqdiff),
    2742           0 :                             PF_ALGNMNT(startoff + sizeof(sack.start)));
    2743           0 :                         memcpy(&opt[i], &sack, sizeof(sack));
    2744             :                 }
    2745             :                 copyback = 1;
    2746           0 :                 opt += opt[1];
    2747             :         }
    2748             : 
    2749           0 :         if (copyback)
    2750           0 :                 m_copyback(pd->m, optsoff, olen, opts, M_NOWAIT);
    2751           0 :         return (copyback);
    2752           0 : }
    2753             : 
    2754             : struct mbuf *
    2755           0 : pf_build_tcp(const struct pf_rule *r, sa_family_t af,
    2756             :     const struct pf_addr *saddr, const struct pf_addr *daddr,
    2757             :     u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
    2758             :     u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
    2759             :     u_int16_t rtag, u_int sack, u_int rdom)
    2760             : {
    2761             :         struct mbuf     *m;
    2762             :         int              len, tlen;
    2763             :         struct ip       *h;
    2764             : #ifdef INET6
    2765             :         struct ip6_hdr  *h6;
    2766             : #endif /* INET6 */
    2767             :         struct tcphdr   *th;
    2768             :         char            *opt;
    2769             : 
    2770             :         /* maximum segment size tcp option */
    2771             :         tlen = sizeof(struct tcphdr);
    2772           0 :         if (mss)
    2773           0 :                 tlen += 4;
    2774           0 :         if (sack)
    2775           0 :                 tlen += 2;
    2776             : 
    2777           0 :         switch (af) {
    2778             :         case AF_INET:
    2779           0 :                 len = sizeof(struct ip) + tlen;
    2780           0 :                 break;
    2781             : #ifdef INET6
    2782             :         case AF_INET6:
    2783           0 :                 len = sizeof(struct ip6_hdr) + tlen;
    2784           0 :                 break;
    2785             : #endif /* INET6 */
    2786             :         default:
    2787           0 :                 unhandled_af(af);
    2788             :         }
    2789             : 
    2790             :         /* create outgoing mbuf */
    2791           0 :         m = m_gethdr(M_DONTWAIT, MT_HEADER);
    2792           0 :         if (m == NULL)
    2793           0 :                 return (NULL);
    2794           0 :         if (tag)
    2795           0 :                 m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
    2796           0 :         m->m_pkthdr.pf.tag = rtag;
    2797           0 :         m->m_pkthdr.ph_rtableid = rdom;
    2798           0 :         if (r && (r->scrub_flags & PFSTATE_SETPRIO))
    2799           0 :                 m->m_pkthdr.pf.prio = r->set_prio[0];
    2800           0 :         if (r && r->qid)
    2801           0 :                 m->m_pkthdr.pf.qid = r->qid;
    2802           0 :         m->m_data += max_linkhdr;
    2803           0 :         m->m_pkthdr.len = m->m_len = len;
    2804           0 :         m->m_pkthdr.ph_ifidx = 0;
    2805           0 :         m->m_pkthdr.csum_flags |= M_TCP_CSUM_OUT;
    2806           0 :         memset(m->m_data, 0, len);
    2807           0 :         switch (af) {
    2808             :         case AF_INET:
    2809           0 :                 h = mtod(m, struct ip *);
    2810           0 :                 h->ip_p = IPPROTO_TCP;
    2811           0 :                 h->ip_len = htons(tlen);
    2812           0 :                 h->ip_v = 4;
    2813           0 :                 h->ip_hl = sizeof(*h) >> 2;
    2814           0 :                 h->ip_tos = IPTOS_LOWDELAY;
    2815           0 :                 h->ip_len = htons(len);
    2816           0 :                 h->ip_off = htons(ip_mtudisc ? IP_DF : 0);
    2817           0 :                 h->ip_ttl = ttl ? ttl : ip_defttl;
    2818           0 :                 h->ip_sum = 0;
    2819           0 :                 h->ip_src.s_addr = saddr->v4.s_addr;
    2820           0 :                 h->ip_dst.s_addr = daddr->v4.s_addr;
    2821             : 
    2822           0 :                 th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip));
    2823           0 :                 break;
    2824             : #ifdef INET6
    2825             :         case AF_INET6:
    2826           0 :                 h6 = mtod(m, struct ip6_hdr *);
    2827           0 :                 h6->ip6_nxt = IPPROTO_TCP;
    2828           0 :                 h6->ip6_plen = htons(tlen);
    2829           0 :                 h6->ip6_vfc |= IPV6_VERSION;
    2830           0 :                 h6->ip6_hlim = IPV6_DEFHLIM;
    2831           0 :                 memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr));
    2832           0 :                 memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr));
    2833             : 
    2834           0 :                 th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr));
    2835           0 :                 break;
    2836             : #endif /* INET6 */
    2837             :         default:
    2838           0 :                 unhandled_af(af);
    2839             :         }
    2840             : 
    2841             :         /* TCP header */
    2842           0 :         th->th_sport = sport;
    2843           0 :         th->th_dport = dport;
    2844           0 :         th->th_seq = htonl(seq);
    2845           0 :         th->th_ack = htonl(ack);
    2846           0 :         th->th_off = tlen >> 2;
    2847           0 :         th->th_flags = flags;
    2848           0 :         th->th_win = htons(win);
    2849             : 
    2850           0 :         opt = (char *)(th + 1);
    2851           0 :         if (mss) {
    2852           0 :                 opt[0] = TCPOPT_MAXSEG;
    2853           0 :                 opt[1] = 4;
    2854           0 :                 mss = htons(mss);
    2855           0 :                 memcpy((opt + 2), &mss, 2);
    2856           0 :                 opt += 4;
    2857           0 :         }
    2858           0 :         if (sack) {
    2859           0 :                 opt[0] = TCPOPT_SACK_PERMITTED;
    2860           0 :                 opt[1] = 2;
    2861             :                 opt += 2;
    2862           0 :         }
    2863             : 
    2864           0 :         return (m);
    2865           0 : }
    2866             : 
    2867             : void
    2868           0 : pf_send_tcp(const struct pf_rule *r, sa_family_t af,
    2869             :     const struct pf_addr *saddr, const struct pf_addr *daddr,
    2870             :     u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
    2871             :     u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
    2872             :     u_int16_t rtag, u_int rdom)
    2873             : {
    2874             :         struct mbuf     *m;
    2875             : 
    2876           0 :         if ((m = pf_build_tcp(r, af, saddr, daddr, sport, dport, seq, ack,
    2877           0 :             flags, win, mss, ttl, tag, rtag, 0, rdom)) == NULL)
    2878           0 :                 return;
    2879             : 
    2880           0 :         switch (af) {
    2881             :         case AF_INET:
    2882           0 :                 ip_send(m);
    2883           0 :                 break;
    2884             : #ifdef INET6
    2885             :         case AF_INET6:
    2886           0 :                 ip6_send(m);
    2887           0 :                 break;
    2888             : #endif /* INET6 */
    2889             :         }
    2890           0 : }
    2891             : 
    2892             : static void
    2893           0 : pf_send_challenge_ack(struct pf_pdesc *pd, struct pf_state *s,
    2894             :     struct pf_state_peer *src, struct pf_state_peer *dst)
    2895             : {
    2896             :         /*
    2897             :          * We are sending challenge ACK as a response to SYN packet, which
    2898             :          * matches existing state (modulo TCP window check). Therefore packet
    2899             :          * must be sent on behalf of destination.
    2900             :          *
    2901             :          * We expect sender to remain either silent, or send RST packet
    2902             :          * so both, firewall and remote peer, can purge dead state from
    2903             :          * memory.
    2904             :          */
    2905           0 :         pf_send_tcp(s->rule.ptr, pd->af, pd->dst, pd->src,
    2906           0 :             pd->hdr.tcp.th_dport, pd->hdr.tcp.th_sport, dst->seqlo,
    2907           0 :             src->seqlo, TH_ACK, 0, 0, s->rule.ptr->return_ttl, 1, 0,
    2908           0 :             pd->rdomain);
    2909           0 : }
    2910             : 
    2911             : void
    2912           0 : pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, int param,
    2913             :     sa_family_t af, struct pf_rule *r, u_int rdomain)
    2914             : {
    2915             :         struct mbuf     *m0;
    2916             : 
    2917           0 :         if ((m0 = m_copym(m, 0, M_COPYALL, M_NOWAIT)) == NULL)
    2918           0 :                 return;
    2919             : 
    2920           0 :         m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
    2921           0 :         m0->m_pkthdr.ph_rtableid = rdomain;
    2922           0 :         if (r && (r->scrub_flags & PFSTATE_SETPRIO))
    2923           0 :                 m0->m_pkthdr.pf.prio = r->set_prio[0];
    2924           0 :         if (r && r->qid)
    2925           0 :                 m0->m_pkthdr.pf.qid = r->qid;
    2926             : 
    2927           0 :         switch (af) {
    2928             :         case AF_INET:
    2929           0 :                 icmp_error(m0, type, code, 0, param);
    2930           0 :                 break;
    2931             : #ifdef INET6
    2932             :         case AF_INET6:
    2933           0 :                 icmp6_error(m0, type, code, param);
    2934           0 :                 break;
    2935             : #endif /* INET6 */
    2936             :         }
    2937           0 : }
    2938             : 
    2939             : /*
    2940             :  * Return ((n = 0) == (a = b [with mask m]))
    2941             :  * Note: n != 0 => returns (a != b [with mask m])
    2942             :  */
    2943             : int
    2944           0 : pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
    2945             :     struct pf_addr *b, sa_family_t af)
    2946             : {
    2947           0 :         switch (af) {
    2948             :         case AF_INET:
    2949           0 :                 if ((a->addr32[0] & m->addr32[0]) ==
    2950           0 :                     (b->addr32[0] & m->addr32[0]))
    2951           0 :                         return (n == 0);
    2952             :                 break;
    2953             : #ifdef INET6
    2954             :         case AF_INET6:
    2955           0 :                 if (((a->addr32[0] & m->addr32[0]) ==
    2956           0 :                      (b->addr32[0] & m->addr32[0])) &&
    2957           0 :                     ((a->addr32[1] & m->addr32[1]) ==
    2958           0 :                      (b->addr32[1] & m->addr32[1])) &&
    2959           0 :                     ((a->addr32[2] & m->addr32[2]) ==
    2960           0 :                      (b->addr32[2] & m->addr32[2])) &&
    2961           0 :                     ((a->addr32[3] & m->addr32[3]) ==
    2962           0 :                      (b->addr32[3] & m->addr32[3])))
    2963           0 :                         return (n == 0);
    2964             :                 break;
    2965             : #endif /* INET6 */
    2966             :         }
    2967             : 
    2968           0 :         return (n != 0);
    2969           0 : }
    2970             : 
    2971             : /*
    2972             :  * Return 1 if b <= a <= e, otherwise return 0.
    2973             :  */
    2974             : int
    2975           0 : pf_match_addr_range(struct pf_addr *b, struct pf_addr *e,
    2976             :     struct pf_addr *a, sa_family_t af)
    2977             : {
    2978           0 :         switch (af) {
    2979             :         case AF_INET:
    2980           0 :                 if ((ntohl(a->addr32[0]) < ntohl(b->addr32[0])) ||
    2981           0 :                     (ntohl(a->addr32[0]) > ntohl(e->addr32[0])))
    2982           0 :                         return (0);
    2983             :                 break;
    2984             : #ifdef INET6
    2985             :         case AF_INET6: {
    2986             :                 int     i;
    2987             : 
    2988             :                 /* check a >= b */
    2989           0 :                 for (i = 0; i < 4; ++i)
    2990           0 :                         if (ntohl(a->addr32[i]) > ntohl(b->addr32[i]))
    2991             :                                 break;
    2992           0 :                         else if (ntohl(a->addr32[i]) < ntohl(b->addr32[i]))
    2993           0 :                                 return (0);
    2994             :                 /* check a <= e */
    2995           0 :                 for (i = 0; i < 4; ++i)
    2996           0 :                         if (ntohl(a->addr32[i]) < ntohl(e->addr32[i]))
    2997             :                                 break;
    2998           0 :                         else if (ntohl(a->addr32[i]) > ntohl(e->addr32[i]))
    2999           0 :                                 return (0);
    3000           0 :                 break;
    3001             :         }
    3002             : #endif /* INET6 */
    3003             :         }
    3004           0 :         return (1);
    3005           0 : }
    3006             : 
    3007             : int
    3008           0 : pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
    3009             : {
    3010           0 :         switch (op) {
    3011             :         case PF_OP_IRG:
    3012           0 :                 return ((p > a1) && (p < a2));
    3013             :         case PF_OP_XRG:
    3014           0 :                 return ((p < a1) || (p > a2));
    3015             :         case PF_OP_RRG:
    3016           0 :                 return ((p >= a1) && (p <= a2));
    3017             :         case PF_OP_EQ:
    3018           0 :                 return (p == a1);
    3019             :         case PF_OP_NE:
    3020           0 :                 return (p != a1);
    3021             :         case PF_OP_LT:
    3022           0 :                 return (p < a1);
    3023             :         case PF_OP_LE:
    3024           0 :                 return (p <= a1);
    3025             :         case PF_OP_GT:
    3026           0 :                 return (p > a1);
    3027             :         case PF_OP_GE:
    3028           0 :                 return (p >= a1);
    3029             :         }
    3030           0 :         return (0); /* never reached */
    3031           0 : }
    3032             : 
    3033             : int
    3034           0 : pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
    3035             : {
    3036           0 :         return (pf_match(op, ntohs(a1), ntohs(a2), ntohs(p)));
    3037             : }
    3038             : 
    3039             : int
    3040           0 : pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
    3041             : {
    3042           0 :         if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
    3043           0 :                 return (0);
    3044           0 :         return (pf_match(op, a1, a2, u));
    3045           0 : }
    3046             : 
    3047             : int
    3048           0 : pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
    3049             : {
    3050           0 :         if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
    3051           0 :                 return (0);
    3052           0 :         return (pf_match(op, a1, a2, g));
    3053           0 : }
    3054             : 
    3055             : int
    3056           0 : pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag)
    3057             : {
    3058           0 :         if (*tag == -1)
    3059           0 :                 *tag = m->m_pkthdr.pf.tag;
    3060             : 
    3061           0 :         return ((!r->match_tag_not && r->match_tag == *tag) ||
    3062           0 :             (r->match_tag_not && r->match_tag != *tag));
    3063             : }
    3064             : 
    3065             : int
    3066           0 : pf_match_rcvif(struct mbuf *m, struct pf_rule *r)
    3067             : {
    3068             :         struct ifnet *ifp;
    3069             :         struct pfi_kif *kif;
    3070             : 
    3071           0 :         ifp = if_get(m->m_pkthdr.ph_ifidx);
    3072           0 :         if (ifp == NULL)
    3073           0 :                 return (0);
    3074             : 
    3075             : #if NCARP > 0
    3076           0 :         if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
    3077           0 :                 kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
    3078             :         else
    3079             : #endif /* NCARP */
    3080           0 :                 kif = (struct pfi_kif *)ifp->if_pf_kif;
    3081             : 
    3082           0 :         if_put(ifp);
    3083             : 
    3084           0 :         if (kif == NULL) {
    3085           0 :                 DPFPRINTF(LOG_ERR,
    3086             :                     "%s: kif == NULL, @%d via %s", __func__,
    3087             :                     r->nr, r->rcv_ifname);
    3088           0 :                 return (0);
    3089             :         }
    3090             : 
    3091           0 :         return (pfi_kif_match(r->rcv_kif, kif));
    3092           0 : }
    3093             : 
    3094             : void
    3095           0 : pf_tag_packet(struct mbuf *m, int tag, int rtableid)
    3096             : {
    3097           0 :         if (tag > 0)
    3098           0 :                 m->m_pkthdr.pf.tag = tag;
    3099           0 :         if (rtableid >= 0)
    3100           0 :                 m->m_pkthdr.ph_rtableid = (u_int)rtableid;
    3101           0 : }
    3102             : 
    3103             : enum pf_test_status
    3104           0 : pf_step_into_anchor(struct pf_test_ctx *ctx, struct pf_rule *r)
    3105             : {
    3106             :         int     rv;
    3107             : 
    3108           0 :         if (ctx->depth >= PF_ANCHOR_STACK_MAX) {
    3109           0 :                 log(LOG_ERR, "pf_step_into_anchor: stack overflow\n");
    3110           0 :                 return (PF_TEST_FAIL);
    3111             :         }
    3112             : 
    3113           0 :         ctx->depth++;
    3114             : 
    3115           0 :         if (r->anchor_wildcard) {
    3116             :                 struct pf_anchor        *child;
    3117             :                 rv = PF_TEST_OK;
    3118           0 :                 RB_FOREACH(child, pf_anchor_node, &r->anchor->children) {
    3119           0 :                         rv = pf_match_rule(ctx, &child->ruleset);
    3120           0 :                         if ((rv == PF_TEST_QUICK) || (rv == PF_TEST_FAIL)) {
    3121             :                                 /*
    3122             :                                  * we either hit a rule with quick action
    3123             :                                  * (more likely), or hit some runtime
    3124             :                                  * error (e.g. pool_get() failure).
    3125             :                                  */
    3126             :                                 break;
    3127             :                         }
    3128             :                 }
    3129           0 :         } else {
    3130           0 :                 rv = pf_match_rule(ctx, &r->anchor->ruleset);
    3131             :         }
    3132             : 
    3133           0 :         ctx->depth--;
    3134             : 
    3135           0 :         return (rv);
    3136           0 : }
    3137             : 
    3138             : void
    3139           0 : pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
    3140             :     struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af)
    3141             : {
    3142           0 :         switch (af) {
    3143             :         case AF_INET:
    3144           0 :                 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
    3145           0 :                 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
    3146           0 :                 break;
    3147             : #ifdef INET6
    3148             :         case AF_INET6:
    3149           0 :                 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
    3150           0 :                 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
    3151           0 :                 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) |
    3152           0 :                 ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]);
    3153           0 :                 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) |
    3154           0 :                 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]);
    3155           0 :                 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) |
    3156           0 :                 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]);
    3157           0 :                 break;
    3158             : #endif /* INET6 */
    3159             :         default:
    3160           0 :                 unhandled_af(af);
    3161             :         }
    3162           0 : }
    3163             : 
    3164             : void
    3165           0 : pf_addr_inc(struct pf_addr *addr, sa_family_t af)
    3166             : {
    3167           0 :         switch (af) {
    3168             :         case AF_INET:
    3169           0 :                 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1);
    3170           0 :                 break;
    3171             : #ifdef INET6
    3172             :         case AF_INET6:
    3173           0 :                 if (addr->addr32[3] == 0xffffffff) {
    3174           0 :                         addr->addr32[3] = 0;
    3175           0 :                         if (addr->addr32[2] == 0xffffffff) {
    3176           0 :                                 addr->addr32[2] = 0;
    3177           0 :                                 if (addr->addr32[1] == 0xffffffff) {
    3178           0 :                                         addr->addr32[1] = 0;
    3179           0 :                                         addr->addr32[0] =
    3180           0 :                                             htonl(ntohl(addr->addr32[0]) + 1);
    3181           0 :                                 } else
    3182           0 :                                         addr->addr32[1] =
    3183           0 :                                             htonl(ntohl(addr->addr32[1]) + 1);
    3184             :                         } else
    3185           0 :                                 addr->addr32[2] =
    3186           0 :                                     htonl(ntohl(addr->addr32[2]) + 1);
    3187             :                 } else
    3188           0 :                         addr->addr32[3] =
    3189           0 :                             htonl(ntohl(addr->addr32[3]) + 1);
    3190             :                 break;
    3191             : #endif /* INET6 */
    3192             :         default:
    3193           0 :                 unhandled_af(af);
    3194             :         }
    3195           0 : }
    3196             : 
    3197             : int
    3198           0 : pf_socket_lookup(struct pf_pdesc *pd)
    3199             : {
    3200             :         struct pf_addr          *saddr, *daddr;
    3201             :         u_int16_t                sport, dport;
    3202             :         struct inpcbtable       *tb;
    3203             :         struct inpcb            *inp;
    3204             : 
    3205           0 :         pd->lookup.uid = UID_MAX;
    3206           0 :         pd->lookup.gid = GID_MAX;
    3207           0 :         pd->lookup.pid = NO_PID;
    3208           0 :         switch (pd->virtual_proto) {
    3209             :         case IPPROTO_TCP:
    3210           0 :                 sport = pd->hdr.tcp.th_sport;
    3211           0 :                 dport = pd->hdr.tcp.th_dport;
    3212             :                 PF_ASSERT_LOCKED();
    3213           0 :                 NET_ASSERT_LOCKED();
    3214             :                 tb = &tcbtable;
    3215           0 :                 break;
    3216             :         case IPPROTO_UDP:
    3217           0 :                 sport = pd->hdr.udp.uh_sport;
    3218           0 :                 dport = pd->hdr.udp.uh_dport;
    3219             :                 PF_ASSERT_LOCKED();
    3220           0 :                 NET_ASSERT_LOCKED();
    3221             :                 tb = &udbtable;
    3222           0 :                 break;
    3223             :         default:
    3224           0 :                 return (-1);
    3225             :         }
    3226           0 :         if (pd->dir == PF_IN) {
    3227           0 :                 saddr = pd->src;
    3228           0 :                 daddr = pd->dst;
    3229           0 :         } else {
    3230             :                 u_int16_t       p;
    3231             : 
    3232             :                 p = sport;
    3233             :                 sport = dport;
    3234             :                 dport = p;
    3235           0 :                 saddr = pd->dst;
    3236           0 :                 daddr = pd->src;
    3237             :         }
    3238           0 :         switch (pd->af) {
    3239             :         case AF_INET:
    3240             :                 /*
    3241             :                  * Fails when rtable is changed while evaluating the ruleset
    3242             :                  * The socket looked up will not match the one hit in the end.
    3243             :                  */
    3244           0 :                 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport,
    3245           0 :                     pd->rdomain);
    3246           0 :                 if (inp == NULL) {
    3247           0 :                         inp = in_pcblookup_listen(tb, daddr->v4, dport,
    3248           0 :                             NULL, pd->rdomain);
    3249           0 :                         if (inp == NULL)
    3250           0 :                                 return (-1);
    3251             :                 }
    3252             :                 break;
    3253             : #ifdef INET6
    3254             :         case AF_INET6:
    3255           0 :                 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6,
    3256           0 :                     dport, pd->rdomain);
    3257           0 :                 if (inp == NULL) {
    3258           0 :                         inp = in6_pcblookup_listen(tb, &daddr->v6, dport,
    3259           0 :                             NULL, pd->rdomain);
    3260           0 :                         if (inp == NULL)
    3261           0 :                                 return (-1);
    3262             :                 }
    3263             :                 break;
    3264             : #endif /* INET6 */
    3265             :         default:
    3266           0 :                 unhandled_af(pd->af);
    3267             :         }
    3268           0 :         pd->lookup.uid = inp->inp_socket->so_euid;
    3269           0 :         pd->lookup.gid = inp->inp_socket->so_egid;
    3270           0 :         pd->lookup.pid = inp->inp_socket->so_cpid;
    3271           0 :         return (1);
    3272           0 : }
    3273             : 
    3274             : /* post: r  => (r[0] == type /\ r[1] >= min_typelen >= 2  "validity"
    3275             :  *                      /\ (eoh - r) >= min_typelen >= 2  "safety"  )
    3276             :  *
    3277             :  * warning: r + r[1] may exceed opts bounds for r[1] > min_typelen
    3278             :  */
    3279             : u_int8_t*
    3280           0 : pf_find_tcpopt(u_int8_t *opt, u_int8_t *opts, size_t hlen, u_int8_t type,
    3281             :     u_int8_t min_typelen)
    3282             : {
    3283           0 :         u_int8_t *eoh = opts + hlen;
    3284             : 
    3285           0 :         if (min_typelen < 2)
    3286           0 :                 return (NULL);
    3287             : 
    3288           0 :         while ((eoh - opt) >= min_typelen) {
    3289           0 :                 switch (*opt) {
    3290             :                 case TCPOPT_EOL:
    3291             :                         /* FALLTHROUGH - Workaround the failure of some
    3292             :                            systems to NOP-pad their bzero'd option buffers,
    3293             :                            producing spurious EOLs */
    3294             :                 case TCPOPT_NOP:
    3295           0 :                         opt++;
    3296           0 :                         continue;
    3297             :                 default:
    3298           0 :                         if (opt[0] == type &&
    3299           0 :                             opt[1] >= min_typelen)
    3300           0 :                                 return (opt);
    3301             :                 }
    3302             : 
    3303           0 :                 opt += MAX(opt[1], 2); /* evade infinite loops */
    3304             :         }
    3305             : 
    3306           0 :         return (NULL);
    3307           0 : }
    3308             : 
    3309             : u_int8_t
    3310           0 : pf_get_wscale(struct pf_pdesc *pd)
    3311             : {
    3312             :         int              olen;
    3313           0 :         u_int8_t         opts[MAX_TCPOPTLEN], *opt;
    3314             :         u_int8_t         wscale = 0;
    3315             : 
    3316           0 :         olen = (pd->hdr.tcp.th_off << 2) - sizeof(struct tcphdr);
    3317           0 :         if (olen < TCPOLEN_WINDOW || !pf_pull_hdr(pd->m,
    3318           0 :             pd->off + sizeof(struct tcphdr), opts, olen, NULL, NULL, pd->af))
    3319           0 :                 return (0);
    3320             : 
    3321             :         opt = opts;
    3322           0 :         while ((opt = pf_find_tcpopt(opt, opts, olen,
    3323           0 :                     TCPOPT_WINDOW, TCPOLEN_WINDOW)) != NULL) {
    3324           0 :                 wscale = opt[2];
    3325           0 :                 wscale = MIN(wscale, TCP_MAX_WINSHIFT);
    3326           0 :                 wscale |= PF_WSCALE_FLAG;
    3327             : 
    3328           0 :                 opt += opt[1];
    3329             :         }
    3330             : 
    3331           0 :         return (wscale);
    3332           0 : }
    3333             : 
    3334             : u_int16_t
    3335           0 : pf_get_mss(struct pf_pdesc *pd)
    3336             : {
    3337             :         int              olen;
    3338           0 :         u_int8_t         opts[MAX_TCPOPTLEN], *opt;
    3339           0 :         u_int16_t        mss = tcp_mssdflt;
    3340             : 
    3341           0 :         olen = (pd->hdr.tcp.th_off << 2) - sizeof(struct tcphdr);
    3342           0 :         if (olen < TCPOLEN_MAXSEG || !pf_pull_hdr(pd->m,
    3343           0 :             pd->off + sizeof(struct tcphdr), opts, olen, NULL, NULL, pd->af))
    3344           0 :                 return (0);
    3345             : 
    3346             :         opt = opts;
    3347           0 :         while ((opt = pf_find_tcpopt(opt, opts, olen,
    3348           0 :                     TCPOPT_MAXSEG, TCPOLEN_MAXSEG)) != NULL) {
    3349           0 :                         memcpy(&mss, (opt + 2), 2);
    3350           0 :                         mss = ntohs(mss);
    3351             : 
    3352           0 :                         opt += opt[1];
    3353             :         }
    3354           0 :         return (mss);
    3355           0 : }
    3356             : 
    3357             : u_int16_t
    3358           0 : pf_calc_mss(struct pf_addr *addr, sa_family_t af, int rtableid, u_int16_t offer)
    3359             : {
    3360             :         struct ifnet            *ifp;
    3361             :         struct sockaddr_in      *dst;
    3362             : #ifdef INET6
    3363             :         struct sockaddr_in6     *dst6;
    3364             : #endif /* INET6 */
    3365             :         struct rtentry          *rt = NULL;
    3366           0 :         struct sockaddr_storage  ss;
    3367             :         int                      hlen;
    3368           0 :         u_int16_t                mss = tcp_mssdflt;
    3369             : 
    3370           0 :         memset(&ss, 0, sizeof(ss));
    3371             : 
    3372           0 :         switch (af) {
    3373             :         case AF_INET:
    3374             :                 hlen = sizeof(struct ip);
    3375           0 :                 dst = (struct sockaddr_in *)&ss;
    3376           0 :                 dst->sin_family = AF_INET;
    3377           0 :                 dst->sin_len = sizeof(*dst);
    3378           0 :                 dst->sin_addr = addr->v4;
    3379           0 :                 rt = rtalloc(sintosa(dst), 0, rtableid);
    3380           0 :                 break;
    3381             : #ifdef INET6
    3382             :         case AF_INET6:
    3383             :                 hlen = sizeof(struct ip6_hdr);
    3384           0 :                 dst6 = (struct sockaddr_in6 *)&ss;
    3385           0 :                 dst6->sin6_family = AF_INET6;
    3386           0 :                 dst6->sin6_len = sizeof(*dst6);
    3387           0 :                 dst6->sin6_addr = addr->v6;
    3388           0 :                 rt = rtalloc(sin6tosa(dst6), 0, rtableid);
    3389           0 :                 break;
    3390             : #endif /* INET6 */
    3391             :         }
    3392             : 
    3393           0 :         if (rt != NULL && (ifp = if_get(rt->rt_ifidx)) != NULL) {
    3394           0 :                 mss = ifp->if_mtu - hlen - sizeof(struct tcphdr);
    3395           0 :                 mss = max(tcp_mssdflt, mss);
    3396           0 :                 if_put(ifp);
    3397           0 :         }
    3398           0 :         rtfree(rt);
    3399           0 :         mss = min(mss, offer);
    3400           0 :         mss = max(mss, 64);             /* sanity - at least max opt space */
    3401           0 :         return (mss);
    3402           0 : }
    3403             : 
    3404             : static __inline int
    3405           0 : pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr, sa_family_t af)
    3406             : {
    3407           0 :         struct pf_rule *r = s->rule.ptr;
    3408           0 :         struct pf_src_node *sns[PF_SN_MAX];
    3409             :         int     rv;
    3410             : 
    3411           0 :         s->rt_kif = NULL;
    3412           0 :         if (!r->rt)
    3413           0 :                 return (0);
    3414             : 
    3415           0 :         memset(sns, 0, sizeof(sns));
    3416           0 :         switch (af) {
    3417             :         case AF_INET:
    3418           0 :                 rv = pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, sns,
    3419           0 :                     &r->route, PF_SN_ROUTE);
    3420           0 :                 break;
    3421             : #ifdef INET6
    3422             :         case AF_INET6:
    3423           0 :                 rv = pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, sns,
    3424           0 :                     &r->route, PF_SN_ROUTE);
    3425           0 :                 break;
    3426             : #endif /* INET6 */
    3427             :         default:
    3428             :                 rv = 1;
    3429           0 :         }
    3430             : 
    3431           0 :         if (rv == 0) {
    3432           0 :                 s->rt_kif = r->route.kif;
    3433           0 :                 s->natrule.ptr = r;
    3434           0 :         }
    3435             : 
    3436           0 :         return (rv);
    3437           0 : }
    3438             : 
    3439             : u_int32_t
    3440           0 : pf_tcp_iss(struct pf_pdesc *pd)
    3441             : {
    3442           0 :         SHA2_CTX ctx;
    3443           0 :         union {
    3444             :                 uint8_t bytes[SHA512_DIGEST_LENGTH];
    3445             :                 uint32_t words[1];
    3446             :         } digest;
    3447             : 
    3448           0 :         if (pf_tcp_secret_init == 0) {
    3449           0 :                 arc4random_buf(pf_tcp_secret, sizeof(pf_tcp_secret));
    3450           0 :                 SHA512Init(&pf_tcp_secret_ctx);
    3451           0 :                 SHA512Update(&pf_tcp_secret_ctx, pf_tcp_secret,
    3452             :                     sizeof(pf_tcp_secret));
    3453           0 :                 pf_tcp_secret_init = 1;
    3454           0 :         }
    3455           0 :         ctx = pf_tcp_secret_ctx;
    3456             : 
    3457           0 :         SHA512Update(&ctx, &pd->rdomain, sizeof(pd->rdomain));
    3458           0 :         SHA512Update(&ctx, &pd->hdr.tcp.th_sport, sizeof(u_short));
    3459           0 :         SHA512Update(&ctx, &pd->hdr.tcp.th_dport, sizeof(u_short));
    3460           0 :         switch (pd->af) {
    3461             :         case AF_INET:
    3462           0 :                 SHA512Update(&ctx, &pd->src->v4, sizeof(struct in_addr));
    3463           0 :                 SHA512Update(&ctx, &pd->dst->v4, sizeof(struct in_addr));
    3464           0 :                 break;
    3465             : #ifdef INET6
    3466             :         case AF_INET6:
    3467           0 :                 SHA512Update(&ctx, &pd->src->v6, sizeof(struct in6_addr));
    3468           0 :                 SHA512Update(&ctx, &pd->dst->v6, sizeof(struct in6_addr));
    3469           0 :                 break;
    3470             : #endif /* INET6 */
    3471             :         }
    3472           0 :         SHA512Final(digest.bytes, &ctx);
    3473           0 :         pf_tcp_iss_off += 4096;
    3474           0 :         return (digest.words[0] + tcp_iss + pf_tcp_iss_off);
    3475           0 : }
    3476             : 
    3477             : void
    3478           0 : pf_rule_to_actions(struct pf_rule *r, struct pf_rule_actions *a)
    3479             : {
    3480           0 :         if (r->qid)
    3481           0 :                 a->qid = r->qid;
    3482           0 :         if (r->pqid)
    3483           0 :                 a->pqid = r->pqid;
    3484           0 :         if (r->rtableid >= 0)
    3485           0 :                 a->rtableid = r->rtableid;
    3486             : #if NPFLOG > 0
    3487           0 :         a->log |= r->log;
    3488             : #endif  /* NPFLOG > 0 */
    3489           0 :         if (r->scrub_flags & PFSTATE_SETTOS)
    3490           0 :                 a->set_tos = r->set_tos;
    3491           0 :         if (r->min_ttl)
    3492           0 :                 a->min_ttl = r->min_ttl;
    3493           0 :         if (r->max_mss)
    3494           0 :                 a->max_mss = r->max_mss;
    3495           0 :         a->flags |= (r->scrub_flags & (PFSTATE_NODF|PFSTATE_RANDOMID|
    3496             :             PFSTATE_SETTOS|PFSTATE_SCRUB_TCP|PFSTATE_SETPRIO));
    3497           0 :         if (r->scrub_flags & PFSTATE_SETPRIO) {
    3498           0 :                 a->set_prio[0] = r->set_prio[0];
    3499           0 :                 a->set_prio[1] = r->set_prio[1];
    3500           0 :         }
    3501           0 :         if (r->rule_flag & PFRULE_SETDELAY)
    3502           0 :                 a->delay = r->delay;
    3503           0 : }
    3504             : 
    3505             : #define PF_TEST_ATTRIB(t, a)                    \
    3506             :         if (t) {                                \
    3507             :                 r = a;                          \
    3508             :                 continue;                       \
    3509             :         } else do {                             \
    3510             :         } while (0)
    3511             : 
    3512             : enum pf_test_status
    3513           0 : pf_match_rule(struct pf_test_ctx *ctx, struct pf_ruleset *ruleset)
    3514             : {
    3515             :         struct pf_rule  *r;
    3516             :         struct pf_rule  *save_a;
    3517             :         struct pf_ruleset       *save_aruleset;
    3518             : 
    3519           0 :         r = TAILQ_FIRST(ruleset->rules.active.ptr);
    3520           0 :         while (r != NULL) {
    3521           0 :                 r->evaluations++;
    3522           0 :                 PF_TEST_ATTRIB(
    3523             :                     (pfi_kif_match(r->kif, ctx->pd->kif) == r->ifnot),
    3524             :                         r->skip[PF_SKIP_IFP].ptr);
    3525           0 :                 PF_TEST_ATTRIB((r->direction && r->direction != ctx->pd->dir),
    3526             :                         r->skip[PF_SKIP_DIR].ptr);
    3527           0 :                 PF_TEST_ATTRIB((r->onrdomain >= 0  &&
    3528             :                     (r->onrdomain == ctx->pd->rdomain) == r->ifnot),
    3529             :                         r->skip[PF_SKIP_RDOM].ptr);
    3530           0 :                 PF_TEST_ATTRIB((r->af && r->af != ctx->pd->af),
    3531             :                         r->skip[PF_SKIP_AF].ptr);
    3532           0 :                 PF_TEST_ATTRIB((r->proto && r->proto != ctx->pd->proto),
    3533             :                         r->skip[PF_SKIP_PROTO].ptr);
    3534           0 :                 PF_TEST_ATTRIB((PF_MISMATCHAW(&r->src.addr, &ctx->pd->nsaddr,
    3535             :                     ctx->pd->naf, r->src.neg, ctx->pd->kif,
    3536             :                     ctx->act.rtableid)),
    3537             :                         r->skip[PF_SKIP_SRC_ADDR].ptr);
    3538           0 :                 PF_TEST_ATTRIB((PF_MISMATCHAW(&r->dst.addr, &ctx->pd->ndaddr,
    3539             :                     ctx->pd->af, r->dst.neg, NULL, ctx->act.rtableid)),
    3540             :                         r->skip[PF_SKIP_DST_ADDR].ptr);
    3541             : 
    3542           0 :                 switch (ctx->pd->virtual_proto) {
    3543             :                 case PF_VPROTO_FRAGMENT:
    3544             :                         /* tcp/udp only. port_op always 0 in other cases */
    3545           0 :                         PF_TEST_ATTRIB((r->src.port_op || r->dst.port_op),
    3546             :                                 TAILQ_NEXT(r, entries));
    3547           0 :                         PF_TEST_ATTRIB((ctx->pd->proto == IPPROTO_TCP &&
    3548             :                             r->flagset),
    3549             :                                 TAILQ_NEXT(r, entries));
    3550             :                         /* icmp only. type/code always 0 in other cases */
    3551           0 :                         PF_TEST_ATTRIB((r->type || r->code),
    3552             :                                 TAILQ_NEXT(r, entries));
    3553             :                         /* tcp/udp only. {uid|gid}.op always 0 in other cases */
    3554           0 :                         PF_TEST_ATTRIB((r->gid.op || r->uid.op),
    3555             :                                 TAILQ_NEXT(r, entries));
    3556             :                         break;
    3557             : 
    3558             :                 case IPPROTO_TCP:
    3559           0 :                         PF_TEST_ATTRIB(((r->flagset & ctx->th->th_flags) !=
    3560             :                             r->flags),
    3561             :                                 TAILQ_NEXT(r, entries));
    3562           0 :                         PF_TEST_ATTRIB((r->os_fingerprint != PF_OSFP_ANY &&
    3563             :                             !pf_osfp_match(pf_osfp_fingerprint(ctx->pd),
    3564             :                             r->os_fingerprint)),
    3565             :                                 TAILQ_NEXT(r, entries));
    3566             :                         /* FALLTHROUGH */
    3567             : 
    3568             :                 case IPPROTO_UDP:
    3569             :                         /* tcp/udp only. port_op always 0 in other cases */
    3570           0 :                         PF_TEST_ATTRIB((r->src.port_op &&
    3571             :                             !pf_match_port(r->src.port_op, r->src.port[0],
    3572             :                             r->src.port[1], ctx->pd->nsport)),
    3573             :                                 r->skip[PF_SKIP_SRC_PORT].ptr);
    3574           0 :                         PF_TEST_ATTRIB((r->dst.port_op &&
    3575             :                             !pf_match_port(r->dst.port_op, r->dst.port[0],
    3576             :                             r->dst.port[1], ctx->pd->ndport)),
    3577             :                                 r->skip[PF_SKIP_DST_PORT].ptr);
    3578             :                         /* tcp/udp only. uid.op always 0 in other cases */
    3579           0 :                         PF_TEST_ATTRIB((r->uid.op && (ctx->pd->lookup.done ||
    3580             :                             (ctx->pd->lookup.done =
    3581             :                             pf_socket_lookup(ctx->pd), 1)) &&
    3582             :                             !pf_match_uid(r->uid.op, r->uid.uid[0],
    3583             :                             r->uid.uid[1], ctx->pd->lookup.uid)),
    3584             :                                 TAILQ_NEXT(r, entries));
    3585             :                         /* tcp/udp only. gid.op always 0 in other cases */
    3586           0 :                         PF_TEST_ATTRIB((r->gid.op && (ctx->pd->lookup.done ||
    3587             :                             (ctx->pd->lookup.done =
    3588             :                             pf_socket_lookup(ctx->pd), 1)) &&
    3589             :                             !pf_match_gid(r->gid.op, r->gid.gid[0],
    3590             :                             r->gid.gid[1], ctx->pd->lookup.gid)),
    3591             :                                 TAILQ_NEXT(r, entries));
    3592             :                         break;
    3593             : 
    3594             :                 case IPPROTO_ICMP:
    3595             :                 case IPPROTO_ICMPV6:
    3596             :                         /* icmp only. type always 0 in other cases */
    3597           0 :                         PF_TEST_ATTRIB((r->type &&
    3598             :                             r->type != ctx->icmptype + 1),
    3599             :                                 TAILQ_NEXT(r, entries));
    3600             :                         /* icmp only. type always 0 in other cases */
    3601           0 :                         PF_TEST_ATTRIB((r->code &&
    3602             :                             r->code != ctx->icmpcode + 1),
    3603             :                                 TAILQ_NEXT(r, entries));
    3604             :                         /* icmp only. don't create states on replies */
    3605           0 :                         PF_TEST_ATTRIB((r->keep_state && !ctx->state_icmp &&
    3606             :                             (r->rule_flag & PFRULE_STATESLOPPY) == 0 &&
    3607             :                             ctx->icmp_dir != PF_IN),
    3608             :                                 TAILQ_NEXT(r, entries));
    3609             :                         break;
    3610             : 
    3611             :                 default:
    3612             :                         break;
    3613             :                 }
    3614             : 
    3615           0 :                 PF_TEST_ATTRIB((r->rule_flag & PFRULE_FRAGMENT &&
    3616             :                     ctx->pd->virtual_proto != PF_VPROTO_FRAGMENT),
    3617             :                         TAILQ_NEXT(r, entries));
    3618           0 :                 PF_TEST_ATTRIB((r->tos && !(r->tos == ctx->pd->tos)),
    3619             :                         TAILQ_NEXT(r, entries));
    3620           0 :                 PF_TEST_ATTRIB((r->prob &&
    3621             :                     r->prob <= arc4random_uniform(UINT_MAX - 1) + 1),
    3622             :                         TAILQ_NEXT(r, entries));
    3623           0 :                 PF_TEST_ATTRIB((r->match_tag &&
    3624             :                     !pf_match_tag(ctx->pd->m, r, &ctx->tag)),
    3625             :                         TAILQ_NEXT(r, entries));
    3626           0 :                 PF_TEST_ATTRIB((r->rcv_kif && pf_match_rcvif(ctx->pd->m, r) ==
    3627             :                     r->rcvifnot),
    3628             :                         TAILQ_NEXT(r, entries));
    3629           0 :                 PF_TEST_ATTRIB((r->prio &&
    3630             :                     (r->prio == PF_PRIO_ZERO ? 0 : r->prio) !=
    3631             :                     ctx->pd->m->m_pkthdr.pf.prio),
    3632             :                         TAILQ_NEXT(r, entries));
    3633             : 
    3634             :                 /* must be last! */
    3635           0 :                 if (r->pktrate.limit) {
    3636           0 :                         pf_add_threshold(&r->pktrate);
    3637           0 :                         PF_TEST_ATTRIB((pf_check_threshold(&r->pktrate)),
    3638             :                                 TAILQ_NEXT(r, entries));
    3639             :                 }
    3640             : 
    3641             :                 /* FALLTHROUGH */
    3642           0 :                 if (r->tag)
    3643           0 :                         ctx->tag = r->tag;
    3644           0 :                 if (r->anchor == NULL) {
    3645           0 :                         if (r->action == PF_MATCH) {
    3646           0 :                                 if ((ctx->ri = pool_get(&pf_rule_item_pl,
    3647           0 :                                     PR_NOWAIT)) == NULL) {
    3648           0 :                                         REASON_SET(&ctx->reason, PFRES_MEMORY);
    3649           0 :                                         ctx->test_status = PF_TEST_FAIL;
    3650           0 :                                         break;
    3651             :                                 }
    3652           0 :                                 ctx->ri->r = r;
    3653             :                                 /* order is irrelevant */
    3654           0 :                                 SLIST_INSERT_HEAD(&ctx->rules, ctx->ri, entry);
    3655           0 :                                 ctx->ri = NULL;
    3656           0 :                                 pf_rule_to_actions(r, &ctx->act);
    3657           0 :                                 if (r->rule_flag & PFRULE_AFTO)
    3658           0 :                                         ctx->pd->naf = r->naf;
    3659           0 :                                 if (pf_get_transaddr(r, ctx->pd, ctx->sns,
    3660           0 :                                     &ctx->nr) == -1) {
    3661           0 :                                         REASON_SET(&ctx->reason,
    3662             :                                             PFRES_TRANSLATE);
    3663           0 :                                         ctx->test_status = PF_TEST_FAIL;
    3664           0 :                                         break;
    3665             :                                 }
    3666             : #if NPFLOG > 0
    3667           0 :                                 if (r->log) {
    3668           0 :                                         REASON_SET(&ctx->reason, PFRES_MATCH);
    3669           0 :                                         pflog_packet(ctx->pd, ctx->reason, r,
    3670           0 :                                             ctx->a, ruleset, NULL);
    3671           0 :                                 }
    3672             : #endif  /* NPFLOG > 0 */
    3673             :                         } else {
    3674             :                                 /*
    3675             :                                  * found matching r
    3676             :                                  */
    3677           0 :                                 *ctx->rm = r;
    3678             :                                 /*
    3679             :                                  * anchor, with ruleset, where r belongs to
    3680             :                                  */
    3681           0 :                                 *ctx->am = ctx->a;
    3682             :                                 /*
    3683             :                                  * ruleset where r belongs to
    3684             :                                  */
    3685           0 :                                 *ctx->rsm = ruleset;
    3686             :                                 /*
    3687             :                                  * ruleset, where anchor belongs to.
    3688             :                                  */
    3689           0 :                                 ctx->arsm = ctx->aruleset;
    3690             :                         }
    3691             : 
    3692             : #if NPFLOG > 0
    3693           0 :                         if (ctx->act.log & PF_LOG_MATCHES)
    3694           0 :                                 pf_log_matches(ctx->pd, r, ctx->a, ruleset,
    3695           0 :                                     &ctx->rules);
    3696             : #endif  /* NPFLOG > 0 */
    3697             : 
    3698           0 :                         if (r->quick) {
    3699           0 :                                 ctx->test_status = PF_TEST_QUICK;
    3700           0 :                                 break;
    3701             :                         }
    3702             :                 } else {
    3703           0 :                         save_a = ctx->a;
    3704           0 :                         save_aruleset = ctx->aruleset;
    3705           0 :                         ctx->a = r;          /* remember anchor */
    3706           0 :                         ctx->aruleset = ruleset;     /* and its ruleset */
    3707             :                         /*
    3708             :                          * Note: we don't need to restore if we are not going
    3709             :                          * to continue with ruleset evaluation.
    3710             :                          */
    3711           0 :                         if (pf_step_into_anchor(ctx, r) != PF_TEST_OK)
    3712             :                                 break;
    3713           0 :                         ctx->a = save_a;
    3714           0 :                         ctx->aruleset = save_aruleset;
    3715             :                 }
    3716           0 :                 r = TAILQ_NEXT(r, entries);
    3717             :         }
    3718             : 
    3719           0 :         return (ctx->test_status);
    3720             : }
    3721             : 
    3722             : int
    3723           0 : pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, struct pf_state **sm,
    3724             :     struct pf_rule **am, struct pf_ruleset **rsm, u_short *reason)
    3725             : {
    3726             :         struct pf_rule          *r = NULL;
    3727             :         struct pf_rule          *a = NULL;
    3728             :         struct pf_ruleset       *ruleset = NULL;
    3729           0 :         struct pf_state_key     *skw = NULL, *sks = NULL;
    3730           0 :         int                      rewrite = 0;
    3731           0 :         u_int16_t                virtual_type, virtual_id;
    3732             :         int                      action = PF_DROP;
    3733           0 :         struct pf_test_ctx       ctx;
    3734             :         int                      rv;
    3735             : 
    3736           0 :         memset(&ctx, 0, sizeof(ctx));
    3737           0 :         ctx.pd = pd;
    3738           0 :         ctx.rm = rm;
    3739           0 :         ctx.am = am;
    3740           0 :         ctx.rsm = rsm;
    3741           0 :         ctx.th = &pd->hdr.tcp;
    3742           0 :         ctx.act.rtableid = pd->rdomain;
    3743           0 :         ctx.tag = -1;
    3744           0 :         SLIST_INIT(&ctx.rules);
    3745             : 
    3746           0 :         if (pd->dir == PF_IN && if_congested()) {
    3747           0 :                 REASON_SET(&ctx.reason, PFRES_CONGEST);
    3748           0 :                 return (PF_DROP);
    3749             :         }
    3750             : 
    3751           0 :         switch (pd->virtual_proto) {
    3752             :         case IPPROTO_ICMP:
    3753           0 :                 ctx.icmptype = pd->hdr.icmp.icmp_type;
    3754           0 :                 ctx.icmpcode = pd->hdr.icmp.icmp_code;
    3755           0 :                 ctx.state_icmp = pf_icmp_mapping(pd, ctx.icmptype,
    3756           0 :                     &ctx.icmp_dir, &virtual_id, &virtual_type);
    3757           0 :                 if (ctx.icmp_dir == PF_IN) {
    3758           0 :                         pd->osport = pd->nsport = virtual_id;
    3759           0 :                         pd->odport = pd->ndport = virtual_type;
    3760           0 :                 } else {
    3761           0 :                         pd->osport = pd->nsport = virtual_type;
    3762           0 :                         pd->odport = pd->ndport = virtual_id;
    3763             :                 }
    3764             :                 break;
    3765             : #ifdef INET6
    3766             :         case IPPROTO_ICMPV6:
    3767           0 :                 ctx.icmptype = pd->hdr.icmp6.icmp6_type;
    3768           0 :                 ctx.icmpcode = pd->hdr.icmp6.icmp6_code;
    3769           0 :                 ctx.state_icmp = pf_icmp_mapping(pd, ctx.icmptype,
    3770           0 :                     &ctx.icmp_dir, &virtual_id, &virtual_type);
    3771           0 :                 if (ctx.icmp_dir == PF_IN) {
    3772           0 :                         pd->osport = pd->nsport = virtual_id;
    3773           0 :                         pd->odport = pd->ndport = virtual_type;
    3774           0 :                 } else {
    3775           0 :                         pd->osport = pd->nsport = virtual_type;
    3776           0 :                         pd->odport = pd->ndport = virtual_id;
    3777             :                 }
    3778             :                 break;
    3779             : #endif /* INET6 */
    3780             :         }
    3781             : 
    3782             :         ruleset = &pf_main_ruleset;
    3783           0 :         rv = pf_match_rule(&ctx, ruleset);
    3784           0 :         if (rv == PF_TEST_FAIL) {
    3785             :                 /*
    3786             :                  * Reason has been set in pf_match_rule() already.
    3787             :                  */
    3788             :                 goto cleanup;
    3789             :         }
    3790             : 
    3791           0 :         r = *ctx.rm;    /* matching rule */
    3792           0 :         a = *ctx.am;    /* rule that defines an anchor containing 'r' */
    3793           0 :         ruleset = *ctx.rsm;/* ruleset of the anchor defined by the rule 'a' */
    3794           0 :         ctx.aruleset = ctx.arsm;/* ruleset of the 'a' rule itself */
    3795             : 
    3796             :         /* apply actions for last matching pass/block rule */
    3797           0 :         pf_rule_to_actions(r, &ctx.act);
    3798           0 :         if (r->rule_flag & PFRULE_AFTO)
    3799           0 :                 pd->naf = r->naf;
    3800           0 :         if (pf_get_transaddr(r, pd, ctx.sns, &ctx.nr) == -1) {
    3801           0 :                 REASON_SET(&ctx.reason, PFRES_TRANSLATE);
    3802           0 :                 goto cleanup;
    3803             :         }
    3804           0 :         REASON_SET(&ctx.reason, PFRES_MATCH);
    3805             : 
    3806             : #if NPFLOG > 0
    3807           0 :         if (r->log)
    3808           0 :                 pflog_packet(pd, ctx.reason, r, a, ruleset, NULL);
    3809           0 :         if (ctx.act.log & PF_LOG_MATCHES)
    3810           0 :                 pf_log_matches(pd, r, a, ruleset, &ctx.rules);
    3811             : #endif  /* NPFLOG > 0 */
    3812             : 
    3813           0 :         if (pd->virtual_proto != PF_VPROTO_FRAGMENT &&
    3814           0 :             (r->action == PF_DROP) &&
    3815           0 :             ((r->rule_flag & PFRULE_RETURNRST) ||
    3816           0 :             (r->rule_flag & PFRULE_RETURNICMP) ||
    3817           0 :             (r->rule_flag & PFRULE_RETURN))) {
    3818           0 :                 if (pd->proto == IPPROTO_TCP &&
    3819           0 :                     ((r->rule_flag & PFRULE_RETURNRST) ||
    3820           0 :                     (r->rule_flag & PFRULE_RETURN)) &&
    3821           0 :                     !(ctx.th->th_flags & TH_RST)) {
    3822             :                         u_int32_t        ack =
    3823           0 :                             ntohl(ctx.th->th_seq) + pd->p_len;
    3824             : 
    3825           0 :                         if (pf_check_tcp_cksum(pd->m, pd->off,
    3826           0 :                             pd->tot_len - pd->off, pd->af))
    3827           0 :                                 REASON_SET(&ctx.reason, PFRES_PROTCKSUM);
    3828             :                         else {
    3829           0 :                                 if (ctx.th->th_flags & TH_SYN)
    3830           0 :                                         ack++;
    3831           0 :                                 if (ctx.th->th_flags & TH_FIN)
    3832           0 :                                         ack++;
    3833           0 :                                 pf_send_tcp(r, pd->af, pd->dst,
    3834           0 :                                     pd->src, ctx.th->th_dport,
    3835           0 :                                     ctx.th->th_sport, ntohl(ctx.th->th_ack),
    3836           0 :                                     ack, TH_RST|TH_ACK, 0, 0, r->return_ttl,
    3837           0 :                                     1, 0, pd->rdomain);
    3838             :                         }
    3839           0 :                 } else if ((pd->proto != IPPROTO_ICMP ||
    3840           0 :                     ICMP_INFOTYPE(ctx.icmptype)) && pd->af == AF_INET &&
    3841           0 :                     r->return_icmp)
    3842           0 :                         pf_send_icmp(pd->m, r->return_icmp >> 8,
    3843           0 :                             r->return_icmp & 255, 0, pd->af, r, pd->rdomain);
    3844           0 :                 else if ((pd->proto != IPPROTO_ICMPV6 ||
    3845           0 :                     (ctx.icmptype >= ICMP6_ECHO_REQUEST &&
    3846           0 :                     ctx.icmptype != ND_REDIRECT)) && pd->af == AF_INET6 &&
    3847           0 :                     r->return_icmp6)
    3848           0 :                         pf_send_icmp(pd->m, r->return_icmp6 >> 8,
    3849           0 :                             r->return_icmp6 & 255, 0, pd->af, r, pd->rdomain);
    3850             :         }
    3851             : 
    3852           0 :         if (r->action == PF_DROP)
    3853             :                 goto cleanup;
    3854             : 
    3855           0 :         pf_tag_packet(pd->m, ctx.tag, ctx.act.rtableid);
    3856           0 :         if (ctx.act.rtableid >= 0 &&
    3857           0 :             rtable_l2(ctx.act.rtableid) != pd->rdomain)
    3858           0 :                 pd->destchg = 1;
    3859             : 
    3860           0 :         if (r->action == PF_PASS && pd->badopts && ! r->allow_opts) {
    3861           0 :                 REASON_SET(&ctx.reason, PFRES_IPOPTIONS);
    3862             : #if NPFLOG > 0
    3863           0 :                 pd->pflog |= PF_LOG_FORCE;
    3864             : #endif  /* NPFLOG > 0 */
    3865           0 :                 DPFPRINTF(LOG_NOTICE, "dropping packet with "
    3866             :                     "ip/ipv6 options in pf_test_rule()");
    3867             :                 goto cleanup;
    3868             :         }
    3869             : 
    3870             :         action = PF_PASS;
    3871             : 
    3872           0 :         if (pd->virtual_proto != PF_VPROTO_FRAGMENT
    3873           0 :             && !ctx.state_icmp && r->keep_state) {
    3874             : 
    3875           0 :                 if (r->rule_flag & PFRULE_SRCTRACK &&
    3876           0 :                     pf_insert_src_node(&ctx.sns[PF_SN_NONE], r, PF_SN_NONE,
    3877           0 :                     pd->af, pd->src, NULL) != 0) {
    3878           0 :                         REASON_SET(&ctx.reason, PFRES_SRCLIMIT);
    3879           0 :                         goto cleanup;
    3880             :                 }
    3881             : 
    3882           0 :                 if (r->max_states && (r->states_cur >= r->max_states)) {
    3883           0 :                         pf_status.lcounters[LCNT_STATES]++;
    3884           0 :                         REASON_SET(&ctx.reason, PFRES_MAXSTATES);
    3885           0 :                         goto cleanup;
    3886             :                 }
    3887             : 
    3888           0 :                 action = pf_create_state(pd, r, a, ctx.nr, &skw, &sks,
    3889           0 :                     &rewrite, sm, ctx.tag, &ctx.rules, &ctx.act, ctx.sns);
    3890             : 
    3891           0 :                 if (action != PF_PASS)
    3892             :                         goto cleanup;
    3893           0 :                 if (sks != skw) {
    3894             :                         struct pf_state_key     *sk;
    3895             : 
    3896           0 :                         if (pd->dir == PF_IN)
    3897           0 :                                 sk = sks;
    3898             :                         else
    3899             :                                 sk = skw;
    3900           0 :                         rewrite += pf_translate(pd,
    3901           0 :                             &sk->addr[pd->af == pd->naf ? pd->sidx : pd->didx],
    3902           0 :                             sk->port[pd->af == pd->naf ? pd->sidx : pd->didx],
    3903           0 :                             &sk->addr[pd->af == pd->naf ? pd->didx : pd->sidx],
    3904           0 :                             sk->port[pd->af == pd->naf ? pd->didx : pd->sidx],
    3905           0 :                             virtual_type, ctx.icmp_dir);
    3906           0 :                 }
    3907             : 
    3908             : #ifdef INET6
    3909           0 :                 if (rewrite && skw->af != sks->af)
    3910           0 :                         action = PF_AFRT;
    3911             : #endif /* INET6 */
    3912             : 
    3913             :         } else {
    3914           0 :                 while ((ctx.ri = SLIST_FIRST(&ctx.rules))) {
    3915           0 :                         SLIST_REMOVE_HEAD(&ctx.rules, entry);
    3916           0 :                         pool_put(&pf_rule_item_pl, ctx.ri);
    3917             :                 }
    3918             :         }
    3919             : 
    3920             :         /* copy back packet headers if needed */
    3921           0 :         if (rewrite && pd->hdrlen) {
    3922           0 :                 m_copyback(pd->m, pd->off, pd->hdrlen, &pd->hdr, M_NOWAIT);
    3923           0 :         }
    3924             : 
    3925             : #if NPFSYNC > 0
    3926           0 :         if (*sm != NULL && !ISSET((*sm)->state_flags, PFSTATE_NOSYNC) &&
    3927           0 :             pd->dir == PF_OUT && pfsync_up()) {
    3928             :                 /*
    3929             :                  * We want the state created, but we dont
    3930             :                  * want to send this in case a partner
    3931             :                  * firewall has to know about it to allow
    3932             :                  * replies through it.
    3933             :                  */
    3934           0 :                 if (pfsync_defer(*sm, pd->m))
    3935           0 :                         return (PF_DEFER);
    3936             :         }
    3937             : #endif  /* NPFSYNC > 0 */
    3938             : 
    3939           0 :         if (r->rule_flag & PFRULE_ONCE) {
    3940           0 :                 r->rule_flag |= PFRULE_EXPIRED;
    3941           0 :                 r->exptime = time_second;
    3942           0 :                 SLIST_INSERT_HEAD(&pf_rule_gcl, r, gcle);
    3943           0 :         }
    3944             : 
    3945           0 :         return (action);
    3946             : 
    3947             : cleanup:
    3948           0 :         while ((ctx.ri = SLIST_FIRST(&ctx.rules))) {
    3949           0 :                 SLIST_REMOVE_HEAD(&ctx.rules, entry);
    3950           0 :                 pool_put(&pf_rule_item_pl, ctx.ri);
    3951             :         }
    3952             : 
    3953           0 :         return (action);
    3954           0 : }
    3955             : 
    3956             : static __inline int
    3957           0 : pf_create_state(struct pf_pdesc *pd, struct pf_rule *r, struct pf_rule *a,
    3958             :     struct pf_rule *nr, struct pf_state_key **skw, struct pf_state_key **sks,
    3959             :     int *rewrite, struct pf_state **sm, int tag, struct pf_rule_slist *rules,
    3960             :     struct pf_rule_actions *act, struct pf_src_node *sns[PF_SN_MAX])
    3961             : {
    3962             :         struct pf_state         *s = NULL;
    3963           0 :         struct tcphdr           *th = &pd->hdr.tcp;
    3964           0 :         u_int16_t                mss = tcp_mssdflt;
    3965           0 :         u_short                  reason;
    3966             :         u_int                    i;
    3967             : 
    3968           0 :         s = pool_get(&pf_state_pl, PR_NOWAIT | PR_ZERO);
    3969           0 :         if (s == NULL) {
    3970           0 :                 REASON_SET(&reason, PFRES_MEMORY);
    3971           0 :                 goto csfailed;
    3972             :         }
    3973           0 :         s->rule.ptr = r;
    3974           0 :         s->anchor.ptr = a;
    3975           0 :         s->natrule.ptr = nr;
    3976           0 :         if (r->allow_opts)
    3977           0 :                 s->state_flags |= PFSTATE_ALLOWOPTS;
    3978           0 :         if (r->rule_flag & PFRULE_STATESLOPPY)
    3979           0 :                 s->state_flags |= PFSTATE_SLOPPY;
    3980           0 :         if (r->rule_flag & PFRULE_PFLOW)
    3981           0 :                 s->state_flags |= PFSTATE_PFLOW;
    3982             : #if NPFLOG > 0
    3983           0 :         s->log = act->log & PF_LOG_ALL;
    3984             : #endif  /* NPFLOG > 0 */
    3985           0 :         s->qid = act->qid;
    3986           0 :         s->pqid = act->pqid;
    3987           0 :         s->rtableid[pd->didx] = act->rtableid;
    3988           0 :         s->rtableid[pd->sidx] = -1;       /* return traffic is routed normally */
    3989           0 :         s->min_ttl = act->min_ttl;
    3990           0 :         s->set_tos = act->set_tos;
    3991           0 :         s->max_mss = act->max_mss;
    3992           0 :         s->state_flags |= act->flags;
    3993             : #if NPFSYNC > 0
    3994           0 :         s->sync_state = PFSYNC_S_NONE;
    3995             : #endif  /* NPFSYNC > 0 */
    3996           0 :         s->set_prio[0] = act->set_prio[0];
    3997           0 :         s->set_prio[1] = act->set_prio[1];
    3998           0 :         s->delay = act->delay;
    3999           0 :         SLIST_INIT(&s->src_nodes);
    4000             :         /*
    4001             :          * must initialize refcnt, before pf_state_insert() gets called.
    4002             :          * pf_state_inserts() grabs reference for pfsync!
    4003             :          */
    4004           0 :         refcnt_init(&s->refcnt);
    4005             : 
    4006           0 :         switch (pd->proto) {
    4007             :         case IPPROTO_TCP:
    4008           0 :                 s->src.seqlo = ntohl(th->th_seq);
    4009           0 :                 s->src.seqhi = s->src.seqlo + pd->p_len + 1;
    4010           0 :                 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
    4011           0 :                     r->keep_state == PF_STATE_MODULATE) {
    4012             :                         /* Generate sequence number modulator */
    4013           0 :                         if ((s->src.seqdiff = pf_tcp_iss(pd) - s->src.seqlo) ==
    4014             :                             0)
    4015           0 :                                 s->src.seqdiff = 1;
    4016           0 :                         pf_patch_32(pd,
    4017           0 :                             &th->th_seq, htonl(s->src.seqlo + s->src.seqdiff));
    4018           0 :                         *rewrite = 1;
    4019           0 :                 } else
    4020           0 :                         s->src.seqdiff = 0;
    4021           0 :                 if (th->th_flags & TH_SYN) {
    4022           0 :                         s->src.seqhi++;
    4023           0 :                         s->src.wscale = pf_get_wscale(pd);
    4024           0 :                 }
    4025           0 :                 s->src.max_win = MAX(ntohs(th->th_win), 1);
    4026           0 :                 if (s->src.wscale & PF_WSCALE_MASK) {
    4027             :                         /* Remove scale factor from initial window */
    4028           0 :                         int win = s->src.max_win;
    4029           0 :                         win += 1 << (s->src.wscale & PF_WSCALE_MASK);
    4030           0 :                         s->src.max_win = (win - 1) >>
    4031             :                             (s->src.wscale & PF_WSCALE_MASK);
    4032           0 :                 }
    4033           0 :                 if (th->th_flags & TH_FIN)
    4034           0 :                         s->src.seqhi++;
    4035           0 :                 s->dst.seqhi = 1;
    4036           0 :                 s->dst.max_win = 1;
    4037           0 :                 pf_set_protostate(s, PF_PEER_SRC, TCPS_SYN_SENT);
    4038           0 :                 pf_set_protostate(s, PF_PEER_DST, TCPS_CLOSED);
    4039           0 :                 s->timeout = PFTM_TCP_FIRST_PACKET;
    4040           0 :                 pf_status.states_halfopen++;
    4041           0 :                 break;
    4042             :         case IPPROTO_UDP:
    4043           0 :                 pf_set_protostate(s, PF_PEER_SRC, PFUDPS_SINGLE);
    4044           0 :                 pf_set_protostate(s, PF_PEER_DST, PFUDPS_NO_TRAFFIC);
    4045           0 :                 s->timeout = PFTM_UDP_FIRST_PACKET;
    4046           0 :                 break;
    4047             :         case IPPROTO_ICMP:
    4048             : #ifdef INET6
    4049             :         case IPPROTO_ICMPV6:
    4050             : #endif  /* INET6 */
    4051           0 :                 s->timeout = PFTM_ICMP_FIRST_PACKET;
    4052           0 :                 break;
    4053             :         default:
    4054           0 :                 pf_set_protostate(s, PF_PEER_SRC, PFOTHERS_SINGLE);
    4055           0 :                 pf_set_protostate(s, PF_PEER_DST, PFOTHERS_NO_TRAFFIC);
    4056           0 :                 s->timeout = PFTM_OTHER_FIRST_PACKET;
    4057           0 :         }
    4058             : 
    4059           0 :         s->creation = time_uptime;
    4060           0 :         s->expire = time_uptime;
    4061             : 
    4062           0 :         if (pd->proto == IPPROTO_TCP) {
    4063           0 :                 if (s->state_flags & PFSTATE_SCRUB_TCP &&
    4064           0 :                     pf_normalize_tcp_init(pd, &s->src)) {
    4065           0 :                         REASON_SET(&reason, PFRES_MEMORY);
    4066           0 :                         goto csfailed;
    4067             :                 }
    4068           0 :                 if (s->state_flags & PFSTATE_SCRUB_TCP && s->src.scrub &&
    4069           0 :                     pf_normalize_tcp_stateful(pd, &reason, s, &s->src, &s->dst,
    4070             :                     rewrite)) {
    4071             :                         /* This really shouldn't happen!!! */
    4072           0 :                         DPFPRINTF(LOG_ERR,
    4073             :                             "%s: tcp normalize failed on first pkt", __func__);
    4074             :                         goto csfailed;
    4075             :                 }
    4076             :         }
    4077           0 :         s->direction = pd->dir;
    4078             : 
    4079           0 :         if (pf_state_key_setup(pd, skw, sks, act->rtableid)) {
    4080           0 :                 REASON_SET(&reason, PFRES_MEMORY);
    4081           0 :                 goto csfailed;
    4082             :         }
    4083             : 
    4084           0 :         for (i = 0; i < PF_SN_MAX; i++)
    4085           0 :                 if (sns[i] != NULL) {
    4086             :                         struct pf_sn_item       *sni;
    4087             : 
    4088           0 :                         sni = pool_get(&pf_sn_item_pl, PR_NOWAIT);
    4089           0 :                         if (sni == NULL) {
    4090           0 :                                 REASON_SET(&reason, PFRES_MEMORY);
    4091           0 :                                 goto csfailed;
    4092             :                         }
    4093           0 :                         sni->sn = sns[i];
    4094           0 :                         SLIST_INSERT_HEAD(&s->src_nodes, sni, next);
    4095           0 :                         sni->sn->states++;
    4096           0 :                 }
    4097             : 
    4098           0 :         if (pf_set_rt_ifp(s, pd->src, (*skw)->af) != 0) {
    4099           0 :                 REASON_SET(&reason, PFRES_NOROUTE);
    4100           0 :                 goto csfailed;
    4101             :         }
    4102             : 
    4103           0 :         if (pf_state_insert(BOUND_IFACE(r, pd->kif), skw, sks, s)) {
    4104           0 :                 pf_detach_state(s);
    4105           0 :                 *sks = *skw = NULL;
    4106           0 :                 REASON_SET(&reason, PFRES_STATEINS);
    4107           0 :                 goto csfailed;
    4108             :         } else
    4109           0 :                 *sm = s;
    4110             : 
    4111             :         /*
    4112             :          * Make state responsible for rules it binds here.
    4113             :          */
    4114           0 :         memcpy(&s->match_rules, rules, sizeof(s->match_rules));
    4115           0 :         memset(rules, 0, sizeof(*rules));
    4116           0 :         STATE_INC_COUNTERS(s);
    4117             : 
    4118           0 :         if (tag > 0) {
    4119           0 :                 pf_tag_ref(tag);
    4120           0 :                 s->tag = tag;
    4121           0 :         }
    4122           0 :         if (pd->proto == IPPROTO_TCP && (th->th_flags & (TH_SYN|TH_ACK)) ==
    4123           0 :             TH_SYN && r->keep_state == PF_STATE_SYNPROXY) {
    4124           0 :                 int rtid = pd->rdomain;
    4125           0 :                 if (act->rtableid >= 0)
    4126           0 :                         rtid = act->rtableid;
    4127           0 :                 pf_set_protostate(s, PF_PEER_SRC, PF_TCPS_PROXY_SRC);
    4128           0 :                 s->src.seqhi = arc4random();
    4129             :                 /* Find mss option */
    4130           0 :                 mss = pf_get_mss(pd);
    4131           0 :                 mss = pf_calc_mss(pd->src, pd->af, rtid, mss);
    4132           0 :                 mss = pf_calc_mss(pd->dst, pd->af, rtid, mss);
    4133           0 :                 s->src.mss = mss;
    4134           0 :                 pf_send_tcp(r, pd->af, pd->dst, pd->src, th->th_dport,
    4135           0 :                     th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
    4136           0 :                     TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, pd->rdomain);
    4137           0 :                 REASON_SET(&reason, PFRES_SYNPROXY);
    4138             :                 return (PF_SYNPROXY_DROP);
    4139             :         }
    4140             : 
    4141           0 :         return (PF_PASS);
    4142             : 
    4143             : csfailed:
    4144           0 :         if (s) {
    4145           0 :                 pf_normalize_tcp_cleanup(s);    /* safe even w/o init */
    4146           0 :                 pf_src_tree_remove_state(s);
    4147           0 :                 pool_put(&pf_state_pl, s);
    4148           0 :         }
    4149             : 
    4150           0 :         for (i = 0; i < PF_SN_MAX; i++)
    4151           0 :                 if (sns[i] != NULL)
    4152           0 :                         pf_remove_src_node(sns[i]);
    4153             : 
    4154           0 :         return (PF_DROP);
    4155           0 : }
    4156             : 
    4157             : int
    4158           0 : pf_translate(struct pf_pdesc *pd, struct pf_addr *saddr, u_int16_t sport,
    4159             :     struct pf_addr *daddr, u_int16_t dport, u_int16_t virtual_type,
    4160             :     int icmp_dir)
    4161             : {
    4162             :         /*
    4163             :          * when called from bpf_mtap_pflog, there are extra constraints:
    4164             :          * -mbuf is faked, m_data is the bpf buffer
    4165             :          * -pd is not fully set up
    4166             :          */
    4167             :         int     rewrite = 0;
    4168           0 :         int     afto = pd->af != pd->naf;
    4169             : 
    4170           0 :         if (afto || PF_ANEQ(daddr, pd->dst, pd->af))
    4171           0 :                 pd->destchg = 1;
    4172             : 
    4173           0 :         switch (pd->proto) {
    4174             :         case IPPROTO_TCP:       /* FALLTHROUGH */
    4175             :         case IPPROTO_UDP:
    4176           0 :                 rewrite += pf_patch_16(pd, pd->sport, sport);
    4177           0 :                 rewrite += pf_patch_16(pd, pd->dport, dport);
    4178           0 :                 break;
    4179             : 
    4180             :         case IPPROTO_ICMP:
    4181             :                 /* pf_translate() is also used when logging invalid packets */
    4182           0 :                 if (pd->af != AF_INET)
    4183           0 :                         return (0);
    4184             : 
    4185           0 :                 if (afto) {
    4186             : #ifdef INET6
    4187           0 :                         if (pf_translate_icmp_af(pd, AF_INET6, &pd->hdr.icmp))
    4188           0 :                                 return (0);
    4189           0 :                         pd->proto = IPPROTO_ICMPV6;
    4190             :                         rewrite = 1;
    4191             : #endif /* INET6 */
    4192           0 :                 }
    4193           0 :                 if (virtual_type == htons(ICMP_ECHO)) {
    4194           0 :                         u_int16_t icmpid = (icmp_dir == PF_IN) ? sport : dport;
    4195           0 :                         rewrite += pf_patch_16(pd,
    4196           0 :                             &pd->hdr.icmp.icmp_id, icmpid);
    4197           0 :                 }
    4198             :                 break;
    4199             : 
    4200             : #ifdef INET6
    4201             :         case IPPROTO_ICMPV6:
    4202             :                 /* pf_translate() is also used when logging invalid packets */
    4203           0 :                 if (pd->af != AF_INET6)
    4204           0 :                         return (0);
    4205             : 
    4206           0 :                 if (afto) {
    4207           0 :                         if (pf_translate_icmp_af(pd, AF_INET, &pd->hdr.icmp6))
    4208           0 :                                 return (0);
    4209           0 :                         pd->proto = IPPROTO_ICMP;
    4210             :                         rewrite = 1;
    4211           0 :                 }
    4212           0 :                 if (virtual_type == htons(ICMP6_ECHO_REQUEST)) {
    4213           0 :                         u_int16_t icmpid = (icmp_dir == PF_IN) ? sport : dport;
    4214           0 :                         rewrite += pf_patch_16(pd,
    4215           0 :                             &pd->hdr.icmp6.icmp6_id, icmpid);
    4216           0 :                 }
    4217             :                 break;
    4218             : #endif /* INET6 */
    4219             :         }
    4220             : 
    4221           0 :         if (!afto) {
    4222           0 :                 rewrite += pf_translate_a(pd, pd->src, saddr);
    4223           0 :                 rewrite += pf_translate_a(pd, pd->dst, daddr);
    4224           0 :         }
    4225             : 
    4226           0 :         return (rewrite);
    4227           0 : }
    4228             : 
    4229             : int
    4230           0 : pf_tcp_track_full(struct pf_pdesc *pd, struct pf_state **state, u_short *reason,
    4231             :     int *copyback, int reverse)
    4232             : {
    4233           0 :         struct tcphdr           *th = &pd->hdr.tcp;
    4234             :         struct pf_state_peer    *src, *dst;
    4235           0 :         u_int16_t                win = ntohs(th->th_win);
    4236             :         u_int32_t                ack, end, data_end, seq, orig_seq;
    4237             :         u_int8_t                 sws, dws, psrc, pdst;
    4238             :         int                      ackskew;
    4239             : 
    4240           0 :         if ((pd->dir == (*state)->direction && !reverse) ||
    4241           0 :             (pd->dir != (*state)->direction && reverse)) {
    4242           0 :                 src = &(*state)->src;
    4243           0 :                 dst = &(*state)->dst;
    4244             :                 psrc = PF_PEER_SRC;
    4245             :                 pdst = PF_PEER_DST;
    4246           0 :         } else {
    4247           0 :                 src = &(*state)->dst;
    4248           0 :                 dst = &(*state)->src;
    4249             :                 psrc = PF_PEER_DST;
    4250             :                 pdst = PF_PEER_SRC;
    4251             :         }
    4252             : 
    4253           0 :         if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
    4254           0 :                 sws = src->wscale & PF_WSCALE_MASK;
    4255           0 :                 dws = dst->wscale & PF_WSCALE_MASK;
    4256           0 :         } else
    4257             :                 sws = dws = 0;
    4258             : 
    4259             :         /*
    4260             :          * Sequence tracking algorithm from Guido van Rooij's paper:
    4261             :          *   http://www.madison-gurkha.com/publications/tcp_filtering/
    4262             :          *      tcp_filtering.ps
    4263             :          */
    4264             : 
    4265           0 :         orig_seq = seq = ntohl(th->th_seq);
    4266           0 :         if (src->seqlo == 0) {
    4267             :                 /* First packet from this end. Set its state */
    4268             : 
    4269           0 :                 if (((*state)->state_flags & PFSTATE_SCRUB_TCP || dst->scrub) &&
    4270           0 :                     src->scrub == NULL) {
    4271           0 :                         if (pf_normalize_tcp_init(pd, src)) {
    4272           0 :                                 REASON_SET(reason, PFRES_MEMORY);
    4273           0 :                                 return (PF_DROP);
    4274             :                         }
    4275             :                 }
    4276             : 
    4277             :                 /* Deferred generation of sequence number modulator */
    4278           0 :                 if (dst->seqdiff && !src->seqdiff) {
    4279             :                         /* use random iss for the TCP server */
    4280           0 :                         while ((src->seqdiff = arc4random() - seq) == 0)
    4281           0 :                                 continue;
    4282           0 :                         ack = ntohl(th->th_ack) - dst->seqdiff;
    4283           0 :                         pf_patch_32(pd, &th->th_seq, htonl(seq + src->seqdiff));
    4284           0 :                         pf_patch_32(pd, &th->th_ack, htonl(ack));
    4285           0 :                         *copyback = 1;
    4286           0 :                 } else {
    4287           0 :                         ack = ntohl(th->th_ack);
    4288             :                 }
    4289             : 
    4290           0 :                 end = seq + pd->p_len;
    4291           0 :                 if (th->th_flags & TH_SYN) {
    4292           0 :                         end++;
    4293           0 :                         if (dst->wscale & PF_WSCALE_FLAG) {
    4294           0 :                                 src->wscale = pf_get_wscale(pd);
    4295           0 :                                 if (src->wscale & PF_WSCALE_FLAG) {
    4296             :                                         /* Remove scale factor from initial
    4297             :                                          * window */
    4298           0 :                                         sws = src->wscale & PF_WSCALE_MASK;
    4299           0 :                                         win = ((u_int32_t)win + (1 << sws) - 1)
    4300           0 :                                             >> sws;
    4301           0 :                                         dws = dst->wscale & PF_WSCALE_MASK;
    4302           0 :                                 } else {
    4303             :                                         /* fixup other window */
    4304           0 :                                         dst->max_win = MIN(TCP_MAXWIN,
    4305             :                                             (u_int32_t)dst->max_win <<
    4306             :                                             (dst->wscale & PF_WSCALE_MASK));
    4307             :                                         /* in case of a retrans SYN|ACK */
    4308           0 :                                         dst->wscale = 0;
    4309             :                                 }
    4310             :                         }
    4311             :                 }
    4312             :                 data_end = end;
    4313           0 :                 if (th->th_flags & TH_FIN)
    4314           0 :                         end++;
    4315             : 
    4316           0 :                 src->seqlo = seq;
    4317           0 :                 if (src->state < TCPS_SYN_SENT)
    4318           0 :                         pf_set_protostate(*state, psrc, TCPS_SYN_SENT);
    4319             : 
    4320             :                 /*
    4321             :                  * May need to slide the window (seqhi may have been set by
    4322             :                  * the crappy stack check or if we picked up the connection
    4323             :                  * after establishment)
    4324             :                  */
    4325           0 :                 if (src->seqhi == 1 ||
    4326           0 :                     SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi))
    4327           0 :                         src->seqhi = end + MAX(1, dst->max_win << dws);
    4328           0 :                 if (win > src->max_win)
    4329           0 :                         src->max_win = win;
    4330             : 
    4331             :         } else {
    4332           0 :                 ack = ntohl(th->th_ack) - dst->seqdiff;
    4333           0 :                 if (src->seqdiff) {
    4334             :                         /* Modulate sequence numbers */
    4335           0 :                         pf_patch_32(pd, &th->th_seq, htonl(seq + src->seqdiff));
    4336           0 :                         pf_patch_32(pd, &th->th_ack, htonl(ack));
    4337           0 :                         *copyback = 1;
    4338           0 :                 }
    4339           0 :                 end = seq + pd->p_len;
    4340           0 :                 if (th->th_flags & TH_SYN)
    4341           0 :                         end++;
    4342             :                 data_end = end;
    4343           0 :                 if (th->th_flags & TH_FIN)
    4344           0 :                         end++;
    4345             :         }
    4346             : 
    4347           0 :         if ((th->th_flags & TH_ACK) == 0) {
    4348             :                 /* Let it pass through the ack skew check */
    4349           0 :                 ack = dst->seqlo;
    4350           0 :         } else if ((ack == 0 &&
    4351           0 :             (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) ||
    4352             :             /* broken tcp stacks do not set ack */
    4353           0 :             (dst->state < TCPS_SYN_SENT)) {
    4354             :                 /*
    4355             :                  * Many stacks (ours included) will set the ACK number in an
    4356             :                  * FIN|ACK if the SYN times out -- no sequence to ACK.
    4357             :                  */
    4358           0 :                 ack = dst->seqlo;
    4359           0 :         }
    4360             : 
    4361           0 :         if (seq == end) {
    4362             :                 /* Ease sequencing restrictions on no data packets */
    4363           0 :                 seq = src->seqlo;
    4364             :                 data_end = end = seq;
    4365           0 :         }
    4366             : 
    4367           0 :         ackskew = dst->seqlo - ack;
    4368             : 
    4369             : 
    4370             :         /*
    4371             :          * Need to demodulate the sequence numbers in any TCP SACK options
    4372             :          * (Selective ACK). We could optionally validate the SACK values
    4373             :          * against the current ACK window, either forwards or backwards, but
    4374             :          * I'm not confident that SACK has been implemented properly
    4375             :          * everywhere. It wouldn't surprise me if several stacks accidently
    4376             :          * SACK too far backwards of previously ACKed data. There really aren't
    4377             :          * any security implications of bad SACKing unless the target stack
    4378             :          * doesn't validate the option length correctly. Someone trying to
    4379             :          * spoof into a TCP connection won't bother blindly sending SACK
    4380             :          * options anyway.
    4381             :          */
    4382           0 :         if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) {
    4383           0 :                 if (pf_modulate_sack(pd, dst))
    4384           0 :                         *copyback = 1;
    4385             :         }
    4386             : 
    4387             : 
    4388             : #define MAXACKWINDOW (0xffff + 1500)    /* 1500 is an arbitrary fudge factor */
    4389           0 :         if (SEQ_GEQ(src->seqhi, data_end) &&
    4390             :             /* Last octet inside other's window space */
    4391           0 :             SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
    4392             :             /* Retrans: not more than one window back */
    4393           0 :             (ackskew >= -MAXACKWINDOW) &&
    4394             :             /* Acking not more than one reassembled fragment backwards */
    4395           0 :             (ackskew <= (MAXACKWINDOW << sws)) &&
    4396             :             /* Acking not more than one window forward */
    4397           0 :             ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
    4398           0 :             (orig_seq == src->seqlo + 1) || (orig_seq + 1 == src->seqlo))) {
    4399             :             /* Require an exact/+1 sequence match on resets when possible */
    4400             : 
    4401           0 :                 if (dst->scrub || src->scrub) {
    4402           0 :                         if (pf_normalize_tcp_stateful(pd, reason, *state, src,
    4403             :                             dst, copyback))
    4404           0 :                                 return (PF_DROP);
    4405             :                 }
    4406             : 
    4407             :                 /* update max window */
    4408           0 :                 if (src->max_win < win)
    4409           0 :                         src->max_win = win;
    4410             :                 /* synchronize sequencing */
    4411           0 :                 if (SEQ_GT(end, src->seqlo))
    4412           0 :                         src->seqlo = end;
    4413             :                 /* slide the window of what the other end can send */
    4414           0 :                 if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
    4415           0 :                         dst->seqhi = ack + MAX((win << sws), 1);
    4416             : 
    4417             :                 /* update states */
    4418           0 :                 if (th->th_flags & TH_SYN)
    4419           0 :                         if (src->state < TCPS_SYN_SENT)
    4420           0 :                                 pf_set_protostate(*state, psrc, TCPS_SYN_SENT);
    4421           0 :                 if (th->th_flags & TH_FIN)
    4422           0 :                         if (src->state < TCPS_CLOSING)
    4423           0 :                                 pf_set_protostate(*state, psrc, TCPS_CLOSING);
    4424           0 :                 if (th->th_flags & TH_ACK) {
    4425           0 :                         if (dst->state == TCPS_SYN_SENT) {
    4426           0 :                                 pf_set_protostate(*state, pdst,
    4427             :                                     TCPS_ESTABLISHED);
    4428           0 :                                 if (src->state == TCPS_ESTABLISHED &&
    4429           0 :                                     !SLIST_EMPTY(&(*state)->src_nodes) &&
    4430           0 :                                     pf_src_connlimit(state)) {
    4431           0 :                                         REASON_SET(reason, PFRES_SRCLIMIT);
    4432           0 :                                         return (PF_DROP);
    4433             :                                 }
    4434           0 :                         } else if (dst->state == TCPS_CLOSING)
    4435           0 :                                 pf_set_protostate(*state, pdst,
    4436             :                                     TCPS_FIN_WAIT_2);
    4437             :                 }
    4438           0 :                 if (th->th_flags & TH_RST)
    4439           0 :                         pf_set_protostate(*state, PF_PEER_BOTH, TCPS_TIME_WAIT);
    4440             : 
    4441             :                 /* update expire time */
    4442           0 :                 (*state)->expire = time_uptime;
    4443           0 :                 if (src->state >= TCPS_FIN_WAIT_2 &&
    4444           0 :                     dst->state >= TCPS_FIN_WAIT_2)
    4445           0 :                         (*state)->timeout = PFTM_TCP_CLOSED;
    4446           0 :                 else if (src->state >= TCPS_CLOSING &&
    4447           0 :                     dst->state >= TCPS_CLOSING)
    4448           0 :                         (*state)->timeout = PFTM_TCP_FIN_WAIT;
    4449           0 :                 else if (src->state < TCPS_ESTABLISHED ||
    4450           0 :                     dst->state < TCPS_ESTABLISHED)
    4451           0 :                         (*state)->timeout = PFTM_TCP_OPENING;
    4452           0 :                 else if (src->state >= TCPS_CLOSING ||
    4453           0 :                     dst->state >= TCPS_CLOSING)
    4454           0 :                         (*state)->timeout = PFTM_TCP_CLOSING;
    4455             :                 else
    4456           0 :                         (*state)->timeout = PFTM_TCP_ESTABLISHED;
    4457             : 
    4458             :                 /* Fall through to PASS packet */
    4459           0 :         } else if ((dst->state < TCPS_SYN_SENT ||
    4460           0 :                 dst->state >= TCPS_FIN_WAIT_2 ||
    4461           0 :                 src->state >= TCPS_FIN_WAIT_2) &&
    4462           0 :             SEQ_GEQ(src->seqhi + MAXACKWINDOW, data_end) &&
    4463             :             /* Within a window forward of the originating packet */
    4464           0 :             SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) {
    4465             :             /* Within a window backward of the originating packet */
    4466             : 
    4467             :                 /*
    4468             :                  * This currently handles three situations:
    4469             :                  *  1) Stupid stacks will shotgun SYNs before their peer
    4470             :                  *     replies.
    4471             :                  *  2) When PF catches an already established stream (the
    4472             :                  *     firewall rebooted, the state table was flushed, routes
    4473             :                  *     changed...)
    4474             :                  *  3) Packets get funky immediately after the connection
    4475             :                  *     closes (this should catch Solaris spurious ACK|FINs
    4476             :                  *     that web servers like to spew after a close)
    4477             :                  *
    4478             :                  * This must be a little more careful than the above code
    4479             :                  * since packet floods will also be caught here. We don't
    4480             :                  * update the TTL here to mitigate the damage of a packet
    4481             :                  * flood and so the same code can handle awkward establishment
    4482             :                  * and a loosened connection close.
    4483             :                  * In the establishment case, a correct peer response will
    4484             :                  * validate the connection, go through the normal state code
    4485             :                  * and keep updating the state TTL.
    4486             :                  */
    4487             : 
    4488           0 :                 if (pf_status.debug >= LOG_NOTICE) {
    4489           0 :                         log(LOG_NOTICE, "pf: loose state match: ");
    4490           0 :                         pf_print_state(*state);
    4491           0 :                         pf_print_flags(th->th_flags);
    4492           0 :                         addlog(" seq=%u (%u) ack=%u len=%u ackskew=%d "
    4493             :                             "pkts=%llu:%llu dir=%s,%s\n", seq, orig_seq, ack,
    4494           0 :                             pd->p_len, ackskew, (*state)->packets[0],
    4495           0 :                             (*state)->packets[1],
    4496           0 :                             pd->dir == PF_IN ? "in" : "out",
    4497           0 :                             pd->dir == (*state)->direction ? "fwd" : "rev");
    4498           0 :                 }
    4499             : 
    4500           0 :                 if (dst->scrub || src->scrub) {
    4501           0 :                         if (pf_normalize_tcp_stateful(pd, reason, *state, src,
    4502             :                             dst, copyback))
    4503           0 :                                 return (PF_DROP);
    4504             :                 }
    4505             : 
    4506             :                 /* update max window */
    4507           0 :                 if (src->max_win < win)
    4508           0 :                         src->max_win = win;
    4509             :                 /* synchronize sequencing */
    4510           0 :                 if (SEQ_GT(end, src->seqlo))
    4511           0 :                         src->seqlo = end;
    4512             :                 /* slide the window of what the other end can send */
    4513           0 :                 if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
    4514           0 :                         dst->seqhi = ack + MAX((win << sws), 1);
    4515             : 
    4516             :                 /*
    4517             :                  * Cannot set dst->seqhi here since this could be a shotgunned
    4518             :                  * SYN and not an already established connection.
    4519             :                  */
    4520           0 :                 if (th->th_flags & TH_FIN)
    4521           0 :                         if (src->state < TCPS_CLOSING)
    4522           0 :                                 pf_set_protostate(*state, psrc, TCPS_CLOSING);
    4523           0 :                 if (th->th_flags & TH_RST)
    4524           0 :                         pf_set_protostate(*state, PF_PEER_BOTH, TCPS_TIME_WAIT);
    4525             : 
    4526             :                 /* Fall through to PASS packet */
    4527             :         } else {
    4528           0 :                 if ((*state)->dst.state == TCPS_SYN_SENT &&
    4529           0 :                     (*state)->src.state == TCPS_SYN_SENT) {
    4530             :                         /* Send RST for state mismatches during handshake */
    4531           0 :                         if (!(th->th_flags & TH_RST))
    4532           0 :                                 pf_send_tcp((*state)->rule.ptr, pd->af,
    4533           0 :                                     pd->dst, pd->src, th->th_dport,
    4534           0 :                                     th->th_sport, ntohl(th->th_ack), 0,
    4535             :                                     TH_RST, 0, 0,
    4536           0 :                                     (*state)->rule.ptr->return_ttl, 1, 0,
    4537           0 :                                     pd->rdomain);
    4538           0 :                         src->seqlo = 0;
    4539           0 :                         src->seqhi = 1;
    4540           0 :                         src->max_win = 1;
    4541           0 :                 } else if (pf_status.debug >= LOG_NOTICE) {
    4542           0 :                         log(LOG_NOTICE, "pf: BAD state: ");
    4543           0 :                         pf_print_state(*state);
    4544           0 :                         pf_print_flags(th->th_flags);
    4545           0 :                         addlog(" seq=%u (%u) ack=%u len=%u ackskew=%d "
    4546             :                             "pkts=%llu:%llu dir=%s,%s\n",
    4547           0 :                             seq, orig_seq, ack, pd->p_len, ackskew,
    4548           0 :                             (*state)->packets[0], (*state)->packets[1],
    4549           0 :                             pd->dir == PF_IN ? "in" : "out",
    4550           0 :                             pd->dir == (*state)->direction ? "fwd" : "rev");
    4551           0 :                         addlog("pf: State failure on: %c %c %c %c | %c %c\n",
    4552           0 :                             SEQ_GEQ(src->seqhi, data_end) ? ' ' : '1',
    4553           0 :                             SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
    4554             :                             ' ': '2',
    4555           0 :                             (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
    4556           0 :                             (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',
    4557           0 :                             SEQ_GEQ(src->seqhi + MAXACKWINDOW, data_end) ?
    4558             :                             ' ' :'5',
    4559           0 :                             SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6');
    4560           0 :                 }
    4561           0 :                 REASON_SET(reason, PFRES_BADSTATE);
    4562           0 :                 return (PF_DROP);
    4563             :         }
    4564             : 
    4565           0 :         return (PF_PASS);
    4566           0 : }
    4567             : 
    4568             : int
    4569           0 : pf_tcp_track_sloppy(struct pf_pdesc *pd, struct pf_state **state,
    4570             :     u_short *reason)
    4571             : {
    4572           0 :         struct tcphdr           *th = &pd->hdr.tcp;
    4573             :         struct pf_state_peer    *src, *dst;
    4574             :         u_int8_t                 psrc, pdst;
    4575             : 
    4576           0 :         if (pd->dir == (*state)->direction) {
    4577           0 :                 src = &(*state)->src;
    4578           0 :                 dst = &(*state)->dst;
    4579             :                 psrc = PF_PEER_SRC;
    4580             :                 pdst = PF_PEER_DST;
    4581           0 :         } else {
    4582           0 :                 src = &(*state)->dst;
    4583           0 :                 dst = &(*state)->src;
    4584             :                 psrc = PF_PEER_DST;
    4585             :                 pdst = PF_PEER_SRC;
    4586             :         }
    4587             : 
    4588           0 :         if (th->th_flags & TH_SYN)
    4589           0 :                 if (src->state < TCPS_SYN_SENT)
    4590           0 :                         pf_set_protostate(*state, psrc, TCPS_SYN_SENT);
    4591           0 :         if (th->th_flags & TH_FIN)
    4592           0 :                 if (src->state < TCPS_CLOSING)
    4593           0 :                         pf_set_protostate(*state, psrc, TCPS_CLOSING);
    4594           0 :         if (th->th_flags & TH_ACK) {
    4595           0 :                 if (dst->state == TCPS_SYN_SENT) {
    4596           0 :                         pf_set_protostate(*state, pdst, TCPS_ESTABLISHED);
    4597           0 :                         if (src->state == TCPS_ESTABLISHED &&
    4598           0 :                             !SLIST_EMPTY(&(*state)->src_nodes) &&
    4599           0 :                             pf_src_connlimit(state)) {
    4600           0 :                                 REASON_SET(reason, PFRES_SRCLIMIT);
    4601           0 :                                 return (PF_DROP);
    4602             :                         }
    4603           0 :                 } else if (dst->state == TCPS_CLOSING) {
    4604           0 :                         pf_set_protostate(*state, pdst, TCPS_FIN_WAIT_2);
    4605           0 :                 } else if (src->state == TCPS_SYN_SENT &&
    4606           0 :                     dst->state < TCPS_SYN_SENT) {
    4607             :                         /*
    4608             :                          * Handle a special sloppy case where we only see one
    4609             :                          * half of the connection. If there is a ACK after
    4610             :                          * the initial SYN without ever seeing a packet from
    4611             :                          * the destination, set the connection to established.
    4612             :                          */
    4613           0 :                         pf_set_protostate(*state, PF_PEER_BOTH,
    4614             :                             TCPS_ESTABLISHED);
    4615           0 :                         if (!SLIST_EMPTY(&(*state)->src_nodes) &&
    4616           0 :                             pf_src_connlimit(state)) {
    4617           0 :                                 REASON_SET(reason, PFRES_SRCLIMIT);
    4618           0 :                                 return (PF_DROP);
    4619             :                         }
    4620           0 :                 } else if (src->state == TCPS_CLOSING &&
    4621           0 :                     dst->state == TCPS_ESTABLISHED &&
    4622           0 :                     dst->seqlo == 0) {
    4623             :                         /*
    4624             :                          * Handle the closing of half connections where we
    4625             :                          * don't see the full bidirectional FIN/ACK+ACK
    4626             :                          * handshake.
    4627             :                          */
    4628           0 :                         pf_set_protostate(*state, pdst, TCPS_CLOSING);
    4629           0 :                 }
    4630             :         }
    4631           0 :         if (th->th_flags & TH_RST)
    4632           0 :                 pf_set_protostate(*state, PF_PEER_BOTH, TCPS_TIME_WAIT);
    4633             : 
    4634             :         /* update expire time */
    4635           0 :         (*state)->expire = time_uptime;
    4636           0 :         if (src->state >= TCPS_FIN_WAIT_2 &&
    4637           0 :             dst->state >= TCPS_FIN_WAIT_2)
    4638           0 :                 (*state)->timeout = PFTM_TCP_CLOSED;
    4639           0 :         else if (src->state >= TCPS_CLOSING &&
    4640           0 :             dst->state >= TCPS_CLOSING)
    4641           0 :                 (*state)->timeout = PFTM_TCP_FIN_WAIT;
    4642           0 :         else if (src->state < TCPS_ESTABLISHED ||
    4643           0 :             dst->state < TCPS_ESTABLISHED)
    4644           0 :                 (*state)->timeout = PFTM_TCP_OPENING;
    4645           0 :         else if (src->state >= TCPS_CLOSING ||
    4646           0 :             dst->state >= TCPS_CLOSING)
    4647           0 :                 (*state)->timeout = PFTM_TCP_CLOSING;
    4648             :         else
    4649           0 :                 (*state)->timeout = PFTM_TCP_ESTABLISHED;
    4650             : 
    4651           0 :         return (PF_PASS);
    4652           0 : }
    4653             : 
    4654             : static __inline int
    4655           0 : pf_synproxy(struct pf_pdesc *pd, struct pf_state **state, u_short *reason)
    4656             : {
    4657           0 :         struct pf_state_key     *sk = (*state)->key[pd->didx];
    4658             : 
    4659           0 :         if ((*state)->src.state == PF_TCPS_PROXY_SRC) {
    4660           0 :                 struct tcphdr   *th = &pd->hdr.tcp;
    4661             : 
    4662           0 :                 if (pd->dir != (*state)->direction) {
    4663           0 :                         REASON_SET(reason, PFRES_SYNPROXY);
    4664           0 :                         return (PF_SYNPROXY_DROP);
    4665             :                 }
    4666           0 :                 if (th->th_flags & TH_SYN) {
    4667           0 :                         if (ntohl(th->th_seq) != (*state)->src.seqlo) {
    4668           0 :                                 REASON_SET(reason, PFRES_SYNPROXY);
    4669           0 :                                 return (PF_DROP);
    4670             :                         }
    4671           0 :                         pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
    4672           0 :                             pd->src, th->th_dport, th->th_sport,
    4673           0 :                             (*state)->src.seqhi, ntohl(th->th_seq) + 1,
    4674           0 :                             TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1,
    4675           0 :                             0, pd->rdomain);
    4676           0 :                         REASON_SET(reason, PFRES_SYNPROXY);
    4677           0 :                         return (PF_SYNPROXY_DROP);
    4678           0 :                 } else if ((th->th_flags & (TH_ACK|TH_RST|TH_FIN)) != TH_ACK ||
    4679           0 :                     (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
    4680           0 :                     (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
    4681           0 :                         REASON_SET(reason, PFRES_SYNPROXY);
    4682           0 :                         return (PF_DROP);
    4683           0 :                 } else if (!SLIST_EMPTY(&(*state)->src_nodes) &&
    4684           0 :                     pf_src_connlimit(state)) {
    4685           0 :                         REASON_SET(reason, PFRES_SRCLIMIT);
    4686           0 :                         return (PF_DROP);
    4687             :                 } else
    4688           0 :                         pf_set_protostate(*state, PF_PEER_SRC,
    4689             :                             PF_TCPS_PROXY_DST);
    4690           0 :         }
    4691           0 :         if ((*state)->src.state == PF_TCPS_PROXY_DST) {
    4692           0 :                 struct tcphdr   *th = &pd->hdr.tcp;
    4693             : 
    4694           0 :                 if (pd->dir == (*state)->direction) {
    4695           0 :                         if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) ||
    4696           0 :                             (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
    4697           0 :                             (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
    4698           0 :                                 REASON_SET(reason, PFRES_SYNPROXY);
    4699           0 :                                 return (PF_DROP);
    4700             :                         }
    4701           0 :                         (*state)->src.max_win = MAX(ntohs(th->th_win), 1);
    4702           0 :                         if ((*state)->dst.seqhi == 1)
    4703           0 :                                 (*state)->dst.seqhi = arc4random();
    4704           0 :                         pf_send_tcp((*state)->rule.ptr, pd->af,
    4705           0 :                             &sk->addr[pd->sidx], &sk->addr[pd->didx],
    4706           0 :                             sk->port[pd->sidx], sk->port[pd->didx],
    4707           0 :                             (*state)->dst.seqhi, 0, TH_SYN, 0,
    4708           0 :                             (*state)->src.mss, 0, 0, (*state)->tag,
    4709           0 :                             sk->rdomain);
    4710           0 :                         REASON_SET(reason, PFRES_SYNPROXY);
    4711           0 :                         return (PF_SYNPROXY_DROP);
    4712           0 :                 } else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
    4713           0 :                     (TH_SYN|TH_ACK)) ||
    4714           0 :                     (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) {
    4715           0 :                         REASON_SET(reason, PFRES_SYNPROXY);
    4716           0 :                         return (PF_DROP);
    4717             :                 } else {
    4718           0 :                         (*state)->dst.max_win = MAX(ntohs(th->th_win), 1);
    4719           0 :                         (*state)->dst.seqlo = ntohl(th->th_seq);
    4720           0 :                         pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
    4721           0 :                             pd->src, th->th_dport, th->th_sport,
    4722           0 :                             ntohl(th->th_ack), ntohl(th->th_seq) + 1,
    4723           0 :                             TH_ACK, (*state)->src.max_win, 0, 0, 0,
    4724           0 :                             (*state)->tag, pd->rdomain);
    4725           0 :                         pf_send_tcp((*state)->rule.ptr, pd->af,
    4726           0 :                             &sk->addr[pd->sidx], &sk->addr[pd->didx],
    4727           0 :                             sk->port[pd->sidx], sk->port[pd->didx],
    4728           0 :                             (*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
    4729           0 :                             TH_ACK, (*state)->dst.max_win, 0, 0, 1,
    4730           0 :                             0, sk->rdomain);
    4731           0 :                         (*state)->src.seqdiff = (*state)->dst.seqhi -
    4732           0 :                             (*state)->src.seqlo;
    4733           0 :                         (*state)->dst.seqdiff = (*state)->src.seqhi -
    4734           0 :                             (*state)->dst.seqlo;
    4735           0 :                         (*state)->src.seqhi = (*state)->src.seqlo +
    4736           0 :                             (*state)->dst.max_win;
    4737           0 :                         (*state)->dst.seqhi = (*state)->dst.seqlo +
    4738           0 :                             (*state)->src.max_win;
    4739           0 :                         (*state)->src.wscale = (*state)->dst.wscale = 0;
    4740           0 :                         pf_set_protostate(*state, PF_PEER_BOTH,
    4741             :                             TCPS_ESTABLISHED);
    4742           0 :                         REASON_SET(reason, PFRES_SYNPROXY);
    4743           0 :                         return (PF_SYNPROXY_DROP);
    4744             :                 }
    4745             :         }
    4746           0 :         return (PF_PASS);
    4747           0 : }
    4748             : 
    4749             : int
    4750           0 : pf_test_state(struct pf_pdesc *pd, struct pf_state **state, u_short *reason,
    4751             :     int syncookie)
    4752             : {
    4753           0 :         struct pf_state_key_cmp  key;
    4754           0 :         int                      copyback = 0;
    4755             :         struct pf_state_peer    *src, *dst;
    4756             :         int                      action;
    4757             :         struct inpcb            *inp;
    4758             :         u_int8_t                 psrc, pdst;
    4759             : 
    4760           0 :         key.af = pd->af;
    4761           0 :         key.proto = pd->virtual_proto;
    4762           0 :         key.rdomain = pd->rdomain;
    4763           0 :         PF_ACPY(&key.addr[pd->sidx], pd->src, key.af);
    4764           0 :         PF_ACPY(&key.addr[pd->didx], pd->dst, key.af);
    4765           0 :         key.port[pd->sidx] = pd->osport;
    4766           0 :         key.port[pd->didx] = pd->odport;
    4767           0 :         inp = pd->m->m_pkthdr.pf.inp;
    4768             : 
    4769           0 :         action = pf_find_state(pd, &key, state);
    4770           0 :         if (action != PF_MATCH)
    4771           0 :                 return (action);
    4772             : 
    4773             :         action = PF_PASS;
    4774           0 :         if (pd->dir == (*state)->direction) {
    4775           0 :                 src = &(*state)->src;
    4776           0 :                 dst = &(*state)->dst;
    4777             :                 psrc = PF_PEER_SRC;
    4778             :                 pdst = PF_PEER_DST;
    4779           0 :         } else {
    4780           0 :                 src = &(*state)->dst;
    4781           0 :                 dst = &(*state)->src;
    4782             :                 psrc = PF_PEER_DST;
    4783             :                 pdst = PF_PEER_SRC;
    4784             :         }
    4785             : 
    4786           0 :         switch (pd->virtual_proto) {
    4787             :         case IPPROTO_TCP:
    4788           0 :                 if (syncookie) {
    4789           0 :                         pf_set_protostate(*state, PF_PEER_SRC,
    4790             :                             PF_TCPS_PROXY_DST);
    4791           0 :                         (*state)->dst.seqhi = ntohl(pd->hdr.tcp.th_ack) - 1;
    4792           0 :                 }
    4793           0 :                 if ((action = pf_synproxy(pd, state, reason)) != PF_PASS)
    4794           0 :                         return (action);
    4795           0 :                 if ((pd->hdr.tcp.th_flags & (TH_SYN|TH_ACK)) == TH_SYN) {
    4796             : 
    4797           0 :                         if (dst->state >= TCPS_FIN_WAIT_2 &&
    4798           0 :                             src->state >= TCPS_FIN_WAIT_2) {
    4799           0 :                                 if (pf_status.debug >= LOG_NOTICE) {
    4800           0 :                                         log(LOG_NOTICE, "pf: state reuse ");
    4801           0 :                                         pf_print_state(*state);
    4802           0 :                                         pf_print_flags(pd->hdr.tcp.th_flags);
    4803           0 :                                         addlog("\n");
    4804           0 :                                 }
    4805             :                                 /* XXX make sure it's the same direction ?? */
    4806           0 :                                 (*state)->timeout = PFTM_PURGE;
    4807           0 :                                 *state = NULL;
    4808           0 :                                 pf_mbuf_link_inpcb(pd->m, inp);
    4809           0 :                                 return (PF_DROP);
    4810           0 :                         } else if (dst->state >= TCPS_ESTABLISHED &&
    4811           0 :                             src->state >= TCPS_ESTABLISHED) {
    4812             :                                 /*
    4813             :                                  * SYN matches existing state???
    4814             :                                  * Typically happens when sender boots up after
    4815             :                                  * sudden panic. Certain protocols (NFSv3) are
    4816             :                                  * always using same port numbers. Challenge
    4817             :                                  * ACK enables all parties (firewall and peers)
    4818             :                                  * to get in sync again.
    4819             :                                  */
    4820           0 :                                 pf_send_challenge_ack(pd, *state, src, dst);
    4821           0 :                                 return (PF_DROP);
    4822             :                         }
    4823             :                 }
    4824             : 
    4825           0 :                 if ((*state)->state_flags & PFSTATE_SLOPPY) {
    4826           0 :                         if (pf_tcp_track_sloppy(pd, state, reason) == PF_DROP)
    4827           0 :                                 return (PF_DROP);
    4828             :                 } else {
    4829           0 :                         if (pf_tcp_track_full(pd, state, reason, &copyback,
    4830           0 :                             PF_REVERSED_KEY((*state)->key, pd->af)) == PF_DROP)
    4831           0 :                                 return (PF_DROP);
    4832             :                 }
    4833             :                 break;
    4834             :         case IPPROTO_UDP:
    4835             :                 /* update states */
    4836           0 :                 if (src->state < PFUDPS_SINGLE)
    4837           0 :                         pf_set_protostate(*state, psrc, PFUDPS_SINGLE);
    4838           0 :                 if (dst->state == PFUDPS_SINGLE)
    4839           0 :                         pf_set_protostate(*state, pdst, PFUDPS_MULTIPLE);
    4840             : 
    4841             :                 /* update expire time */
    4842           0 :                 (*state)->expire = time_uptime;
    4843           0 :                 if (src->state == PFUDPS_MULTIPLE &&
    4844           0 :                     dst->state == PFUDPS_MULTIPLE)
    4845           0 :                         (*state)->timeout = PFTM_UDP_MULTIPLE;
    4846             :                 else
    4847           0 :                         (*state)->timeout = PFTM_UDP_SINGLE;
    4848             :                 break;
    4849             :         default:
    4850             :                 /* update states */
    4851           0 :                 if (src->state < PFOTHERS_SINGLE)
    4852           0 :                         pf_set_protostate(*state, psrc, PFOTHERS_SINGLE);
    4853           0 :                 if (dst->state == PFOTHERS_SINGLE)
    4854           0 :                         pf_set_protostate(*state, pdst, PFOTHERS_MULTIPLE);
    4855             : 
    4856             :                 /* update expire time */
    4857           0 :                 (*state)->expire = time_uptime;
    4858           0 :                 if (src->state == PFOTHERS_MULTIPLE &&
    4859           0 :                     dst->state == PFOTHERS_MULTIPLE)
    4860           0 :                         (*state)->timeout = PFTM_OTHER_MULTIPLE;
    4861             :                 else
    4862           0 :                         (*state)->timeout = PFTM_OTHER_SINGLE;
    4863             :                 break;
    4864             :         }
    4865             : 
    4866             :         /* translate source/destination address, if necessary */
    4867           0 :         if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
    4868             :                 struct pf_state_key     *nk;
    4869             :                 int                      afto, sidx, didx;
    4870             : 
    4871           0 :                 if (PF_REVERSED_KEY((*state)->key, pd->af))
    4872           0 :                         nk = (*state)->key[pd->sidx];
    4873             :                 else
    4874           0 :                         nk = (*state)->key[pd->didx];
    4875             : 
    4876           0 :                 afto = pd->af != nk->af;
    4877           0 :                 sidx = afto ? pd->didx : pd->sidx;
    4878           0 :                 didx = afto ? pd->sidx : pd->didx;
    4879             : 
    4880             : #ifdef INET6
    4881           0 :                 if (afto) {
    4882           0 :                         PF_ACPY(&pd->nsaddr, &nk->addr[sidx], nk->af);
    4883           0 :                         PF_ACPY(&pd->ndaddr, &nk->addr[didx], nk->af);
    4884           0 :                         pd->naf = nk->af;
    4885             :                         action = PF_AFRT;
    4886           0 :                 }
    4887             : #endif /* INET6 */
    4888             : 
    4889           0 :                 if (!afto)
    4890           0 :                         pf_translate_a(pd, pd->src, &nk->addr[sidx]);
    4891             : 
    4892           0 :                 if (pd->sport != NULL)
    4893           0 :                         pf_patch_16(pd, pd->sport, nk->port[sidx]);
    4894             : 
    4895           0 :                 if (afto || PF_ANEQ(pd->dst, &nk->addr[didx], pd->af) ||
    4896           0 :                     pd->rdomain != nk->rdomain)
    4897           0 :                         pd->destchg = 1;
    4898             : 
    4899           0 :                 if (!afto)
    4900           0 :                         pf_translate_a(pd, pd->dst, &nk->addr[didx]);
    4901             : 
    4902           0 :                 if (pd->dport != NULL)
    4903           0 :                         pf_patch_16(pd, pd->dport, nk->port[didx]);
    4904             : 
    4905           0 :                 pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
    4906           0 :                 copyback = 1;
    4907           0 :         }
    4908             : 
    4909           0 :         if (copyback && pd->hdrlen > 0) {
    4910           0 :                 m_copyback(pd->m, pd->off, pd->hdrlen, &pd->hdr, M_NOWAIT);
    4911           0 :         }
    4912             : 
    4913           0 :         return (action);
    4914           0 : }
    4915             : 
    4916             : int
    4917           0 : pf_icmp_state_lookup(struct pf_pdesc *pd, struct pf_state_key_cmp *key,
    4918             :     struct pf_state **state, u_int16_t icmpid, u_int16_t type,
    4919             :     int icmp_dir, int *iidx, int multi, int inner)
    4920             : {
    4921             :         int direction, action;
    4922             : 
    4923           0 :         key->af = pd->af;
    4924           0 :         key->proto = pd->proto;
    4925           0 :         key->rdomain = pd->rdomain;
    4926           0 :         if (icmp_dir == PF_IN) {
    4927           0 :                 *iidx = pd->sidx;
    4928           0 :                 key->port[pd->sidx] = icmpid;
    4929           0 :                 key->port[pd->didx] = type;
    4930           0 :         } else {
    4931           0 :                 *iidx = pd->didx;
    4932           0 :                 key->port[pd->sidx] = type;
    4933           0 :                 key->port[pd->didx] = icmpid;
    4934             :         }
    4935             : 
    4936           0 :         if (pf_state_key_addr_setup(pd, key, pd->sidx, pd->src, pd->didx,
    4937           0 :             pd->dst, pd->af, multi))
    4938           0 :                 return (PF_DROP);
    4939             : 
    4940           0 :         action = pf_find_state(pd, key, state);
    4941           0 :         if (action != PF_MATCH)
    4942           0 :                 return (action);
    4943             : 
    4944           0 :         if ((*state)->state_flags & PFSTATE_SLOPPY)
    4945           0 :                 return (-1);
    4946             : 
    4947             :         /* Is this ICMP message flowing in right direction? */
    4948           0 :         if ((*state)->key[PF_SK_WIRE]->af != (*state)->key[PF_SK_STACK]->af)
    4949           0 :                 direction = (pd->af == (*state)->key[PF_SK_WIRE]->af) ?
    4950             :                     PF_IN : PF_OUT;
    4951             :         else
    4952           0 :                 direction = (*state)->direction;
    4953           0 :         if ((((!inner && direction == pd->dir) ||
    4954           0 :             (inner && direction != pd->dir)) ?
    4955           0 :             PF_IN : PF_OUT) != icmp_dir) {
    4956           0 :                 if (pf_status.debug >= LOG_NOTICE) {
    4957           0 :                         log(LOG_NOTICE,
    4958             :                             "pf: icmp type %d in wrong direction (%d): ",
    4959           0 :                             ntohs(type), icmp_dir);
    4960           0 :                         pf_print_state(*state);
    4961           0 :                         addlog("\n");
    4962           0 :                 }
    4963           0 :                 return (PF_DROP);
    4964             :         }
    4965           0 :         return (-1);
    4966           0 : }
    4967             : 
    4968             : int
    4969           0 : pf_test_state_icmp(struct pf_pdesc *pd, struct pf_state **state,
    4970             :     u_short *reason)
    4971             : {
    4972           0 :         u_int16_t        virtual_id, virtual_type;
    4973             :         u_int8_t         icmptype;
    4974           0 :         int              icmp_dir, iidx, ret, copyback = 0;
    4975             : 
    4976           0 :         struct pf_state_key_cmp key;
    4977             : 
    4978           0 :         switch (pd->proto) {
    4979             :         case IPPROTO_ICMP:
    4980           0 :                 icmptype = pd->hdr.icmp.icmp_type;
    4981           0 :                 break;
    4982             : #ifdef INET6
    4983             :         case IPPROTO_ICMPV6:
    4984           0 :                 icmptype = pd->hdr.icmp6.icmp6_type;
    4985           0 :                 break;
    4986             : #endif /* INET6 */
    4987             :         default:
    4988           0 :                 panic("unhandled proto %d", pd->proto);
    4989             :         }
    4990             : 
    4991           0 :         if (pf_icmp_mapping(pd, icmptype, &icmp_dir, &virtual_id,
    4992           0 :             &virtual_type) == 0) {
    4993             :                 /*
    4994             :                  * ICMP query/reply message not related to a TCP/UDP packet.
    4995             :                  * Search for an ICMP state.
    4996             :                  */
    4997           0 :                 ret = pf_icmp_state_lookup(pd, &key, state,
    4998           0 :                     virtual_id, virtual_type, icmp_dir, &iidx,
    4999             :                     0, 0);
    5000             :                 /* IPv6? try matching a multicast address */
    5001           0 :                 if (ret == PF_DROP && pd->af == AF_INET6 && icmp_dir == PF_OUT)
    5002           0 :                         ret = pf_icmp_state_lookup(pd, &key, state, virtual_id,
    5003           0 :                             virtual_type, icmp_dir, &iidx, 1, 0);
    5004           0 :                 if (ret >= 0)
    5005           0 :                         return (ret);
    5006             : 
    5007           0 :                 (*state)->expire = time_uptime;
    5008           0 :                 (*state)->timeout = PFTM_ICMP_ERROR_REPLY;
    5009             : 
    5010             :                 /* translate source/destination address, if necessary */
    5011           0 :                 if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
    5012             :                         struct pf_state_key     *nk;
    5013             :                         int                      afto, sidx, didx;
    5014             : 
    5015           0 :                         if (PF_REVERSED_KEY((*state)->key, pd->af))
    5016           0 :                                 nk = (*state)->key[pd->sidx];
    5017             :                         else
    5018           0 :                                 nk = (*state)->key[pd->didx];
    5019             : 
    5020           0 :                         afto = pd->af != nk->af;
    5021           0 :                         sidx = afto ? pd->didx : pd->sidx;
    5022           0 :                         didx = afto ? pd->sidx : pd->didx;
    5023           0 :                         iidx = afto ? !iidx : iidx;
    5024             : #ifdef  INET6
    5025           0 :                         if (afto) {
    5026           0 :                                 PF_ACPY(&pd->nsaddr, &nk->addr[sidx], nk->af);
    5027           0 :                                 PF_ACPY(&pd->ndaddr, &nk->addr[didx], nk->af);
    5028           0 :                                 pd->naf = nk->af;
    5029           0 :                         }
    5030             : #endif /* INET6 */
    5031           0 :                         if (!afto) {
    5032           0 :                                 pf_translate_a(pd, pd->src, &nk->addr[sidx]);
    5033           0 :                                 pf_translate_a(pd, pd->dst, &nk->addr[didx]);
    5034           0 :                         }
    5035             : 
    5036           0 :                         if (pd->rdomain != nk->rdomain)
    5037           0 :                                 pd->destchg = 1;
    5038           0 :                         if (!afto && PF_ANEQ(pd->dst,
    5039             :                                 &nk->addr[didx], pd->af))
    5040           0 :                                 pd->destchg = 1;
    5041           0 :                         pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
    5042             : 
    5043           0 :                         switch (pd->af) {
    5044             :                         case AF_INET:
    5045             : #ifdef INET6
    5046           0 :                                 if (afto) {
    5047           0 :                                         if (pf_translate_icmp_af(pd, AF_INET6,
    5048           0 :                                             &pd->hdr.icmp))
    5049           0 :                                                 return (PF_DROP);
    5050           0 :                                         pd->proto = IPPROTO_ICMPV6;
    5051           0 :                                 }
    5052             : #endif /* INET6 */
    5053           0 :                                 pf_patch_16(pd,
    5054           0 :                                     &pd->hdr.icmp.icmp_id, nk->port[iidx]);
    5055             : 
    5056           0 :                                 m_copyback(pd->m, pd->off, ICMP_MINLEN,
    5057           0 :                                     &pd->hdr.icmp, M_NOWAIT);
    5058             :                                 copyback = 1;
    5059           0 :                                 break;
    5060             : #ifdef INET6
    5061             :                         case AF_INET6:
    5062           0 :                                 if (afto) {
    5063           0 :                                         if (pf_translate_icmp_af(pd, AF_INET,
    5064           0 :                                             &pd->hdr.icmp6))
    5065           0 :                                                 return (PF_DROP);
    5066           0 :                                         pd->proto = IPPROTO_ICMP;
    5067           0 :                                 }
    5068             : 
    5069           0 :                                 pf_patch_16(pd,
    5070           0 :                                     &pd->hdr.icmp6.icmp6_id, nk->port[iidx]);
    5071             : 
    5072           0 :                                 m_copyback(pd->m, pd->off,
    5073           0 :                                     sizeof(struct icmp6_hdr), &pd->hdr.icmp6,
    5074             :                                     M_NOWAIT);
    5075             :                                 copyback = 1;
    5076           0 :                                 break;
    5077             : #endif /* INET6 */
    5078             :                         }
    5079             : #ifdef  INET6
    5080           0 :                         if (afto)
    5081           0 :                                 return (PF_AFRT);
    5082             : #endif /* INET6 */
    5083           0 :                 }
    5084             :         } else {
    5085             :                 /*
    5086             :                  * ICMP error message in response to a TCP/UDP packet.
    5087             :                  * Extract the inner TCP/UDP header and search for that state.
    5088             :                  */
    5089           0 :                 struct pf_pdesc  pd2;
    5090           0 :                 struct ip        h2;
    5091             : #ifdef INET6
    5092           0 :                 struct ip6_hdr   h2_6;
    5093             : #endif /* INET6 */
    5094             :                 int              ipoff2;
    5095             : 
    5096             :                 /* Initialize pd2 fields valid for both packets with pd. */
    5097           0 :                 memset(&pd2, 0, sizeof(pd2));
    5098           0 :                 pd2.af = pd->af;
    5099           0 :                 pd2.dir = pd->dir;
    5100           0 :                 pd2.kif = pd->kif;
    5101           0 :                 pd2.m = pd->m;
    5102           0 :                 pd2.rdomain = pd->rdomain;
    5103             :                 /* Payload packet is from the opposite direction. */
    5104           0 :                 pd2.sidx = (pd2.dir == PF_IN) ? 1 : 0;
    5105           0 :                 pd2.didx = (pd2.dir == PF_IN) ? 0 : 1;
    5106           0 :                 switch (pd->af) {
    5107             :                 case AF_INET:
    5108             :                         /* offset of h2 in mbuf chain */
    5109           0 :                         ipoff2 = pd->off + ICMP_MINLEN;
    5110             : 
    5111           0 :                         if (!pf_pull_hdr(pd2.m, ipoff2, &h2, sizeof(h2),
    5112           0 :                             NULL, reason, pd2.af)) {
    5113           0 :                                 DPFPRINTF(LOG_NOTICE,
    5114             :                                     "ICMP error message too short (ip)");
    5115           0 :                                 return (PF_DROP);
    5116             :                         }
    5117             :                         /*
    5118             :                          * ICMP error messages don't refer to non-first
    5119             :                          * fragments
    5120             :                          */
    5121           0 :                         if (h2.ip_off & htons(IP_OFFMASK)) {
    5122           0 :                                 REASON_SET(reason, PFRES_FRAG);
    5123           0 :                                 return (PF_DROP);
    5124             :                         }
    5125             : 
    5126             :                         /* offset of protocol header that follows h2 */
    5127           0 :                         pd2.off = ipoff2;
    5128           0 :                         if (pf_walk_header(&pd2, &h2, reason) != PF_PASS)
    5129           0 :                                 return (PF_DROP);
    5130             : 
    5131           0 :                         pd2.tot_len = ntohs(h2.ip_len);
    5132           0 :                         pd2.src = (struct pf_addr *)&h2.ip_src;
    5133           0 :                         pd2.dst = (struct pf_addr *)&h2.ip_dst;
    5134           0 :                         break;
    5135             : #ifdef INET6
    5136             :                 case AF_INET6:
    5137           0 :                         ipoff2 = pd->off + sizeof(struct icmp6_hdr);
    5138             : 
    5139           0 :                         if (!pf_pull_hdr(pd2.m, ipoff2, &h2_6, sizeof(h2_6),
    5140           0 :                             NULL, reason, pd2.af)) {
    5141           0 :                                 DPFPRINTF(LOG_NOTICE,
    5142             :                                     "ICMP error message too short (ip6)");
    5143           0 :                                 return (PF_DROP);
    5144             :                         }
    5145             : 
    5146           0 :                         pd2.off = ipoff2;
    5147           0 :                         if (pf_walk_header6(&pd2, &h2_6, reason) != PF_PASS)
    5148           0 :                                 return (PF_DROP);
    5149             : 
    5150           0 :                         pd2.tot_len = ntohs(h2_6.ip6_plen) +
    5151             :                             sizeof(struct ip6_hdr);
    5152           0 :                         pd2.src = (struct pf_addr *)&h2_6.ip6_src;
    5153           0 :                         pd2.dst = (struct pf_addr *)&h2_6.ip6_dst;
    5154           0 :                         break;
    5155             : #endif /* INET6 */
    5156             :                 default:
    5157           0 :                         unhandled_af(pd->af);
    5158             :                 }
    5159             : 
    5160           0 :                 switch (pd2.proto) {
    5161             :                 case IPPROTO_TCP: {
    5162           0 :                         struct tcphdr           *th = &pd2.hdr.tcp;
    5163             :                         u_int32_t                seq;
    5164             :                         struct pf_state_peer    *src, *dst;
    5165             :                         u_int8_t                 dws;
    5166             :                         int                      action;
    5167             : 
    5168             :                         /*
    5169             :                          * Only the first 8 bytes of the TCP header can be
    5170             :                          * expected. Don't access any TCP header fields after
    5171             :                          * th_seq, an ackskew test is not possible.
    5172             :                          */
    5173           0 :                         if (!pf_pull_hdr(pd2.m, pd2.off, th, 8, NULL, reason,
    5174           0 :                             pd2.af)) {
    5175           0 :                                 DPFPRINTF(LOG_NOTICE,
    5176             :                                     "ICMP error message too short (tcp)");
    5177           0 :                                 return (PF_DROP);
    5178             :                         }
    5179             : 
    5180           0 :                         key.af = pd2.af;
    5181           0 :                         key.proto = IPPROTO_TCP;
    5182           0 :                         key.rdomain = pd2.rdomain;
    5183           0 :                         PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
    5184           0 :                         PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
    5185           0 :                         key.port[pd2.sidx] = th->th_sport;
    5186           0 :                         key.port[pd2.didx] = th->th_dport;
    5187             : 
    5188           0 :                         action = pf_find_state(&pd2, &key, state);
    5189           0 :                         if (action != PF_MATCH)
    5190           0 :                                 return (action);
    5191             : 
    5192           0 :                         if (pd2.dir == (*state)->direction) {
    5193           0 :                                 if (PF_REVERSED_KEY((*state)->key, pd->af)) {
    5194           0 :                                         src = &(*state)->src;
    5195           0 :                                         dst = &(*state)->dst;
    5196           0 :                                 } else {
    5197           0 :                                         src = &(*state)->dst;
    5198           0 :                                         dst = &(*state)->src;
    5199             :                                 }
    5200             :                         } else {
    5201           0 :                                 if (PF_REVERSED_KEY((*state)->key, pd->af)) {
    5202           0 :                                         src = &(*state)->dst;
    5203           0 :                                         dst = &(*state)->src;
    5204           0 :                                 } else {
    5205           0 :                                         src = &(*state)->src;
    5206           0 :                                         dst = &(*state)->dst;
    5207             :                                 }
    5208             :                         }
    5209             : 
    5210           0 :                         if (src->wscale && dst->wscale)
    5211           0 :                                 dws = dst->wscale & PF_WSCALE_MASK;
    5212             :                         else
    5213             :                                 dws = 0;
    5214             : 
    5215             :                         /* Demodulate sequence number */
    5216           0 :                         seq = ntohl(th->th_seq) - src->seqdiff;
    5217           0 :                         if (src->seqdiff) {
    5218           0 :                                 pf_patch_32(pd, &th->th_seq, htonl(seq));
    5219             :                                 copyback = 1;
    5220           0 :                         }
    5221             : 
    5222           0 :                         if (!((*state)->state_flags & PFSTATE_SLOPPY) &&
    5223           0 :                             (!SEQ_GEQ(src->seqhi, seq) || !SEQ_GEQ(seq,
    5224             :                             src->seqlo - (dst->max_win << dws)))) {
    5225           0 :                                 if (pf_status.debug >= LOG_NOTICE) {
    5226           0 :                                         log(LOG_NOTICE,
    5227             :                                             "pf: BAD ICMP %d:%d ",
    5228           0 :                                             icmptype, pd->hdr.icmp.icmp_code);
    5229           0 :                                         pf_print_host(pd->src, 0, pd->af);
    5230           0 :                                         addlog(" -> ");
    5231           0 :                                         pf_print_host(pd->dst, 0, pd->af);
    5232           0 :                                         addlog(" state: ");
    5233           0 :                                         pf_print_state(*state);
    5234           0 :                                         addlog(" seq=%u\n", seq);
    5235           0 :                                 }
    5236           0 :                                 REASON_SET(reason, PFRES_BADSTATE);
    5237           0 :                                 return (PF_DROP);
    5238             :                         } else {
    5239           0 :                                 if (pf_status.debug >= LOG_DEBUG) {
    5240           0 :                                         log(LOG_DEBUG,
    5241             :                                             "pf: OK ICMP %d:%d ",
    5242           0 :                                             icmptype, pd->hdr.icmp.icmp_code);
    5243           0 :                                         pf_print_host(pd->src, 0, pd->af);
    5244           0 :                                         addlog(" -> ");
    5245           0 :                                         pf_print_host(pd->dst, 0, pd->af);
    5246           0 :                                         addlog(" state: ");
    5247           0 :                                         pf_print_state(*state);
    5248           0 :                                         addlog(" seq=%u\n", seq);
    5249           0 :                                 }
    5250             :                         }
    5251             : 
    5252             :                         /* translate source/destination address, if necessary */
    5253           0 :                         if ((*state)->key[PF_SK_WIRE] !=
    5254           0 :                             (*state)->key[PF_SK_STACK]) {
    5255             :                                 struct pf_state_key     *nk;
    5256             :                                 int                      afto, sidx, didx;
    5257             : 
    5258           0 :                                 if (PF_REVERSED_KEY((*state)->key, pd->af))
    5259           0 :                                         nk = (*state)->key[pd->sidx];
    5260             :                                 else
    5261           0 :                                         nk = (*state)->key[pd->didx];
    5262             : 
    5263           0 :                                 afto = pd->af != nk->af;
    5264           0 :                                 sidx = afto ? pd2.didx : pd2.sidx;
    5265           0 :                                 didx = afto ? pd2.sidx : pd2.didx;
    5266             : 
    5267             : #ifdef INET6
    5268           0 :                                 if (afto) {
    5269           0 :                                         if (pf_translate_icmp_af(pd, nk->af,
    5270           0 :                                             &pd->hdr.icmp))
    5271           0 :                                                 return (PF_DROP);
    5272           0 :                                         m_copyback(pd->m, pd->off,
    5273             :                                             sizeof(struct icmp6_hdr),
    5274           0 :                                             &pd->hdr.icmp6, M_NOWAIT);
    5275           0 :                                         if (pf_change_icmp_af(pd->m, ipoff2,
    5276           0 :                                             pd, &pd2, &nk->addr[sidx],
    5277           0 :                                             &nk->addr[didx], pd->af, nk->af))
    5278           0 :                                                 return (PF_DROP);
    5279           0 :                                         if (nk->af == AF_INET)
    5280           0 :                                                 pd->proto = IPPROTO_ICMP;
    5281             :                                         else
    5282           0 :                                                 pd->proto = IPPROTO_ICMPV6;
    5283           0 :                                         pd->m->m_pkthdr.ph_rtableid =
    5284           0 :                                             nk->rdomain;
    5285           0 :                                         pd->destchg = 1;
    5286           0 :                                         PF_ACPY(&pd->nsaddr,
    5287             :                                             &nk->addr[pd2.sidx], nk->af);
    5288           0 :                                         PF_ACPY(&pd->ndaddr,
    5289             :                                             &nk->addr[pd2.didx], nk->af);
    5290           0 :                                         pd->naf = nk->af;
    5291             : 
    5292           0 :                                         pf_patch_16(pd,
    5293           0 :                                             &th->th_sport, nk->port[sidx]);
    5294           0 :                                         pf_patch_16(pd,
    5295           0 :                                             &th->th_dport, nk->port[didx]);
    5296             : 
    5297           0 :                                         m_copyback(pd2.m, pd2.off, 8, th,
    5298             :                                             M_NOWAIT);
    5299           0 :                                         return (PF_AFRT);
    5300             :                                 }
    5301             : #endif  /* INET6 */
    5302           0 :                                 if (PF_ANEQ(pd2.src,
    5303           0 :                                     &nk->addr[pd2.sidx], pd2.af) ||
    5304           0 :                                     nk->port[pd2.sidx] != th->th_sport)
    5305           0 :                                         pf_translate_icmp(pd, pd2.src,
    5306           0 :                                             &th->th_sport, pd->dst,
    5307           0 :                                             &nk->addr[pd2.sidx],
    5308           0 :                                             nk->port[pd2.sidx]);
    5309             : 
    5310           0 :                                 if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx],
    5311           0 :                                     pd2.af) || pd2.rdomain != nk->rdomain)
    5312           0 :                                         pd->destchg = 1;
    5313           0 :                                 pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
    5314             : 
    5315           0 :                                 if (PF_ANEQ(pd2.dst,
    5316           0 :                                     &nk->addr[pd2.didx], pd2.af) ||
    5317           0 :                                     nk->port[pd2.didx] != th->th_dport)
    5318           0 :                                         pf_translate_icmp(pd, pd2.dst,
    5319           0 :                                             &th->th_dport, pd->src,
    5320           0 :                                             &nk->addr[pd2.didx],
    5321           0 :                                             nk->port[pd2.didx]);
    5322             :                                 copyback = 1;
    5323           0 :                         }
    5324             : 
    5325           0 :                         if (copyback) {
    5326           0 :                                 switch (pd2.af) {
    5327             :                                 case AF_INET:
    5328           0 :                                         m_copyback(pd->m, pd->off, ICMP_MINLEN,
    5329           0 :                                             &pd->hdr.icmp, M_NOWAIT);
    5330           0 :                                         m_copyback(pd2.m, ipoff2, sizeof(h2),
    5331             :                                             &h2, M_NOWAIT);
    5332           0 :                                         break;
    5333             : #ifdef INET6
    5334             :                                 case AF_INET6:
    5335           0 :                                         m_copyback(pd->m, pd->off,
    5336             :                                             sizeof(struct icmp6_hdr),
    5337           0 :                                             &pd->hdr.icmp6, M_NOWAIT);
    5338           0 :                                         m_copyback(pd2.m, ipoff2, sizeof(h2_6),
    5339             :                                             &h2_6, M_NOWAIT);
    5340           0 :                                         break;
    5341             : #endif /* INET6 */
    5342             :                                 }
    5343           0 :                                 m_copyback(pd2.m, pd2.off, 8, th, M_NOWAIT);
    5344           0 :                         }
    5345           0 :                         break;
    5346             :                 }
    5347             :                 case IPPROTO_UDP: {
    5348           0 :                         struct udphdr   *uh = &pd2.hdr.udp;
    5349             :                         int              action;
    5350             : 
    5351           0 :                         if (!pf_pull_hdr(pd2.m, pd2.off, uh, sizeof(*uh),
    5352           0 :                             NULL, reason, pd2.af)) {
    5353           0 :                                 DPFPRINTF(LOG_NOTICE,
    5354             :                                     "ICMP error message too short (udp)");
    5355           0 :                                 return (PF_DROP);
    5356             :                         }
    5357             : 
    5358           0 :                         key.af = pd2.af;
    5359           0 :                         key.proto = IPPROTO_UDP;
    5360           0 :                         key.rdomain = pd2.rdomain;
    5361           0 :                         PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
    5362           0 :                         PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
    5363           0 :                         key.port[pd2.sidx] = uh->uh_sport;
    5364           0 :                         key.port[pd2.didx] = uh->uh_dport;
    5365             : 
    5366           0 :                         action = pf_find_state(&pd2, &key, state);
    5367           0 :                         if (action != PF_MATCH)
    5368           0 :                                 return (action);
    5369             : 
    5370             :                         /* translate source/destination address, if necessary */
    5371           0 :                         if ((*state)->key[PF_SK_WIRE] !=
    5372           0 :                             (*state)->key[PF_SK_STACK]) {
    5373             :                                 struct pf_state_key     *nk;
    5374             :                                 int                      afto, sidx, didx;
    5375             : 
    5376           0 :                                 if (PF_REVERSED_KEY((*state)->key, pd->af))
    5377           0 :                                         nk = (*state)->key[pd->sidx];
    5378             :                                 else
    5379           0 :                                         nk = (*state)->key[pd->didx];
    5380             : 
    5381           0 :                                 afto = pd->af != nk->af;
    5382           0 :                                 sidx = afto ? pd2.didx : pd2.sidx;
    5383           0 :                                 didx = afto ? pd2.sidx : pd2.didx;
    5384             : 
    5385             : #ifdef INET6
    5386           0 :                                 if (afto) {
    5387           0 :                                         if (pf_translate_icmp_af(pd, nk->af,
    5388           0 :                                             &pd->hdr.icmp))
    5389           0 :                                                 return (PF_DROP);
    5390           0 :                                         m_copyback(pd->m, pd->off,
    5391             :                                             sizeof(struct icmp6_hdr),
    5392           0 :                                             &pd->hdr.icmp6, M_NOWAIT);
    5393           0 :                                         if (pf_change_icmp_af(pd->m, ipoff2,
    5394           0 :                                             pd, &pd2, &nk->addr[sidx],
    5395           0 :                                             &nk->addr[didx], pd->af, nk->af))
    5396           0 :                                                 return (PF_DROP);
    5397           0 :                                         if (nk->af == AF_INET)
    5398           0 :                                                 pd->proto = IPPROTO_ICMP;
    5399             :                                         else
    5400           0 :                                                 pd->proto = IPPROTO_ICMPV6;
    5401           0 :                                         pd->m->m_pkthdr.ph_rtableid =
    5402           0 :                                             nk->rdomain;
    5403           0 :                                         pd->destchg = 1;
    5404           0 :                                         PF_ACPY(&pd->nsaddr,
    5405             :                                             &nk->addr[pd2.sidx], nk->af);
    5406           0 :                                         PF_ACPY(&pd->ndaddr,
    5407             :                                             &nk->addr[pd2.didx], nk->af);
    5408           0 :                                         pd->naf = nk->af;
    5409             : 
    5410           0 :                                         pf_patch_16(pd,
    5411           0 :                                             &uh->uh_sport, nk->port[sidx]);
    5412           0 :                                         pf_patch_16(pd,
    5413           0 :                                             &uh->uh_dport, nk->port[didx]);
    5414             : 
    5415           0 :                                         m_copyback(pd2.m, pd2.off, sizeof(*uh),
    5416             :                                             uh, M_NOWAIT);
    5417           0 :                                         return (PF_AFRT);
    5418             :                                 }
    5419             : #endif /* INET6 */
    5420             : 
    5421           0 :                                 if (PF_ANEQ(pd2.src,
    5422           0 :                                     &nk->addr[pd2.sidx], pd2.af) ||
    5423           0 :                                     nk->port[pd2.sidx] != uh->uh_sport)
    5424           0 :                                         pf_translate_icmp(pd, pd2.src,
    5425           0 :                                             &uh->uh_sport, pd->dst,
    5426           0 :                                             &nk->addr[pd2.sidx],
    5427           0 :                                             nk->port[pd2.sidx]);
    5428             : 
    5429           0 :                                 if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx],
    5430           0 :                                     pd2.af) || pd2.rdomain != nk->rdomain)
    5431           0 :                                         pd->destchg = 1;
    5432           0 :                                 pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
    5433             : 
    5434           0 :                                 if (PF_ANEQ(pd2.dst,
    5435           0 :                                     &nk->addr[pd2.didx], pd2.af) ||
    5436           0 :                                     nk->port[pd2.didx] != uh->uh_dport)
    5437           0 :                                         pf_translate_icmp(pd, pd2.dst,
    5438           0 :                                             &uh->uh_dport, pd->src,
    5439           0 :                                             &nk->addr[pd2.didx],
    5440           0 :                                             nk->port[pd2.didx]);
    5441             : 
    5442           0 :                                 switch (pd2.af) {
    5443             :                                 case AF_INET:
    5444           0 :                                         m_copyback(pd->m, pd->off, ICMP_MINLEN,
    5445           0 :                                             &pd->hdr.icmp, M_NOWAIT);
    5446           0 :                                         m_copyback(pd2.m, ipoff2, sizeof(h2),
    5447             :                                             &h2, M_NOWAIT);
    5448           0 :                                         break;
    5449             : #ifdef INET6
    5450             :                                 case AF_INET6:
    5451           0 :                                         m_copyback(pd->m, pd->off,
    5452             :                                             sizeof(struct icmp6_hdr),
    5453           0 :                                             &pd->hdr.icmp6, M_NOWAIT);
    5454           0 :                                         m_copyback(pd2.m, ipoff2, sizeof(h2_6),
    5455             :                                             &h2_6, M_NOWAIT);
    5456           0 :                                         break;
    5457             : #endif /* INET6 */
    5458             :                                 }
    5459             :                                 /* Avoid recomputing quoted UDP checksum.
    5460             :                                  * note: udp6 0 csum invalid per rfc2460 p27.
    5461             :                                  * but presumed nothing cares in this context */
    5462           0 :                                 pf_patch_16(pd, &uh->uh_sum, 0);
    5463           0 :                                 m_copyback(pd2.m, pd2.off, sizeof(*uh), uh,
    5464             :                                     M_NOWAIT);
    5465             :                                 copyback = 1;
    5466           0 :                         }
    5467           0 :                         break;
    5468             :                 }
    5469             :                 case IPPROTO_ICMP: {
    5470           0 :                         struct icmp     *iih = &pd2.hdr.icmp;
    5471             : 
    5472           0 :                         if (pd2.af != AF_INET) {
    5473           0 :                                 REASON_SET(reason, PFRES_NORM);
    5474           0 :                                 return (PF_DROP);
    5475             :                         }
    5476             : 
    5477           0 :                         if (!pf_pull_hdr(pd2.m, pd2.off, iih, ICMP_MINLEN,
    5478             :                             NULL, reason, pd2.af)) {
    5479           0 :                                 DPFPRINTF(LOG_NOTICE,
    5480             :                                     "ICMP error message too short (icmp)");
    5481           0 :                                 return (PF_DROP);
    5482             :                         }
    5483             : 
    5484           0 :                         pf_icmp_mapping(&pd2, iih->icmp_type,
    5485             :                             &icmp_dir, &virtual_id, &virtual_type);
    5486             : 
    5487           0 :                         ret = pf_icmp_state_lookup(&pd2, &key, state,
    5488           0 :                             virtual_id, virtual_type, icmp_dir, &iidx, 0, 1);
    5489           0 :                         if (ret >= 0)
    5490           0 :                                 return (ret);
    5491             : 
    5492             :                         /* translate source/destination address, if necessary */
    5493           0 :                         if ((*state)->key[PF_SK_WIRE] !=
    5494           0 :                             (*state)->key[PF_SK_STACK]) {
    5495             :                                 struct pf_state_key     *nk;
    5496             :                                 int                      afto, sidx, didx;
    5497             : 
    5498           0 :                                 if (PF_REVERSED_KEY((*state)->key, pd->af))
    5499           0 :                                         nk = (*state)->key[pd->sidx];
    5500             :                                 else
    5501           0 :                                         nk = (*state)->key[pd->didx];
    5502             : 
    5503           0 :                                 afto = pd->af != nk->af;
    5504           0 :                                 sidx = afto ? pd2.didx : pd2.sidx;
    5505           0 :                                 didx = afto ? pd2.sidx : pd2.didx;
    5506           0 :                                 iidx = afto ? !iidx : iidx;
    5507             : 
    5508             : #ifdef INET6
    5509           0 :                                 if (afto) {
    5510           0 :                                         if (nk->af != AF_INET6)
    5511           0 :                                                 return (PF_DROP);
    5512           0 :                                         if (pf_translate_icmp_af(pd, nk->af,
    5513           0 :                                             &pd->hdr.icmp))
    5514           0 :                                                 return (PF_DROP);
    5515           0 :                                         m_copyback(pd->m, pd->off,
    5516             :                                             sizeof(struct icmp6_hdr),
    5517           0 :                                             &pd->hdr.icmp6, M_NOWAIT);
    5518           0 :                                         if (pf_change_icmp_af(pd->m, ipoff2,
    5519           0 :                                             pd, &pd2, &nk->addr[sidx],
    5520           0 :                                             &nk->addr[didx], pd->af, nk->af))
    5521           0 :                                                 return (PF_DROP);
    5522           0 :                                         pd->proto = IPPROTO_ICMPV6;
    5523           0 :                                         if (pf_translate_icmp_af(pd,
    5524           0 :                                                 nk->af, iih))
    5525           0 :                                                 return (PF_DROP);
    5526           0 :                                         if (virtual_type == htons(ICMP_ECHO))
    5527           0 :                                                 pf_patch_16(pd, &iih->icmp_id,
    5528           0 :                                                     nk->port[iidx]);
    5529           0 :                                         m_copyback(pd2.m, pd2.off, ICMP_MINLEN,
    5530             :                                             iih, M_NOWAIT);
    5531           0 :                                         pd->m->m_pkthdr.ph_rtableid =
    5532           0 :                                             nk->rdomain;
    5533           0 :                                         pd->destchg = 1;
    5534           0 :                                         PF_ACPY(&pd->nsaddr,
    5535             :                                             &nk->addr[pd2.sidx], nk->af);
    5536           0 :                                         PF_ACPY(&pd->ndaddr,
    5537             :                                             &nk->addr[pd2.didx], nk->af);
    5538           0 :                                         pd->naf = nk->af;
    5539           0 :                                         return (PF_AFRT);
    5540             :                                 }
    5541             : #endif /* INET6 */
    5542             : 
    5543           0 :                                 if (PF_ANEQ(pd2.src,
    5544           0 :                                     &nk->addr[pd2.sidx], pd2.af) ||
    5545           0 :                                     (virtual_type == htons(ICMP_ECHO) &&
    5546           0 :                                     nk->port[iidx] != iih->icmp_id))
    5547           0 :                                         pf_translate_icmp(pd, pd2.src,
    5548           0 :                                             (virtual_type == htons(ICMP_ECHO)) ?
    5549           0 :                                             &iih->icmp_id : NULL,
    5550           0 :                                             pd->dst, &nk->addr[pd2.sidx],
    5551           0 :                                             (virtual_type == htons(ICMP_ECHO)) ?
    5552           0 :                                             nk->port[iidx] : 0);
    5553             : 
    5554           0 :                                 if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx],
    5555           0 :                                     pd2.af) || pd2.rdomain != nk->rdomain)
    5556           0 :                                         pd->destchg = 1;
    5557           0 :                                 pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
    5558             : 
    5559           0 :                                 if (PF_ANEQ(pd2.dst,
    5560             :                                     &nk->addr[pd2.didx], pd2.af))
    5561           0 :                                         pf_translate_icmp(pd, pd2.dst, NULL,
    5562           0 :                                             pd->src, &nk->addr[pd2.didx], 0);
    5563             : 
    5564           0 :                                 m_copyback(pd->m, pd->off, ICMP_MINLEN,
    5565           0 :                                     &pd->hdr.icmp, M_NOWAIT);
    5566           0 :                                 m_copyback(pd2.m, ipoff2, sizeof(h2), &h2,
    5567             :                                     M_NOWAIT);
    5568           0 :                                 m_copyback(pd2.m, pd2.off, ICMP_MINLEN, iih,
    5569             :                                     M_NOWAIT);
    5570             :                                 copyback = 1;
    5571           0 :                         }
    5572           0 :                         break;
    5573             :                 }
    5574             : #ifdef INET6
    5575             :                 case IPPROTO_ICMPV6: {
    5576           0 :                         struct icmp6_hdr        *iih = &pd2.hdr.icmp6;
    5577             : 
    5578           0 :                         if (pd2.af != AF_INET6) {
    5579           0 :                                 REASON_SET(reason, PFRES_NORM);
    5580           0 :                                 return (PF_DROP);
    5581             :                         }
    5582             : 
    5583           0 :                         if (!pf_pull_hdr(pd2.m, pd2.off, iih,
    5584             :                             sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
    5585           0 :                                 DPFPRINTF(LOG_NOTICE,
    5586             :                                     "ICMP error message too short (icmp6)");
    5587           0 :                                 return (PF_DROP);
    5588             :                         }
    5589             : 
    5590           0 :                         pf_icmp_mapping(&pd2, iih->icmp6_type,
    5591             :                             &icmp_dir, &virtual_id, &virtual_type);
    5592           0 :                         ret = pf_icmp_state_lookup(&pd2, &key, state,
    5593           0 :                             virtual_id, virtual_type, icmp_dir, &iidx, 0, 1);
    5594             :                         /* IPv6? try matching a multicast address */
    5595           0 :                         if (ret == PF_DROP && pd2.af == AF_INET6 &&
    5596           0 :                             icmp_dir == PF_OUT)
    5597           0 :                                 ret = pf_icmp_state_lookup(&pd2, &key, state,
    5598           0 :                                     virtual_id, virtual_type, icmp_dir, &iidx,
    5599             :                                     1, 1);
    5600           0 :                         if (ret >= 0)
    5601           0 :                                 return (ret);
    5602             : 
    5603             :                         /* translate source/destination address, if necessary */
    5604           0 :                         if ((*state)->key[PF_SK_WIRE] !=
    5605           0 :                             (*state)->key[PF_SK_STACK]) {
    5606             :                                 struct pf_state_key     *nk;
    5607             :                                 int                      afto, sidx, didx;
    5608             : 
    5609           0 :                                 if (PF_REVERSED_KEY((*state)->key, pd->af))
    5610           0 :                                         nk = (*state)->key[pd->sidx];
    5611             :                                 else
    5612           0 :                                         nk = (*state)->key[pd->didx];
    5613             : 
    5614           0 :                                 afto = pd->af != nk->af;
    5615           0 :                                 sidx = afto ? pd2.didx : pd2.sidx;
    5616           0 :                                 didx = afto ? pd2.sidx : pd2.didx;
    5617           0 :                                 iidx = afto ? !iidx : iidx;
    5618             : 
    5619           0 :                                 if (afto) {
    5620           0 :                                         if (nk->af != AF_INET)
    5621           0 :                                                 return (PF_DROP);
    5622           0 :                                         if (pf_translate_icmp_af(pd, nk->af,
    5623           0 :                                             &pd->hdr.icmp))
    5624           0 :                                                 return (PF_DROP);
    5625           0 :                                         m_copyback(pd->m, pd->off,
    5626             :                                             sizeof(struct icmp6_hdr),
    5627           0 :                                             &pd->hdr.icmp6, M_NOWAIT);
    5628           0 :                                         if (pf_change_icmp_af(pd->m, ipoff2,
    5629           0 :                                             pd, &pd2, &nk->addr[sidx],
    5630           0 :                                             &nk->addr[didx], pd->af, nk->af))
    5631           0 :                                                 return (PF_DROP);
    5632           0 :                                         pd->proto = IPPROTO_ICMP;
    5633           0 :                                         if (pf_translate_icmp_af(pd,
    5634           0 :                                                 nk->af, iih))
    5635           0 :                                                 return (PF_DROP);
    5636           0 :                                         if (virtual_type ==
    5637             :                                             htons(ICMP6_ECHO_REQUEST))
    5638           0 :                                                 pf_patch_16(pd, &iih->icmp6_id,
    5639           0 :                                                     nk->port[iidx]);
    5640           0 :                                         m_copyback(pd2.m, pd2.off,
    5641             :                                             sizeof(struct icmp6_hdr), iih,
    5642             :                                             M_NOWAIT);
    5643           0 :                                         pd->m->m_pkthdr.ph_rtableid =
    5644           0 :                                             nk->rdomain;
    5645           0 :                                         pd->destchg = 1;
    5646           0 :                                         PF_ACPY(&pd->nsaddr,
    5647             :                                             &nk->addr[pd2.sidx], nk->af);
    5648           0 :                                         PF_ACPY(&pd->ndaddr,
    5649             :                                             &nk->addr[pd2.didx], nk->af);
    5650           0 :                                         pd->naf = nk->af;
    5651           0 :                                         return (PF_AFRT);
    5652             :                                 }
    5653             : 
    5654           0 :                                 if (PF_ANEQ(pd2.src,
    5655           0 :                                     &nk->addr[pd2.sidx], pd2.af) ||
    5656           0 :                                     ((virtual_type ==
    5657           0 :                                     htons(ICMP6_ECHO_REQUEST)) &&
    5658           0 :                                     nk->port[pd2.sidx] != iih->icmp6_id))
    5659           0 :                                         pf_translate_icmp(pd, pd2.src,
    5660           0 :                                             (virtual_type ==
    5661             :                                             htons(ICMP6_ECHO_REQUEST))
    5662           0 :                                             ? &iih->icmp6_id : NULL,
    5663           0 :                                             pd->dst, &nk->addr[pd2.sidx],
    5664           0 :                                             (virtual_type ==
    5665             :                                             htons(ICMP6_ECHO_REQUEST))
    5666           0 :                                             ? nk->port[iidx] : 0);
    5667             : 
    5668           0 :                                 if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx],
    5669           0 :                                     pd2.af) || pd2.rdomain != nk->rdomain)
    5670           0 :                                         pd->destchg = 1;
    5671           0 :                                 pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
    5672             : 
    5673           0 :                                 if (PF_ANEQ(pd2.dst,
    5674             :                                     &nk->addr[pd2.didx], pd2.af))
    5675           0 :                                         pf_translate_icmp(pd, pd2.dst, NULL,
    5676           0 :                                             pd->src, &nk->addr[pd2.didx], 0);
    5677             : 
    5678           0 :                                 m_copyback(pd->m, pd->off,
    5679           0 :                                     sizeof(struct icmp6_hdr), &pd->hdr.icmp6,
    5680             :                                     M_NOWAIT);
    5681           0 :                                 m_copyback(pd2.m, ipoff2, sizeof(h2_6), &h2_6,
    5682             :                                     M_NOWAIT);
    5683           0 :                                 m_copyback(pd2.m, pd2.off,
    5684             :                                     sizeof(struct icmp6_hdr), iih, M_NOWAIT);
    5685             :                                 copyback = 1;
    5686           0 :                         }
    5687           0 :                         break;
    5688             :                 }
    5689             : #endif /* INET6 */
    5690             :                 default: {
    5691             :                         int     action;
    5692             : 
    5693           0 :                         key.af = pd2.af;
    5694           0 :                         key.proto = pd2.proto;
    5695           0 :                         key.rdomain = pd2.rdomain;
    5696           0 :                         PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
    5697           0 :                         PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
    5698           0 :                         key.port[0] = key.port[1] = 0;
    5699             : 
    5700           0 :                         action = pf_find_state(&pd2, &key, state);
    5701           0 :                         if (action != PF_MATCH)
    5702           0 :                                 return (action);
    5703             : 
    5704             :                         /* translate source/destination address, if necessary */
    5705           0 :                         if ((*state)->key[PF_SK_WIRE] !=
    5706           0 :                             (*state)->key[PF_SK_STACK]) {
    5707             :                                 struct pf_state_key *nk =
    5708           0 :                                     (*state)->key[pd->didx];
    5709             : 
    5710           0 :                                 if (PF_ANEQ(pd2.src,
    5711             :                                     &nk->addr[pd2.sidx], pd2.af))
    5712           0 :                                         pf_translate_icmp(pd, pd2.src, NULL,
    5713           0 :                                             pd->dst, &nk->addr[pd2.sidx], 0);
    5714             : 
    5715           0 :                                 if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx],
    5716           0 :                                     pd2.af) || pd2.rdomain != nk->rdomain)
    5717           0 :                                         pd->destchg = 1;
    5718           0 :                                 pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
    5719             : 
    5720           0 :                                 if (PF_ANEQ(pd2.dst,
    5721             :                                     &nk->addr[pd2.didx], pd2.af))
    5722           0 :                                         pf_translate_icmp(pd, pd2.dst, NULL,
    5723           0 :                                             pd->src, &nk->addr[pd2.didx], 0);
    5724             : 
    5725           0 :                                 switch (pd2.af) {
    5726             :                                 case AF_INET:
    5727           0 :                                         m_copyback(pd->m, pd->off, ICMP_MINLEN,
    5728           0 :                                             &pd->hdr.icmp, M_NOWAIT);
    5729           0 :                                         m_copyback(pd2.m, ipoff2, sizeof(h2),
    5730             :                                             &h2, M_NOWAIT);
    5731           0 :                                         break;
    5732             : #ifdef INET6
    5733             :                                 case AF_INET6:
    5734           0 :                                         m_copyback(pd->m, pd->off,
    5735             :                                             sizeof(struct icmp6_hdr),
    5736           0 :                                             &pd->hdr.icmp6, M_NOWAIT);
    5737           0 :                                         m_copyback(pd2.m, ipoff2, sizeof(h2_6),
    5738             :                                             &h2_6, M_NOWAIT);
    5739           0 :                                         break;
    5740             : #endif /* INET6 */
    5741             :                                 }
    5742             :                                 copyback = 1;
    5743           0 :                         }
    5744           0 :                         break;
    5745             :                 }
    5746             :                 }
    5747           0 :         }
    5748           0 :         if (copyback) {
    5749           0 :                 m_copyback(pd->m, pd->off, pd->hdrlen, &pd->hdr, M_NOWAIT);
    5750           0 :         }
    5751             : 
    5752           0 :         return (PF_PASS);
    5753           0 : }
    5754             : 
    5755             : /*
    5756             :  * ipoff and off are measured from the start of the mbuf chain.
    5757             :  * h must be at "ipoff" on the mbuf chain.
    5758             :  */
    5759             : void *
    5760           0 : pf_pull_hdr(struct mbuf *m, int off, void *p, int len,
    5761             :     u_short *actionp, u_short *reasonp, sa_family_t af)
    5762             : {
    5763             :         int iplen = 0;
    5764             : 
    5765           0 :         switch (af) {
    5766             :         case AF_INET: {
    5767           0 :                 struct ip       *h = mtod(m, struct ip *);
    5768           0 :                 u_int16_t        fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
    5769             : 
    5770           0 :                 if (fragoff) {
    5771           0 :                         if (fragoff >= len)
    5772           0 :                                 ACTION_SET(actionp, PF_PASS);
    5773             :                         else {
    5774           0 :                                 ACTION_SET(actionp, PF_DROP);
    5775           0 :                                 REASON_SET(reasonp, PFRES_FRAG);
    5776             :                         }
    5777           0 :                         return (NULL);
    5778             :                 }
    5779           0 :                 iplen = ntohs(h->ip_len);
    5780           0 :                 break;
    5781             :         }
    5782             : #ifdef INET6
    5783             :         case AF_INET6: {
    5784           0 :                 struct ip6_hdr  *h = mtod(m, struct ip6_hdr *);
    5785             : 
    5786           0 :                 iplen = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
    5787             :                 break;
    5788             :         }
    5789             : #endif /* INET6 */
    5790             :         }
    5791           0 :         if (m->m_pkthdr.len < off + len || iplen < off + len) {
    5792           0 :                 ACTION_SET(actionp, PF_DROP);
    5793           0 :                 REASON_SET(reasonp, PFRES_SHORT);
    5794           0 :                 return (NULL);
    5795             :         }
    5796           0 :         m_copydata(m, off, len, p);
    5797           0 :         return (p);
    5798           0 : }
    5799             : 
    5800             : int
    5801           0 : pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif,
    5802             :     int rtableid)
    5803             : {
    5804           0 :         struct sockaddr_storage  ss;
    5805             :         struct sockaddr_in      *dst;
    5806             :         int                      ret = 1;
    5807             :         int                      check_mpath;
    5808             : #ifdef INET6
    5809             :         struct sockaddr_in6     *dst6;
    5810             : #endif  /* INET6 */
    5811             :         struct rtentry          *rt = NULL;
    5812             : 
    5813             :         check_mpath = 0;
    5814           0 :         memset(&ss, 0, sizeof(ss));
    5815           0 :         switch (af) {
    5816             :         case AF_INET:
    5817           0 :                 dst = (struct sockaddr_in *)&ss;
    5818           0 :                 dst->sin_family = AF_INET;
    5819           0 :                 dst->sin_len = sizeof(*dst);
    5820           0 :                 dst->sin_addr = addr->v4;
    5821           0 :                 if (ipmultipath)
    5822           0 :                         check_mpath = 1;
    5823             :                 break;
    5824             : #ifdef INET6
    5825             :         case AF_INET6:
    5826             :                 /*
    5827             :                  * Skip check for addresses with embedded interface scope,
    5828             :                  * as they would always match anyway.
    5829             :                  */
    5830           0 :                 if (IN6_IS_SCOPE_EMBED(&addr->v6))
    5831             :                         goto out;
    5832           0 :                 dst6 = (struct sockaddr_in6 *)&ss;
    5833           0 :                 dst6->sin6_family = AF_INET6;
    5834           0 :                 dst6->sin6_len = sizeof(*dst6);
    5835           0 :                 dst6->sin6_addr = addr->v6;
    5836           0 :                 if (ip6_multipath)
    5837           0 :                         check_mpath = 1;
    5838             :                 break;
    5839             : #endif /* INET6 */
    5840             :         }
    5841             : 
    5842             :         /* Skip checks for ipsec interfaces */
    5843           0 :         if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC)
    5844             :                 goto out;
    5845             : 
    5846           0 :         rt = rtalloc(sstosa(&ss), 0, rtableid);
    5847           0 :         if (rt != NULL) {
    5848             :                 /* No interface given, this is a no-route check */
    5849           0 :                 if (kif == NULL)
    5850             :                         goto out;
    5851             : 
    5852           0 :                 if (kif->pfik_ifp == NULL) {
    5853             :                         ret = 0;
    5854             :                         goto out;
    5855             :                 }
    5856             : 
    5857             :                 /* Perform uRPF check if passed input interface */
    5858             :                 ret = 0;
    5859           0 :                 do {
    5860           0 :                         if (rt->rt_ifidx == kif->pfik_ifp->if_index) {
    5861             :                                 ret = 1;
    5862             : #if NCARP > 0
    5863           0 :                         } else {
    5864             :                                 struct ifnet    *ifp;
    5865             : 
    5866           0 :                                 ifp = if_get(rt->rt_ifidx);
    5867           0 :                                 if (ifp != NULL && ifp->if_type == IFT_CARP &&
    5868           0 :                                     ifp->if_carpdev == kif->pfik_ifp)
    5869           0 :                                         ret = 1;
    5870           0 :                                 if_put(ifp);
    5871             : #endif /* NCARP */
    5872             :                         }
    5873             : 
    5874           0 :                         rt = rtable_iterate(rt);
    5875           0 :                 } while (check_mpath == 1 && rt != NULL && ret == 0);
    5876             :         } else
    5877             :                 ret = 0;
    5878             : out:
    5879           0 :         rtfree(rt);
    5880           0 :         return (ret);
    5881           0 : }
    5882             : 
    5883             : int
    5884           0 : pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw,
    5885             :     int rtableid)
    5886             : {
    5887           0 :         struct sockaddr_storage  ss;
    5888             :         struct sockaddr_in      *dst;
    5889             : #ifdef INET6
    5890             :         struct sockaddr_in6     *dst6;
    5891             : #endif  /* INET6 */
    5892             :         struct rtentry          *rt;
    5893             :         int                      ret = 0;
    5894             : 
    5895           0 :         memset(&ss, 0, sizeof(ss));
    5896           0 :         switch (af) {
    5897             :         case AF_INET:
    5898           0 :                 dst = (struct sockaddr_in *)&ss;
    5899           0 :                 dst->sin_family = AF_INET;
    5900           0 :                 dst->sin_len = sizeof(*dst);
    5901           0 :                 dst->sin_addr = addr->v4;
    5902           0 :                 break;
    5903             : #ifdef INET6
    5904             :         case AF_INET6:
    5905           0 :                 dst6 = (struct sockaddr_in6 *)&ss;
    5906           0 :                 dst6->sin6_family = AF_INET6;
    5907           0 :                 dst6->sin6_len = sizeof(*dst6);
    5908           0 :                 dst6->sin6_addr = addr->v6;
    5909           0 :                 break;
    5910             : #endif /* INET6 */
    5911             :         }
    5912             : 
    5913           0 :         rt = rtalloc(sstosa(&ss), RT_RESOLVE, rtableid);
    5914           0 :         if (rt != NULL) {
    5915           0 :                 if (rt->rt_labelid == aw->v.rtlabel)
    5916           0 :                         ret = 1;
    5917           0 :                 rtfree(rt);
    5918           0 :         }
    5919             : 
    5920           0 :         return (ret);
    5921           0 : }
    5922             : 
    5923             : /* pf_route() may change pd->m, adjust local copies after calling */
    5924             : void
    5925           0 : pf_route(struct pf_pdesc *pd, struct pf_rule *r, struct pf_state *s)
    5926             : {
    5927           0 :         struct mbuf             *m0, *m1;
    5928           0 :         struct sockaddr_in      *dst, sin;
    5929             :         struct rtentry          *rt = NULL;
    5930             :         struct ip               *ip;
    5931             :         struct ifnet            *ifp = NULL;
    5932           0 :         struct pf_addr           naddr;
    5933           0 :         struct pf_src_node      *sns[PF_SN_MAX];
    5934             :         int                      error = 0;
    5935             :         unsigned int             rtableid;
    5936             : 
    5937           0 :         if (pd->m->m_pkthdr.pf.routed++ > 3) {
    5938           0 :                 m_freem(pd->m);
    5939           0 :                 pd->m = NULL;
    5940           0 :                 return;
    5941             :         }
    5942             : 
    5943           0 :         if (r->rt == PF_DUPTO) {
    5944           0 :                 if ((m0 = m_dup_pkt(pd->m, max_linkhdr, M_NOWAIT)) == NULL)
    5945           0 :                         return;
    5946             :         } else {
    5947           0 :                 if ((r->rt == PF_REPLYTO) == (r->direction == pd->dir))
    5948           0 :                         return;
    5949           0 :                 m0 = pd->m;
    5950             :         }
    5951             : 
    5952           0 :         if (m0->m_len < sizeof(struct ip)) {
    5953           0 :                 DPFPRINTF(LOG_ERR,
    5954             :                     "%s: m0->m_len < sizeof(struct ip)", __func__);
    5955             :                 goto bad;
    5956             :         }
    5957             : 
    5958           0 :         ip = mtod(m0, struct ip *);
    5959             : 
    5960           0 :         memset(&sin, 0, sizeof(sin));
    5961             :         dst = &sin;
    5962           0 :         dst->sin_family = AF_INET;
    5963           0 :         dst->sin_len = sizeof(*dst);
    5964           0 :         dst->sin_addr = ip->ip_dst;
    5965           0 :         rtableid = m0->m_pkthdr.ph_rtableid;
    5966             : 
    5967           0 :         if (pd->dir == PF_IN) {
    5968           0 :                 if (ip->ip_ttl <= IPTTLDEC) {
    5969           0 :                         if (r->rt != PF_DUPTO)
    5970           0 :                                 pf_send_icmp(m0, ICMP_TIMXCEED,
    5971             :                                     ICMP_TIMXCEED_INTRANS, 0,
    5972           0 :                                     pd->af, r, pd->rdomain);
    5973             :                         goto bad;
    5974             :                 }
    5975           0 :                 ip->ip_ttl -= IPTTLDEC;
    5976           0 :         }
    5977             : 
    5978           0 :         if (s == NULL) {
    5979           0 :                 memset(sns, 0, sizeof(sns));
    5980           0 :                 if (pf_map_addr(AF_INET, r,
    5981           0 :                     (struct pf_addr *)&ip->ip_src,
    5982           0 :                     &naddr, NULL, sns, &r->route, PF_SN_ROUTE)) {
    5983           0 :                         DPFPRINTF(LOG_ERR,
    5984             :                             "%s: pf_map_addr() failed", __func__);
    5985             :                         goto bad;
    5986             :                 }
    5987             : 
    5988           0 :                 if (!PF_AZERO(&naddr, AF_INET))
    5989           0 :                         dst->sin_addr.s_addr = naddr.v4.s_addr;
    5990           0 :                 ifp = r->route.kif ?
    5991           0 :                     r->route.kif->pfik_ifp : NULL;
    5992           0 :         } else {
    5993           0 :                 if (!PF_AZERO(&s->rt_addr, AF_INET))
    5994           0 :                         dst->sin_addr.s_addr =
    5995           0 :                             s->rt_addr.v4.s_addr;
    5996           0 :                 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
    5997             :         }
    5998           0 :         if (ifp == NULL)
    5999             :                 goto bad;
    6000             : 
    6001           0 :         if (pd->kif->pfik_ifp != ifp) {
    6002           0 :                 if (pf_test(AF_INET, PF_OUT, ifp, &m0) != PF_PASS)
    6003             :                         goto bad;
    6004           0 :                 else if (m0 == NULL)
    6005             :                         goto done;
    6006           0 :                 if (m0->m_len < sizeof(struct ip)) {
    6007           0 :                         DPFPRINTF(LOG_ERR,
    6008             :                             "%s: m0->m_len < sizeof(struct ip)", __func__);
    6009             :                         goto bad;
    6010             :                 }
    6011           0 :                 ip = mtod(m0, struct ip *);
    6012           0 :         }
    6013             : 
    6014           0 :         rt = rtalloc(sintosa(dst), RT_RESOLVE, rtableid);
    6015           0 :         if (!rtisvalid(rt)) {
    6016           0 :                 ipstat_inc(ips_noroute);
    6017           0 :                 goto bad;
    6018             :         }
    6019             :         /* A locally generated packet may have invalid source address. */
    6020           0 :         if ((ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET &&
    6021           0 :             (ifp->if_flags & IFF_LOOPBACK) == 0)
    6022           0 :                 ip->ip_src = ifatoia(rt->rt_ifa)->ia_addr.sin_addr;
    6023             : 
    6024           0 :         in_proto_cksum_out(m0, ifp);
    6025             : 
    6026           0 :         if (ntohs(ip->ip_len) <= ifp->if_mtu) {
    6027           0 :                 ip->ip_sum = 0;
    6028           0 :                 if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
    6029           0 :                         m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
    6030             :                 else {
    6031           0 :                         ipstat_inc(ips_outswcsum);
    6032           0 :                         ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
    6033             :                 }
    6034           0 :                 error = ifp->if_output(ifp, m0, sintosa(dst), rt);
    6035           0 :                 goto done;
    6036             :         }
    6037             : 
    6038             :         /*
    6039             :          * Too large for interface; fragment if possible.
    6040             :          * Must be able to put at least 8 bytes per fragment.
    6041             :          */
    6042           0 :         if (ip->ip_off & htons(IP_DF)) {
    6043           0 :                 ipstat_inc(ips_cantfrag);
    6044           0 :                 if (r->rt != PF_DUPTO)
    6045           0 :                         pf_send_icmp(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG,
    6046           0 :                             ifp->if_mtu, pd->af, r, pd->rdomain);
    6047             :                 goto bad;
    6048             :         }
    6049             : 
    6050           0 :         m1 = m0;
    6051           0 :         error = ip_fragment(m0, ifp, ifp->if_mtu);
    6052           0 :         if (error) {
    6053           0 :                 m0 = NULL;
    6054           0 :                 goto bad;
    6055             :         }
    6056             : 
    6057           0 :         for (m0 = m1; m0; m0 = m1) {
    6058           0 :                 m1 = m0->m_nextpkt;
    6059           0 :                 m0->m_nextpkt = 0;
    6060           0 :                 if (error == 0)
    6061           0 :                         error = ifp->if_output(ifp, m0, sintosa(dst), rt);
    6062             :                 else
    6063           0 :                         m_freem(m0);
    6064             :         }
    6065             : 
    6066           0 :         if (error == 0)
    6067           0 :                 ipstat_inc(ips_fragmented);
    6068             : 
    6069             : done:
    6070           0 :         if (r->rt != PF_DUPTO)
    6071           0 :                 pd->m = NULL;
    6072           0 :         rtfree(rt);
    6073           0 :         return;
    6074             : 
    6075             : bad:
    6076           0 :         m_freem(m0);
    6077           0 :         goto done;
    6078           0 : }
    6079             : 
    6080             : #ifdef INET6
    6081             : /* pf_route6() may change pd->m, adjust local copies after calling */
    6082             : void
    6083           0 : pf_route6(struct pf_pdesc *pd, struct pf_rule *r, struct pf_state *s)
    6084             : {
    6085           0 :         struct mbuf             *m0;
    6086           0 :         struct sockaddr_in6     *dst, sin6;
    6087             :         struct rtentry          *rt = NULL;
    6088             :         struct ip6_hdr          *ip6;
    6089             :         struct ifnet            *ifp = NULL;
    6090           0 :         struct pf_addr           naddr;
    6091           0 :         struct pf_src_node      *sns[PF_SN_MAX];
    6092             :         struct m_tag            *mtag;
    6093             :         unsigned int             rtableid;
    6094             : 
    6095           0 :         if (pd->m->m_pkthdr.pf.routed++ > 3) {
    6096           0 :                 m_freem(pd->m);
    6097           0 :                 pd->m = NULL;
    6098           0 :                 return;
    6099             :         }
    6100             : 
    6101           0 :         if (r->rt == PF_DUPTO) {
    6102           0 :                 if ((m0 = m_dup_pkt(pd->m, max_linkhdr, M_NOWAIT)) == NULL)
    6103           0 :                         return;
    6104             :         } else {
    6105           0 :                 if ((r->rt == PF_REPLYTO) == (r->direction == pd->dir))
    6106           0 :                         return;
    6107           0 :                 m0 = pd->m;
    6108             :         }
    6109             : 
    6110           0 :         if (m0->m_len < sizeof(struct ip6_hdr)) {
    6111           0 :                 DPFPRINTF(LOG_ERR,
    6112             :                     "%s: m0->m_len < sizeof(struct ip6_hdr)", __func__);
    6113             :                 goto bad;
    6114             :         }
    6115           0 :         ip6 = mtod(m0, struct ip6_hdr *);
    6116             : 
    6117           0 :         memset(&sin6, 0, sizeof(sin6));
    6118             :         dst = &sin6;
    6119           0 :         dst->sin6_family = AF_INET6;
    6120           0 :         dst->sin6_len = sizeof(*dst);
    6121           0 :         dst->sin6_addr = ip6->ip6_dst;
    6122           0 :         rtableid = m0->m_pkthdr.ph_rtableid;
    6123             : 
    6124           0 :         if (pd->dir == PF_IN) {
    6125           0 :                 if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
    6126           0 :                         if (r->rt != PF_DUPTO)
    6127           0 :                                 pf_send_icmp(m0, ICMP6_TIME_EXCEEDED,
    6128             :                                     ICMP6_TIME_EXCEED_TRANSIT, 0,
    6129           0 :                                     pd->af, r, pd->rdomain);
    6130             :                         goto bad;
    6131             :                 }
    6132           0 :                 ip6->ip6_hlim -= IPV6_HLIMDEC;
    6133           0 :         }
    6134             : 
    6135           0 :         if (s == NULL) {
    6136           0 :                 memset(sns, 0, sizeof(sns));
    6137           0 :                 if (pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
    6138           0 :                     &naddr, NULL, sns, &r->route, PF_SN_ROUTE)) {
    6139           0 :                         DPFPRINTF(LOG_ERR,
    6140             :                             "%s: pf_map_addr() failed", __func__);
    6141             :                         goto bad;
    6142             :                 }
    6143           0 :                 if (!PF_AZERO(&naddr, AF_INET6))
    6144           0 :                         PF_ACPY((struct pf_addr *)&dst->sin6_addr,
    6145             :                             &naddr, AF_INET6);
    6146           0 :                 ifp = r->route.kif ? r->route.kif->pfik_ifp : NULL;
    6147           0 :         } else {
    6148           0 :                 if (!PF_AZERO(&s->rt_addr, AF_INET6))
    6149           0 :                         PF_ACPY((struct pf_addr *)&dst->sin6_addr,
    6150             :                             &s->rt_addr, AF_INET6);
    6151           0 :                 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
    6152             :         }
    6153           0 :         if (ifp == NULL)
    6154             :                 goto bad;
    6155             : 
    6156           0 :         if (pd->kif->pfik_ifp != ifp) {
    6157           0 :                 if (pf_test(AF_INET6, PF_OUT, ifp, &m0) != PF_PASS)
    6158             :                         goto bad;
    6159           0 :                 else if (m0 == NULL)
    6160             :                         goto done;
    6161           0 :                 if (m0->m_len < sizeof(struct ip6_hdr)) {
    6162           0 :                         DPFPRINTF(LOG_ERR,
    6163             :                             "%s: m0->m_len < sizeof(struct ip6_hdr)", __func__);
    6164             :                         goto bad;
    6165             :                 }
    6166             :         }
    6167             : 
    6168           0 :         if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr))
    6169           0 :                 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
    6170           0 :         rt = rtalloc(sin6tosa(dst), RT_RESOLVE, rtableid);
    6171           0 :         if (!rtisvalid(rt)) {
    6172           0 :                 ip6stat_inc(ip6s_noroute);
    6173           0 :                 goto bad;
    6174             :         }
    6175             :         /* A locally generated packet may have invalid source address. */
    6176           0 :         if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) &&
    6177           0 :             (ifp->if_flags & IFF_LOOPBACK) == 0)
    6178           0 :                 ip6->ip6_src = ifatoia6(rt->rt_ifa)->ia_addr.sin6_addr;
    6179             : 
    6180           0 :         in6_proto_cksum_out(m0, ifp);
    6181             : 
    6182             :         /*
    6183             :          * If packet has been reassembled by PF earlier, we have to
    6184             :          * use pf_refragment6() here to turn it back to fragments.
    6185             :          */
    6186           0 :         if ((mtag = m_tag_find(m0, PACKET_TAG_PF_REASSEMBLED, NULL))) {
    6187           0 :                 (void) pf_refragment6(&m0, mtag, dst, ifp, rt);
    6188           0 :         } else if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
    6189           0 :                 ifp->if_output(ifp, m0, sin6tosa(dst), rt);
    6190             :         } else {
    6191           0 :                 ip6stat_inc(ip6s_cantfrag);
    6192           0 :                 if (r->rt != PF_DUPTO)
    6193           0 :                         pf_send_icmp(m0, ICMP6_PACKET_TOO_BIG, 0,
    6194           0 :                             ifp->if_mtu, pd->af, r, pd->rdomain);
    6195             :                 goto bad;
    6196             :         }
    6197             : 
    6198             : done:
    6199           0 :         if (r->rt != PF_DUPTO)
    6200           0 :                 pd->m = NULL;
    6201           0 :         rtfree(rt);
    6202           0 :         return;
    6203             : 
    6204             : bad:
    6205           0 :         m_freem(m0);
    6206           0 :         goto done;
    6207           0 : }
    6208             : #endif /* INET6 */
    6209             : 
    6210             : 
    6211             : /*
    6212             :  * check TCP checksum and set mbuf flag
    6213             :  *   off is the offset where the protocol header starts
    6214             :  *   len is the total length of protocol header plus payload
    6215             :  * returns 0 when the checksum is valid, otherwise returns 1.
    6216             :  * if the _OUT flag is set the checksum isn't done yet, consider these ok
    6217             :  */
    6218             : int
    6219           0 : pf_check_tcp_cksum(struct mbuf *m, int off, int len, sa_family_t af)
    6220             : {
    6221             :         u_int16_t sum;
    6222             : 
    6223           0 :         if (m->m_pkthdr.csum_flags &
    6224             :             (M_TCP_CSUM_IN_OK | M_TCP_CSUM_OUT)) {
    6225           0 :                 return (0);
    6226             :         }
    6227           0 :         if (m->m_pkthdr.csum_flags & M_TCP_CSUM_IN_BAD ||
    6228           0 :             off < sizeof(struct ip) ||
    6229           0 :             m->m_pkthdr.len < off + len) {
    6230           0 :                 return (1);
    6231             :         }
    6232             : 
    6233             :         /* need to do it in software */
    6234           0 :         tcpstat_inc(tcps_inswcsum);
    6235             : 
    6236           0 :         switch (af) {
    6237             :         case AF_INET:
    6238           0 :                 if (m->m_len < sizeof(struct ip))
    6239           0 :                         return (1);
    6240             : 
    6241           0 :                 sum = in4_cksum(m, IPPROTO_TCP, off, len);
    6242           0 :                 break;
    6243             : #ifdef INET6
    6244             :         case AF_INET6:
    6245           0 :                 if (m->m_len < sizeof(struct ip6_hdr))
    6246           0 :                         return (1);
    6247             : 
    6248           0 :                 sum = in6_cksum(m, IPPROTO_TCP, off, len);
    6249           0 :                 break;
    6250             : #endif /* INET6 */
    6251             :         default:
    6252           0 :                 unhandled_af(af);
    6253             :         }
    6254           0 :         if (sum) {
    6255           0 :                 tcpstat_inc(tcps_rcvbadsum);
    6256           0 :                 m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_BAD;
    6257           0 :                 return (1);
    6258             :         }
    6259             : 
    6260           0 :         m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK;
    6261           0 :         return (0);
    6262           0 : }
    6263             : 
    6264             : struct pf_divert *
    6265           0 : pf_find_divert(struct mbuf *m)
    6266             : {
    6267             :         struct m_tag    *mtag;
    6268             : 
    6269           0 :         if ((mtag = m_tag_find(m, PACKET_TAG_PF_DIVERT, NULL)) == NULL)
    6270           0 :                 return (NULL);
    6271             : 
    6272           0 :         return ((struct pf_divert *)(mtag + 1));
    6273           0 : }
    6274             : 
    6275             : struct pf_divert *
    6276           0 : pf_get_divert(struct mbuf *m)
    6277             : {
    6278             :         struct m_tag    *mtag;
    6279             : 
    6280           0 :         if ((mtag = m_tag_find(m, PACKET_TAG_PF_DIVERT, NULL)) == NULL) {
    6281           0 :                 mtag = m_tag_get(PACKET_TAG_PF_DIVERT, sizeof(struct pf_divert),
    6282             :                     M_NOWAIT);
    6283           0 :                 if (mtag == NULL)
    6284           0 :                         return (NULL);
    6285           0 :                 memset(mtag + 1, 0, sizeof(struct pf_divert));
    6286           0 :                 m_tag_prepend(m, mtag);
    6287           0 :         }
    6288             : 
    6289           0 :         return ((struct pf_divert *)(mtag + 1));
    6290           0 : }
    6291             : 
    6292             : int
    6293           0 : pf_walk_header(struct pf_pdesc *pd, struct ip *h, u_short *reason)
    6294             : {
    6295           0 :         struct ip6_ext           ext;
    6296             :         u_int32_t                hlen, end;
    6297             :         int                      hdr_cnt;
    6298             : 
    6299           0 :         hlen = h->ip_hl << 2;
    6300           0 :         if (hlen < sizeof(struct ip) || hlen > ntohs(h->ip_len)) {
    6301           0 :                 REASON_SET(reason, PFRES_SHORT);
    6302           0 :                 return (PF_DROP);
    6303             :         }
    6304           0 :         if (hlen != sizeof(struct ip))
    6305           0 :                 pd->badopts++;
    6306           0 :         end = pd->off + ntohs(h->ip_len);
    6307           0 :         pd->off += hlen;
    6308           0 :         pd->proto = h->ip_p;
    6309             :         /* stop walking over non initial fragments */
    6310           0 :         if ((h->ip_off & htons(IP_OFFMASK)) != 0)
    6311           0 :                 return (PF_PASS);
    6312             : 
    6313           0 :         for (hdr_cnt = 0; hdr_cnt < pf_hdr_limit; hdr_cnt++) {
    6314           0 :                 switch (pd->proto) {
    6315             :                 case IPPROTO_AH:
    6316             :                         /* fragments may be short */
    6317           0 :                         if ((h->ip_off & htons(IP_MF | IP_OFFMASK)) != 0 &&
    6318           0 :                             end < pd->off + sizeof(ext))
    6319           0 :                                 return (PF_PASS);
    6320           0 :                         if (!pf_pull_hdr(pd->m, pd->off, &ext, sizeof(ext),
    6321             :                             NULL, reason, AF_INET)) {
    6322           0 :                                 DPFPRINTF(LOG_NOTICE, "IP short exthdr");
    6323           0 :                                 return (PF_DROP);
    6324             :                         }
    6325           0 :                         pd->off += (ext.ip6e_len + 2) * 4;
    6326           0 :                         pd->proto = ext.ip6e_nxt;
    6327             :                         break;
    6328             :                 default:
    6329           0 :                         return (PF_PASS);
    6330             :                 }
    6331             :         }
    6332           0 :         DPFPRINTF(LOG_NOTICE, "IPv4 nested authentication header limit");
    6333           0 :         REASON_SET(reason, PFRES_IPOPTIONS);
    6334           0 :         return (PF_DROP);
    6335           0 : }
    6336             : 
    6337             : #ifdef INET6
    6338             : int
    6339           0 : pf_walk_option6(struct pf_pdesc *pd, struct ip6_hdr *h, int off, int end,
    6340             :     u_short *reason)
    6341             : {
    6342           0 :         struct ip6_opt           opt;
    6343           0 :         struct ip6_opt_jumbo     jumbo;
    6344             : 
    6345           0 :         while (off < end) {
    6346           0 :                 if (!pf_pull_hdr(pd->m, off, &opt.ip6o_type,
    6347             :                     sizeof(opt.ip6o_type), NULL, reason, AF_INET6)) {
    6348           0 :                         DPFPRINTF(LOG_NOTICE, "IPv6 short opt type");
    6349           0 :                         return (PF_DROP);
    6350             :                 }
    6351           0 :                 if (opt.ip6o_type == IP6OPT_PAD1) {
    6352           0 :                         off++;
    6353           0 :                         continue;
    6354             :                 }
    6355           0 :                 if (!pf_pull_hdr(pd->m, off, &opt, sizeof(opt),
    6356             :                     NULL, reason, AF_INET6)) {
    6357           0 :                         DPFPRINTF(LOG_NOTICE, "IPv6 short opt");
    6358           0 :                         return (PF_DROP);
    6359             :                 }
    6360           0 :                 if (off + sizeof(opt) + opt.ip6o_len > end) {
    6361           0 :                         DPFPRINTF(LOG_NOTICE, "IPv6 long opt");
    6362           0 :                         REASON_SET(reason, PFRES_IPOPTIONS);
    6363           0 :                         return (PF_DROP);
    6364             :                 }
    6365           0 :                 switch (opt.ip6o_type) {
    6366             :                 case IP6OPT_JUMBO:
    6367           0 :                         if (pd->jumbolen != 0) {
    6368           0 :                                 DPFPRINTF(LOG_NOTICE, "IPv6 multiple jumbo");
    6369           0 :                                 REASON_SET(reason, PFRES_IPOPTIONS);
    6370           0 :                                 return (PF_DROP);
    6371             :                         }
    6372           0 :                         if (ntohs(h->ip6_plen) != 0) {
    6373           0 :                                 DPFPRINTF(LOG_NOTICE, "IPv6 bad jumbo plen");
    6374           0 :                                 REASON_SET(reason, PFRES_IPOPTIONS);
    6375           0 :                                 return (PF_DROP);
    6376             :                         }
    6377           0 :                         if (!pf_pull_hdr(pd->m, off, &jumbo, sizeof(jumbo),
    6378             :                             NULL, reason, AF_INET6)) {
    6379           0 :                                 DPFPRINTF(LOG_NOTICE, "IPv6 short jumbo");
    6380           0 :                                 return (PF_DROP);
    6381             :                         }
    6382           0 :                         memcpy(&pd->jumbolen, jumbo.ip6oj_jumbo_len,
    6383             :                             sizeof(pd->jumbolen));
    6384           0 :                         pd->jumbolen = ntohl(pd->jumbolen);
    6385           0 :                         if (pd->jumbolen < IPV6_MAXPACKET) {
    6386           0 :                                 DPFPRINTF(LOG_NOTICE, "IPv6 short jumbolen");
    6387           0 :                                 REASON_SET(reason, PFRES_IPOPTIONS);
    6388           0 :                                 return (PF_DROP);
    6389             :                         }
    6390             :                         break;
    6391             :                 default:
    6392             :                         break;
    6393             :                 }
    6394           0 :                 off += sizeof(opt) + opt.ip6o_len;
    6395             :         }
    6396             : 
    6397           0 :         return (PF_PASS);
    6398           0 : }
    6399             : 
    6400             : int
    6401           0 : pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
    6402             : {
    6403           0 :         struct ip6_frag          frag;
    6404           0 :         struct ip6_ext           ext;
    6405           0 :         struct ip6_rthdr         rthdr;
    6406             :         u_int32_t                end;
    6407             :         int                      hdr_cnt, fraghdr_cnt = 0, rthdr_cnt = 0;
    6408             : 
    6409           0 :         pd->off += sizeof(struct ip6_hdr);
    6410           0 :         end = pd->off + ntohs(h->ip6_plen);
    6411           0 :         pd->fragoff = pd->extoff = pd->jumbolen = 0;
    6412           0 :         pd->proto = h->ip6_nxt;
    6413             : 
    6414           0 :         for (hdr_cnt = 0; hdr_cnt < pf_hdr_limit; hdr_cnt++) {
    6415           0 :                 switch (pd->proto) {
    6416             :                 case IPPROTO_ROUTING:
    6417             :                 case IPPROTO_HOPOPTS:
    6418             :                 case IPPROTO_DSTOPTS:
    6419           0 :                         pd->badopts++;
    6420           0 :                         break;
    6421             :                 }
    6422           0 :                 switch (pd->proto) {
    6423             :                 case IPPROTO_FRAGMENT:
    6424           0 :                         if (fraghdr_cnt++) {
    6425           0 :                                 DPFPRINTF(LOG_NOTICE, "IPv6 multiple fragment");
    6426           0 :                                 REASON_SET(reason, PFRES_FRAG);
    6427           0 :                                 return (PF_DROP);
    6428             :                         }
    6429             :                         /* jumbo payload packets cannot be fragmented */
    6430           0 :                         if (pd->jumbolen != 0) {
    6431           0 :                                 DPFPRINTF(LOG_NOTICE, "IPv6 fragmented jumbo");
    6432           0 :                                 REASON_SET(reason, PFRES_FRAG);
    6433           0 :                                 return (PF_DROP);
    6434             :                         }
    6435           0 :                         if (!pf_pull_hdr(pd->m, pd->off, &frag, sizeof(frag),
    6436             :                             NULL, reason, AF_INET6)) {
    6437           0 :                                 DPFPRINTF(LOG_NOTICE, "IPv6 short fragment");
    6438           0 :                                 return (PF_DROP);
    6439             :                         }
    6440             :                         /* stop walking over non initial fragments */
    6441           0 :                         if (ntohs((frag.ip6f_offlg & IP6F_OFF_MASK)) != 0) {
    6442           0 :                                 pd->fragoff = pd->off;
    6443           0 :                                 return (PF_PASS);
    6444             :                         }
    6445             :                         /* RFC6946:  reassemble only non atomic fragments */
    6446           0 :                         if (frag.ip6f_offlg & IP6F_MORE_FRAG)
    6447           0 :                                 pd->fragoff = pd->off;
    6448           0 :                         pd->off += sizeof(frag);
    6449           0 :                         pd->proto = frag.ip6f_nxt;
    6450           0 :                         break;
    6451             :                 case IPPROTO_ROUTING:
    6452           0 :                         if (rthdr_cnt++) {
    6453           0 :                                 DPFPRINTF(LOG_NOTICE, "IPv6 multiple rthdr");
    6454           0 :                                 REASON_SET(reason, PFRES_IPOPTIONS);
    6455           0 :                                 return (PF_DROP);
    6456             :                         }
    6457             :                         /* fragments may be short */
    6458           0 :                         if (pd->fragoff != 0 && end < pd->off + sizeof(rthdr)) {
    6459           0 :                                 pd->off = pd->fragoff;
    6460           0 :                                 pd->proto = IPPROTO_FRAGMENT;
    6461           0 :                                 return (PF_PASS);
    6462             :                         }
    6463           0 :                         if (!pf_pull_hdr(pd->m, pd->off, &rthdr, sizeof(rthdr),
    6464             :                             NULL, reason, AF_INET6)) {
    6465           0 :                                 DPFPRINTF(LOG_NOTICE, "IPv6 short rthdr");
    6466           0 :                                 return (PF_DROP);
    6467             :                         }
    6468           0 :                         if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) {
    6469           0 :                                 DPFPRINTF(LOG_NOTICE, "IPv6 rthdr0");
    6470           0 :                                 REASON_SET(reason, PFRES_IPOPTIONS);
    6471           0 :                                 return (PF_DROP);
    6472             :                         }
    6473             :                         /* FALLTHROUGH */
    6474             :                 case IPPROTO_HOPOPTS:
    6475             :                         /* RFC2460 4.1:  Hop-by-Hop only after IPv6 header */
    6476           0 :                         if (pd->proto == IPPROTO_HOPOPTS && hdr_cnt > 0) {
    6477           0 :                                 DPFPRINTF(LOG_NOTICE, "IPv6 hopopts not first");
    6478           0 :                                 REASON_SET(reason, PFRES_IPOPTIONS);
    6479           0 :                                 return (PF_DROP);
    6480             :                         }
    6481             :                         /* FALLTHROUGH */
    6482             :                 case IPPROTO_AH:
    6483             :                 case IPPROTO_DSTOPTS:
    6484             :                         /* fragments may be short */
    6485           0 :                         if (pd->fragoff != 0 && end < pd->off + sizeof(ext)) {
    6486           0 :                                 pd->off = pd->fragoff;
    6487           0 :                                 pd->proto = IPPROTO_FRAGMENT;
    6488           0 :                                 return (PF_PASS);
    6489             :                         }
    6490           0 :                         if (!pf_pull_hdr(pd->m, pd->off, &ext, sizeof(ext),
    6491             :                             NULL, reason, AF_INET6)) {
    6492           0 :                                 DPFPRINTF(LOG_NOTICE, "IPv6 short exthdr");
    6493           0 :                                 return (PF_DROP);
    6494             :                         }
    6495             :                         /* reassembly needs the ext header before the frag */
    6496           0 :                         if (pd->fragoff == 0)
    6497           0 :                                 pd->extoff = pd->off;
    6498           0 :                         if (pd->proto == IPPROTO_HOPOPTS && pd->fragoff == 0) {
    6499           0 :                                 if (pf_walk_option6(pd, h,
    6500           0 :                                     pd->off + sizeof(ext),
    6501           0 :                                     pd->off + (ext.ip6e_len + 1) * 8, reason)
    6502           0 :                                     != PF_PASS)
    6503           0 :                                         return (PF_DROP);
    6504           0 :                                 if (ntohs(h->ip6_plen) == 0 &&
    6505           0 :                                     pd->jumbolen != 0) {
    6506           0 :                                         DPFPRINTF(LOG_NOTICE,
    6507             :                                             "IPv6 missing jumbo");
    6508           0 :                                         REASON_SET(reason, PFRES_IPOPTIONS);
    6509           0 :                                         return (PF_DROP);
    6510             :                                 }
    6511             :                         }
    6512           0 :                         if (pd->proto == IPPROTO_AH)
    6513           0 :                                 pd->off += (ext.ip6e_len + 2) * 4;
    6514             :                         else
    6515           0 :                                 pd->off += (ext.ip6e_len + 1) * 8;
    6516           0 :                         pd->proto = ext.ip6e_nxt;
    6517           0 :                         break;
    6518             :                 case IPPROTO_TCP:
    6519             :                 case IPPROTO_UDP:
    6520             :                 case IPPROTO_ICMPV6:
    6521             :                         /* fragments may be short, ignore inner header then */
    6522           0 :                         if (pd->fragoff != 0 && end < pd->off +
    6523           0 :                             (pd->proto == IPPROTO_TCP ? sizeof(struct tcphdr) :
    6524           0 :                             pd->proto == IPPROTO_UDP ? sizeof(struct udphdr) :
    6525             :                             sizeof(struct icmp6_hdr))) {
    6526           0 :                                 pd->off = pd->fragoff;
    6527           0 :                                 pd->proto = IPPROTO_FRAGMENT;
    6528           0 :                         }
    6529             :                         /* FALLTHROUGH */
    6530             :                 default:
    6531           0 :                         return (PF_PASS);
    6532             :                 }
    6533             :         }
    6534           0 :         DPFPRINTF(LOG_NOTICE, "IPv6 nested extension header limit");
    6535           0 :         REASON_SET(reason, PFRES_IPOPTIONS);
    6536           0 :         return (PF_DROP);
    6537           0 : }
    6538             : #endif /* INET6 */
    6539             : 
    6540             : int
    6541           0 : pf_setup_pdesc(struct pf_pdesc *pd, sa_family_t af, int dir,
    6542             :     struct pfi_kif *kif, struct mbuf *m, u_short *reason)
    6543             : {
    6544           0 :         memset(pd, 0, sizeof(*pd));
    6545           0 :         pd->dir = dir;
    6546           0 :         pd->kif = kif;               /* kif is NULL when called by pflog */
    6547           0 :         pd->m = m;
    6548           0 :         pd->sidx = (dir == PF_IN) ? 0 : 1;
    6549           0 :         pd->didx = (dir == PF_IN) ? 1 : 0;
    6550           0 :         pd->af = pd->naf = af;
    6551           0 :         pd->rdomain = rtable_l2(pd->m->m_pkthdr.ph_rtableid);
    6552             : 
    6553           0 :         switch (pd->af) {
    6554             :         case AF_INET: {
    6555             :                 struct ip       *h;
    6556             : 
    6557             :                 /* Check for illegal packets */
    6558           0 :                 if (pd->m->m_pkthdr.len < (int)sizeof(struct ip)) {
    6559           0 :                         REASON_SET(reason, PFRES_SHORT);
    6560           0 :                         return (PF_DROP);
    6561             :                 }
    6562             : 
    6563           0 :                 h = mtod(pd->m, struct ip *);
    6564           0 :                 if (pd->m->m_pkthdr.len < ntohs(h->ip_len)) {
    6565           0 :                         REASON_SET(reason, PFRES_SHORT);
    6566           0 :                         return (PF_DROP);
    6567             :                 }
    6568             : 
    6569           0 :                 if (pf_walk_header(pd, h, reason) != PF_PASS)
    6570           0 :                         return (PF_DROP);
    6571             : 
    6572           0 :                 pd->src = (struct pf_addr *)&h->ip_src;
    6573           0 :                 pd->dst = (struct pf_addr *)&h->ip_dst;
    6574           0 :                 pd->tot_len = ntohs(h->ip_len);
    6575           0 :                 pd->tos = h->ip_tos & ~IPTOS_ECN_MASK;
    6576           0 :                 pd->ttl = h->ip_ttl;
    6577           0 :                 pd->virtual_proto = (h->ip_off & htons(IP_MF | IP_OFFMASK)) ?
    6578           0 :                      PF_VPROTO_FRAGMENT : pd->proto;
    6579             : 
    6580           0 :                 break;
    6581             :         }
    6582             : #ifdef INET6
    6583             :         case AF_INET6: {
    6584             :                 struct ip6_hdr  *h;
    6585             : 
    6586             :                 /* Check for illegal packets */
    6587           0 :                 if (pd->m->m_pkthdr.len < (int)sizeof(struct ip6_hdr)) {
    6588           0 :                         REASON_SET(reason, PFRES_SHORT);
    6589           0 :                         return (PF_DROP);
    6590             :                 }
    6591             : 
    6592           0 :                 h = mtod(pd->m, struct ip6_hdr *);
    6593           0 :                 if (pd->m->m_pkthdr.len <
    6594           0 :                     sizeof(struct ip6_hdr) + ntohs(h->ip6_plen)) {
    6595           0 :                         REASON_SET(reason, PFRES_SHORT);
    6596           0 :                         return (PF_DROP);
    6597             :                 }
    6598             : 
    6599           0 :                 if (pf_walk_header6(pd, h, reason) != PF_PASS)
    6600           0 :                         return (PF_DROP);
    6601             : 
    6602             : #if 1
    6603             :                 /*
    6604             :                  * we do not support jumbogram yet.  if we keep going, zero
    6605             :                  * ip6_plen will do something bad, so drop the packet for now.
    6606             :                  */
    6607           0 :                 if (pd->jumbolen != 0) {
    6608           0 :                         REASON_SET(reason, PFRES_NORM);
    6609           0 :                         return (PF_DROP);
    6610             :                 }
    6611             : #endif  /* 1 */
    6612             : 
    6613           0 :                 pd->src = (struct pf_addr *)&h->ip6_src;
    6614           0 :                 pd->dst = (struct pf_addr *)&h->ip6_dst;
    6615           0 :                 pd->tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
    6616           0 :                 pd->tos = (ntohl(h->ip6_flow) & 0x0fc00000) >> 20;
    6617           0 :                 pd->ttl = h->ip6_hlim;
    6618           0 :                 pd->virtual_proto = (pd->fragoff != 0) ?
    6619           0 :                         PF_VPROTO_FRAGMENT : pd->proto;
    6620             : 
    6621           0 :                 break;
    6622             :         }
    6623             : #endif /* INET6 */
    6624             :         default:
    6625           0 :                 panic("pf_setup_pdesc called with illegal af %u", pd->af);
    6626             : 
    6627             :         }
    6628             : 
    6629           0 :         PF_ACPY(&pd->nsaddr, pd->src, pd->af);
    6630           0 :         PF_ACPY(&pd->ndaddr, pd->dst, pd->af);
    6631             : 
    6632           0 :         switch (pd->virtual_proto) {
    6633             :         case IPPROTO_TCP: {
    6634           0 :                 struct tcphdr   *th = &pd->hdr.tcp;
    6635             : 
    6636           0 :                 if (!pf_pull_hdr(pd->m, pd->off, th, sizeof(*th),
    6637           0 :                     NULL, reason, pd->af))
    6638           0 :                         return (PF_DROP);
    6639           0 :                 pd->hdrlen = sizeof(*th);
    6640           0 :                 if (pd->off + (th->th_off << 2) > pd->tot_len ||
    6641           0 :                     (th->th_off << 2) < sizeof(struct tcphdr)) {
    6642           0 :                         REASON_SET(reason, PFRES_SHORT);
    6643           0 :                         return (PF_DROP);
    6644             :                 }
    6645           0 :                 pd->p_len = pd->tot_len - pd->off - (th->th_off << 2);
    6646           0 :                 pd->sport = &th->th_sport;
    6647           0 :                 pd->dport = &th->th_dport;
    6648           0 :                 pd->pcksum = &th->th_sum;
    6649           0 :                 break;
    6650             :         }
    6651             :         case IPPROTO_UDP: {
    6652           0 :                 struct udphdr   *uh = &pd->hdr.udp;
    6653             : 
    6654           0 :                 if (!pf_pull_hdr(pd->m, pd->off, uh, sizeof(*uh),
    6655           0 :                     NULL, reason, pd->af))
    6656           0 :                         return (PF_DROP);
    6657           0 :                 pd->hdrlen = sizeof(*uh);
    6658           0 :                 if (uh->uh_dport == 0 ||
    6659           0 :                     pd->off + ntohs(uh->uh_ulen) > pd->tot_len ||
    6660           0 :                     ntohs(uh->uh_ulen) < sizeof(struct udphdr)) {
    6661           0 :                         REASON_SET(reason, PFRES_SHORT);
    6662           0 :                         return (PF_DROP);
    6663             :                 }
    6664           0 :                 pd->sport = &uh->uh_sport;
    6665           0 :                 pd->dport = &uh->uh_dport;
    6666           0 :                 pd->pcksum = &uh->uh_sum;
    6667           0 :                 break;
    6668             :         }
    6669             :         case IPPROTO_ICMP: {
    6670           0 :                 if (!pf_pull_hdr(pd->m, pd->off, &pd->hdr.icmp, ICMP_MINLEN,
    6671           0 :                     NULL, reason, pd->af))
    6672           0 :                         return (PF_DROP);
    6673           0 :                 pd->hdrlen = ICMP_MINLEN;
    6674           0 :                 if (pd->off + pd->hdrlen > pd->tot_len) {
    6675           0 :                         REASON_SET(reason, PFRES_SHORT);
    6676           0 :                         return (PF_DROP);
    6677             :                 }
    6678           0 :                 pd->pcksum = &pd->hdr.icmp.icmp_cksum;
    6679           0 :                 break;
    6680             :         }
    6681             : #ifdef INET6
    6682             :         case IPPROTO_ICMPV6: {
    6683             :                 size_t  icmp_hlen = sizeof(struct icmp6_hdr);
    6684             : 
    6685           0 :                 if (!pf_pull_hdr(pd->m, pd->off, &pd->hdr.icmp6, icmp_hlen,
    6686           0 :                     NULL, reason, pd->af))
    6687           0 :                         return (PF_DROP);
    6688             :                 /* ICMP headers we look further into to match state */
    6689           0 :                 switch (pd->hdr.icmp6.icmp6_type) {
    6690             :                 case MLD_LISTENER_QUERY:
    6691             :                 case MLD_LISTENER_REPORT:
    6692             :                         icmp_hlen = sizeof(struct mld_hdr);
    6693           0 :                         break;
    6694             :                 case ND_NEIGHBOR_SOLICIT:
    6695             :                 case ND_NEIGHBOR_ADVERT:
    6696           0 :                         icmp_hlen = sizeof(struct nd_neighbor_solicit);
    6697             :                         /* FALLTHROUGH */
    6698             :                 case ND_ROUTER_SOLICIT:
    6699             :                 case ND_ROUTER_ADVERT:
    6700             :                 case ND_REDIRECT:
    6701           0 :                         if (pd->ttl != 255) {
    6702           0 :                                 REASON_SET(reason, PFRES_NORM);
    6703           0 :                                 return (PF_DROP);
    6704             :                         }
    6705             :                         break;
    6706             :                 }
    6707           0 :                 if (icmp_hlen > sizeof(struct icmp6_hdr) &&
    6708           0 :                     !pf_pull_hdr(pd->m, pd->off, &pd->hdr.icmp6, icmp_hlen,
    6709           0 :                     NULL, reason, pd->af))
    6710           0 :                         return (PF_DROP);
    6711           0 :                 pd->hdrlen = icmp_hlen;
    6712           0 :                 if (pd->off + pd->hdrlen > pd->tot_len) {
    6713           0 :                         REASON_SET(reason, PFRES_SHORT);
    6714           0 :                         return (PF_DROP);
    6715             :                 }
    6716           0 :                 pd->pcksum = &pd->hdr.icmp6.icmp6_cksum;
    6717           0 :                 break;
    6718             :         }
    6719             : #endif  /* INET6 */
    6720             :         }
    6721             : 
    6722           0 :         if (pd->sport)
    6723           0 :                 pd->osport = pd->nsport = *pd->sport;
    6724           0 :         if (pd->dport)
    6725           0 :                 pd->odport = pd->ndport = *pd->dport;
    6726             : 
    6727           0 :         return (PF_PASS);
    6728           0 : }
    6729             : 
    6730             : void
    6731           0 : pf_counters_inc(int action, struct pf_pdesc *pd, struct pf_state *s,
    6732             :     struct pf_rule *r, struct pf_rule *a)
    6733             : {
    6734             :         int dirndx;
    6735           0 :         pd->kif->pfik_bytes[pd->af == AF_INET6][pd->dir == PF_OUT]
    6736           0 :             [action != PF_PASS] += pd->tot_len;
    6737           0 :         pd->kif->pfik_packets[pd->af == AF_INET6][pd->dir == PF_OUT]
    6738           0 :             [action != PF_PASS]++;
    6739             : 
    6740           0 :         if (action == PF_PASS || action == PF_AFRT || r->action == PF_DROP) {
    6741           0 :                 dirndx = (pd->dir == PF_OUT);
    6742           0 :                 r->packets[dirndx]++;
    6743           0 :                 r->bytes[dirndx] += pd->tot_len;
    6744           0 :                 if (a != NULL) {
    6745           0 :                         a->packets[dirndx]++;
    6746           0 :                         a->bytes[dirndx] += pd->tot_len;
    6747           0 :                 }
    6748           0 :                 if (s != NULL) {
    6749             :                         struct pf_rule_item     *ri;
    6750             :                         struct pf_sn_item       *sni;
    6751             : 
    6752           0 :                         SLIST_FOREACH(sni, &s->src_nodes, next) {
    6753           0 :                                 sni->sn->packets[dirndx]++;
    6754           0 :                                 sni->sn->bytes[dirndx] += pd->tot_len;
    6755             :                         }
    6756           0 :                         dirndx = (pd->dir == s->direction) ? 0 : 1;
    6757           0 :                         s->packets[dirndx]++;
    6758           0 :                         s->bytes[dirndx] += pd->tot_len;
    6759             : 
    6760           0 :                         SLIST_FOREACH(ri, &s->match_rules, entry) {
    6761           0 :                                 ri->r->packets[dirndx]++;
    6762           0 :                                 ri->r->bytes[dirndx] += pd->tot_len;
    6763             : 
    6764           0 :                                 if (ri->r->src.addr.type == PF_ADDR_TABLE)
    6765           0 :                                         pfr_update_stats(ri->r->src.addr.p.tbl,
    6766           0 :                                             &s->key[(s->direction == PF_IN)]->
    6767           0 :                                                 addr[(s->direction == PF_OUT)],
    6768           0 :                                             pd, ri->r->action, ri->r->src.neg);
    6769           0 :                                 if (ri->r->dst.addr.type == PF_ADDR_TABLE)
    6770           0 :                                         pfr_update_stats(ri->r->dst.addr.p.tbl,
    6771           0 :                                             &s->key[(s->direction == PF_IN)]->
    6772           0 :                                                 addr[(s->direction == PF_IN)],
    6773           0 :                                             pd, ri->r->action, ri->r->dst.neg);
    6774             :                         }
    6775           0 :                 }
    6776           0 :                 if (r->src.addr.type == PF_ADDR_TABLE)
    6777           0 :                         pfr_update_stats(r->src.addr.p.tbl,
    6778           0 :                             (s == NULL) ? pd->src :
    6779           0 :                             &s->key[(s->direction == PF_IN)]->
    6780           0 :                                 addr[(s->direction == PF_OUT)],
    6781           0 :                             pd, r->action, r->src.neg);
    6782           0 :                 if (r->dst.addr.type == PF_ADDR_TABLE)
    6783           0 :                         pfr_update_stats(r->dst.addr.p.tbl,
    6784           0 :                             (s == NULL) ? pd->dst :
    6785           0 :                             &s->key[(s->direction == PF_IN)]->
    6786           0 :                                 addr[(s->direction == PF_IN)],
    6787           0 :                             pd, r->action, r->dst.neg);
    6788             :         }
    6789           0 : }
    6790             : 
    6791             : int
    6792           0 : pf_test(sa_family_t af, int fwdir, struct ifnet *ifp, struct mbuf **m0)
    6793             : {
    6794             :         struct pfi_kif          *kif;
    6795           0 :         u_short                  action, reason = 0;
    6796           0 :         struct pf_rule          *a = NULL, *r = &pf_default_rule;
    6797           0 :         struct pf_state         *s = NULL;
    6798           0 :         struct pf_ruleset       *ruleset = NULL;
    6799           0 :         struct pf_pdesc          pd;
    6800           0 :         int                      dir = (fwdir == PF_FWD) ? PF_OUT : fwdir;
    6801             :         u_int32_t                qid, pqid = 0;
    6802           0 :         int                      have_pf_lock = 0;
    6803             : 
    6804           0 :         if (!pf_status.running)
    6805           0 :                 return (PF_PASS);
    6806             : 
    6807             : #if NCARP > 0
    6808           0 :         if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
    6809           0 :                 kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
    6810             :         else
    6811             : #endif /* NCARP */
    6812           0 :                 kif = (struct pfi_kif *)ifp->if_pf_kif;
    6813             : 
    6814           0 :         if (kif == NULL) {
    6815           0 :                 DPFPRINTF(LOG_ERR,
    6816             :                     "%s: kif == NULL, if_xname %s", __func__, ifp->if_xname);
    6817           0 :                 return (PF_DROP);
    6818             :         }
    6819           0 :         if (kif->pfik_flags & PFI_IFLAG_SKIP)
    6820           0 :                 return (PF_PASS);
    6821             : 
    6822             : #ifdef DIAGNOSTIC
    6823           0 :         if (((*m0)->m_flags & M_PKTHDR) == 0)
    6824           0 :                 panic("non-M_PKTHDR is passed to pf_test");
    6825             : #endif /* DIAGNOSTIC */
    6826             : 
    6827           0 :         if ((*m0)->m_pkthdr.pf.flags & PF_TAG_GENERATED)
    6828           0 :                 return (PF_PASS);
    6829             : 
    6830           0 :         if ((*m0)->m_pkthdr.pf.flags & PF_TAG_DIVERTED_PACKET)
    6831           0 :                 return (PF_PASS);
    6832             : 
    6833           0 :         if ((*m0)->m_pkthdr.pf.flags & PF_TAG_REFRAGMENTED) {
    6834           0 :                 (*m0)->m_pkthdr.pf.flags &= ~PF_TAG_REFRAGMENTED;
    6835           0 :                 return (PF_PASS);
    6836             :         }
    6837             : 
    6838           0 :         action = pf_setup_pdesc(&pd, af, dir, kif, *m0, &reason);
    6839           0 :         if (action != PF_PASS) {
    6840             : #if NPFLOG > 0
    6841           0 :                 pd.pflog |= PF_LOG_FORCE;
    6842             : #endif  /* NPFLOG > 0 */
    6843           0 :                 goto done;
    6844             :         }
    6845             : 
    6846             :         /* packet normalization and reassembly */
    6847           0 :         switch (pd.af) {
    6848             :         case AF_INET:
    6849           0 :                 action = pf_normalize_ip(&pd, &reason);
    6850           0 :                 break;
    6851             : #ifdef INET6
    6852             :         case AF_INET6:
    6853           0 :                 action = pf_normalize_ip6(&pd, &reason);
    6854           0 :                 break;
    6855             : #endif  /* INET6 */
    6856             :         }
    6857           0 :         *m0 = pd.m;
    6858             :         /* if packet sits in reassembly queue, return without error */
    6859           0 :         if (pd.m == NULL)
    6860           0 :                 return PF_PASS;
    6861             : 
    6862           0 :         if (action != PF_PASS) {
    6863             : #if NPFLOG > 0
    6864           0 :                 pd.pflog |= PF_LOG_FORCE;
    6865             : #endif  /* NPFLOG > 0 */
    6866           0 :                 goto done;
    6867             :         }
    6868             : 
    6869             :         /* if packet has been reassembled, update packet description */
    6870           0 :         if (pf_status.reass && pd.virtual_proto == PF_VPROTO_FRAGMENT) {
    6871           0 :                 action = pf_setup_pdesc(&pd, af, dir, kif, pd.m, &reason);
    6872           0 :                 if (action != PF_PASS) {
    6873             : #if NPFLOG > 0
    6874           0 :                         pd.pflog |= PF_LOG_FORCE;
    6875             : #endif  /* NPFLOG > 0 */
    6876           0 :                         goto done;
    6877             :                 }
    6878             :         }
    6879           0 :         pd.m->m_pkthdr.pf.flags |= PF_TAG_PROCESSED;
    6880             : 
    6881             :         /*
    6882             :          * Avoid pcb-lookups from the forwarding path.  They should never
    6883             :          * match and would cause MP locking problems.
    6884             :          */
    6885           0 :         if (fwdir == PF_FWD) {
    6886           0 :                 pd.lookup.done = -1;
    6887           0 :                 pd.lookup.uid = UID_MAX;
    6888           0 :                 pd.lookup.gid = GID_MAX;
    6889           0 :                 pd.lookup.pid = NO_PID;
    6890           0 :         }
    6891             : 
    6892           0 :         switch (pd.virtual_proto) {
    6893             : 
    6894             :         case PF_VPROTO_FRAGMENT: {
    6895             :                 /*
    6896             :                  * handle fragments that aren't reassembled by
    6897             :                  * normalization
    6898             :                  */
    6899             :                 PF_LOCK();
    6900           0 :                 have_pf_lock = 1;
    6901           0 :                 action = pf_test_rule(&pd, &r, &s, &a, &ruleset, &reason);
    6902           0 :                 s = pf_state_ref(s);
    6903           0 :                 if (action != PF_PASS)
    6904           0 :                         REASON_SET(&reason, PFRES_FRAG);
    6905             :                 break;
    6906             :         }
    6907             : 
    6908             :         case IPPROTO_ICMP: {
    6909           0 :                 if (pd.af != AF_INET) {
    6910             :                         action = PF_DROP;
    6911           0 :                         REASON_SET(&reason, PFRES_NORM);
    6912           0 :                         DPFPRINTF(LOG_NOTICE,
    6913             :                             "dropping IPv6 packet with ICMPv4 payload");
    6914             :                         break;
    6915             :                 }
    6916             :                 PF_STATE_ENTER_READ();
    6917           0 :                 action = pf_test_state_icmp(&pd, &s, &reason);
    6918           0 :                 s = pf_state_ref(s);
    6919             :                 PF_STATE_EXIT_READ();
    6920           0 :                 if (action == PF_PASS || action == PF_AFRT) {
    6921             : #if NPFSYNC > 0
    6922           0 :                         pfsync_update_state(s, &have_pf_lock);
    6923             : #endif /* NPFSYNC > 0 */
    6924           0 :                         r = s->rule.ptr;
    6925           0 :                         a = s->anchor.ptr;
    6926             : #if NPFLOG > 0
    6927           0 :                         pd.pflog |= s->log;
    6928             : #endif  /* NPFLOG > 0 */
    6929           0 :                 } else if (s == NULL) {
    6930             :                         PF_LOCK();
    6931           0 :                         have_pf_lock = 1;
    6932           0 :                         action = pf_test_rule(&pd, &r, &s, &a, &ruleset,
    6933             :                             &reason);
    6934           0 :                         s = pf_state_ref(s);
    6935           0 :                 }
    6936             :                 break;
    6937             :         }
    6938             : 
    6939             : #ifdef INET6
    6940             :         case IPPROTO_ICMPV6: {
    6941           0 :                 if (pd.af != AF_INET6) {
    6942             :                         action = PF_DROP;
    6943           0 :                         REASON_SET(&reason, PFRES_NORM);
    6944           0 :                         DPFPRINTF(LOG_NOTICE,
    6945             :                             "dropping IPv4 packet with ICMPv6 payload");
    6946             :                         break;
    6947             :                 }
    6948             :                 PF_STATE_ENTER_READ();
    6949           0 :                 action = pf_test_state_icmp(&pd, &s, &reason);
    6950           0 :                 s = pf_state_ref(s);
    6951             :                 PF_STATE_EXIT_READ();
    6952           0 :                 if (action == PF_PASS || action == PF_AFRT) {
    6953             : #if NPFSYNC > 0
    6954           0 :                         pfsync_update_state(s, &have_pf_lock);
    6955             : #endif /* NPFSYNC > 0 */
    6956           0 :                         r = s->rule.ptr;
    6957           0 :                         a = s->anchor.ptr;
    6958             : #if NPFLOG > 0
    6959           0 :                         pd.pflog |= s->log;
    6960             : #endif  /* NPFLOG > 0 */
    6961           0 :                 } else if (s == NULL) {
    6962             :                         PF_LOCK();
    6963           0 :                         have_pf_lock = 1;
    6964           0 :                         action = pf_test_rule(&pd, &r, &s, &a, &ruleset,
    6965             :                             &reason);
    6966           0 :                         s = pf_state_ref(s);
    6967           0 :                 }
    6968             :                 break;
    6969             :         }
    6970             : #endif /* INET6 */
    6971             : 
    6972             :         default:
    6973           0 :                 if (pd.virtual_proto == IPPROTO_TCP) {
    6974           0 :                         if (pd.dir == PF_IN && (pd.hdr.tcp.th_flags &
    6975           0 :                             (TH_SYN|TH_ACK)) == TH_SYN &&
    6976           0 :                             pf_synflood_check(&pd)) {
    6977             :                                 PF_LOCK();
    6978           0 :                                 have_pf_lock = 1;
    6979           0 :                                 pf_syncookie_send(&pd);
    6980             :                                 action = PF_DROP;
    6981           0 :                                 break;
    6982             :                         }
    6983           0 :                         if ((pd.hdr.tcp.th_flags & TH_ACK) && pd.p_len == 0)
    6984           0 :                                 pqid = 1;
    6985           0 :                         action = pf_normalize_tcp(&pd);
    6986           0 :                         if (action == PF_DROP)
    6987             :                                 break;
    6988             :                 }
    6989             :                 PF_STATE_ENTER_READ();
    6990           0 :                 action = pf_test_state(&pd, &s, &reason, 0);
    6991           0 :                 s = pf_state_ref(s);
    6992             :                 PF_STATE_EXIT_READ();
    6993           0 :                 if (s == NULL && action != PF_PASS && action != PF_AFRT &&
    6994           0 :                     pd.dir == PF_IN && pd.virtual_proto == IPPROTO_TCP &&
    6995           0 :                     (pd.hdr.tcp.th_flags & (TH_SYN|TH_ACK|TH_RST)) == TH_ACK &&
    6996           0 :                     pf_syncookie_validate(&pd)) {
    6997           0 :                         struct mbuf     *msyn;
    6998           0 :                         msyn = pf_syncookie_recreate_syn(&pd);
    6999           0 :                         if (msyn) {
    7000           0 :                                 action = pf_test(af, fwdir, ifp, &msyn);
    7001           0 :                                 m_freem(msyn);
    7002           0 :                                 if (action == PF_PASS || action == PF_AFRT) {
    7003             :                                         PF_STATE_ENTER_READ();
    7004           0 :                                         pf_test_state(&pd, &s, &reason, 1);
    7005           0 :                                         s = pf_state_ref(s);
    7006             :                                         PF_STATE_EXIT_READ();
    7007           0 :                                         if (s == NULL)
    7008           0 :                                                 return (PF_DROP);
    7009           0 :                                         s->src.seqhi =
    7010           0 :                                             ntohl(pd.hdr.tcp.th_ack) - 1;
    7011           0 :                                         s->src.seqlo =
    7012           0 :                                             ntohl(pd.hdr.tcp.th_seq) - 1;
    7013           0 :                                         pf_set_protostate(s, PF_PEER_SRC,
    7014             :                                             PF_TCPS_PROXY_DST);
    7015             :                                         PF_LOCK();
    7016           0 :                                         have_pf_lock = 1;
    7017           0 :                                         action = pf_synproxy(&pd, &s, &reason);
    7018           0 :                                         if (action != PF_PASS) {
    7019             :                                                 PF_UNLOCK();
    7020           0 :                                                 pf_state_unref(s);
    7021           0 :                                                 return (action);
    7022             :                                         }
    7023             :                                 }
    7024             :                         } else
    7025             :                                 action = PF_DROP;
    7026           0 :                 }
    7027             : 
    7028           0 :                 if (action == PF_PASS || action == PF_AFRT) {
    7029             : #if NPFSYNC > 0
    7030           0 :                         pfsync_update_state(s, &have_pf_lock);
    7031             : #endif /* NPFSYNC > 0 */
    7032           0 :                         r = s->rule.ptr;
    7033           0 :                         a = s->anchor.ptr;
    7034             : #if NPFLOG > 0
    7035           0 :                         pd.pflog |= s->log;
    7036             : #endif  /* NPFLOG > 0 */
    7037           0 :                 } else if (s == NULL) {
    7038             :                         PF_LOCK();
    7039           0 :                         have_pf_lock = 1;
    7040           0 :                         action = pf_test_rule(&pd, &r, &s, &a, &ruleset,
    7041             :                             &reason);
    7042           0 :                         s = pf_state_ref(s);
    7043           0 :                 }
    7044             : 
    7045           0 :                 if (pd.virtual_proto == IPPROTO_TCP) {
    7046           0 :                         if (s) {
    7047           0 :                                 if (s->max_mss)
    7048           0 :                                         pf_normalize_mss(&pd, s->max_mss);
    7049           0 :                         } else if (r->max_mss)
    7050           0 :                                 pf_normalize_mss(&pd, r->max_mss);
    7051             :                 }
    7052             : 
    7053             :                 break;
    7054             :         }
    7055             : 
    7056           0 :         if (have_pf_lock != 0)
    7057             :                 PF_UNLOCK();
    7058             : 
    7059             :         /*
    7060             :          * At the moment, we rely on NET_LOCK() to prevent removal of items
    7061             :          * we've collected above ('r', 'anchor' and 'ruleset').  They'll have
    7062             :          * to be refcounted when NET_LOCK() is gone.
    7063             :          */
    7064             : 
    7065             : done:
    7066           0 :         if (action != PF_DROP) {
    7067           0 :                 if (s) {
    7068             :                         /* The non-state case is handled in pf_test_rule() */
    7069           0 :                         if (action == PF_PASS && pd.badopts &&
    7070           0 :                             !(s->state_flags & PFSTATE_ALLOWOPTS)) {
    7071             :                                 action = PF_DROP;
    7072           0 :                                 REASON_SET(&reason, PFRES_IPOPTIONS);
    7073             : #if NPFLOG > 0
    7074           0 :                                 pd.pflog |= PF_LOG_FORCE;
    7075             : #endif  /* NPFLOG > 0 */
    7076           0 :                                 DPFPRINTF(LOG_NOTICE, "dropping packet with "
    7077             :                                     "ip/ipv6 options in pf_test()");
    7078             :                         }
    7079             : 
    7080           0 :                         pf_scrub(pd.m, s->state_flags, pd.af, s->min_ttl,
    7081           0 :                             s->set_tos);
    7082           0 :                         pf_tag_packet(pd.m, s->tag, s->rtableid[pd.didx]);
    7083           0 :                         if (pqid || (pd.tos & IPTOS_LOWDELAY)) {
    7084           0 :                                 qid = s->pqid;
    7085           0 :                                 if (s->state_flags & PFSTATE_SETPRIO)
    7086           0 :                                         pd.m->m_pkthdr.pf.prio = s->set_prio[1];
    7087             :                         } else {
    7088           0 :                                 qid = s->qid;
    7089           0 :                                 if (s->state_flags & PFSTATE_SETPRIO)
    7090           0 :                                         pd.m->m_pkthdr.pf.prio = s->set_prio[0];
    7091             :                         }
    7092           0 :                         pd.m->m_pkthdr.pf.delay = s->delay;
    7093           0 :                 } else {
    7094           0 :                         pf_scrub(pd.m, r->scrub_flags, pd.af, r->min_ttl,
    7095           0 :                             r->set_tos);
    7096           0 :                         if (pqid || (pd.tos & IPTOS_LOWDELAY)) {
    7097           0 :                                 qid = r->pqid;
    7098           0 :                                 if (r->scrub_flags & PFSTATE_SETPRIO)
    7099           0 :                                         pd.m->m_pkthdr.pf.prio = r->set_prio[1];
    7100             :                         } else {
    7101           0 :                                 qid = r->qid;
    7102           0 :                                 if (r->scrub_flags & PFSTATE_SETPRIO)
    7103           0 :                                         pd.m->m_pkthdr.pf.prio = r->set_prio[0];
    7104             :                         }
    7105           0 :                         pd.m->m_pkthdr.pf.delay = r->delay;
    7106             :                 }
    7107             :         }
    7108             : 
    7109           0 :         if (action == PF_PASS && qid)
    7110           0 :                 pd.m->m_pkthdr.pf.qid = qid;
    7111           0 :         if (pd.dir == PF_IN && s && s->key[PF_SK_STACK])
    7112           0 :                 pf_mbuf_link_state_key(pd.m, s->key[PF_SK_STACK]);
    7113           0 :         if (pd.dir == PF_OUT &&
    7114           0 :             pd.m->m_pkthdr.pf.inp && !pd.m->m_pkthdr.pf.inp->inp_pf_sk &&
    7115           0 :             s && s->key[PF_SK_STACK] && !s->key[PF_SK_STACK]->inp)
    7116           0 :                 pf_state_key_link_inpcb(s->key[PF_SK_STACK],
    7117             :                     pd.m->m_pkthdr.pf.inp);
    7118             : 
    7119           0 :         if (s && (pd.m->m_pkthdr.ph_flowid & M_FLOWID_VALID) == 0) {
    7120           0 :                 pd.m->m_pkthdr.ph_flowid = M_FLOWID_VALID |
    7121           0 :                     (M_FLOWID_MASK & bemtoh64(&s->id));
    7122           0 :         }
    7123             : 
    7124             :         /*
    7125             :          * connections redirected to loopback should not match sockets
    7126             :          * bound specifically to loopback due to security implications,
    7127             :          * see in_pcblookup_listen().
    7128             :          */
    7129           0 :         if (pd.destchg)
    7130           0 :                 if ((pd.af == AF_INET && (ntohl(pd.dst->v4.s_addr) >>
    7131           0 :                     IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) ||
    7132           0 :                     (pd.af == AF_INET6 && IN6_IS_ADDR_LOOPBACK(&pd.dst->v6)))
    7133           0 :                         pd.m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST;
    7134             :         /* We need to redo the route lookup on outgoing routes. */
    7135           0 :         if (pd.destchg && pd.dir == PF_OUT)
    7136           0 :                 pd.m->m_pkthdr.pf.flags |= PF_TAG_REROUTE;
    7137             : 
    7138           0 :         if (pd.dir == PF_IN && action == PF_PASS &&
    7139           0 :             (r->divert.type == PF_DIVERT_TO ||
    7140           0 :             r->divert.type == PF_DIVERT_REPLY)) {
    7141             :                 struct pf_divert *divert;
    7142             : 
    7143           0 :                 if ((divert = pf_get_divert(pd.m))) {
    7144           0 :                         pd.m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED;
    7145           0 :                         divert->addr = r->divert.addr;
    7146           0 :                         divert->port = r->divert.port;
    7147           0 :                         divert->rdomain = pd.rdomain;
    7148           0 :                         divert->type = r->divert.type;
    7149           0 :                 }
    7150           0 :         }
    7151             : 
    7152           0 :         if (action == PF_PASS && r->divert.type == PF_DIVERT_PACKET)
    7153           0 :                 action = PF_DIVERT;
    7154             : 
    7155             : #if NPFLOG > 0
    7156           0 :         if (pd.pflog) {
    7157             :                 struct pf_rule_item     *ri;
    7158             : 
    7159           0 :                 if (pd.pflog & PF_LOG_FORCE || r->log & PF_LOG_ALL)
    7160           0 :                         pflog_packet(&pd, reason, r, a, ruleset, NULL);
    7161           0 :                 if (s) {
    7162           0 :                         SLIST_FOREACH(ri, &s->match_rules, entry)
    7163           0 :                                 if (ri->r->log & PF_LOG_ALL)
    7164           0 :                                         pflog_packet(&pd, reason, ri->r, a,
    7165           0 :                                             ruleset, NULL);
    7166             :                 }
    7167           0 :         }
    7168             : #endif  /* NPFLOG > 0 */
    7169             : 
    7170           0 :         pf_counters_inc(action, &pd, s, r, a);
    7171             : 
    7172           0 :         switch (action) {
    7173             :         case PF_SYNPROXY_DROP:
    7174           0 :                 m_freem(pd.m);
    7175             :                 /* FALLTHROUGH */
    7176             :         case PF_DEFER:
    7177           0 :                 pd.m = NULL;
    7178             :                 action = PF_PASS;
    7179           0 :                 break;
    7180             :         case PF_DIVERT:
    7181           0 :                 switch (pd.af) {
    7182             :                 case AF_INET:
    7183           0 :                         if (!divert_packet(pd.m, pd.dir, r->divert.port))
    7184           0 :                                 pd.m = NULL;
    7185             :                         break;
    7186             : #ifdef INET6
    7187             :                 case AF_INET6:
    7188           0 :                         if (!divert6_packet(pd.m, pd.dir, r->divert.port))
    7189           0 :                                 pd.m = NULL;
    7190             :                         break;
    7191             : #endif /* INET6 */
    7192             :                 }
    7193             :                 action = PF_PASS;
    7194           0 :                 break;
    7195             : #ifdef INET6
    7196             :         case PF_AFRT:
    7197           0 :                 if (pf_translate_af(&pd)) {
    7198             :                         action = PF_DROP;
    7199           0 :                         break;
    7200             :                 }
    7201           0 :                 pd.m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
    7202           0 :                 switch (pd.naf) {
    7203             :                 case AF_INET:
    7204           0 :                         if (pd.dir == PF_IN)
    7205           0 :                                 ip_forward(pd.m, ifp, NULL, 1);
    7206             :                         else
    7207           0 :                                 ip_output(pd.m, NULL, NULL, 0, NULL, NULL, 0);
    7208             :                         break;
    7209             :                 case AF_INET6:
    7210           0 :                         if (pd.dir == PF_IN)
    7211           0 :                                 ip6_forward(pd.m, NULL, 1);
    7212             :                         else
    7213           0 :                                 ip6_output(pd.m, NULL, NULL, 0, NULL, NULL);
    7214             :                         break;
    7215             :                 }
    7216           0 :                 pd.m = NULL;
    7217             :                 action = PF_PASS;
    7218           0 :                 break;
    7219             : #endif /* INET6 */
    7220             :         case PF_DROP:
    7221           0 :                 m_freem(pd.m);
    7222           0 :                 pd.m = NULL;
    7223           0 :                 break;
    7224             :         default:
    7225           0 :                 if (r->rt) {
    7226           0 :                         switch (pd.af) {
    7227             :                         case AF_INET:
    7228           0 :                                 pf_route(&pd, r, s);
    7229           0 :                                 break;
    7230             : #ifdef INET6
    7231             :                         case AF_INET6:
    7232           0 :                                 pf_route6(&pd, r, s);
    7233           0 :                                 break;
    7234             : #endif /* INET6 */
    7235             :                         }
    7236             :                 }
    7237             :                 break;
    7238             :         }
    7239             : 
    7240             : #ifdef INET6
    7241             :         /* if reassembled packet passed, create new fragments */
    7242           0 :         if (pf_status.reass && action == PF_PASS && pd.m && fwdir == PF_FWD &&
    7243           0 :             pd.af == AF_INET6) {
    7244             :                 struct m_tag    *mtag;
    7245             : 
    7246           0 :                 if ((mtag = m_tag_find(pd.m, PACKET_TAG_PF_REASSEMBLED, NULL)))
    7247           0 :                         action = pf_refragment6(&pd.m, mtag, NULL, NULL, NULL);
    7248           0 :         }
    7249             : #endif  /* INET6 */
    7250           0 :         if (s && action != PF_DROP) {
    7251           0 :                 if (!s->if_index_in && dir == PF_IN)
    7252           0 :                         s->if_index_in = ifp->if_index;
    7253           0 :                 else if (!s->if_index_out && dir == PF_OUT)
    7254           0 :                         s->if_index_out = ifp->if_index;
    7255             :         }
    7256             : 
    7257           0 :         *m0 = pd.m;
    7258             : 
    7259           0 :         pf_state_unref(s);
    7260             : 
    7261           0 :         return (action);
    7262           0 : }
    7263             : 
    7264             : int
    7265           0 : pf_ouraddr(struct mbuf *m)
    7266             : {
    7267             :         struct pf_state_key     *sk;
    7268             : 
    7269           0 :         if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED)
    7270           0 :                 return (1);
    7271             : 
    7272           0 :         sk = m->m_pkthdr.pf.statekey;
    7273           0 :         if (sk != NULL) {
    7274           0 :                 if (sk->inp != NULL)
    7275           0 :                         return (1);
    7276             :         }
    7277             : 
    7278           0 :         return (-1);
    7279           0 : }
    7280             : 
    7281             : /*
    7282             :  * must be called whenever any addressing information such as
    7283             :  * address, port, protocol has changed
    7284             :  */
    7285             : void
    7286           0 : pf_pkt_addr_changed(struct mbuf *m)
    7287             : {
    7288           0 :         pf_mbuf_unlink_state_key(m);
    7289           0 :         pf_mbuf_unlink_inpcb(m);
    7290           0 : }
    7291             : 
    7292             : struct inpcb *
    7293           0 : pf_inp_lookup(struct mbuf *m)
    7294             : {
    7295             :         struct inpcb *inp = NULL;
    7296           0 :         struct pf_state_key *sk = m->m_pkthdr.pf.statekey;
    7297             : 
    7298           0 :         if (!pf_state_key_isvalid(sk))
    7299           0 :                 pf_mbuf_unlink_state_key(m);
    7300             :         else
    7301           0 :                 inp = m->m_pkthdr.pf.statekey->inp;
    7302             : 
    7303           0 :         if (inp && inp->inp_pf_sk)
    7304           0 :                 KASSERT(m->m_pkthdr.pf.statekey == inp->inp_pf_sk);
    7305             : 
    7306           0 :         return (inp);
    7307             : }
    7308             : 
    7309             : void
    7310           0 : pf_inp_link(struct mbuf *m, struct inpcb *inp)
    7311             : {
    7312           0 :         struct pf_state_key *sk = m->m_pkthdr.pf.statekey;
    7313             : 
    7314           0 :         if (!pf_state_key_isvalid(sk)) {
    7315           0 :                 pf_mbuf_unlink_state_key(m);
    7316           0 :                 return;
    7317             :         }
    7318             : 
    7319             :         /*
    7320             :          * we don't need to grab PF-lock here. At worst case we link inp to
    7321             :          * state, which might be just being marked as deleted by another
    7322             :          * thread.
    7323             :          */
    7324           0 :         if (inp && !sk->inp && !inp->inp_pf_sk)
    7325           0 :                 pf_state_key_link_inpcb(sk, inp);
    7326             : 
    7327             :         /* The statekey has finished finding the inp, it is no longer needed. */
    7328           0 :         pf_mbuf_unlink_state_key(m);
    7329           0 : }
    7330             : 
    7331             : void
    7332           0 : pf_inp_unlink(struct inpcb *inp)
    7333             : {
    7334           0 :         pf_inpcb_unlink_state_key(inp);
    7335           0 : }
    7336             : 
    7337             : void
    7338           0 : pf_state_key_link_reverse(struct pf_state_key *sk, struct pf_state_key *skrev)
    7339             : {
    7340             :         /* Note that sk and skrev may be equal, then we refcount twice. */
    7341           0 :         KASSERT(sk->reverse == NULL);
    7342           0 :         KASSERT(skrev->reverse == NULL);
    7343           0 :         sk->reverse = pf_state_key_ref(skrev);
    7344           0 :         skrev->reverse = pf_state_key_ref(sk);
    7345           0 : }
    7346             : 
    7347             : #if NPFLOG > 0
    7348             : void
    7349           0 : pf_log_matches(struct pf_pdesc *pd, struct pf_rule *rm, struct pf_rule *am,
    7350             :     struct pf_ruleset *ruleset, struct pf_rule_slist *matchrules)
    7351             : {
    7352             :         struct pf_rule_item     *ri;
    7353             : 
    7354             :         /* if this is the log(matches) rule, packet has been logged already */
    7355           0 :         if (rm->log & PF_LOG_MATCHES)
    7356           0 :                 return;
    7357             : 
    7358           0 :         SLIST_FOREACH(ri, matchrules, entry)
    7359           0 :                 if (ri->r->log & PF_LOG_MATCHES)
    7360           0 :                         pflog_packet(pd, PFRES_MATCH, rm, am, ruleset, ri->r);
    7361           0 : }
    7362             : #endif  /* NPFLOG > 0 */
    7363             : 
    7364             : struct pf_state_key *
    7365           0 : pf_state_key_ref(struct pf_state_key *sk)
    7366             : {
    7367           0 :         if (sk != NULL)
    7368           0 :                 PF_REF_TAKE(sk->refcnt);
    7369             : 
    7370           0 :         return (sk);
    7371             : }
    7372             : 
    7373             : void
    7374           0 : pf_state_key_unref(struct pf_state_key *sk)
    7375             : {
    7376           0 :         if (PF_REF_RELE(sk->refcnt)) {
    7377             :                 /* state key must be removed from tree */
    7378           0 :                 KASSERT(!pf_state_key_isvalid(sk));
    7379             :                 /* state key must be unlinked from reverse key */
    7380           0 :                 KASSERT(sk->reverse == NULL);
    7381             :                 /* state key must be unlinked from socket */
    7382           0 :                 KASSERT(sk->inp == NULL);
    7383           0 :                 pool_put(&pf_state_key_pl, sk);
    7384           0 :         }
    7385           0 : }
    7386             : 
    7387             : int
    7388           0 : pf_state_key_isvalid(struct pf_state_key *sk)
    7389             : {
    7390           0 :         return ((sk != NULL) && (sk->removed == 0));
    7391             : }
    7392             : 
    7393             : void
    7394           0 : pf_mbuf_link_state_key(struct mbuf *m, struct pf_state_key *sk)
    7395             : {
    7396           0 :         KASSERT(m->m_pkthdr.pf.statekey == NULL);
    7397           0 :         m->m_pkthdr.pf.statekey = pf_state_key_ref(sk);
    7398           0 : }
    7399             : 
    7400             : void
    7401           0 : pf_mbuf_unlink_state_key(struct mbuf *m)
    7402             : {
    7403           0 :         struct pf_state_key *sk = m->m_pkthdr.pf.statekey;
    7404             : 
    7405           0 :         if (sk != NULL) {
    7406           0 :                 m->m_pkthdr.pf.statekey = NULL;
    7407           0 :                 pf_state_key_unref(sk);
    7408           0 :         }
    7409           0 : }
    7410             : 
    7411             : void
    7412           0 : pf_mbuf_link_inpcb(struct mbuf *m, struct inpcb *inp)
    7413             : {
    7414           0 :         KASSERT(m->m_pkthdr.pf.inp == NULL);
    7415           0 :         m->m_pkthdr.pf.inp = in_pcbref(inp);
    7416           0 : }
    7417             : 
    7418             : void
    7419           0 : pf_mbuf_unlink_inpcb(struct mbuf *m)
    7420             : {
    7421           0 :         struct inpcb *inp = m->m_pkthdr.pf.inp;
    7422             : 
    7423           0 :         if (inp != NULL) {
    7424           0 :                 m->m_pkthdr.pf.inp = NULL;
    7425           0 :                 in_pcbunref(inp);
    7426           0 :         }
    7427           0 : }
    7428             : 
    7429             : void
    7430           0 : pf_state_key_link_inpcb(struct pf_state_key *sk, struct inpcb *inp)
    7431             : {
    7432           0 :         KASSERT(sk->inp == NULL);
    7433           0 :         sk->inp = in_pcbref(inp);
    7434           0 :         KASSERT(inp->inp_pf_sk == NULL);
    7435           0 :         inp->inp_pf_sk = pf_state_key_ref(sk);
    7436           0 : }
    7437             : 
    7438             : void
    7439           0 : pf_inpcb_unlink_state_key(struct inpcb *inp)
    7440             : {
    7441           0 :         struct pf_state_key *sk = inp->inp_pf_sk;
    7442             : 
    7443           0 :         if (sk != NULL) {
    7444           0 :                 KASSERT(sk->inp == inp);
    7445           0 :                 sk->inp = NULL;
    7446           0 :                 inp->inp_pf_sk = NULL;
    7447           0 :                 pf_state_key_unref(sk);
    7448           0 :                 in_pcbunref(inp);
    7449           0 :         }
    7450           0 : }
    7451             : 
    7452             : void
    7453           0 : pf_state_key_unlink_inpcb(struct pf_state_key *sk)
    7454             : {
    7455           0 :         struct inpcb *inp = sk->inp;
    7456             : 
    7457           0 :         if (inp != NULL) {
    7458           0 :                 KASSERT(inp->inp_pf_sk == sk);
    7459           0 :                 sk->inp = NULL;
    7460           0 :                 inp->inp_pf_sk = NULL;
    7461           0 :                 pf_state_key_unref(sk);
    7462           0 :                 in_pcbunref(inp);
    7463           0 :         }
    7464           0 : }
    7465             : 
    7466             : void
    7467           0 : pf_state_key_unlink_reverse(struct pf_state_key *sk)
    7468             : {
    7469           0 :         struct pf_state_key *skrev = sk->reverse;
    7470             : 
    7471             :         /* Note that sk and skrev may be equal, then we unref twice. */
    7472           0 :         if (skrev != NULL) {
    7473           0 :                 KASSERT(skrev->reverse == sk);
    7474           0 :                 sk->reverse = NULL;
    7475           0 :                 skrev->reverse = NULL;
    7476           0 :                 pf_state_key_unref(skrev);
    7477           0 :                 pf_state_key_unref(sk);
    7478           0 :         }
    7479           0 : }
    7480             : 
    7481             : struct pf_state *
    7482           0 : pf_state_ref(struct pf_state *s)
    7483             : {
    7484           0 :         if (s != NULL)
    7485           0 :                 PF_REF_TAKE(s->refcnt);
    7486           0 :         return (s);
    7487             : }
    7488             : 
    7489             : void
    7490           0 : pf_state_unref(struct pf_state *s)
    7491             : {
    7492           0 :         if ((s != NULL) && PF_REF_RELE(s->refcnt)) {
    7493             :                 /* never inserted or removed */
    7494             : #if NPFSYNC > 0
    7495           0 :                 KASSERT((TAILQ_NEXT(s, sync_list) == NULL) ||
    7496             :                     ((TAILQ_NEXT(s, sync_list) == _Q_INVALID) &&
    7497             :                     (s->sync_state == PFSYNC_S_NONE)));
    7498             : #endif  /* NPFSYNC */
    7499           0 :                 KASSERT((TAILQ_NEXT(s, entry_list) == NULL) ||
    7500             :                     (TAILQ_NEXT(s, entry_list) == _Q_INVALID));
    7501           0 :                 KASSERT((s->key[PF_SK_WIRE] == NULL) &&
    7502             :                     (s->key[PF_SK_STACK] == NULL));
    7503             : 
    7504           0 :                 pool_put(&pf_state_pl, s);
    7505           0 :         }
    7506           0 : }
    7507             : 
    7508             : int
    7509           0 : pf_delay_pkt(struct mbuf *m, u_int ifidx)
    7510             : {
    7511             :         struct pf_pktdelay      *pdy;
    7512             : 
    7513           0 :         if ((pdy = pool_get(&pf_pktdelay_pl, PR_NOWAIT)) == NULL) {
    7514           0 :                 m_freem(m);
    7515           0 :                 return (ENOBUFS);
    7516             :         }
    7517           0 :         pdy->ifidx = ifidx;
    7518           0 :         pdy->m = m;
    7519           0 :         timeout_set(pdy->to, pf_pktenqueue_delayed, pdy);
    7520           0 :         timeout_add_msec(pdy->to, m->m_pkthdr.pf.delay);
    7521           0 :         m->m_pkthdr.pf.delay = 0;
    7522           0 :         return (0);
    7523           0 : }
    7524             : 
    7525             : void
    7526           0 : pf_pktenqueue_delayed(void *arg)
    7527             : {
    7528           0 :         struct pf_pktdelay      *pdy = arg;
    7529             :         struct ifnet            *ifp;
    7530             : 
    7531           0 :         ifp = if_get(pdy->ifidx);
    7532           0 :         if (ifp != NULL) {
    7533           0 :                 if_enqueue(ifp, pdy->m);
    7534           0 :                 if_put(ifp);
    7535           0 :         } else
    7536           0 :                 m_freem(pdy->m);
    7537             : 
    7538           0 :         pool_put(&pf_pktdelay_pl, pdy);
    7539           0 : }

Generated by: LCOV version 1.13