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