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