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