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