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