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