]> git.saurik.com Git - apple/xnu.git/blame - bsd/net/pf.c
xnu-3248.30.4.tar.gz
[apple/xnu.git] / bsd / net / pf.c
CommitLineData
39236c6e 1/*
3e170ce0 2 * Copyright (c) 2007-2015 Apple Inc. All rights reserved.
b0d623f7
A
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
d1ecb069 29/* $apfw: git commit 6602420f2f101b74305cd78f7cd9e0c8fdedae97 $ */
b0d623f7
A
30/* $OpenBSD: pf.c,v 1.567 2008/02/20 23:40:13 henning Exp $ */
31
32/*
33 * Copyright (c) 2001 Daniel Hartmeier
3e170ce0
A
34 * Copyright (c) 2002 - 2013 Henning Brauer
35 * NAT64 - Copyright (c) 2010 Viagenie Inc. (http://www.viagenie.ca)
b0d623f7
A
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 *
42 * - Redistributions of source code must retain the above copyright
43 * notice, this list of conditions and the following disclaimer.
44 * - Redistributions in binary form must reproduce the above
45 * copyright notice, this list of conditions and the following
46 * disclaimer in the documentation and/or other materials provided
47 * with the distribution.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
52 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
53 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
54 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
55 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
56 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
57 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
59 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60 * POSSIBILITY OF SUCH DAMAGE.
61 *
62 * Effort sponsored in part by the Defense Advanced Research Projects
63 * Agency (DARPA) and Air Force Research Laboratory, Air Force
64 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
65 *
66 */
67
68#include <machine/endian.h>
69#include <sys/param.h>
70#include <sys/systm.h>
71#include <sys/mbuf.h>
72#include <sys/filio.h>
73#include <sys/socket.h>
74#include <sys/socketvar.h>
75#include <sys/kernel.h>
76#include <sys/time.h>
77#include <sys/proc.h>
78#include <sys/random.h>
79#include <sys/mcache.h>
39236c6e 80#include <sys/protosw.h>
b0d623f7
A
81
82#include <libkern/crypto/md5.h>
83#include <libkern/libkern.h>
84
85#include <mach/thread_act.h>
86
87#include <net/if.h>
88#include <net/if_types.h>
89#include <net/bpf.h>
90#include <net/route.h>
39236c6e 91#include <net/dlil.h>
b0d623f7
A
92
93#include <netinet/in.h>
94#include <netinet/in_var.h>
95#include <netinet/in_systm.h>
96#include <netinet/ip.h>
97#include <netinet/ip_var.h>
98#include <netinet/tcp.h>
99#include <netinet/tcp_seq.h>
100#include <netinet/udp.h>
101#include <netinet/ip_icmp.h>
102#include <netinet/in_pcb.h>
103#include <netinet/tcp_timer.h>
104#include <netinet/tcp_var.h>
105#include <netinet/tcp_fsm.h>
106#include <netinet/udp_var.h>
107#include <netinet/icmp_var.h>
108#include <net/if_ether.h>
109#include <net/ethernet.h>
316670eb 110#include <net/flowhash.h>
b0d623f7
A
111#include <net/pfvar.h>
112#include <net/if_pflog.h>
113
114#if NPFSYNC
115#include <net/if_pfsync.h>
116#endif /* NPFSYNC */
117
118#if INET6
119#include <netinet/ip6.h>
120#include <netinet6/in6_pcb.h>
121#include <netinet6/ip6_var.h>
122#include <netinet/icmp6.h>
123#include <netinet6/nd6.h>
124#endif /* INET6 */
125
316670eb
A
126#if DUMMYNET
127#include <netinet/ip_dummynet.h>
128#endif /* DUMMYNET */
b0d623f7 129
39236c6e
A
130/*
131 * For RandomULong(), to get a 32 bits random value
132 * Note that random() returns a 31 bits value, see rdar://11159750
133 */
134#include <dev/random/randomdev.h>
135
316670eb 136#define DPFPRINTF(n, x) (pf_status.debug >= (n) ? printf x : ((void)0))
b0d623f7
A
137
138/*
139 * On Mac OS X, the rtableid value is treated as the interface scope
140 * value that is equivalent to the interface index used for scoped
141 * routing. A valid scope value is anything but IFSCOPE_NONE (0),
142 * as per definition of ifindex which is a positive, non-zero number.
143 * The other BSDs treat a negative rtableid value as invalid, hence
144 * the test against INT_MAX to handle userland apps which initialize
145 * the field with a negative number.
146 */
147#define PF_RTABLEID_IS_VALID(r) \
148 ((r) > IFSCOPE_NONE && (r) <= INT_MAX)
149
150/*
151 * Global variables
152 */
316670eb
A
153decl_lck_mtx_data(,pf_lock_data);
154decl_lck_rw_data(,pf_perim_lock_data);
155lck_mtx_t *pf_lock = &pf_lock_data;
156lck_rw_t *pf_perim_lock = &pf_perim_lock_data;
b0d623f7
A
157
158/* state tables */
159struct pf_state_tree_lan_ext pf_statetbl_lan_ext;
160struct pf_state_tree_ext_gwy pf_statetbl_ext_gwy;
161
162struct pf_palist pf_pabuf;
163struct pf_status pf_status;
164
316670eb 165#if PF_ALTQ
b0d623f7
A
166struct pf_altqqueue pf_altqs[2];
167struct pf_altqqueue *pf_altqs_active;
168struct pf_altqqueue *pf_altqs_inactive;
169u_int32_t ticket_altqs_active;
170u_int32_t ticket_altqs_inactive;
171int altqs_inactive_open;
316670eb 172#endif /* PF_ALTQ */
b0d623f7
A
173u_int32_t ticket_pabuf;
174
175static MD5_CTX pf_tcp_secret_ctx;
176static u_char pf_tcp_secret[16];
177static int pf_tcp_secret_init;
178static int pf_tcp_iss_off;
179
180static struct pf_anchor_stackframe {
181 struct pf_ruleset *rs;
182 struct pf_rule *r;
183 struct pf_anchor_node *parent;
184 struct pf_anchor *child;
185} pf_anchor_stack[64];
186
187struct pool pf_src_tree_pl, pf_rule_pl, pf_pooladdr_pl;
188struct pool pf_state_pl, pf_state_key_pl;
316670eb 189#if PF_ALTQ
b0d623f7 190struct pool pf_altq_pl;
316670eb 191#endif /* PF_ALTQ */
b0d623f7 192
b0d623f7
A
193typedef void (*hook_fn_t)(void *);
194
195struct hook_desc {
196 TAILQ_ENTRY(hook_desc) hd_list;
197 hook_fn_t hd_fn;
198 void *hd_arg;
199};
200
201#define HOOK_REMOVE 0x01
202#define HOOK_FREE 0x02
203#define HOOK_ABORT 0x04
204
205static void *hook_establish(struct hook_desc_head *, int,
206 hook_fn_t, void *);
207static void hook_runloop(struct hook_desc_head *, int flags);
208
209struct pool pf_app_state_pl;
210static void pf_print_addr(struct pf_addr *addr, sa_family_t af);
211static void pf_print_sk_host(struct pf_state_host *, u_int8_t, int,
212 u_int8_t);
b0d623f7
A
213
214static void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
215
216static void pf_init_threshold(struct pf_threshold *, u_int32_t,
217 u_int32_t);
218static void pf_add_threshold(struct pf_threshold *);
219static int pf_check_threshold(struct pf_threshold *);
220
221static void pf_change_ap(int, struct mbuf *, struct pf_addr *,
222 u_int16_t *, u_int16_t *, u_int16_t *,
3e170ce0
A
223 struct pf_addr *, u_int16_t, u_int8_t, sa_family_t,
224 sa_family_t, int);
b0d623f7
A
225static int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *,
226 struct tcphdr *, struct pf_state_peer *);
227#if INET6
228static void pf_change_a6(struct pf_addr *, u_int16_t *,
229 struct pf_addr *, u_int8_t);
3e170ce0
A
230void pf_change_addr(struct pf_addr *a, u_int16_t *c,
231 struct pf_addr *an, u_int8_t u,
232 sa_family_t af, sa_family_t afn);
b0d623f7
A
233#endif /* INET6 */
234static void pf_change_icmp(struct pf_addr *, u_int16_t *,
235 struct pf_addr *, struct pf_addr *, u_int16_t,
236 u_int16_t *, u_int16_t *, u_int16_t *,
237 u_int16_t *, u_int8_t, sa_family_t);
238static void pf_send_tcp(const struct pf_rule *, sa_family_t,
239 const struct pf_addr *, const struct pf_addr *,
240 u_int16_t, u_int16_t, u_int32_t, u_int32_t,
241 u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
242 u_int16_t, struct ether_header *, struct ifnet *);
243static void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
244 sa_family_t, struct pf_rule *);
b0d623f7
A
245static struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
246 int, int, struct pfi_kif *, struct pf_addr *,
247 union pf_state_xport *, struct pf_addr *,
248 union pf_state_xport *, int);
249static struct pf_rule *pf_get_translation_aux(struct pf_pdesc *,
250 struct mbuf *, int, int, struct pfi_kif *,
251 struct pf_src_node **, struct pf_addr *,
252 union pf_state_xport *, struct pf_addr *,
3e170ce0 253 union pf_state_xport *, union pf_state_xport *);
b0d623f7
A
254static void pf_attach_state(struct pf_state_key *,
255 struct pf_state *, int);
256static void pf_detach_state(struct pf_state *, int);
257static u_int32_t pf_tcp_iss(struct pf_pdesc *);
258static int pf_test_rule(struct pf_rule **, struct pf_state **,
259 int, struct pfi_kif *, struct mbuf *, int,
260 void *, struct pf_pdesc *, struct pf_rule **,
261 struct pf_ruleset **, struct ifqueue *);
316670eb
A
262#if DUMMYNET
263static int pf_test_dummynet(struct pf_rule **, int,
264 struct pfi_kif *, struct mbuf **,
265 struct pf_pdesc *, struct ip_fw_args *);
266#endif /* DUMMYNET */
b0d623f7
A
267static int pf_test_fragment(struct pf_rule **, int,
268 struct pfi_kif *, struct mbuf *, void *,
269 struct pf_pdesc *, struct pf_rule **,
270 struct pf_ruleset **);
271static int pf_test_state_tcp(struct pf_state **, int,
272 struct pfi_kif *, struct mbuf *, int,
273 void *, struct pf_pdesc *, u_short *);
274static int pf_test_state_udp(struct pf_state **, int,
275 struct pfi_kif *, struct mbuf *, int,
b7266188 276 void *, struct pf_pdesc *, u_short *);
b0d623f7
A
277static int pf_test_state_icmp(struct pf_state **, int,
278 struct pfi_kif *, struct mbuf *, int,
279 void *, struct pf_pdesc *, u_short *);
280static int pf_test_state_other(struct pf_state **, int,
281 struct pfi_kif *, struct pf_pdesc *);
282static int pf_match_tag(struct mbuf *, struct pf_rule *,
283 struct pf_mtag *, int *);
b0d623f7
A
284static void pf_hash(struct pf_addr *, struct pf_addr *,
285 struct pf_poolhashkey *, sa_family_t);
286static int pf_map_addr(u_int8_t, struct pf_rule *,
287 struct pf_addr *, struct pf_addr *,
288 struct pf_addr *, struct pf_src_node **);
b0d623f7
A
289static int pf_get_sport(struct pf_pdesc *, struct pfi_kif *,
290 struct pf_rule *, struct pf_addr *,
291 union pf_state_xport *, struct pf_addr *,
292 union pf_state_xport *, struct pf_addr *,
293 union pf_state_xport *, struct pf_src_node **);
b0d623f7
A
294static void pf_route(struct mbuf **, struct pf_rule *, int,
295 struct ifnet *, struct pf_state *,
296 struct pf_pdesc *);
297#if INET6
298static void pf_route6(struct mbuf **, struct pf_rule *, int,
299 struct ifnet *, struct pf_state *,
300 struct pf_pdesc *);
301#endif /* INET6 */
302static u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t,
303 sa_family_t);
304static u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
305 sa_family_t);
306static u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t,
307 u_int16_t);
308static void pf_set_rt_ifp(struct pf_state *,
3e170ce0 309 struct pf_addr *, sa_family_t af);
b0d623f7
A
310static int pf_check_proto_cksum(struct mbuf *, int, int,
311 u_int8_t, sa_family_t);
312static int pf_addr_wrap_neq(struct pf_addr_wrap *,
313 struct pf_addr_wrap *);
314static struct pf_state *pf_find_state(struct pfi_kif *,
315 struct pf_state_key_cmp *, u_int);
316static int pf_src_connlimit(struct pf_state **);
317static void pf_stateins_err(const char *, struct pf_state *,
318 struct pfi_kif *);
319static int pf_check_congestion(struct ifqueue *);
320
b0d623f7
A
321#if 0
322static const char *pf_pptp_ctrl_type_name(u_int16_t code);
323#endif
324static void pf_pptp_handler(struct pf_state *, int, int,
325 struct pf_pdesc *, struct pfi_kif *);
326static void pf_pptp_unlink(struct pf_state *);
d1ecb069 327static void pf_grev1_unlink(struct pf_state *);
b0d623f7
A
328static int pf_test_state_grev1(struct pf_state **, int,
329 struct pfi_kif *, int, struct pf_pdesc *);
330static int pf_ike_compare(struct pf_app_state *,
331 struct pf_app_state *);
332static int pf_test_state_esp(struct pf_state **, int,
333 struct pfi_kif *, int, struct pf_pdesc *);
b0d623f7
A
334
335extern struct pool pfr_ktable_pl;
336extern struct pool pfr_kentry_pl;
337extern int path_mtu_discovery;
338
339struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
340 { &pf_state_pl, PFSTATE_HIWAT },
341 { &pf_app_state_pl, PFAPPSTATE_HIWAT },
342 { &pf_src_tree_pl, PFSNODE_HIWAT },
343 { &pf_frent_pl, PFFRAG_FRENT_HIWAT },
344 { &pfr_ktable_pl, PFR_KTABLE_HIWAT },
316670eb 345 { &pfr_kentry_pl, PFR_KENTRY_HIWAT },
b0d623f7
A
346};
347
b0d623f7
A
348struct mbuf *
349pf_lazy_makewritable(struct pf_pdesc *pd, struct mbuf *m, int len)
350{
351 if (pd->lmw < 0)
352 return (0);
353
354 VERIFY(m == pd->mp);
355
356 if (len > pd->lmw) {
357 if (m_makewritable(&m, 0, len, M_DONTWAIT))
358 len = -1;
359 pd->lmw = len;
360 if (len >= 0 && m != pd->mp) {
361 pd->mp = m;
6d2010ae 362 pd->pf_mtag = pf_find_mtag(m);
b0d623f7
A
363
364 switch (pd->af) {
365 case AF_INET: {
366 struct ip *h = mtod(m, struct ip *);
367 pd->src = (struct pf_addr *)&h->ip_src;
368 pd->dst = (struct pf_addr *)&h->ip_dst;
369 pd->ip_sum = &h->ip_sum;
370 break;
371 }
372#if INET6
373 case AF_INET6: {
374 struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
375 pd->src = (struct pf_addr *)&h->ip6_src;
376 pd->dst = (struct pf_addr *)&h->ip6_dst;
377 break;
378 }
379#endif /* INET6 */
380 }
381 }
382 }
383
384 return (len < 0 ? 0 : m);
385}
386
387static const int *
388pf_state_lookup_aux(struct pf_state **state, struct pfi_kif *kif,
389 int direction, int *action)
390{
391 if (*state == NULL || (*state)->timeout == PFTM_PURGE) {
392 *action = PF_DROP;
393 return (action);
394 }
395
396 if (direction == PF_OUT &&
397 (((*state)->rule.ptr->rt == PF_ROUTETO &&
398 (*state)->rule.ptr->direction == PF_OUT) ||
399 ((*state)->rule.ptr->rt == PF_REPLYTO &&
400 (*state)->rule.ptr->direction == PF_IN)) &&
401 (*state)->rt_kif != NULL && (*state)->rt_kif != kif) {
402 *action = PF_PASS;
403 return (action);
404 }
405
406 return (0);
407}
408
409#define STATE_LOOKUP() \
410 do { \
411 int action; \
412 *state = pf_find_state(kif, &key, direction); \
39236c6e
A
413 if (*state != NULL && pd != NULL && \
414 !(pd->pktflags & PKTF_FLOW_ID)) { \
415 pd->flowsrc = (*state)->state_key->flowsrc; \
316670eb 416 pd->flowhash = (*state)->state_key->flowhash; \
39236c6e
A
417 if (pd->flowhash != 0) { \
418 pd->pktflags |= PKTF_FLOW_ID; \
419 pd->pktflags &= ~PKTF_FLOW_ADV; \
420 } \
316670eb 421 } \
b0d623f7
A
422 if (pf_state_lookup_aux(state, kif, direction, &action)) \
423 return (action); \
424 } while (0)
425
426#define STATE_ADDR_TRANSLATE(sk) \
427 (sk)->lan.addr.addr32[0] != (sk)->gwy.addr.addr32[0] || \
3e170ce0 428 ((sk)->af_lan == AF_INET6 && \
b0d623f7
A
429 ((sk)->lan.addr.addr32[1] != (sk)->gwy.addr.addr32[1] || \
430 (sk)->lan.addr.addr32[2] != (sk)->gwy.addr.addr32[2] || \
431 (sk)->lan.addr.addr32[3] != (sk)->gwy.addr.addr32[3]))
432
433#define STATE_TRANSLATE(sk) \
3e170ce0
A
434 ((sk)->af_lan != (sk)->af_gwy || \
435 STATE_ADDR_TRANSLATE(sk) || \
b0d623f7
A
436 (sk)->lan.xport.port != (sk)->gwy.xport.port)
437
438#define STATE_GRE_TRANSLATE(sk) \
439 (STATE_ADDR_TRANSLATE(sk) || \
440 (sk)->lan.xport.call_id != (sk)->gwy.xport.call_id)
441
b0d623f7
A
442#define BOUND_IFACE(r, k) \
443 ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all
444
b7266188
A
445#define STATE_INC_COUNTERS(s) \
446 do { \
447 s->rule.ptr->states++; \
448 VERIFY(s->rule.ptr->states != 0); \
449 if (s->anchor.ptr != NULL) { \
450 s->anchor.ptr->states++; \
451 VERIFY(s->anchor.ptr->states != 0); \
452 } \
453 if (s->nat_rule.ptr != NULL) { \
454 s->nat_rule.ptr->states++; \
455 VERIFY(s->nat_rule.ptr->states != 0); \
456 } \
b0d623f7
A
457 } while (0)
458
b7266188
A
459#define STATE_DEC_COUNTERS(s) \
460 do { \
461 if (s->nat_rule.ptr != NULL) { \
462 VERIFY(s->nat_rule.ptr->states > 0); \
463 s->nat_rule.ptr->states--; \
464 } \
465 if (s->anchor.ptr != NULL) { \
466 VERIFY(s->anchor.ptr->states > 0); \
467 s->anchor.ptr->states--; \
468 } \
469 VERIFY(s->rule.ptr->states > 0); \
470 s->rule.ptr->states--; \
b0d623f7
A
471 } while (0)
472
473static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
474static __inline int pf_state_compare_lan_ext(struct pf_state_key *,
475 struct pf_state_key *);
476static __inline int pf_state_compare_ext_gwy(struct pf_state_key *,
477 struct pf_state_key *);
478static __inline int pf_state_compare_id(struct pf_state *,
479 struct pf_state *);
480
481struct pf_src_tree tree_src_tracking;
482
483struct pf_state_tree_id tree_id;
484struct pf_state_queue state_list;
485
486RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
487RB_GENERATE(pf_state_tree_lan_ext, pf_state_key,
488 entry_lan_ext, pf_state_compare_lan_ext);
489RB_GENERATE(pf_state_tree_ext_gwy, pf_state_key,
490 entry_ext_gwy, pf_state_compare_ext_gwy);
491RB_GENERATE(pf_state_tree_id, pf_state,
492 entry_id, pf_state_compare_id);
493
494#define PF_DT_SKIP_LANEXT 0x01
495#define PF_DT_SKIP_EXTGWY 0x02
496
b7266188
A
497static const u_int16_t PF_PPTP_PORT = 1723;
498static const u_int32_t PF_PPTP_MAGIC_NUMBER = 0x1A2B3C4D;
b0d623f7
A
499
500struct pf_pptp_hdr {
501 u_int16_t length;
502 u_int16_t type;
503 u_int32_t magic;
504};
505
506struct pf_pptp_ctrl_hdr {
507 u_int16_t type;
508 u_int16_t reserved_0;
509};
510
511struct pf_pptp_ctrl_generic {
512 u_int16_t data[0];
513};
514
515#define PF_PPTP_CTRL_TYPE_START_REQ 1
516struct pf_pptp_ctrl_start_req {
517 u_int16_t protocol_version;
518 u_int16_t reserved_1;
519 u_int32_t framing_capabilities;
520 u_int32_t bearer_capabilities;
521 u_int16_t maximum_channels;
522 u_int16_t firmware_revision;
523 u_int8_t host_name[64];
524 u_int8_t vendor_string[64];
525};
526
527#define PF_PPTP_CTRL_TYPE_START_RPY 2
528struct pf_pptp_ctrl_start_rpy {
529 u_int16_t protocol_version;
530 u_int8_t result_code;
531 u_int8_t error_code;
532 u_int32_t framing_capabilities;
533 u_int32_t bearer_capabilities;
534 u_int16_t maximum_channels;
535 u_int16_t firmware_revision;
536 u_int8_t host_name[64];
537 u_int8_t vendor_string[64];
538};
539
540#define PF_PPTP_CTRL_TYPE_STOP_REQ 3
541struct pf_pptp_ctrl_stop_req {
542 u_int8_t reason;
543 u_int8_t reserved_1;
544 u_int16_t reserved_2;
545};
546
547#define PF_PPTP_CTRL_TYPE_STOP_RPY 4
548struct pf_pptp_ctrl_stop_rpy {
549 u_int8_t reason;
550 u_int8_t error_code;
551 u_int16_t reserved_1;
552};
553
554#define PF_PPTP_CTRL_TYPE_ECHO_REQ 5
555struct pf_pptp_ctrl_echo_req {
556 u_int32_t identifier;
557};
558
559#define PF_PPTP_CTRL_TYPE_ECHO_RPY 6
560struct pf_pptp_ctrl_echo_rpy {
561 u_int32_t identifier;
562 u_int8_t result_code;
563 u_int8_t error_code;
564 u_int16_t reserved_1;
565};
566
567#define PF_PPTP_CTRL_TYPE_CALL_OUT_REQ 7
568struct pf_pptp_ctrl_call_out_req {
569 u_int16_t call_id;
570 u_int16_t call_sernum;
571 u_int32_t min_bps;
572 u_int32_t bearer_type;
573 u_int32_t framing_type;
574 u_int16_t rxwindow_size;
575 u_int16_t proc_delay;
576 u_int8_t phone_num[64];
577 u_int8_t sub_addr[64];
578};
579
580#define PF_PPTP_CTRL_TYPE_CALL_OUT_RPY 8
581struct pf_pptp_ctrl_call_out_rpy {
582 u_int16_t call_id;
583 u_int16_t peer_call_id;
584 u_int8_t result_code;
585 u_int8_t error_code;
586 u_int16_t cause_code;
587 u_int32_t connect_speed;
588 u_int16_t rxwindow_size;
589 u_int16_t proc_delay;
590 u_int32_t phy_channel_id;
591};
592
593#define PF_PPTP_CTRL_TYPE_CALL_IN_1ST 9
594struct pf_pptp_ctrl_call_in_1st {
595 u_int16_t call_id;
596 u_int16_t call_sernum;
597 u_int32_t bearer_type;
598 u_int32_t phy_channel_id;
599 u_int16_t dialed_number_len;
600 u_int16_t dialing_number_len;
601 u_int8_t dialed_num[64];
602 u_int8_t dialing_num[64];
603 u_int8_t sub_addr[64];
604};
605
606#define PF_PPTP_CTRL_TYPE_CALL_IN_2ND 10
607struct pf_pptp_ctrl_call_in_2nd {
608 u_int16_t call_id;
609 u_int16_t peer_call_id;
610 u_int8_t result_code;
611 u_int8_t error_code;
612 u_int16_t rxwindow_size;
613 u_int16_t txdelay;
614 u_int16_t reserved_1;
615};
616
617#define PF_PPTP_CTRL_TYPE_CALL_IN_3RD 11
618struct pf_pptp_ctrl_call_in_3rd {
619 u_int16_t call_id;
620 u_int16_t reserved_1;
621 u_int32_t connect_speed;
622 u_int16_t rxwindow_size;
623 u_int16_t txdelay;
624 u_int32_t framing_type;
625};
626
627#define PF_PPTP_CTRL_TYPE_CALL_CLR 12
628struct pf_pptp_ctrl_call_clr {
629 u_int16_t call_id;
630 u_int16_t reserved_1;
631};
632
633#define PF_PPTP_CTRL_TYPE_CALL_DISC 13
634struct pf_pptp_ctrl_call_disc {
635 u_int16_t call_id;
636 u_int8_t result_code;
637 u_int8_t error_code;
638 u_int16_t cause_code;
639 u_int16_t reserved_1;
640 u_int8_t statistics[128];
641};
642
643#define PF_PPTP_CTRL_TYPE_ERROR 14
644struct pf_pptp_ctrl_error {
645 u_int16_t peer_call_id;
646 u_int16_t reserved_1;
647 u_int32_t crc_errors;
648 u_int32_t fr_errors;
649 u_int32_t hw_errors;
650 u_int32_t buf_errors;
651 u_int32_t tim_errors;
652 u_int32_t align_errors;
653};
654
655#define PF_PPTP_CTRL_TYPE_SET_LINKINFO 15
656struct pf_pptp_ctrl_set_linkinfo {
657 u_int16_t peer_call_id;
658 u_int16_t reserved_1;
659 u_int32_t tx_accm;
660 u_int32_t rx_accm;
661};
662
663#if 0
664static const char *pf_pptp_ctrl_type_name(u_int16_t code)
665{
666 code = ntohs(code);
667
668 if (code < PF_PPTP_CTRL_TYPE_START_REQ ||
669 code > PF_PPTP_CTRL_TYPE_SET_LINKINFO) {
670 static char reserved[] = "reserved-00";
671
672 sprintf(&reserved[9], "%02x", code);
673 return (reserved);
674 } else {
675 static const char *name[] = {
676 "start_req", "start_rpy", "stop_req", "stop_rpy",
677 "echo_req", "echo_rpy", "call_out_req", "call_out_rpy",
678 "call_in_1st", "call_in_2nd", "call_in_3rd",
679 "call_clr", "call_disc", "error", "set_linkinfo"
680 };
681
682 return (name[code - 1]);
683 }
684};
685#endif
686
687static const size_t PF_PPTP_CTRL_MSG_MINSIZE =
688 sizeof (struct pf_pptp_hdr) +
689 sizeof (struct pf_pptp_ctrl_hdr) +
690 MIN(sizeof (struct pf_pptp_ctrl_start_req),
691 MIN(sizeof (struct pf_pptp_ctrl_start_rpy),
692 MIN(sizeof (struct pf_pptp_ctrl_stop_req),
693 MIN(sizeof (struct pf_pptp_ctrl_stop_rpy),
694 MIN(sizeof (struct pf_pptp_ctrl_echo_req),
695 MIN(sizeof (struct pf_pptp_ctrl_echo_rpy),
696 MIN(sizeof (struct pf_pptp_ctrl_call_out_req),
697 MIN(sizeof (struct pf_pptp_ctrl_call_out_rpy),
698 MIN(sizeof (struct pf_pptp_ctrl_call_in_1st),
699 MIN(sizeof (struct pf_pptp_ctrl_call_in_2nd),
700 MIN(sizeof (struct pf_pptp_ctrl_call_in_3rd),
701 MIN(sizeof (struct pf_pptp_ctrl_call_clr),
702 MIN(sizeof (struct pf_pptp_ctrl_call_disc),
703 MIN(sizeof (struct pf_pptp_ctrl_error),
704 sizeof (struct pf_pptp_ctrl_set_linkinfo)
705 ))))))))))))));
706
707union pf_pptp_ctrl_msg_union {
708 struct pf_pptp_ctrl_start_req start_req;
709 struct pf_pptp_ctrl_start_rpy start_rpy;
710 struct pf_pptp_ctrl_stop_req stop_req;
711 struct pf_pptp_ctrl_stop_rpy stop_rpy;
712 struct pf_pptp_ctrl_echo_req echo_req;
713 struct pf_pptp_ctrl_echo_rpy echo_rpy;
714 struct pf_pptp_ctrl_call_out_req call_out_req;
715 struct pf_pptp_ctrl_call_out_rpy call_out_rpy;
716 struct pf_pptp_ctrl_call_in_1st call_in_1st;
717 struct pf_pptp_ctrl_call_in_2nd call_in_2nd;
718 struct pf_pptp_ctrl_call_in_3rd call_in_3rd;
719 struct pf_pptp_ctrl_call_clr call_clr;
720 struct pf_pptp_ctrl_call_disc call_disc;
721 struct pf_pptp_ctrl_error error;
722 struct pf_pptp_ctrl_set_linkinfo set_linkinfo;
723 u_int8_t data[0];
724};
725
726struct pf_pptp_ctrl_msg {
727 struct pf_pptp_hdr hdr;
728 struct pf_pptp_ctrl_hdr ctrl;
729 union pf_pptp_ctrl_msg_union msg;
730};
731
732#define PF_GRE_FLAG_CHECKSUM_PRESENT 0x8000
733#define PF_GRE_FLAG_VERSION_MASK 0x0007
734#define PF_GRE_PPP_ETHERTYPE 0x880B
735
736struct pf_grev1_hdr {
737 u_int16_t flags;
738 u_int16_t protocol_type;
739 u_int16_t payload_length;
740 u_int16_t call_id;
741 /*
742 u_int32_t seqno;
743 u_int32_t ackno;
744 */
745};
746
b7266188 747static const u_int16_t PF_IKE_PORT = 500;
b0d623f7
A
748
749struct pf_ike_hdr {
750 u_int64_t initiator_cookie, responder_cookie;
751 u_int8_t next_payload, version, exchange_type, flags;
752 u_int32_t message_id, length;
753};
754
755#define PF_IKE_PACKET_MINSIZE (sizeof (struct pf_ike_hdr))
756
757#define PF_IKEv1_EXCHTYPE_BASE 1
758#define PF_IKEv1_EXCHTYPE_ID_PROTECT 2
759#define PF_IKEv1_EXCHTYPE_AUTH_ONLY 3
760#define PF_IKEv1_EXCHTYPE_AGGRESSIVE 4
761#define PF_IKEv1_EXCHTYPE_INFORMATIONAL 5
762#define PF_IKEv2_EXCHTYPE_SA_INIT 34
763#define PF_IKEv2_EXCHTYPE_AUTH 35
764#define PF_IKEv2_EXCHTYPE_CREATE_CHILD_SA 36
765#define PF_IKEv2_EXCHTYPE_INFORMATIONAL 37
766
767#define PF_IKEv1_FLAG_E 0x01
768#define PF_IKEv1_FLAG_C 0x02
769#define PF_IKEv1_FLAG_A 0x04
770#define PF_IKEv2_FLAG_I 0x08
771#define PF_IKEv2_FLAG_V 0x10
772#define PF_IKEv2_FLAG_R 0x20
773
774struct pf_esp_hdr {
775 u_int32_t spi;
776 u_int32_t seqno;
777 u_int8_t payload[];
778};
b0d623f7
A
779
780static __inline int
3e170ce0 781pf_addr_compare(struct pf_addr *a, struct pf_addr *b, sa_family_t af)
b0d623f7 782{
3e170ce0
A
783 switch (af) {
784#ifdef INET
b0d623f7 785 case AF_INET:
3e170ce0 786 if (a->addr32[0] > b->addr32[0])
b0d623f7 787 return (1);
3e170ce0 788 if (a->addr32[0] < b->addr32[0])
b0d623f7
A
789 return (-1);
790 break;
791#endif /* INET */
3e170ce0 792#ifdef INET6
b0d623f7 793 case AF_INET6:
3e170ce0 794 if (a->addr32[3] > b->addr32[3])
b0d623f7 795 return (1);
3e170ce0 796 if (a->addr32[3] < b->addr32[3])
b0d623f7 797 return (-1);
3e170ce0 798 if (a->addr32[2] > b->addr32[2])
b0d623f7 799 return (1);
3e170ce0 800 if (a->addr32[2] < b->addr32[2])
b0d623f7 801 return (-1);
3e170ce0 802 if (a->addr32[1] > b->addr32[1])
b0d623f7 803 return (1);
3e170ce0 804 if (a->addr32[1] < b->addr32[1])
b0d623f7 805 return (-1);
3e170ce0 806 if (a->addr32[0] > b->addr32[0])
b0d623f7 807 return (1);
3e170ce0 808 if (a->addr32[0] < b->addr32[0])
b0d623f7
A
809 return (-1);
810 break;
811#endif /* INET6 */
812 }
813 return (0);
814}
815
3e170ce0
A
816static __inline int
817pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
818{
819 int diff;
820
821 if (a->rule.ptr > b->rule.ptr)
822 return (1);
823 if (a->rule.ptr < b->rule.ptr)
824 return (-1);
825 if ((diff = a->af - b->af) != 0)
826 return (diff);
827 if ((diff = pf_addr_compare(&a->addr, &b->addr, a->af)) != 0)
828 return (diff);
829 return (0);
830}
831
b0d623f7
A
832static __inline int
833pf_state_compare_lan_ext(struct pf_state_key *a, struct pf_state_key *b)
834{
835 int diff;
316670eb 836 int extfilter;
b0d623f7
A
837
838 if ((diff = a->proto - b->proto) != 0)
839 return (diff);
3e170ce0 840 if ((diff = a->af_lan - b->af_lan) != 0)
b0d623f7
A
841 return (diff);
842
b0d623f7
A
843 extfilter = PF_EXTFILTER_APD;
844
845 switch (a->proto) {
846 case IPPROTO_ICMP:
847 case IPPROTO_ICMPV6:
848 if ((diff = a->lan.xport.port - b->lan.xport.port) != 0)
849 return (diff);
850 break;
851
852 case IPPROTO_TCP:
853 if ((diff = a->lan.xport.port - b->lan.xport.port) != 0)
854 return (diff);
3e170ce0 855 if ((diff = a->ext_lan.xport.port - b->ext_lan.xport.port) != 0)
b0d623f7
A
856 return (diff);
857 break;
858
859 case IPPROTO_UDP:
860 if ((diff = a->proto_variant - b->proto_variant))
861 return (diff);
862 extfilter = a->proto_variant;
863 if ((diff = a->lan.xport.port - b->lan.xport.port) != 0)
864 return (diff);
865 if ((extfilter < PF_EXTFILTER_AD) &&
3e170ce0 866 (diff = a->ext_lan.xport.port - b->ext_lan.xport.port) != 0)
b0d623f7
A
867 return (diff);
868 break;
869
870 case IPPROTO_GRE:
871 if (a->proto_variant == PF_GRE_PPTP_VARIANT &&
872 a->proto_variant == b->proto_variant) {
3e170ce0
A
873 if (!!(diff = a->ext_lan.xport.call_id -
874 b->ext_lan.xport.call_id))
b0d623f7
A
875 return (diff);
876 }
877 break;
878
879 case IPPROTO_ESP:
3e170ce0 880 if (!!(diff = a->ext_lan.xport.spi - b->ext_lan.xport.spi))
b0d623f7
A
881 return (diff);
882 break;
883
884 default:
885 break;
886 }
b0d623f7 887
3e170ce0 888 switch (a->af_lan) {
b0d623f7
A
889#if INET
890 case AF_INET:
3e170ce0
A
891 if ((diff = pf_addr_compare(&a->lan.addr, &b->lan.addr,
892 a->af_lan)) != 0)
893 return (diff);
894
b0d623f7 895 if (extfilter < PF_EXTFILTER_EI) {
3e170ce0
A
896 if ((diff = pf_addr_compare(&a->ext_lan.addr,
897 &b->ext_lan.addr,
898 a->af_lan)) != 0)
899 return (diff);
b0d623f7 900 }
b0d623f7
A
901 break;
902#endif /* INET */
903#if INET6
904 case AF_INET6:
3e170ce0
A
905 if ((diff = pf_addr_compare(&a->lan.addr, &b->lan.addr,
906 a->af_lan)) != 0)
907 return (diff);
908
b0d623f7 909 if (extfilter < PF_EXTFILTER_EI ||
3e170ce0
A
910 !PF_AZERO(&b->ext_lan.addr, AF_INET6)) {
911 if ((diff = pf_addr_compare(&a->ext_lan.addr,
912 &b->ext_lan.addr,
913 a->af_lan)) != 0)
914 return (diff);
b0d623f7 915 }
b0d623f7
A
916 break;
917#endif /* INET6 */
918 }
919
b0d623f7
A
920 if (a->app_state && b->app_state) {
921 if (a->app_state->compare_lan_ext &&
922 b->app_state->compare_lan_ext) {
923 diff = (const char *)b->app_state->compare_lan_ext -
924 (const char *)a->app_state->compare_lan_ext;
925 if (diff != 0)
926 return (diff);
927 diff = a->app_state->compare_lan_ext(a->app_state,
928 b->app_state);
929 if (diff != 0)
930 return (diff);
931 }
932 }
b0d623f7
A
933
934 return (0);
935}
936
937static __inline int
938pf_state_compare_ext_gwy(struct pf_state_key *a, struct pf_state_key *b)
939{
940 int diff;
316670eb 941 int extfilter;
b0d623f7
A
942
943 if ((diff = a->proto - b->proto) != 0)
944 return (diff);
945
3e170ce0 946 if ((diff = a->af_gwy - b->af_gwy) != 0)
b0d623f7
A
947 return (diff);
948
b0d623f7
A
949 extfilter = PF_EXTFILTER_APD;
950
951 switch (a->proto) {
952 case IPPROTO_ICMP:
953 case IPPROTO_ICMPV6:
954 if ((diff = a->gwy.xport.port - b->gwy.xport.port) != 0)
955 return (diff);
956 break;
957
958 case IPPROTO_TCP:
3e170ce0 959 if ((diff = a->ext_gwy.xport.port - b->ext_gwy.xport.port) != 0)
b0d623f7
A
960 return (diff);
961 if ((diff = a->gwy.xport.port - b->gwy.xport.port) != 0)
962 return (diff);
963 break;
964
965 case IPPROTO_UDP:
966 if ((diff = a->proto_variant - b->proto_variant))
967 return (diff);
968 extfilter = a->proto_variant;
969 if ((diff = a->gwy.xport.port - b->gwy.xport.port) != 0)
970 return (diff);
971 if ((extfilter < PF_EXTFILTER_AD) &&
3e170ce0 972 (diff = a->ext_gwy.xport.port - b->ext_gwy.xport.port) != 0)
b0d623f7
A
973 return (diff);
974 break;
975
976 case IPPROTO_GRE:
977 if (a->proto_variant == PF_GRE_PPTP_VARIANT &&
978 a->proto_variant == b->proto_variant) {
979 if (!!(diff = a->gwy.xport.call_id -
980 b->gwy.xport.call_id))
981 return (diff);
982 }
983 break;
984
985 case IPPROTO_ESP:
986 if (!!(diff = a->gwy.xport.spi - b->gwy.xport.spi))
987 return (diff);
988 break;
989
990 default:
991 break;
992 }
b0d623f7 993
3e170ce0 994 switch (a->af_gwy) {
b0d623f7
A
995#if INET
996 case AF_INET:
3e170ce0
A
997 if ((diff = pf_addr_compare(&a->gwy.addr, &b->gwy.addr,
998 a->af_gwy)) != 0)
999 return (diff);
1000
b0d623f7 1001 if (extfilter < PF_EXTFILTER_EI) {
3e170ce0
A
1002 if ((diff = pf_addr_compare(&a->ext_gwy.addr, &b->ext_gwy.addr,
1003 a->af_gwy)) != 0)
1004 return (diff);
b0d623f7 1005 }
b0d623f7
A
1006 break;
1007#endif /* INET */
1008#if INET6
1009 case AF_INET6:
3e170ce0
A
1010 if ((diff = pf_addr_compare(&a->gwy.addr, &b->gwy.addr,
1011 a->af_gwy)) != 0)
1012 return (diff);
1013
b0d623f7 1014 if (extfilter < PF_EXTFILTER_EI ||
3e170ce0
A
1015 !PF_AZERO(&b->ext_gwy.addr, AF_INET6)) {
1016 if ((diff = pf_addr_compare(&a->ext_gwy.addr, &b->ext_gwy.addr,
1017 a->af_gwy)) != 0)
1018 return (diff);
b0d623f7 1019 }
b0d623f7
A
1020 break;
1021#endif /* INET6 */
1022 }
1023
b0d623f7
A
1024 if (a->app_state && b->app_state) {
1025 if (a->app_state->compare_ext_gwy &&
1026 b->app_state->compare_ext_gwy) {
1027 diff = (const char *)b->app_state->compare_ext_gwy -
1028 (const char *)a->app_state->compare_ext_gwy;
1029 if (diff != 0)
1030 return (diff);
1031 diff = a->app_state->compare_ext_gwy(a->app_state,
1032 b->app_state);
1033 if (diff != 0)
1034 return (diff);
1035 }
1036 }
b0d623f7
A
1037
1038 return (0);
1039}
1040
1041static __inline int
1042pf_state_compare_id(struct pf_state *a, struct pf_state *b)
1043{
1044 if (a->id > b->id)
1045 return (1);
1046 if (a->id < b->id)
1047 return (-1);
1048 if (a->creatorid > b->creatorid)
1049 return (1);
1050 if (a->creatorid < b->creatorid)
1051 return (-1);
1052
1053 return (0);
1054}
1055
1056#if INET6
1057void
1058pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
1059{
1060 switch (af) {
1061#if INET
1062 case AF_INET:
1063 dst->addr32[0] = src->addr32[0];
1064 break;
1065#endif /* INET */
1066 case AF_INET6:
1067 dst->addr32[0] = src->addr32[0];
1068 dst->addr32[1] = src->addr32[1];
1069 dst->addr32[2] = src->addr32[2];
1070 dst->addr32[3] = src->addr32[3];
1071 break;
1072 }
1073}
1074#endif /* INET6 */
1075
1076struct pf_state *
1077pf_find_state_byid(struct pf_state_cmp *key)
1078{
1079 pf_status.fcounters[FCNT_STATE_SEARCH]++;
1080
316670eb
A
1081 return (RB_FIND(pf_state_tree_id, &tree_id,
1082 (struct pf_state *)(void *)key));
b0d623f7
A
1083}
1084
1085static struct pf_state *
1086pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int dir)
1087{
1088 struct pf_state_key *sk = NULL;
1089 struct pf_state *s;
1090
1091 pf_status.fcounters[FCNT_STATE_SEARCH]++;
1092
1093 switch (dir) {
1094 case PF_OUT:
1095 sk = RB_FIND(pf_state_tree_lan_ext, &pf_statetbl_lan_ext,
1096 (struct pf_state_key *)key);
1097 break;
1098 case PF_IN:
1099 sk = RB_FIND(pf_state_tree_ext_gwy, &pf_statetbl_ext_gwy,
1100 (struct pf_state_key *)key);
3e170ce0
A
1101 /*
1102 * NAT64 is done only on input, for packets coming in from
1103 * from the LAN side, need to lookup the lan_ext tree.
1104 */
1105 if (sk == NULL) {
1106 sk = RB_FIND(pf_state_tree_lan_ext,
1107 &pf_statetbl_lan_ext,
1108 (struct pf_state_key *)key);
1109 if (sk && sk->af_lan == sk->af_gwy)
1110 sk = NULL;
1111 }
b0d623f7
A
1112 break;
1113 default:
1114 panic("pf_find_state");
1115 }
1116
1117 /* list is sorted, if-bound states before floating ones */
1118 if (sk != NULL)
1119 TAILQ_FOREACH(s, &sk->states, next)
1120 if (s->kif == pfi_all || s->kif == kif)
1121 return (s);
1122
1123 return (NULL);
1124}
1125
1126struct pf_state *
1127pf_find_state_all(struct pf_state_key_cmp *key, u_int dir, int *more)
1128{
1129 struct pf_state_key *sk = NULL;
1130 struct pf_state *s, *ret = NULL;
1131
1132 pf_status.fcounters[FCNT_STATE_SEARCH]++;
1133
1134 switch (dir) {
1135 case PF_OUT:
1136 sk = RB_FIND(pf_state_tree_lan_ext,
1137 &pf_statetbl_lan_ext, (struct pf_state_key *)key);
1138 break;
1139 case PF_IN:
1140 sk = RB_FIND(pf_state_tree_ext_gwy,
1141 &pf_statetbl_ext_gwy, (struct pf_state_key *)key);
3e170ce0
A
1142 /*
1143 * NAT64 is done only on input, for packets coming in from
1144 * from the LAN side, need to lookup the lan_ext tree.
1145 */
1146 if ((sk == NULL) && pf_nat64_configured) {
1147 sk = RB_FIND(pf_state_tree_lan_ext,
1148 &pf_statetbl_lan_ext,
1149 (struct pf_state_key *)key);
1150 if (sk && sk->af_lan == sk->af_gwy)
1151 sk = NULL;
1152 }
b0d623f7
A
1153 break;
1154 default:
1155 panic("pf_find_state_all");
1156 }
1157
1158 if (sk != NULL) {
1159 ret = TAILQ_FIRST(&sk->states);
1160 if (more == NULL)
1161 return (ret);
1162
1163 TAILQ_FOREACH(s, &sk->states, next)
1164 (*more)++;
1165 }
1166
1167 return (ret);
1168}
1169
1170static void
1171pf_init_threshold(struct pf_threshold *threshold,
1172 u_int32_t limit, u_int32_t seconds)
1173{
1174 threshold->limit = limit * PF_THRESHOLD_MULT;
1175 threshold->seconds = seconds;
1176 threshold->count = 0;
1177 threshold->last = pf_time_second();
1178}
1179
1180static void
1181pf_add_threshold(struct pf_threshold *threshold)
1182{
1183 u_int32_t t = pf_time_second(), diff = t - threshold->last;
1184
1185 if (diff >= threshold->seconds)
1186 threshold->count = 0;
1187 else
1188 threshold->count -= threshold->count * diff /
1189 threshold->seconds;
1190 threshold->count += PF_THRESHOLD_MULT;
1191 threshold->last = t;
1192}
1193
1194static int
1195pf_check_threshold(struct pf_threshold *threshold)
1196{
1197 return (threshold->count > threshold->limit);
1198}
1199
1200static int
1201pf_src_connlimit(struct pf_state **state)
1202{
1203 int bad = 0;
b0d623f7 1204 (*state)->src_node->conn++;
b7266188 1205 VERIFY((*state)->src_node->conn != 0);
b0d623f7
A
1206 (*state)->src.tcp_est = 1;
1207 pf_add_threshold(&(*state)->src_node->conn_rate);
1208
1209 if ((*state)->rule.ptr->max_src_conn &&
1210 (*state)->rule.ptr->max_src_conn <
1211 (*state)->src_node->conn) {
1212 pf_status.lcounters[LCNT_SRCCONN]++;
1213 bad++;
1214 }
1215
1216 if ((*state)->rule.ptr->max_src_conn_rate.limit &&
1217 pf_check_threshold(&(*state)->src_node->conn_rate)) {
1218 pf_status.lcounters[LCNT_SRCCONNRATE]++;
1219 bad++;
1220 }
1221
1222 if (!bad)
1223 return (0);
1224
1225 if ((*state)->rule.ptr->overload_tbl) {
1226 struct pfr_addr p;
1227 u_int32_t killed = 0;
1228
1229 pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
1230 if (pf_status.debug >= PF_DEBUG_MISC) {
1231 printf("pf_src_connlimit: blocking address ");
1232 pf_print_host(&(*state)->src_node->addr, 0,
3e170ce0 1233 (*state)->state_key->af_lan);
b0d623f7
A
1234 }
1235
1236 bzero(&p, sizeof (p));
3e170ce0
A
1237 p.pfra_af = (*state)->state_key->af_lan;
1238 switch ((*state)->state_key->af_lan) {
b0d623f7
A
1239#if INET
1240 case AF_INET:
1241 p.pfra_net = 32;
1242 p.pfra_ip4addr = (*state)->src_node->addr.v4;
1243 break;
1244#endif /* INET */
1245#if INET6
1246 case AF_INET6:
1247 p.pfra_net = 128;
1248 p.pfra_ip6addr = (*state)->src_node->addr.v6;
1249 break;
1250#endif /* INET6 */
1251 }
1252
1253 pfr_insert_kentry((*state)->rule.ptr->overload_tbl,
d1ecb069 1254 &p, pf_calendar_time_second());
b0d623f7
A
1255
1256 /* kill existing states if that's required. */
1257 if ((*state)->rule.ptr->flush) {
1258 struct pf_state_key *sk;
1259 struct pf_state *st;
1260
1261 pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
1262 RB_FOREACH(st, pf_state_tree_id, &tree_id) {
1263 sk = st->state_key;
1264 /*
1265 * Kill states from this source. (Only those
1266 * from the same rule if PF_FLUSH_GLOBAL is not
1267 * set)
1268 */
3e170ce0
A
1269 if (sk->af_lan ==
1270 (*state)->state_key->af_lan &&
b0d623f7
A
1271 (((*state)->state_key->direction ==
1272 PF_OUT &&
1273 PF_AEQ(&(*state)->src_node->addr,
3e170ce0 1274 &sk->lan.addr, sk->af_lan)) ||
b0d623f7
A
1275 ((*state)->state_key->direction == PF_IN &&
1276 PF_AEQ(&(*state)->src_node->addr,
3e170ce0 1277 &sk->ext_lan.addr, sk->af_lan))) &&
b0d623f7
A
1278 ((*state)->rule.ptr->flush &
1279 PF_FLUSH_GLOBAL ||
1280 (*state)->rule.ptr == st->rule.ptr)) {
1281 st->timeout = PFTM_PURGE;
1282 st->src.state = st->dst.state =
1283 TCPS_CLOSED;
1284 killed++;
1285 }
1286 }
1287 if (pf_status.debug >= PF_DEBUG_MISC)
1288 printf(", %u states killed", killed);
1289 }
1290 if (pf_status.debug >= PF_DEBUG_MISC)
1291 printf("\n");
1292 }
1293
1294 /* kill this state */
1295 (*state)->timeout = PFTM_PURGE;
1296 (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
1297 return (1);
1298}
1299
1300int
1301pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
1302 struct pf_addr *src, sa_family_t af)
1303{
1304 struct pf_src_node k;
1305
1306 if (*sn == NULL) {
1307 k.af = af;
1308 PF_ACPY(&k.addr, src, af);
1309 if (rule->rule_flag & PFRULE_RULESRCTRACK ||
1310 rule->rpool.opts & PF_POOL_STICKYADDR)
1311 k.rule.ptr = rule;
1312 else
1313 k.rule.ptr = NULL;
1314 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
1315 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
1316 }
1317 if (*sn == NULL) {
1318 if (!rule->max_src_nodes ||
1319 rule->src_nodes < rule->max_src_nodes)
1320 (*sn) = pool_get(&pf_src_tree_pl, PR_WAITOK);
1321 else
1322 pf_status.lcounters[LCNT_SRCNODES]++;
1323 if ((*sn) == NULL)
1324 return (-1);
1325 bzero(*sn, sizeof (struct pf_src_node));
1326
1327 pf_init_threshold(&(*sn)->conn_rate,
1328 rule->max_src_conn_rate.limit,
1329 rule->max_src_conn_rate.seconds);
1330
1331 (*sn)->af = af;
1332 if (rule->rule_flag & PFRULE_RULESRCTRACK ||
1333 rule->rpool.opts & PF_POOL_STICKYADDR)
1334 (*sn)->rule.ptr = rule;
1335 else
1336 (*sn)->rule.ptr = NULL;
1337 PF_ACPY(&(*sn)->addr, src, af);
1338 if (RB_INSERT(pf_src_tree,
1339 &tree_src_tracking, *sn) != NULL) {
1340 if (pf_status.debug >= PF_DEBUG_MISC) {
1341 printf("pf: src_tree insert failed: ");
1342 pf_print_host(&(*sn)->addr, 0, af);
1343 printf("\n");
1344 }
1345 pool_put(&pf_src_tree_pl, *sn);
1346 return (-1);
1347 }
1348 (*sn)->creation = pf_time_second();
1349 (*sn)->ruletype = rule->action;
1350 if ((*sn)->rule.ptr != NULL)
1351 (*sn)->rule.ptr->src_nodes++;
1352 pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
1353 pf_status.src_nodes++;
1354 } else {
1355 if (rule->max_src_states &&
1356 (*sn)->states >= rule->max_src_states) {
1357 pf_status.lcounters[LCNT_SRCSTATES]++;
1358 return (-1);
1359 }
1360 }
1361 return (0);
1362}
1363
1364static void
1365pf_stateins_err(const char *tree, struct pf_state *s, struct pfi_kif *kif)
1366{
1367 struct pf_state_key *sk = s->state_key;
1368
1369 if (pf_status.debug >= PF_DEBUG_MISC) {
b0d623f7
A
1370 printf("pf: state insert failed: %s %s ", tree, kif->pfik_name);
1371 switch (sk->proto) {
1372 case IPPROTO_TCP:
1373 printf("TCP");
1374 break;
1375 case IPPROTO_UDP:
1376 printf("UDP");
1377 break;
1378 case IPPROTO_ICMP:
1379 printf("ICMP4");
1380 break;
1381 case IPPROTO_ICMPV6:
1382 printf("ICMP6");
1383 break;
1384 default:
1385 printf("PROTO=%u", sk->proto);
1386 break;
1387 }
1388 printf(" lan: ");
3e170ce0 1389 pf_print_sk_host(&sk->lan, sk->af_lan, sk->proto,
b0d623f7
A
1390 sk->proto_variant);
1391 printf(" gwy: ");
3e170ce0
A
1392 pf_print_sk_host(&sk->gwy, sk->af_gwy, sk->proto,
1393 sk->proto_variant);
1394 printf(" ext_lan: ");
1395 pf_print_sk_host(&sk->ext_lan, sk->af_lan, sk->proto,
b0d623f7 1396 sk->proto_variant);
3e170ce0
A
1397 printf(" ext_gwy: ");
1398 pf_print_sk_host(&sk->ext_gwy, sk->af_gwy, sk->proto,
b0d623f7 1399 sk->proto_variant);
b0d623f7
A
1400 if (s->sync_flags & PFSTATE_FROMSYNC)
1401 printf(" (from sync)");
1402 printf("\n");
1403 }
1404}
1405
1406int
1407pf_insert_state(struct pfi_kif *kif, struct pf_state *s)
1408{
1409 struct pf_state_key *cur;
1410 struct pf_state *sp;
1411
1412 VERIFY(s->state_key != NULL);
1413 s->kif = kif;
1414
1415 if ((cur = RB_INSERT(pf_state_tree_lan_ext, &pf_statetbl_lan_ext,
1416 s->state_key)) != NULL) {
1417 /* key exists. check for same kif, if none, add to key */
1418 TAILQ_FOREACH(sp, &cur->states, next)
1419 if (sp->kif == kif) { /* collision! */
1420 pf_stateins_err("tree_lan_ext", s, kif);
1421 pf_detach_state(s,
1422 PF_DT_SKIP_LANEXT|PF_DT_SKIP_EXTGWY);
1423 return (-1);
1424 }
1425 pf_detach_state(s, PF_DT_SKIP_LANEXT|PF_DT_SKIP_EXTGWY);
1426 pf_attach_state(cur, s, kif == pfi_all ? 1 : 0);
1427 }
1428
1429 /* if cur != NULL, we already found a state key and attached to it */
1430 if (cur == NULL && (cur = RB_INSERT(pf_state_tree_ext_gwy,
1431 &pf_statetbl_ext_gwy, s->state_key)) != NULL) {
1432 /* must not happen. we must have found the sk above! */
1433 pf_stateins_err("tree_ext_gwy", s, kif);
1434 pf_detach_state(s, PF_DT_SKIP_EXTGWY);
1435 return (-1);
1436 }
1437
1438 if (s->id == 0 && s->creatorid == 0) {
1439 s->id = htobe64(pf_status.stateid++);
1440 s->creatorid = pf_status.hostid;
1441 }
1442 if (RB_INSERT(pf_state_tree_id, &tree_id, s) != NULL) {
1443 if (pf_status.debug >= PF_DEBUG_MISC) {
1444 printf("pf: state insert failed: "
1445 "id: %016llx creatorid: %08x",
1446 be64toh(s->id), ntohl(s->creatorid));
1447 if (s->sync_flags & PFSTATE_FROMSYNC)
1448 printf(" (from sync)");
1449 printf("\n");
1450 }
1451 pf_detach_state(s, 0);
1452 return (-1);
1453 }
1454 TAILQ_INSERT_TAIL(&state_list, s, entry_list);
1455 pf_status.fcounters[FCNT_STATE_INSERT]++;
1456 pf_status.states++;
b7266188 1457 VERIFY(pf_status.states != 0);
b0d623f7
A
1458 pfi_kif_ref(kif, PFI_KIF_REF_STATE);
1459#if NPFSYNC
1460 pfsync_insert_state(s);
1461#endif
1462 return (0);
1463}
1464
316670eb
A
1465static int
1466pf_purge_thread_cont(int err)
b0d623f7 1467{
316670eb
A
1468#pragma unused(err)
1469 static u_int32_t nloops = 0;
1470 int t = 1; /* 1 second */
1471
39236c6e
A
1472 /*
1473 * Update coarse-grained networking timestamp (in sec.); the idea
1474 * is to piggy-back on the periodic timeout callout to update
1475 * the counter returnable via net_uptime().
1476 */
1477 net_update_uptime();
1478
316670eb
A
1479 lck_rw_lock_shared(pf_perim_lock);
1480 lck_mtx_lock(pf_lock);
1481
1482 /* purge everything if not running */
1483 if (!pf_status.running) {
1484 pf_purge_expired_states(pf_status.states);
1485 pf_purge_expired_fragments();
1486 pf_purge_expired_src_nodes();
1487
1488 /* terminate thread (we don't currently do this) */
1489 if (pf_purge_thread == NULL) {
1490 lck_mtx_unlock(pf_lock);
1491 lck_rw_done(pf_perim_lock);
1492
1493 thread_deallocate(current_thread());
1494 thread_terminate(current_thread());
1495 /* NOTREACHED */
1496 return (0);
1497 } else {
1498 /* if there's nothing left, sleep w/o timeout */
1499 if (pf_status.states == 0 &&
1500 pf_normalize_isempty() &&
1501 RB_EMPTY(&tree_src_tracking)) {
1502 nloops = 0;
1503 t = 0;
b0d623f7 1504 }
316670eb 1505 goto done;
b0d623f7 1506 }
316670eb 1507 }
b0d623f7 1508
316670eb
A
1509 /* process a fraction of the state table every second */
1510 pf_purge_expired_states(1 + (pf_status.states
1511 / pf_default_rule.timeout[PFTM_INTERVAL]));
b0d623f7 1512
316670eb
A
1513 /* purge other expired types every PFTM_INTERVAL seconds */
1514 if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) {
1515 pf_purge_expired_fragments();
1516 pf_purge_expired_src_nodes();
1517 nloops = 0;
b0d623f7 1518 }
316670eb
A
1519done:
1520 lck_mtx_unlock(pf_lock);
1521 lck_rw_done(pf_perim_lock);
1522
1523 (void) tsleep0(pf_purge_thread_fn, PWAIT, "pf_purge_cont",
1524 t * hz, pf_purge_thread_cont);
1525 /* NOTREACHED */
1526 VERIFY(0);
1527
1528 return (0);
1529}
1530
1531void
1532pf_purge_thread_fn(void *v, wait_result_t w)
1533{
1534#pragma unused(v, w)
1535 (void) tsleep0(pf_purge_thread_fn, PWAIT, "pf_purge", 0,
1536 pf_purge_thread_cont);
1537 /*
1538 * tsleep0() shouldn't have returned as PCATCH was not set;
1539 * therefore assert in this case.
1540 */
1541 VERIFY(0);
b0d623f7
A
1542}
1543
1544u_int64_t
1545pf_state_expires(const struct pf_state *state)
1546{
1547 u_int32_t t;
1548 u_int32_t start;
1549 u_int32_t end;
1550 u_int32_t states;
1551
1552 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
1553
1554 /* handle all PFTM_* > PFTM_MAX here */
1555 if (state->timeout == PFTM_PURGE)
1556 return (pf_time_second());
fe8ab488 1557
b0d623f7
A
1558 VERIFY(state->timeout != PFTM_UNLINKED);
1559 VERIFY(state->timeout < PFTM_MAX);
1560 t = state->rule.ptr->timeout[state->timeout];
1561 if (!t)
1562 t = pf_default_rule.timeout[state->timeout];
1563 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
1564 if (start) {
1565 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];
1566 states = state->rule.ptr->states;
1567 } else {
1568 start = pf_default_rule.timeout[PFTM_ADAPTIVE_START];
1569 end = pf_default_rule.timeout[PFTM_ADAPTIVE_END];
1570 states = pf_status.states;
1571 }
1572 if (end && states > start && start < end) {
1573 if (states < end)
1574 return (state->expire + t * (end - states) /
1575 (end - start));
1576 else
1577 return (pf_time_second());
1578 }
1579 return (state->expire + t);
1580}
1581
1582void
1583pf_purge_expired_src_nodes(void)
1584{
1585 struct pf_src_node *cur, *next;
1586
1587 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
1588
1589 for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
1590 next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
1591
1592 if (cur->states <= 0 && cur->expire <= pf_time_second()) {
1593 if (cur->rule.ptr != NULL) {
1594 cur->rule.ptr->src_nodes--;
1595 if (cur->rule.ptr->states <= 0 &&
1596 cur->rule.ptr->max_src_nodes <= 0)
1597 pf_rm_rule(NULL, cur->rule.ptr);
1598 }
1599 RB_REMOVE(pf_src_tree, &tree_src_tracking, cur);
1600 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
1601 pf_status.src_nodes--;
1602 pool_put(&pf_src_tree_pl, cur);
1603 }
1604 }
1605}
1606
1607void
1608pf_src_tree_remove_state(struct pf_state *s)
1609{
1610 u_int32_t t;
1611
1612 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
1613
1614 if (s->src_node != NULL) {
b7266188
A
1615 if (s->src.tcp_est) {
1616 VERIFY(s->src_node->conn > 0);
b0d623f7 1617 --s->src_node->conn;
b7266188
A
1618 }
1619 VERIFY(s->src_node->states > 0);
b0d623f7
A
1620 if (--s->src_node->states <= 0) {
1621 t = s->rule.ptr->timeout[PFTM_SRC_NODE];
1622 if (!t)
1623 t = pf_default_rule.timeout[PFTM_SRC_NODE];
1624 s->src_node->expire = pf_time_second() + t;
1625 }
1626 }
1627 if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
b7266188 1628 VERIFY(s->nat_src_node->states > 0);
b0d623f7
A
1629 if (--s->nat_src_node->states <= 0) {
1630 t = s->rule.ptr->timeout[PFTM_SRC_NODE];
1631 if (!t)
1632 t = pf_default_rule.timeout[PFTM_SRC_NODE];
1633 s->nat_src_node->expire = pf_time_second() + t;
1634 }
1635 }
1636 s->src_node = s->nat_src_node = NULL;
1637}
1638
1639void
1640pf_unlink_state(struct pf_state *cur)
1641{
1642 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
1643
b0d623f7 1644 if (cur->src.state == PF_TCPS_PROXY_DST) {
3e170ce0
A
1645 pf_send_tcp(cur->rule.ptr, cur->state_key->af_lan,
1646 &cur->state_key->ext_lan.addr, &cur->state_key->lan.addr,
1647 cur->state_key->ext_lan.xport.port,
b0d623f7
A
1648 cur->state_key->lan.xport.port,
1649 cur->src.seqhi, cur->src.seqlo + 1,
1650 TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL);
1651 }
1652
1653 hook_runloop(&cur->unlink_hooks, HOOK_REMOVE|HOOK_FREE);
b0d623f7
A
1654 RB_REMOVE(pf_state_tree_id, &tree_id, cur);
1655#if NPFSYNC
1656 if (cur->creatorid == pf_status.hostid)
1657 pfsync_delete_state(cur);
1658#endif
1659 cur->timeout = PFTM_UNLINKED;
1660 pf_src_tree_remove_state(cur);
1661 pf_detach_state(cur, 0);
1662}
1663
1664/* callers should be at splpf and hold the
1665 * write_lock on pf_consistency_lock */
1666void
1667pf_free_state(struct pf_state *cur)
1668{
1669 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
1670#if NPFSYNC
1671 if (pfsyncif != NULL &&
1672 (pfsyncif->sc_bulk_send_next == cur ||
1673 pfsyncif->sc_bulk_terminator == cur))
1674 return;
1675#endif
1676 VERIFY(cur->timeout == PFTM_UNLINKED);
b7266188 1677 VERIFY(cur->rule.ptr->states > 0);
b0d623f7
A
1678 if (--cur->rule.ptr->states <= 0 &&
1679 cur->rule.ptr->src_nodes <= 0)
1680 pf_rm_rule(NULL, cur->rule.ptr);
b7266188
A
1681 if (cur->nat_rule.ptr != NULL) {
1682 VERIFY(cur->nat_rule.ptr->states > 0);
b0d623f7
A
1683 if (--cur->nat_rule.ptr->states <= 0 &&
1684 cur->nat_rule.ptr->src_nodes <= 0)
1685 pf_rm_rule(NULL, cur->nat_rule.ptr);
b7266188
A
1686 }
1687 if (cur->anchor.ptr != NULL) {
1688 VERIFY(cur->anchor.ptr->states > 0);
b0d623f7
A
1689 if (--cur->anchor.ptr->states <= 0)
1690 pf_rm_rule(NULL, cur->anchor.ptr);
b7266188 1691 }
b0d623f7
A
1692 pf_normalize_tcp_cleanup(cur);
1693 pfi_kif_unref(cur->kif, PFI_KIF_REF_STATE);
1694 TAILQ_REMOVE(&state_list, cur, entry_list);
1695 if (cur->tag)
1696 pf_tag_unref(cur->tag);
1697 pool_put(&pf_state_pl, cur);
1698 pf_status.fcounters[FCNT_STATE_REMOVALS]++;
b7266188 1699 VERIFY(pf_status.states > 0);
b0d623f7
A
1700 pf_status.states--;
1701}
1702
1703void
1704pf_purge_expired_states(u_int32_t maxcheck)
1705{
1706 static struct pf_state *cur = NULL;
1707 struct pf_state *next;
1708
1709 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
1710
1711 while (maxcheck--) {
1712 /* wrap to start of list when we hit the end */
1713 if (cur == NULL) {
1714 cur = TAILQ_FIRST(&state_list);
1715 if (cur == NULL)
1716 break; /* list empty */
1717 }
1718
1719 /* get next state, as cur may get deleted */
1720 next = TAILQ_NEXT(cur, entry_list);
1721
1722 if (cur->timeout == PFTM_UNLINKED) {
1723 pf_free_state(cur);
1724 } else if (pf_state_expires(cur) <= pf_time_second()) {
1725 /* unlink and free expired state */
1726 pf_unlink_state(cur);
1727 pf_free_state(cur);
1728 }
1729 cur = next;
1730 }
1731}
1732
1733int
1734pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
1735{
1736 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
1737
1738 if (aw->type != PF_ADDR_TABLE)
1739 return (0);
1740 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)
1741 return (1);
1742 return (0);
1743}
1744
1745void
1746pf_tbladdr_remove(struct pf_addr_wrap *aw)
1747{
1748 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
1749
1750 if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL)
1751 return;
1752 pfr_detach_table(aw->p.tbl);
1753 aw->p.tbl = NULL;
1754}
1755
1756void
1757pf_tbladdr_copyout(struct pf_addr_wrap *aw)
1758{
1759 struct pfr_ktable *kt = aw->p.tbl;
1760
1761 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
1762
1763 if (aw->type != PF_ADDR_TABLE || kt == NULL)
1764 return;
1765 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
1766 kt = kt->pfrkt_root;
1767 aw->p.tbl = NULL;
1768 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
1769 kt->pfrkt_cnt : -1;
1770}
1771
b0d623f7
A
1772static void
1773pf_print_addr(struct pf_addr *addr, sa_family_t af)
1774{
1775 switch (af) {
1776#if INET
1777 case AF_INET: {
1778 u_int32_t a = ntohl(addr->addr32[0]);
1779 printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255,
1780 (a>>8)&255, a&255);
1781 break;
1782 }
1783#endif /* INET */
1784#if INET6
1785 case AF_INET6: {
1786 u_int16_t b;
1787 u_int8_t i, curstart = 255, curend = 0,
1788 maxstart = 0, maxend = 0;
1789 for (i = 0; i < 8; i++) {
1790 if (!addr->addr16[i]) {
1791 if (curstart == 255)
1792 curstart = i;
1793 else
1794 curend = i;
1795 } else {
1796 if (curstart) {
1797 if ((curend - curstart) >
1798 (maxend - maxstart)) {
1799 maxstart = curstart;
1800 maxend = curend;
1801 curstart = 255;
1802 }
1803 }
1804 }
1805 }
1806 for (i = 0; i < 8; i++) {
1807 if (i >= maxstart && i <= maxend) {
1808 if (maxend != 7) {
1809 if (i == maxstart)
1810 printf(":");
1811 } else {
1812 if (i == maxend)
1813 printf(":");
1814 }
1815 } else {
1816 b = ntohs(addr->addr16[i]);
1817 printf("%x", b);
1818 if (i < 7)
1819 printf(":");
1820 }
1821 }
1822 break;
1823 }
1824#endif /* INET6 */
1825 }
1826}
1827
1828static void
1829pf_print_sk_host(struct pf_state_host *sh, sa_family_t af, int proto,
1830 u_int8_t proto_variant)
1831{
1832 pf_print_addr(&sh->addr, af);
1833
1834 switch (proto) {
1835 case IPPROTO_ESP:
1836 if (sh->xport.spi)
1837 printf("[%08x]", ntohl(sh->xport.spi));
1838 break;
1839
1840 case IPPROTO_GRE:
1841 if (proto_variant == PF_GRE_PPTP_VARIANT)
1842 printf("[%u]", ntohs(sh->xport.call_id));
1843 break;
1844
1845 case IPPROTO_TCP:
1846 case IPPROTO_UDP:
1847 printf("[%u]", ntohs(sh->xport.port));
1848 break;
1849
1850 default:
1851 break;
1852 }
1853}
b0d623f7
A
1854
1855static void
1856pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
1857{
b0d623f7
A
1858 pf_print_addr(addr, af);
1859 if (p)
1860 printf("[%u]", ntohs(p));
b0d623f7
A
1861}
1862
1863void
1864pf_print_state(struct pf_state *s)
1865{
1866 struct pf_state_key *sk = s->state_key;
1867 switch (sk->proto) {
b0d623f7
A
1868 case IPPROTO_ESP:
1869 printf("ESP ");
1870 break;
1871 case IPPROTO_GRE:
1872 printf("GRE%u ", sk->proto_variant);
1873 break;
b0d623f7
A
1874 case IPPROTO_TCP:
1875 printf("TCP ");
1876 break;
1877 case IPPROTO_UDP:
1878 printf("UDP ");
1879 break;
1880 case IPPROTO_ICMP:
1881 printf("ICMP ");
1882 break;
1883 case IPPROTO_ICMPV6:
1884 printf("ICMPV6 ");
1885 break;
1886 default:
1887 printf("%u ", sk->proto);
1888 break;
1889 }
3e170ce0
A
1890 pf_print_sk_host(&sk->lan, sk->af_lan, sk->proto, sk->proto_variant);
1891 printf(" ");
1892 pf_print_sk_host(&sk->gwy, sk->af_gwy, sk->proto, sk->proto_variant);
b0d623f7 1893 printf(" ");
3e170ce0
A
1894 pf_print_sk_host(&sk->ext_lan, sk->af_lan, sk->proto,
1895 sk->proto_variant);
b0d623f7 1896 printf(" ");
3e170ce0
A
1897 pf_print_sk_host(&sk->ext_gwy, sk->af_gwy, sk->proto,
1898 sk->proto_variant);
b0d623f7
A
1899 printf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo,
1900 s->src.seqhi, s->src.max_win, s->src.seqdiff);
1901 if (s->src.wscale && s->dst.wscale)
1902 printf(" wscale=%u", s->src.wscale & PF_WSCALE_MASK);
1903 printf("]");
1904 printf(" [lo=%u high=%u win=%u modulator=%u", s->dst.seqlo,
1905 s->dst.seqhi, s->dst.max_win, s->dst.seqdiff);
1906 if (s->src.wscale && s->dst.wscale)
1907 printf(" wscale=%u", s->dst.wscale & PF_WSCALE_MASK);
1908 printf("]");
1909 printf(" %u:%u", s->src.state, s->dst.state);
1910}
1911
1912void
1913pf_print_flags(u_int8_t f)
1914{
1915 if (f)
1916 printf(" ");
1917 if (f & TH_FIN)
1918 printf("F");
1919 if (f & TH_SYN)
1920 printf("S");
1921 if (f & TH_RST)
1922 printf("R");
1923 if (f & TH_PUSH)
1924 printf("P");
1925 if (f & TH_ACK)
1926 printf("A");
1927 if (f & TH_URG)
1928 printf("U");
1929 if (f & TH_ECE)
1930 printf("E");
1931 if (f & TH_CWR)
1932 printf("W");
1933}
1934
1935#define PF_SET_SKIP_STEPS(i) \
1936 do { \
1937 while (head[i] != cur) { \
1938 head[i]->skip[i].ptr = cur; \
1939 head[i] = TAILQ_NEXT(head[i], entries); \
1940 } \
1941 } while (0)
1942
1943void
1944pf_calc_skip_steps(struct pf_rulequeue *rules)
1945{
1946 struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT];
1947 int i;
1948
1949 cur = TAILQ_FIRST(rules);
1950 prev = cur;
1951 for (i = 0; i < PF_SKIP_COUNT; ++i)
1952 head[i] = cur;
1953 while (cur != NULL) {
1954
1955 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
1956 PF_SET_SKIP_STEPS(PF_SKIP_IFP);
1957 if (cur->direction != prev->direction)
1958 PF_SET_SKIP_STEPS(PF_SKIP_DIR);
1959 if (cur->af != prev->af)
1960 PF_SET_SKIP_STEPS(PF_SKIP_AF);
1961 if (cur->proto != prev->proto)
1962 PF_SET_SKIP_STEPS(PF_SKIP_PROTO);
1963 if (cur->src.neg != prev->src.neg ||
1964 pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr))
1965 PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR);
b0d623f7
A
1966 {
1967 union pf_rule_xport *cx = &cur->src.xport;
1968 union pf_rule_xport *px = &prev->src.xport;
1969
1970 switch (cur->proto) {
1971 case IPPROTO_GRE:
1972 case IPPROTO_ESP:
1973 PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
1974 break;
1975 default:
1976 if (prev->proto == IPPROTO_GRE ||
1977 prev->proto == IPPROTO_ESP ||
1978 cx->range.op != px->range.op ||
1979 cx->range.port[0] != px->range.port[0] ||
1980 cx->range.port[1] != px->range.port[1])
1981 PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
1982 break;
1983 }
1984 }
b0d623f7
A
1985 if (cur->dst.neg != prev->dst.neg ||
1986 pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
1987 PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
b0d623f7
A
1988 {
1989 union pf_rule_xport *cx = &cur->dst.xport;
1990 union pf_rule_xport *px = &prev->dst.xport;
1991
1992 switch (cur->proto) {
1993 case IPPROTO_GRE:
1994 if (cur->proto != prev->proto ||
1995 cx->call_id != px->call_id)
1996 PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
1997 break;
1998 case IPPROTO_ESP:
1999 if (cur->proto != prev->proto ||
2000 cx->spi != px->spi)
2001 PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
2002 break;
2003 default:
2004 if (prev->proto == IPPROTO_GRE ||
2005 prev->proto == IPPROTO_ESP ||
2006 cx->range.op != px->range.op ||
2007 cx->range.port[0] != px->range.port[0] ||
2008 cx->range.port[1] != px->range.port[1])
2009 PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
2010 break;
2011 }
2012 }
b0d623f7
A
2013
2014 prev = cur;
2015 cur = TAILQ_NEXT(cur, entries);
2016 }
2017 for (i = 0; i < PF_SKIP_COUNT; ++i)
2018 PF_SET_SKIP_STEPS(i);
2019}
2020
316670eb
A
2021u_int32_t
2022pf_calc_state_key_flowhash(struct pf_state_key *sk)
2023{
2024 struct pf_flowhash_key fh __attribute__((aligned(8)));
39236c6e 2025 uint32_t flowhash = 0;
316670eb
A
2026
2027 bzero(&fh, sizeof (fh));
3e170ce0 2028 if (PF_ALEQ(&sk->lan.addr, &sk->ext_lan.addr, sk->af_lan)) {
316670eb 2029 bcopy(&sk->lan.addr, &fh.ap1.addr, sizeof (fh.ap1.addr));
3e170ce0 2030 bcopy(&sk->ext_lan.addr, &fh.ap2.addr, sizeof (fh.ap2.addr));
316670eb 2031 } else {
3e170ce0 2032 bcopy(&sk->ext_lan.addr, &fh.ap1.addr, sizeof (fh.ap1.addr));
316670eb
A
2033 bcopy(&sk->lan.addr, &fh.ap2.addr, sizeof (fh.ap2.addr));
2034 }
3e170ce0 2035 if (sk->lan.xport.spi <= sk->ext_lan.xport.spi) {
316670eb 2036 fh.ap1.xport.spi = sk->lan.xport.spi;
3e170ce0 2037 fh.ap2.xport.spi = sk->ext_lan.xport.spi;
316670eb 2038 } else {
3e170ce0 2039 fh.ap1.xport.spi = sk->ext_lan.xport.spi;
316670eb
A
2040 fh.ap2.xport.spi = sk->lan.xport.spi;
2041 }
3e170ce0 2042 fh.af = sk->af_lan;
316670eb
A
2043 fh.proto = sk->proto;
2044
39236c6e
A
2045try_again:
2046 flowhash = net_flowhash(&fh, sizeof (fh), pf_hash_seed);
2047 if (flowhash == 0) {
2048 /* try to get a non-zero flowhash */
2049 pf_hash_seed = RandomULong();
2050 goto try_again;
2051 }
2052
2053 return (flowhash);
316670eb
A
2054}
2055
b0d623f7
A
2056static int
2057pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
2058{
2059 if (aw1->type != aw2->type)
2060 return (1);
2061 switch (aw1->type) {
2062 case PF_ADDR_ADDRMASK:
2063 case PF_ADDR_RANGE:
2064 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
2065 return (1);
2066 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
2067 return (1);
2068 return (0);
2069 case PF_ADDR_DYNIFTL:
39236c6e
A
2070 return (aw1->p.dyn == NULL || aw2->p.dyn == NULL ||
2071 aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
b0d623f7
A
2072 case PF_ADDR_NOROUTE:
2073 case PF_ADDR_URPFFAILED:
2074 return (0);
2075 case PF_ADDR_TABLE:
2076 return (aw1->p.tbl != aw2->p.tbl);
2077 case PF_ADDR_RTLABEL:
2078 return (aw1->v.rtlabel != aw2->v.rtlabel);
2079 default:
2080 printf("invalid address type: %d\n", aw1->type);
2081 return (1);
2082 }
2083}
2084
2085u_int16_t
2086pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp)
2087{
2088 u_int32_t l;
2089
2090 if (udp && !cksum)
2091 return (0);
2092 l = cksum + old - new;
2093 l = (l >> 16) + (l & 0xffff);
2094 l = l & 0xffff;
2095 if (udp && !l)
2096 return (0xffff);
2097 return (l);
2098}
2099
3e170ce0
A
2100/*
2101 * change ip address & port
2102 * dir : packet direction
2103 * a : address to be changed
2104 * p : port to be changed
2105 * ic : ip header checksum
2106 * pc : protocol checksum
2107 * an : new ip address
2108 * pn : new port
2109 * u : should be 1 if UDP packet else 0
2110 * af : address family of the packet
2111 * afn : address family of the new address
2112 * ua : should be 1 if ip address needs to be updated in the packet else
2113 * only the checksum is recalculated & updated.
2114 */
b0d623f7
A
2115static void
2116pf_change_ap(int dir, struct mbuf *m, struct pf_addr *a, u_int16_t *p,
2117 u_int16_t *ic, u_int16_t *pc, struct pf_addr *an, u_int16_t pn,
3e170ce0 2118 u_int8_t u, sa_family_t af, sa_family_t afn, int ua)
b0d623f7
A
2119{
2120 struct pf_addr ao;
2121 u_int16_t po = *p;
2122
2123 PF_ACPY(&ao, a, af);
3e170ce0
A
2124 if (ua)
2125 PF_ACPY(a, an, afn);
b0d623f7
A
2126
2127 *p = pn;
2128
2129 switch (af) {
2130#if INET
2131 case AF_INET:
3e170ce0
A
2132 switch (afn) {
2133 case AF_INET:
2134 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
2135 ao.addr16[0], an->addr16[0], 0),
2136 ao.addr16[1], an->addr16[1], 0);
2137 *p = pn;
b0d623f7
A
2138 /*
2139 * If the packet is originated from an ALG on the NAT gateway
2140 * (source address is loopback or local), in which case the
2141 * TCP/UDP checksum field contains the pseudo header checksum
3e170ce0
A
2142 * that's not yet complemented. A packet generated locally
2143 * will have UDP/TCP CSUM flag set (gets set in protocol
2144 * output).
b0d623f7 2145 */
3e170ce0
A
2146 if (dir == PF_OUT && m != NULL &&
2147 (m->m_flags & M_PKTHDR) &&
2148 (m->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))) {
b0d623f7 2149 /* Pseudo-header checksum does not include ports */
3e170ce0
A
2150 *pc = ~pf_cksum_fixup(pf_cksum_fixup(~*pc,
2151 ao.addr16[0], an->addr16[0], u),
2152 ao.addr16[1], an->addr16[1], u);
2153 } else {
2154 *pc =
2155 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2156 *pc, ao.addr16[0], an->addr16[0], u),
2157 ao.addr16[1], an->addr16[1], u),
2158 po, pn, u);
2159 }
2160 break;
2161#ifdef INET6
2162 case AF_INET6:
2163 *p = pn;
2164 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2165 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2166
2167 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
b0d623f7
A
2168 ao.addr16[0], an->addr16[0], u),
2169 ao.addr16[1], an->addr16[1], u),
3e170ce0
A
2170 0, an->addr16[2], u),
2171 0, an->addr16[3], u),
2172 0, an->addr16[4], u),
2173 0, an->addr16[5], u),
2174 0, an->addr16[6], u),
2175 0, an->addr16[7], u),
b0d623f7 2176 po, pn, u);
3e170ce0
A
2177 break;
2178#endif /* INET6 */
b0d623f7
A
2179 }
2180 break;
2181#endif /* INET */
2182#if INET6
2183 case AF_INET6:
3e170ce0
A
2184 switch (afn) {
2185 case AF_INET6:
6d2010ae
A
2186 /*
2187 * If the packet is originated from an ALG on the NAT gateway
2188 * (source address is loopback or local), in which case the
2189 * TCP/UDP checksum field contains the pseudo header checksum
2190 * that's not yet complemented.
3e170ce0
A
2191 * A packet generated locally
2192 * will have UDP/TCP CSUM flag set (gets set in protocol
2193 * output).
6d2010ae 2194 */
3e170ce0
A
2195 if (dir == PF_OUT && m != NULL &&
2196 (m->m_flags & M_PKTHDR) &&
2197 (m->m_pkthdr.csum_flags & (CSUM_TCPIPV6 |
2198 CSUM_UDPIPV6))) {
6d2010ae 2199 /* Pseudo-header checksum does not include ports */
3e170ce0
A
2200 *pc =
2201 ~pf_cksum_fixup(pf_cksum_fixup(
2202 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2203 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2204 ~*pc,
2205 ao.addr16[0], an->addr16[0], u),
2206 ao.addr16[1], an->addr16[1], u),
2207 ao.addr16[2], an->addr16[2], u),
2208 ao.addr16[3], an->addr16[3], u),
2209 ao.addr16[4], an->addr16[4], u),
2210 ao.addr16[5], an->addr16[5], u),
2211 ao.addr16[6], an->addr16[6], u),
2212 ao.addr16[7], an->addr16[7], u);
2213 } else {
2214 *pc =
2215 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2216 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2217 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2218 *pc,
2219 ao.addr16[0], an->addr16[0], u),
2220 ao.addr16[1], an->addr16[1], u),
2221 ao.addr16[2], an->addr16[2], u),
2222 ao.addr16[3], an->addr16[3], u),
2223 ao.addr16[4], an->addr16[4], u),
2224 ao.addr16[5], an->addr16[5], u),
2225 ao.addr16[6], an->addr16[6], u),
2226 ao.addr16[7], an->addr16[7], u),
2227 po, pn, u);
2228 }
2229 break;
2230#ifdef INET
2231 case AF_INET:
6d2010ae 2232 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
3e170ce0
A
2233 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2234 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
2235 ao.addr16[0], an->addr16[0], u),
2236 ao.addr16[1], an->addr16[1], u),
2237 ao.addr16[2], 0, u),
2238 ao.addr16[3], 0, u),
2239 ao.addr16[4], 0, u),
2240 ao.addr16[5], 0, u),
2241 ao.addr16[6], 0, u),
2242 ao.addr16[7], 0, u),
2243 po, pn, u);
2244 break;
2245#endif /* INET */
6d2010ae 2246 }
b0d623f7
A
2247 break;
2248#endif /* INET6 */
2249 }
2250}
2251
2252
2253/* Changes a u_int32_t. Uses a void * so there are no align restrictions */
2254void
2255pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u)
2256{
2257 u_int32_t ao;
2258
2259 memcpy(&ao, a, sizeof (ao));
2260 memcpy(a, &an, sizeof (u_int32_t));
2261 *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u),
2262 ao % 65536, an % 65536, u);
2263}
2264
2265#if INET6
2266static void
2267pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u)
2268{
2269 struct pf_addr ao;
2270
2271 PF_ACPY(&ao, a, AF_INET6);
2272 PF_ACPY(a, an, AF_INET6);
2273
2274 *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2275 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2276 pf_cksum_fixup(pf_cksum_fixup(*c,
2277 ao.addr16[0], an->addr16[0], u),
2278 ao.addr16[1], an->addr16[1], u),
2279 ao.addr16[2], an->addr16[2], u),
2280 ao.addr16[3], an->addr16[3], u),
2281 ao.addr16[4], an->addr16[4], u),
2282 ao.addr16[5], an->addr16[5], u),
2283 ao.addr16[6], an->addr16[6], u),
2284 ao.addr16[7], an->addr16[7], u);
2285}
3e170ce0
A
2286
2287void
2288pf_change_addr(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u,
2289 sa_family_t af, sa_family_t afn)
2290{
2291 struct pf_addr ao;
2292
2293 PF_ACPY(&ao, a, af);
2294 PF_ACPY(a, an, afn);
2295
2296 switch (af) {
2297 case AF_INET:
2298 switch (afn) {
2299 case AF_INET:
2300 pf_change_a(a, c, an->v4.s_addr, u);
2301 break;
2302 case AF_INET6:
2303 *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2304 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2305 pf_cksum_fixup(pf_cksum_fixup(*c,
2306 ao.addr16[0], an->addr16[0], u),
2307 ao.addr16[1], an->addr16[1], u),
2308 0, an->addr16[2], u),
2309 0, an->addr16[3], u),
2310 0, an->addr16[4], u),
2311 0, an->addr16[5], u),
2312 0, an->addr16[6], u),
2313 0, an->addr16[7], u);
2314 break;
2315 }
2316 break;
2317 case AF_INET6:
2318 switch (afn) {
2319 case AF_INET:
2320 *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2321 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2322 pf_cksum_fixup(pf_cksum_fixup(*c,
2323 ao.addr16[0], an->addr16[0], u),
2324 ao.addr16[1], an->addr16[1], u),
2325 ao.addr16[2], 0, u),
2326 ao.addr16[3], 0, u),
2327 ao.addr16[4], 0, u),
2328 ao.addr16[5], 0, u),
2329 ao.addr16[6], 0, u),
2330 ao.addr16[7], 0, u);
2331 break;
2332 case AF_INET6:
2333 pf_change_a6(a, c, an, u);
2334 break;
2335 }
2336 break;
2337 }
2338}
2339
b0d623f7
A
2340#endif /* INET6 */
2341
2342static void
2343pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa,
2344 struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c,
2345 u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af)
2346{
2347 struct pf_addr oia, ooa;
2348
2349 PF_ACPY(&oia, ia, af);
2350 PF_ACPY(&ooa, oa, af);
2351
2352 /* Change inner protocol port, fix inner protocol checksum. */
2353 if (ip != NULL) {
2354 u_int16_t oip = *ip;
2355 u_int32_t opc = 0;
2356
2357 if (pc != NULL)
2358 opc = *pc;
2359 *ip = np;
2360 if (pc != NULL)
2361 *pc = pf_cksum_fixup(*pc, oip, *ip, u);
2362 *ic = pf_cksum_fixup(*ic, oip, *ip, 0);
2363 if (pc != NULL)
2364 *ic = pf_cksum_fixup(*ic, opc, *pc, 0);
2365 }
2366 /* Change inner ip address, fix inner ip and icmp checksums. */
2367 PF_ACPY(ia, na, af);
2368 switch (af) {
2369#if INET
2370 case AF_INET: {
2371 u_int32_t oh2c = *h2c;
2372
2373 *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c,
2374 oia.addr16[0], ia->addr16[0], 0),
2375 oia.addr16[1], ia->addr16[1], 0);
2376 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
2377 oia.addr16[0], ia->addr16[0], 0),
2378 oia.addr16[1], ia->addr16[1], 0);
2379 *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0);
2380 break;
2381 }
2382#endif /* INET */
2383#if INET6
2384 case AF_INET6:
2385 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2386 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2387 pf_cksum_fixup(pf_cksum_fixup(*ic,
2388 oia.addr16[0], ia->addr16[0], u),
2389 oia.addr16[1], ia->addr16[1], u),
2390 oia.addr16[2], ia->addr16[2], u),
2391 oia.addr16[3], ia->addr16[3], u),
2392 oia.addr16[4], ia->addr16[4], u),
2393 oia.addr16[5], ia->addr16[5], u),
2394 oia.addr16[6], ia->addr16[6], u),
2395 oia.addr16[7], ia->addr16[7], u);
2396 break;
2397#endif /* INET6 */
2398 }
2399 /* Change outer ip address, fix outer ip or icmpv6 checksum. */
2400 PF_ACPY(oa, na, af);
2401 switch (af) {
2402#if INET
2403 case AF_INET:
2404 *hc = pf_cksum_fixup(pf_cksum_fixup(*hc,
2405 ooa.addr16[0], oa->addr16[0], 0),
2406 ooa.addr16[1], oa->addr16[1], 0);
2407 break;
2408#endif /* INET */
2409#if INET6
2410 case AF_INET6:
2411 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2412 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
2413 pf_cksum_fixup(pf_cksum_fixup(*ic,
2414 ooa.addr16[0], oa->addr16[0], u),
2415 ooa.addr16[1], oa->addr16[1], u),
2416 ooa.addr16[2], oa->addr16[2], u),
2417 ooa.addr16[3], oa->addr16[3], u),
2418 ooa.addr16[4], oa->addr16[4], u),
2419 ooa.addr16[5], oa->addr16[5], u),
2420 ooa.addr16[6], oa->addr16[6], u),
2421 ooa.addr16[7], oa->addr16[7], u);
2422 break;
2423#endif /* INET6 */
2424 }
2425}
2426
2427
2428/*
2429 * Need to modulate the sequence numbers in the TCP SACK option
2430 * (credits to Krzysztof Pfaff for report and patch)
2431 */
2432static int
2433pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd,
2434 struct tcphdr *th, struct pf_state_peer *dst)
2435{
2436 int hlen = (th->th_off << 2) - sizeof (*th), thoptlen = hlen;
2437 u_int8_t opts[MAX_TCPOPTLEN], *opt = opts;
2438 int copyback = 0, i, olen;
2439 struct sackblk sack;
2440
2441#define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2)
2442 if (hlen < TCPOLEN_SACKLEN ||
2443 !pf_pull_hdr(m, off + sizeof (*th), opts, hlen, NULL, NULL, pd->af))
2444 return (0);
2445
2446 while (hlen >= TCPOLEN_SACKLEN) {
2447 olen = opt[1];
2448 switch (*opt) {
2449 case TCPOPT_EOL: /* FALLTHROUGH */
2450 case TCPOPT_NOP:
2451 opt++;
2452 hlen--;
2453 break;
2454 case TCPOPT_SACK:
2455 if (olen > hlen)
2456 olen = hlen;
2457 if (olen >= TCPOLEN_SACKLEN) {
2458 for (i = 2; i + TCPOLEN_SACK <= olen;
2459 i += TCPOLEN_SACK) {
2460 memcpy(&sack, &opt[i], sizeof (sack));
2461 pf_change_a(&sack.start, &th->th_sum,
2462 htonl(ntohl(sack.start) -
2463 dst->seqdiff), 0);
2464 pf_change_a(&sack.end, &th->th_sum,
2465 htonl(ntohl(sack.end) -
2466 dst->seqdiff), 0);
2467 memcpy(&opt[i], &sack, sizeof (sack));
2468 }
b0d623f7 2469 copyback = off + sizeof (*th) + thoptlen;
b0d623f7
A
2470 }
2471 /* FALLTHROUGH */
2472 default:
2473 if (olen < 2)
2474 olen = 2;
2475 hlen -= olen;
2476 opt += olen;
2477 }
2478 }
2479
b0d623f7
A
2480 if (copyback) {
2481 m = pf_lazy_makewritable(pd, m, copyback);
2482 if (!m)
2483 return (-1);
2484 m_copyback(m, off + sizeof (*th), thoptlen, opts);
2485 }
b0d623f7
A
2486 return (copyback);
2487}
2488
2489static void
2490pf_send_tcp(const struct pf_rule *r, sa_family_t af,
2491 const struct pf_addr *saddr, const struct pf_addr *daddr,
2492 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
2493 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
2494 u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp)
2495{
2496#pragma unused(eh, ifp)
2497 struct mbuf *m;
2498 int len, tlen;
2499#if INET
2500 struct ip *h = NULL;
2501#endif /* INET */
2502#if INET6
2503 struct ip6_hdr *h6 = NULL;
2504#endif /* INET6 */
2505 struct tcphdr *th = NULL;
2506 char *opt;
2507 struct pf_mtag *pf_mtag;
2508
2509 /* maximum segment size tcp option */
2510 tlen = sizeof (struct tcphdr);
2511 if (mss)
2512 tlen += 4;
2513
2514 switch (af) {
2515#if INET
2516 case AF_INET:
2517 len = sizeof (struct ip) + tlen;
2518 break;
2519#endif /* INET */
2520#if INET6
2521 case AF_INET6:
2522 len = sizeof (struct ip6_hdr) + tlen;
2523 break;
2524#endif /* INET6 */
2525 default:
2526 panic("pf_send_tcp: not AF_INET or AF_INET6!");
2527 return;
2528 }
2529
2530 /* create outgoing mbuf */
2531 m = m_gethdr(M_DONTWAIT, MT_HEADER);
2532 if (m == NULL)
2533 return;
2534
2535 if ((pf_mtag = pf_get_mtag(m)) == NULL) {
2536 m_free(m);
2537 return;
2538 }
2539
2540 if (tag)
316670eb
A
2541 pf_mtag->pftag_flags |= PF_TAG_GENERATED;
2542 pf_mtag->pftag_tag = rtag;
b0d623f7
A
2543
2544 if (r != NULL && PF_RTABLEID_IS_VALID(r->rtableid))
316670eb 2545 pf_mtag->pftag_rtableid = r->rtableid;
b0d623f7 2546
316670eb
A
2547#if PF_ALTQ
2548 if (altq_allowed && r != NULL && r->qid)
2549 pf_mtag->pftag_qid = r->qid;
2550#endif /* PF_ALTQ */
2551
39236c6e 2552#if PF_ECN
316670eb
A
2553 /* add hints for ecn */
2554 pf_mtag->pftag_hdr = mtod(m, struct ip *);
2555 /* record address family */
2556 pf_mtag->pftag_flags &= ~(PF_TAG_HDR_INET | PF_TAG_HDR_INET6);
2557 switch (af) {
2558#if INET
2559 case AF_INET:
2560 pf_mtag->pftag_flags |= PF_TAG_HDR_INET;
2561 break;
2562#endif /* INET */
2563#if INET6
2564 case AF_INET6:
2565 pf_mtag->pftag_flags |= PF_TAG_HDR_INET6;
2566 break;
2567#endif /* INET6 */
b0d623f7 2568 }
39236c6e
A
2569#endif /* PF_ECN */
2570
316670eb 2571 /* indicate this is TCP */
39236c6e 2572 m->m_pkthdr.pkt_proto = IPPROTO_TCP;
316670eb
A
2573
2574 /* Make sure headers are 32-bit aligned */
b0d623f7
A
2575 m->m_data += max_linkhdr;
2576 m->m_pkthdr.len = m->m_len = len;
2577 m->m_pkthdr.rcvif = NULL;
2578 bzero(m->m_data, len);
2579 switch (af) {
2580#if INET
2581 case AF_INET:
2582 h = mtod(m, struct ip *);
2583
2584 /* IP header fields included in the TCP checksum */
2585 h->ip_p = IPPROTO_TCP;
2586 h->ip_len = htons(tlen);
2587 h->ip_src.s_addr = saddr->v4.s_addr;
2588 h->ip_dst.s_addr = daddr->v4.s_addr;
2589
316670eb 2590 th = (struct tcphdr *)(void *)((caddr_t)h + sizeof (struct ip));
b0d623f7
A
2591 break;
2592#endif /* INET */
2593#if INET6
2594 case AF_INET6:
2595 h6 = mtod(m, struct ip6_hdr *);
2596
2597 /* IP header fields included in the TCP checksum */
2598 h6->ip6_nxt = IPPROTO_TCP;
2599 h6->ip6_plen = htons(tlen);
2600 memcpy(&h6->ip6_src, &saddr->v6, sizeof (struct in6_addr));
2601 memcpy(&h6->ip6_dst, &daddr->v6, sizeof (struct in6_addr));
2602
316670eb
A
2603 th = (struct tcphdr *)(void *)
2604 ((caddr_t)h6 + sizeof (struct ip6_hdr));
b0d623f7
A
2605 break;
2606#endif /* INET6 */
2607 }
2608
2609 /* TCP header */
2610 th->th_sport = sport;
2611 th->th_dport = dport;
2612 th->th_seq = htonl(seq);
2613 th->th_ack = htonl(ack);
2614 th->th_off = tlen >> 2;
2615 th->th_flags = flags;
2616 th->th_win = htons(win);
2617
2618 if (mss) {
2619 opt = (char *)(th + 1);
2620 opt[0] = TCPOPT_MAXSEG;
2621 opt[1] = 4;
2622#if BYTE_ORDER != BIG_ENDIAN
2623 HTONS(mss);
2624#endif
2625 bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2);
2626 }
2627
2628 switch (af) {
2629#if INET
2630 case AF_INET: {
2631 struct route ro;
2632
2633 /* TCP checksum */
2634 th->th_sum = in_cksum(m, len);
2635
2636 /* Finish the IP header */
2637 h->ip_v = 4;
2638 h->ip_hl = sizeof (*h) >> 2;
2639 h->ip_tos = IPTOS_LOWDELAY;
2640 /*
2641 * ip_output() expects ip_len and ip_off to be in host order.
2642 */
2643 h->ip_len = len;
2644 h->ip_off = (path_mtu_discovery ? IP_DF : 0);
2645 h->ip_ttl = ttl ? ttl : ip_defttl;
2646 h->ip_sum = 0;
2647
2648 bzero(&ro, sizeof (ro));
2649 ip_output(m, NULL, &ro, 0, NULL, NULL);
39236c6e 2650 ROUTE_RELEASE(&ro);
b0d623f7
A
2651 break;
2652 }
2653#endif /* INET */
2654#if INET6
2655 case AF_INET6: {
2656 struct route_in6 ro6;
2657
2658 /* TCP checksum */
2659 th->th_sum = in6_cksum(m, IPPROTO_TCP,
2660 sizeof (struct ip6_hdr), tlen);
2661
2662 h6->ip6_vfc |= IPV6_VERSION;
2663 h6->ip6_hlim = IPV6_DEFHLIM;
2664
2665 bzero(&ro6, sizeof (ro6));
6d2010ae 2666 ip6_output(m, NULL, &ro6, 0, NULL, NULL, NULL);
39236c6e 2667 ROUTE_RELEASE(&ro6);
b0d623f7
A
2668 break;
2669 }
2670#endif /* INET6 */
2671 }
2672}
2673
2674static void
2675pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
2676 struct pf_rule *r)
2677{
2678 struct mbuf *m0;
2679 struct pf_mtag *pf_mtag;
2680
2681 m0 = m_copy(m, 0, M_COPYALL);
2682 if (m0 == NULL)
2683 return;
2684
2685 if ((pf_mtag = pf_get_mtag(m0)) == NULL)
2686 return;
2687
316670eb 2688 pf_mtag->pftag_flags |= PF_TAG_GENERATED;
b0d623f7
A
2689
2690 if (PF_RTABLEID_IS_VALID(r->rtableid))
316670eb
A
2691 pf_mtag->pftag_rtableid = r->rtableid;
2692
2693#if PF_ALTQ
2694 if (altq_allowed && r->qid)
2695 pf_mtag->pftag_qid = r->qid;
2696#endif /* PF_ALTQ */
2697
39236c6e 2698#if PF_ECN
316670eb
A
2699 /* add hints for ecn */
2700 pf_mtag->pftag_hdr = mtod(m0, struct ip *);
2701 /* record address family */
39236c6e 2702 pf_mtag->pftag_flags &= ~(PF_TAG_HDR_INET | PF_TAG_HDR_INET6);
316670eb
A
2703 switch (af) {
2704#if INET
2705 case AF_INET:
2706 pf_mtag->pftag_flags |= PF_TAG_HDR_INET;
39236c6e 2707 m0->m_pkthdr.pkt_proto = IPPROTO_ICMP;
316670eb
A
2708 break;
2709#endif /* INET */
2710#if INET6
2711 case AF_INET6:
2712 pf_mtag->pftag_flags |= PF_TAG_HDR_INET6;
39236c6e 2713 m0->m_pkthdr.pkt_proto = IPPROTO_ICMPV6;
316670eb
A
2714 break;
2715#endif /* INET6 */
b0d623f7 2716 }
39236c6e 2717#endif /* PF_ECN */
316670eb 2718
b0d623f7
A
2719 switch (af) {
2720#if INET
2721 case AF_INET:
2722 icmp_error(m0, type, code, 0, 0);
2723 break;
2724#endif /* INET */
2725#if INET6
2726 case AF_INET6:
2727 icmp6_error(m0, type, code, 0);
2728 break;
2729#endif /* INET6 */
2730 }
2731}
2732
2733/*
2734 * Return 1 if the addresses a and b match (with mask m), otherwise return 0.
2735 * If n is 0, they match if they are equal. If n is != 0, they match if they
2736 * are different.
2737 */
2738int
2739pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
2740 struct pf_addr *b, sa_family_t af)
2741{
2742 int match = 0;
2743
2744 switch (af) {
2745#if INET
2746 case AF_INET:
2747 if ((a->addr32[0] & m->addr32[0]) ==
2748 (b->addr32[0] & m->addr32[0]))
2749 match++;
2750 break;
2751#endif /* INET */
2752#if INET6
2753 case AF_INET6:
2754 if (((a->addr32[0] & m->addr32[0]) ==
2755 (b->addr32[0] & m->addr32[0])) &&
2756 ((a->addr32[1] & m->addr32[1]) ==
2757 (b->addr32[1] & m->addr32[1])) &&
2758 ((a->addr32[2] & m->addr32[2]) ==
2759 (b->addr32[2] & m->addr32[2])) &&
2760 ((a->addr32[3] & m->addr32[3]) ==
2761 (b->addr32[3] & m->addr32[3])))
2762 match++;
2763 break;
2764#endif /* INET6 */
2765 }
2766 if (match) {
2767 if (n)
2768 return (0);
2769 else
2770 return (1);
2771 } else {
2772 if (n)
2773 return (1);
2774 else
2775 return (0);
2776 }
2777}
2778
2779/*
2780 * Return 1 if b <= a <= e, otherwise return 0.
2781 */
2782int
2783pf_match_addr_range(struct pf_addr *b, struct pf_addr *e,
2784 struct pf_addr *a, sa_family_t af)
2785{
2786 switch (af) {
2787#if INET
2788 case AF_INET:
2789 if ((a->addr32[0] < b->addr32[0]) ||
2790 (a->addr32[0] > e->addr32[0]))
2791 return (0);
2792 break;
2793#endif /* INET */
2794#if INET6
2795 case AF_INET6: {
2796 int i;
2797
2798 /* check a >= b */
2799 for (i = 0; i < 4; ++i)
2800 if (a->addr32[i] > b->addr32[i])
2801 break;
2802 else if (a->addr32[i] < b->addr32[i])
2803 return (0);
2804 /* check a <= e */
2805 for (i = 0; i < 4; ++i)
2806 if (a->addr32[i] < e->addr32[i])
2807 break;
2808 else if (a->addr32[i] > e->addr32[i])
2809 return (0);
2810 break;
2811 }
2812#endif /* INET6 */
2813 }
2814 return (1);
2815}
2816
2817int
2818pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
2819{
2820 switch (op) {
2821 case PF_OP_IRG:
2822 return ((p > a1) && (p < a2));
2823 case PF_OP_XRG:
2824 return ((p < a1) || (p > a2));
2825 case PF_OP_RRG:
2826 return ((p >= a1) && (p <= a2));
2827 case PF_OP_EQ:
2828 return (p == a1);
2829 case PF_OP_NE:
2830 return (p != a1);
2831 case PF_OP_LT:
2832 return (p < a1);
2833 case PF_OP_LE:
2834 return (p <= a1);
2835 case PF_OP_GT:
2836 return (p > a1);
2837 case PF_OP_GE:
2838 return (p >= a1);
2839 }
2840 return (0); /* never reached */
2841}
2842
2843int
2844pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
2845{
2846#if BYTE_ORDER != BIG_ENDIAN
2847 NTOHS(a1);
2848 NTOHS(a2);
2849 NTOHS(p);
2850#endif
2851 return (pf_match(op, a1, a2, p));
2852}
2853
b0d623f7
A
2854int
2855pf_match_xport(u_int8_t proto, u_int8_t proto_variant, union pf_rule_xport *rx,
2856 union pf_state_xport *sx)
2857{
2858 int d = !0;
2859
2860 if (sx) {
2861 switch (proto) {
2862 case IPPROTO_GRE:
2863 if (proto_variant == PF_GRE_PPTP_VARIANT)
2864 d = (rx->call_id == sx->call_id);
2865 break;
2866
2867 case IPPROTO_ESP:
2868 d = (rx->spi == sx->spi);
2869 break;
2870
2871 case IPPROTO_TCP:
2872 case IPPROTO_UDP:
2873 case IPPROTO_ICMP:
2874 case IPPROTO_ICMPV6:
2875 if (rx->range.op)
2876 d = pf_match_port(rx->range.op,
2877 rx->range.port[0], rx->range.port[1],
2878 sx->port);
2879 break;
2880
2881 default:
2882 break;
2883 }
2884 }
2885
2886 return (d);
2887}
b0d623f7
A
2888
2889int
2890pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
2891{
2892 if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
2893 return (0);
2894 return (pf_match(op, a1, a2, u));
2895}
2896
2897int
2898pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
2899{
2900 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
2901 return (0);
2902 return (pf_match(op, a1, a2, g));
2903}
2904
2905static int
2906pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_mtag *pf_mtag,
2907 int *tag)
2908{
2909#pragma unused(m)
2910 if (*tag == -1)
316670eb 2911 *tag = pf_mtag->pftag_tag;
b0d623f7
A
2912
2913 return ((!r->match_tag_not && r->match_tag == *tag) ||
2914 (r->match_tag_not && r->match_tag != *tag));
2915}
2916
2917int
2918pf_tag_packet(struct mbuf *m, struct pf_mtag *pf_mtag, int tag,
316670eb 2919 unsigned int rtableid, struct pf_pdesc *pd)
b0d623f7 2920{
39236c6e
A
2921 if (tag <= 0 && !PF_RTABLEID_IS_VALID(rtableid) &&
2922 (pd == NULL || !(pd->pktflags & PKTF_FLOW_ID)))
b0d623f7
A
2923 return (0);
2924
2925 if (pf_mtag == NULL && (pf_mtag = pf_get_mtag(m)) == NULL)
2926 return (1);
2927
2928 if (tag > 0)
316670eb 2929 pf_mtag->pftag_tag = tag;
b0d623f7 2930 if (PF_RTABLEID_IS_VALID(rtableid))
316670eb 2931 pf_mtag->pftag_rtableid = rtableid;
39236c6e
A
2932 if (pd != NULL && (pd->pktflags & PKTF_FLOW_ID)) {
2933 m->m_pkthdr.pkt_flowsrc = pd->flowsrc;
2934 m->m_pkthdr.pkt_flowid = pd->flowhash;
2935 m->m_pkthdr.pkt_flags |= pd->pktflags;
2936 m->m_pkthdr.pkt_proto = pd->proto;
316670eb 2937 }
b0d623f7
A
2938
2939 return (0);
2940}
2941
13f56ec4 2942void
b0d623f7
A
2943pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n,
2944 struct pf_rule **r, struct pf_rule **a, int *match)
2945{
2946 struct pf_anchor_stackframe *f;
2947
2948 (*r)->anchor->match = 0;
2949 if (match)
2950 *match = 0;
2951 if (*depth >= (int)sizeof (pf_anchor_stack) /
2952 (int)sizeof (pf_anchor_stack[0])) {
2953 printf("pf_step_into_anchor: stack overflow\n");
2954 *r = TAILQ_NEXT(*r, entries);
2955 return;
2956 } else if (*depth == 0 && a != NULL)
2957 *a = *r;
2958 f = pf_anchor_stack + (*depth)++;
2959 f->rs = *rs;
2960 f->r = *r;
2961 if ((*r)->anchor_wildcard) {
2962 f->parent = &(*r)->anchor->children;
2963 if ((f->child = RB_MIN(pf_anchor_node, f->parent)) ==
2964 NULL) {
2965 *r = NULL;
2966 return;
2967 }
2968 *rs = &f->child->ruleset;
2969 } else {
2970 f->parent = NULL;
2971 f->child = NULL;
2972 *rs = &(*r)->anchor->ruleset;
2973 }
2974 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2975}
2976
13f56ec4 2977int
b0d623f7
A
2978pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n,
2979 struct pf_rule **r, struct pf_rule **a, int *match)
2980{
2981 struct pf_anchor_stackframe *f;
2982 int quick = 0;
2983
2984 do {
2985 if (*depth <= 0)
2986 break;
2987 f = pf_anchor_stack + *depth - 1;
2988 if (f->parent != NULL && f->child != NULL) {
2989 if (f->child->match ||
2990 (match != NULL && *match)) {
2991 f->r->anchor->match = 1;
2992 *match = 0;
2993 }
2994 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child);
2995 if (f->child != NULL) {
2996 *rs = &f->child->ruleset;
2997 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2998 if (*r == NULL)
2999 continue;
3000 else
3001 break;
3002 }
3003 }
3004 (*depth)--;
3005 if (*depth == 0 && a != NULL)
3006 *a = NULL;
3007 *rs = f->rs;
3008 if (f->r->anchor->match || (match != NULL && *match))
3009 quick = f->r->quick;
3010 *r = TAILQ_NEXT(f->r, entries);
3011 } while (*r == NULL);
3012
3013 return (quick);
3014}
3015
3016#if INET6
3017void
3018pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
3019 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af)
3020{
3021 switch (af) {
3022#if INET
3023 case AF_INET:
3024 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
3025 ((rmask->addr32[0] ^ 0xffffffff) & saddr->addr32[0]);
3026 break;
3027#endif /* INET */
3028 case AF_INET6:
3029 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
3030 ((rmask->addr32[0] ^ 0xffffffff) & saddr->addr32[0]);
3031 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) |
3032 ((rmask->addr32[1] ^ 0xffffffff) & saddr->addr32[1]);
3033 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) |
3034 ((rmask->addr32[2] ^ 0xffffffff) & saddr->addr32[2]);
3035 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) |
3036 ((rmask->addr32[3] ^ 0xffffffff) & saddr->addr32[3]);
3037 break;
3038 }
3039}
3040
3041void
3042pf_addr_inc(struct pf_addr *addr, sa_family_t af)
3043{
3044 switch (af) {
3045#if INET
3046 case AF_INET:
3047 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1);
3048 break;
3049#endif /* INET */
3050 case AF_INET6:
3051 if (addr->addr32[3] == 0xffffffff) {
3052 addr->addr32[3] = 0;
3053 if (addr->addr32[2] == 0xffffffff) {
3054 addr->addr32[2] = 0;
3055 if (addr->addr32[1] == 0xffffffff) {
3056 addr->addr32[1] = 0;
3057 addr->addr32[0] =
3058 htonl(ntohl(addr->addr32[0]) + 1);
3059 } else
3060 addr->addr32[1] =
3061 htonl(ntohl(addr->addr32[1]) + 1);
3062 } else
3063 addr->addr32[2] =
3064 htonl(ntohl(addr->addr32[2]) + 1);
3065 } else
3066 addr->addr32[3] =
3067 htonl(ntohl(addr->addr32[3]) + 1);
3068 break;
3069 }
3070}
3071#endif /* INET6 */
3072
3073#define mix(a, b, c) \
3074 do { \
3075 a -= b; a -= c; a ^= (c >> 13); \
3076 b -= c; b -= a; b ^= (a << 8); \
3077 c -= a; c -= b; c ^= (b >> 13); \
3078 a -= b; a -= c; a ^= (c >> 12); \
3079 b -= c; b -= a; b ^= (a << 16); \
3080 c -= a; c -= b; c ^= (b >> 5); \
3081 a -= b; a -= c; a ^= (c >> 3); \
3082 b -= c; b -= a; b ^= (a << 10); \
3083 c -= a; c -= b; c ^= (b >> 15); \
3084 } while (0)
3085
3086/*
3087 * hash function based on bridge_hash in if_bridge.c
3088 */
3089static void
3090pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
3091 struct pf_poolhashkey *key, sa_family_t af)
3092{
3093 u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0];
3094
3095 switch (af) {
3096#if INET
3097 case AF_INET:
3098 a += inaddr->addr32[0];
3099 b += key->key32[1];
3100 mix(a, b, c);
3101 hash->addr32[0] = c + key->key32[2];
3102 break;
3103#endif /* INET */
3104#if INET6
3105 case AF_INET6:
3106 a += inaddr->addr32[0];
3107 b += inaddr->addr32[2];
3108 mix(a, b, c);
3109 hash->addr32[0] = c;
3110 a += inaddr->addr32[1];
3111 b += inaddr->addr32[3];
3112 c += key->key32[1];
3113 mix(a, b, c);
3114 hash->addr32[1] = c;
3115 a += inaddr->addr32[2];
3116 b += inaddr->addr32[1];
3117 c += key->key32[2];
3118 mix(a, b, c);
3119 hash->addr32[2] = c;
3120 a += inaddr->addr32[3];
3121 b += inaddr->addr32[0];
3122 c += key->key32[3];
3123 mix(a, b, c);
3124 hash->addr32[3] = c;
3125 break;
3126#endif /* INET6 */
3127 }
3128}
3129
3130static int
3131pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
3132 struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
3133{
3134 unsigned char hash[16];
3135 struct pf_pool *rpool = &r->rpool;
3136 struct pf_addr *raddr = &rpool->cur->addr.v.a.addr;
3137 struct pf_addr *rmask = &rpool->cur->addr.v.a.mask;
3138 struct pf_pooladdr *acur = rpool->cur;
3139 struct pf_src_node k;
3140
3141 if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
3142 (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
3143 k.af = af;
3144 PF_ACPY(&k.addr, saddr, af);
3145 if (r->rule_flag & PFRULE_RULESRCTRACK ||
3146 r->rpool.opts & PF_POOL_STICKYADDR)
3147 k.rule.ptr = r;
3148 else
3149 k.rule.ptr = NULL;
3150 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
3151 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
3e170ce0
A
3152 if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, rpool->af)) {
3153 PF_ACPY(naddr, &(*sn)->raddr, rpool->af);
b0d623f7
A
3154 if (pf_status.debug >= PF_DEBUG_MISC) {
3155 printf("pf_map_addr: src tracking maps ");
3156 pf_print_host(&k.addr, 0, af);
3157 printf(" to ");
3e170ce0 3158 pf_print_host(naddr, 0, rpool->af);
b0d623f7
A
3159 printf("\n");
3160 }
3161 return (0);
3162 }
3163 }
3164
3165 if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
3166 return (1);
3167 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
39236c6e
A
3168 if (rpool->cur->addr.p.dyn == NULL)
3169 return (1);
3e170ce0 3170 switch (rpool->af) {
b0d623f7
A
3171#if INET
3172 case AF_INET:
3173 if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
3174 (rpool->opts & PF_POOL_TYPEMASK) !=
3175 PF_POOL_ROUNDROBIN)
3176 return (1);
3177 raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
3178 rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
3179 break;
3180#endif /* INET */
3181#if INET6
3182 case AF_INET6:
3183 if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
3184 (rpool->opts & PF_POOL_TYPEMASK) !=
3185 PF_POOL_ROUNDROBIN)
3186 return (1);
3187 raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
3188 rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
3189 break;
3190#endif /* INET6 */
3191 }
3192 } else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
3193 if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
3194 return (1); /* unsupported */
3195 } else {
3196 raddr = &rpool->cur->addr.v.a.addr;
3197 rmask = &rpool->cur->addr.v.a.mask;
3198 }
3199
3200 switch (rpool->opts & PF_POOL_TYPEMASK) {
3201 case PF_POOL_NONE:
3e170ce0 3202 PF_ACPY(naddr, raddr, rpool->af);
b0d623f7
A
3203 break;
3204 case PF_POOL_BITMASK:
3e170ce0 3205 ASSERT(af == rpool->af);
b0d623f7
A
3206 PF_POOLMASK(naddr, raddr, rmask, saddr, af);
3207 break;
3208 case PF_POOL_RANDOM:
3e170ce0 3209 if (init_addr != NULL && PF_AZERO(init_addr, rpool->af)) {
b0d623f7
A
3210 switch (af) {
3211#if INET
3212 case AF_INET:
3213 rpool->counter.addr32[0] = htonl(random());
3214 break;
3215#endif /* INET */
3216#if INET6
3217 case AF_INET6:
3218 if (rmask->addr32[3] != 0xffffffff)
3219 rpool->counter.addr32[3] =
39236c6e 3220 RandomULong();
b0d623f7
A
3221 else
3222 break;
3223 if (rmask->addr32[2] != 0xffffffff)
3224 rpool->counter.addr32[2] =
39236c6e 3225 RandomULong();
b0d623f7
A
3226 else
3227 break;
3228 if (rmask->addr32[1] != 0xffffffff)
3229 rpool->counter.addr32[1] =
39236c6e 3230 RandomULong();
b0d623f7
A
3231 else
3232 break;
3233 if (rmask->addr32[0] != 0xffffffff)
3234 rpool->counter.addr32[0] =
39236c6e 3235 RandomULong();
b0d623f7
A
3236 break;
3237#endif /* INET6 */
3238 }
3e170ce0
A
3239 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter,
3240 rpool->af);
3241 PF_ACPY(init_addr, naddr, rpool->af);
b0d623f7
A
3242
3243 } else {
3e170ce0
A
3244 PF_AINC(&rpool->counter, rpool->af);
3245 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter,
3246 rpool->af);
b0d623f7
A
3247 }
3248 break;
3249 case PF_POOL_SRCHASH:
3e170ce0
A
3250 ASSERT(af == rpool->af);
3251 PF_POOLMASK(naddr, raddr, rmask, saddr, af);
316670eb
A
3252 pf_hash(saddr, (struct pf_addr *)(void *)&hash,
3253 &rpool->key, af);
3254 PF_POOLMASK(naddr, raddr, rmask,
3255 (struct pf_addr *)(void *)&hash, af);
b0d623f7
A
3256 break;
3257 case PF_POOL_ROUNDROBIN:
3258 if (rpool->cur->addr.type == PF_ADDR_TABLE) {
3259 if (!pfr_pool_get(rpool->cur->addr.p.tbl,
3260 &rpool->tblidx, &rpool->counter,
3e170ce0 3261 &raddr, &rmask, rpool->af))
b0d623f7
A
3262 goto get_addr;
3263 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
39236c6e
A
3264 if (rpool->cur->addr.p.dyn != NULL &&
3265 !pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
b0d623f7
A
3266 &rpool->tblidx, &rpool->counter,
3267 &raddr, &rmask, af))
3268 goto get_addr;
3e170ce0
A
3269 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter,
3270 rpool->af))
b0d623f7
A
3271 goto get_addr;
3272
3273 try_next:
3274 if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL)
3275 rpool->cur = TAILQ_FIRST(&rpool->list);
3276 if (rpool->cur->addr.type == PF_ADDR_TABLE) {
3277 rpool->tblidx = -1;
3278 if (pfr_pool_get(rpool->cur->addr.p.tbl,
3279 &rpool->tblidx, &rpool->counter,
3e170ce0
A
3280 &raddr, &rmask, rpool->af)) {
3281 /* table contains no address of type
3282 * 'rpool->af' */
b0d623f7
A
3283 if (rpool->cur != acur)
3284 goto try_next;
3285 return (1);
3286 }
3287 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
3288 rpool->tblidx = -1;
39236c6e
A
3289 if (rpool->cur->addr.p.dyn == NULL)
3290 return (1);
b0d623f7
A
3291 if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
3292 &rpool->tblidx, &rpool->counter,
3e170ce0
A
3293 &raddr, &rmask, rpool->af)) {
3294 /* table contains no address of type
3295 * 'rpool->af' */
b0d623f7
A
3296 if (rpool->cur != acur)
3297 goto try_next;
3298 return (1);
3299 }
3300 } else {
3301 raddr = &rpool->cur->addr.v.a.addr;
3302 rmask = &rpool->cur->addr.v.a.mask;
3e170ce0 3303 PF_ACPY(&rpool->counter, raddr, rpool->af);
b0d623f7
A
3304 }
3305
3306 get_addr:
3e170ce0
A
3307 PF_ACPY(naddr, &rpool->counter, rpool->af);
3308 if (init_addr != NULL && PF_AZERO(init_addr, rpool->af))
3309 PF_ACPY(init_addr, naddr, rpool->af);
3310 PF_AINC(&rpool->counter, rpool->af);
b0d623f7
A
3311 break;
3312 }
3313 if (*sn != NULL)
3e170ce0 3314 PF_ACPY(&(*sn)->raddr, naddr, rpool->af);
b0d623f7
A
3315
3316 if (pf_status.debug >= PF_DEBUG_MISC &&
3317 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
3318 printf("pf_map_addr: selected address ");
3e170ce0 3319 pf_print_host(naddr, 0, rpool->af);
b0d623f7
A
3320 printf("\n");
3321 }
3322
3323 return (0);
3324}
3325
b0d623f7
A
3326static int
3327pf_get_sport(struct pf_pdesc *pd, struct pfi_kif *kif, struct pf_rule *r,
3328 struct pf_addr *saddr, union pf_state_xport *sxport, struct pf_addr *daddr,
3329 union pf_state_xport *dxport, struct pf_addr *naddr,
3330 union pf_state_xport *nxport, struct pf_src_node **sn)
b0d623f7
A
3331{
3332#pragma unused(kif)
3333 struct pf_state_key_cmp key;
3334 struct pf_addr init_addr;
b0d623f7
A
3335 unsigned int cut;
3336 sa_family_t af = pd->af;
3337 u_int8_t proto = pd->proto;
b7266188
A
3338 unsigned int low = r->rpool.proxy_port[0];
3339 unsigned int high = r->rpool.proxy_port[1];
b0d623f7
A
3340
3341 bzero(&init_addr, sizeof (init_addr));
3342 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
3343 return (1);
3344
3345 if (proto == IPPROTO_ICMP) {
3346 low = 1;
3347 high = 65535;
3348 }
3349
b0d623f7
A
3350 if (!nxport)
3351 return (0); /* No output necessary. */
3352
3353 /*--- Special mapping rules for UDP ---*/
3354 if (proto == IPPROTO_UDP) {
3355
3356 /*--- Never float IKE source port ---*/
b7266188 3357 if (ntohs(sxport->port) == PF_IKE_PORT) {
b0d623f7
A
3358 nxport->port = sxport->port;
3359 return (0);
3360 }
3361
3362 /*--- Apply exterior mapping options ---*/
3363 if (r->extmap > PF_EXTMAP_APD) {
3364 struct pf_state *s;
3365
3366 TAILQ_FOREACH(s, &state_list, entry_list) {
3367 struct pf_state_key *sk = s->state_key;
3368 if (!sk)
3369 continue;
3370 if (s->nat_rule.ptr != r)
3371 continue;
3e170ce0
A
3372 if (sk->proto != IPPROTO_UDP ||
3373 sk->af_lan != af)
b0d623f7
A
3374 continue;
3375 if (sk->lan.xport.port != sxport->port)
3376 continue;
3377 if (PF_ANEQ(&sk->lan.addr, saddr, af))
3378 continue;
3379 if (r->extmap < PF_EXTMAP_EI &&
3e170ce0 3380 PF_ANEQ(&sk->ext_lan.addr, daddr, af))
b0d623f7
A
3381 continue;
3382
3383 nxport->port = sk->gwy.xport.port;
3384 return (0);
3385 }
3386 }
b7266188
A
3387 } else if (proto == IPPROTO_TCP) {
3388 struct pf_state* s;
3389 /*
3390 * APPLE MODIFICATION: <rdar://problem/6546358>
3391 * Fix allows....NAT to use a single binding for TCP session
3392 * with same source IP and source port
3393 */
3394 TAILQ_FOREACH(s, &state_list, entry_list) {
3395 struct pf_state_key* sk = s->state_key;
3396 if (!sk)
3397 continue;
3398 if (s->nat_rule.ptr != r)
3399 continue;
3e170ce0 3400 if (sk->proto != IPPROTO_TCP || sk->af_lan != af)
b7266188
A
3401 continue;
3402 if (sk->lan.xport.port != sxport->port)
3403 continue;
3404 if (!(PF_AEQ(&sk->lan.addr, saddr, af)))
3405 continue;
3406 nxport->port = sk->gwy.xport.port;
3407 return (0);
3408 }
b0d623f7 3409 }
b0d623f7 3410 do {
3e170ce0 3411 key.af_gwy = af;
b0d623f7 3412 key.proto = proto;
3e170ce0
A
3413 PF_ACPY(&key.ext_gwy.addr, daddr, key.af_gwy);
3414 PF_ACPY(&key.gwy.addr, naddr, key.af_gwy);
b0d623f7
A
3415 switch (proto) {
3416 case IPPROTO_UDP:
3417 key.proto_variant = r->extfilter;
3418 break;
3419 default:
3420 key.proto_variant = 0;
3421 break;
3422 }
3423 if (dxport)
3e170ce0 3424 key.ext_gwy.xport = *dxport;
b0d623f7 3425 else
3e170ce0
A
3426 memset(&key.ext_gwy.xport, 0,
3427 sizeof (key.ext_gwy.xport));
b0d623f7
A
3428 /*
3429 * port search; start random, step;
3430 * similar 2 portloop in in_pcbbind
3431 */
3432 if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
3433 proto == IPPROTO_ICMP)) {
b0d623f7
A
3434 if (dxport)
3435 key.gwy.xport = *dxport;
3436 else
3437 memset(&key.gwy.xport, 0,
3e170ce0 3438 sizeof (key.gwy.xport));
b0d623f7
A
3439 if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
3440 return (0);
3441 } else if (low == 0 && high == 0) {
b0d623f7 3442 key.gwy.xport = *nxport;
b0d623f7
A
3443 if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
3444 return (0);
3445 } else if (low == high) {
b0d623f7
A
3446 key.gwy.xport.port = htons(low);
3447 if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
3448 nxport->port = htons(low);
3449 return (0);
3450 }
b0d623f7 3451 } else {
b0d623f7 3452 unsigned int tmp;
b0d623f7
A
3453 if (low > high) {
3454 tmp = low;
3455 low = high;
3456 high = tmp;
3457 }
3458 /* low < high */
3459 cut = htonl(random()) % (1 + high - low) + low;
3460 /* low <= cut <= high */
3461 for (tmp = cut; tmp <= high; ++(tmp)) {
b0d623f7
A
3462 key.gwy.xport.port = htons(tmp);
3463 if (pf_find_state_all(&key, PF_IN, NULL) ==
3464 NULL) {
3465 nxport->port = htons(tmp);
3466 return (0);
3467 }
b0d623f7
A
3468 }
3469 for (tmp = cut - 1; tmp >= low; --(tmp)) {
b0d623f7
A
3470 key.gwy.xport.port = htons(tmp);
3471 if (pf_find_state_all(&key, PF_IN, NULL) ==
3472 NULL) {
3473 nxport->port = htons(tmp);
3474 return (0);
3475 }
b0d623f7
A
3476 }
3477 }
3478
3479 switch (r->rpool.opts & PF_POOL_TYPEMASK) {
3480 case PF_POOL_RANDOM:
3481 case PF_POOL_ROUNDROBIN:
3482 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
3483 return (1);
3484 break;
3485 case PF_POOL_NONE:
3486 case PF_POOL_SRCHASH:
3487 case PF_POOL_BITMASK:
3488 default:
3489 return (1);
3490 }
3491 } while (!PF_AEQ(&init_addr, naddr, af));
3492
3493 return (1); /* none available */
3494}
3495
b0d623f7
A
3496static struct pf_rule *
3497pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
3498 int direction, struct pfi_kif *kif, struct pf_addr *saddr,
3499 union pf_state_xport *sxport, struct pf_addr *daddr,
3500 union pf_state_xport *dxport, int rs_num)
b0d623f7
A
3501{
3502 struct pf_rule *r, *rm = NULL;
3503 struct pf_ruleset *ruleset = NULL;
3504 int tag = -1;
3505 unsigned int rtableid = IFSCOPE_NONE;
3506 int asd = 0;
3507
3508 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
3509 while (r && rm == NULL) {
3510 struct pf_rule_addr *src = NULL, *dst = NULL;
3511 struct pf_addr_wrap *xdst = NULL;
b0d623f7 3512 struct pf_addr_wrap *xsrc = NULL;
d1ecb069 3513 union pf_rule_xport rdrxport;
b0d623f7
A
3514
3515 if (r->action == PF_BINAT && direction == PF_IN) {
3516 src = &r->dst;
3517 if (r->rpool.cur != NULL)
3518 xdst = &r->rpool.cur->addr;
b0d623f7
A
3519 } else if (r->action == PF_RDR && direction == PF_OUT) {
3520 dst = &r->src;
3521 src = &r->dst;
d1ecb069
A
3522 if (r->rpool.cur != NULL) {
3523 rdrxport.range.op = PF_OP_EQ;
3524 rdrxport.range.port[0] =
3525 htons(r->rpool.proxy_port[0]);
b0d623f7 3526 xsrc = &r->rpool.cur->addr;
d1ecb069 3527 }
b0d623f7
A
3528 } else {
3529 src = &r->src;
3530 dst = &r->dst;
3531 }
3532
3533 r->evaluations++;
3534 if (pfi_kif_match(r->kif, kif) == r->ifnot)
3535 r = r->skip[PF_SKIP_IFP].ptr;
3536 else if (r->direction && r->direction != direction)
3537 r = r->skip[PF_SKIP_DIR].ptr;
3538 else if (r->af && r->af != pd->af)
3539 r = r->skip[PF_SKIP_AF].ptr;
3540 else if (r->proto && r->proto != pd->proto)
3541 r = r->skip[PF_SKIP_PROTO].ptr;
b0d623f7
A
3542 else if (xsrc && PF_MISMATCHAW(xsrc, saddr, pd->af, 0, NULL))
3543 r = TAILQ_NEXT(r, entries);
3544 else if (!xsrc && PF_MISMATCHAW(&src->addr, saddr, pd->af,
3545 src->neg, kif))
d1ecb069
A
3546 r = TAILQ_NEXT(r, entries);
3547 else if (xsrc && (!rdrxport.range.port[0] ||
3548 !pf_match_xport(r->proto, r->proto_variant, &rdrxport,
3549 sxport)))
3550 r = TAILQ_NEXT(r, entries);
3551 else if (!xsrc && !pf_match_xport(r->proto,
b7266188 3552 r->proto_variant, &src->xport, sxport))
b0d623f7
A
3553 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
3554 PF_SKIP_DST_PORT].ptr;
3555 else if (dst != NULL &&
3556 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL))
3557 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3558 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af,
3559 0, NULL))
3560 r = TAILQ_NEXT(r, entries);
b0d623f7
A
3561 else if (dst && !pf_match_xport(r->proto, r->proto_variant,
3562 &dst->xport, dxport))
b0d623f7
A
3563 r = r->skip[PF_SKIP_DST_PORT].ptr;
3564 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
3565 r = TAILQ_NEXT(r, entries);
3566 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
3567 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
3568 off, pd->hdr.tcp), r->os_fingerprint)))
3569 r = TAILQ_NEXT(r, entries);
3570 else {
3571 if (r->tag)
3572 tag = r->tag;
3573 if (PF_RTABLEID_IS_VALID(r->rtableid))
3574 rtableid = r->rtableid;
3575 if (r->anchor == NULL) {
3576 rm = r;
3577 } else
3578 pf_step_into_anchor(&asd, &ruleset, rs_num,
3579 &r, NULL, NULL);
3580 }
3581 if (r == NULL)
3582 pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r,
3583 NULL, NULL);
3584 }
316670eb 3585 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid, NULL))
b0d623f7
A
3586 return (NULL);
3587 if (rm != NULL && (rm->action == PF_NONAT ||
3e170ce0
A
3588 rm->action == PF_NORDR || rm->action == PF_NOBINAT ||
3589 rm->action == PF_NONAT64))
b0d623f7
A
3590 return (NULL);
3591 return (rm);
3592}
3593
3e170ce0
A
3594/*
3595 * Get address translation information for NAT/BINAT/RDR
3596 * pd : pf packet descriptor
3597 * m : mbuf holding the packet
3598 * off : offset to protocol header
3599 * direction : direction of packet
3600 * kif : pf interface info obtained from the packet's recv interface
3601 * sn : source node pointer (output)
3602 * saddr : packet source address
3603 * sxport : packet source port
3604 * daddr : packet destination address
3605 * dxport : packet destination port
3606 * nsxport : translated source port (output)
3607 *
3608 * Translated source & destination address are updated in pd->nsaddr &
3609 * pd->ndaddr
3610 */
b0d623f7
A
3611static struct pf_rule *
3612pf_get_translation_aux(struct pf_pdesc *pd, struct mbuf *m, int off,
3613 int direction, struct pfi_kif *kif, struct pf_src_node **sn,
3614 struct pf_addr *saddr, union pf_state_xport *sxport, struct pf_addr *daddr,
3e170ce0 3615 union pf_state_xport *dxport, union pf_state_xport *nsxport)
b0d623f7
A
3616{
3617 struct pf_rule *r = NULL;
3e170ce0 3618 pd->naf = pd->af;
b0d623f7 3619
b0d623f7
A
3620 if (direction == PF_OUT) {
3621 r = pf_match_translation(pd, m, off, direction, kif, saddr,
3622 sxport, daddr, dxport, PF_RULESET_BINAT);
3623 if (r == NULL)
3624 r = pf_match_translation(pd, m, off, direction, kif,
3625 saddr, sxport, daddr, dxport, PF_RULESET_RDR);
3626 if (r == NULL)
3627 r = pf_match_translation(pd, m, off, direction, kif,
3628 saddr, sxport, daddr, dxport, PF_RULESET_NAT);
3629 } else {
3630 r = pf_match_translation(pd, m, off, direction, kif, saddr,
3631 sxport, daddr, dxport, PF_RULESET_RDR);
3632 if (r == NULL)
3633 r = pf_match_translation(pd, m, off, direction, kif,
3634 saddr, sxport, daddr, dxport, PF_RULESET_BINAT);
3635 }
b0d623f7
A
3636
3637 if (r != NULL) {
3e170ce0
A
3638 struct pf_addr *nsaddr = &pd->naddr;
3639 struct pf_addr *ndaddr = &pd->ndaddr;
3640
3641 *nsaddr = *saddr;
3642 *ndaddr = *daddr;
3643
b0d623f7
A
3644 switch (r->action) {
3645 case PF_NONAT:
3e170ce0 3646 case PF_NONAT64:
b0d623f7
A
3647 case PF_NOBINAT:
3648 case PF_NORDR:
3649 return (NULL);
3650 case PF_NAT:
3e170ce0
A
3651 case PF_NAT64:
3652 /*
3653 * we do NAT64 on incoming path and we call ip_input
3654 * which asserts receive interface to be not NULL.
3655 * The below check is to prevent NAT64 action on any
3656 * packet generated by local entity using synthesized
3657 * IPv6 address.
3658 */
3659 if ((r->action == PF_NAT64) && (direction == PF_OUT))
3660 return (NULL);
3661
b0d623f7 3662 if (pf_get_sport(pd, kif, r, saddr, sxport, daddr,
3e170ce0 3663 dxport, nsaddr, nsxport, sn)) {
b0d623f7
A
3664 DPFPRINTF(PF_DEBUG_MISC,
3665 ("pf: NAT proxy port allocation "
3666 "(%u-%u) failed\n",
3667 r->rpool.proxy_port[0],
3668 r->rpool.proxy_port[1]));
3669 return (NULL);
3670 }
3e170ce0
A
3671 /*
3672 * For NAT64 the destination IPv4 address is derived
3673 * from the last 32 bits of synthesized IPv6 address
3674 */
3675 if (r->action == PF_NAT64) {
3676 ndaddr->v4.s_addr = daddr->addr32[3];
3677 pd->naf = AF_INET;
3678 }
b0d623f7
A
3679 break;
3680 case PF_BINAT:
3681 switch (direction) {
3682 case PF_OUT:
3683 if (r->rpool.cur->addr.type ==
3684 PF_ADDR_DYNIFTL) {
39236c6e
A
3685 if (r->rpool.cur->addr.p.dyn == NULL)
3686 return (NULL);
b0d623f7
A
3687 switch (pd->af) {
3688#if INET
3689 case AF_INET:
3690 if (r->rpool.cur->addr.p.dyn->
3691 pfid_acnt4 < 1)
3692 return (NULL);
3e170ce0 3693 PF_POOLMASK(nsaddr,
b0d623f7
A
3694 &r->rpool.cur->addr.p.dyn->
3695 pfid_addr4,
3696 &r->rpool.cur->addr.p.dyn->
3697 pfid_mask4,
3698 saddr, AF_INET);
3699 break;
3700#endif /* INET */
3701#if INET6
3702 case AF_INET6:
3703 if (r->rpool.cur->addr.p.dyn->
3704 pfid_acnt6 < 1)
3705 return (NULL);
3e170ce0 3706 PF_POOLMASK(nsaddr,
b0d623f7
A
3707 &r->rpool.cur->addr.p.dyn->
3708 pfid_addr6,
3709 &r->rpool.cur->addr.p.dyn->
3710 pfid_mask6,
3711 saddr, AF_INET6);
3712 break;
3713#endif /* INET6 */
3714 }
3715 } else {
3e170ce0 3716 PF_POOLMASK(nsaddr,
b0d623f7
A
3717 &r->rpool.cur->addr.v.a.addr,
3718 &r->rpool.cur->addr.v.a.mask,
3719 saddr, pd->af);
3720 }
3721 break;
3722 case PF_IN:
3723 if (r->src.addr.type == PF_ADDR_DYNIFTL) {
39236c6e
A
3724 if (r->src.addr.p.dyn == NULL)
3725 return (NULL);
b0d623f7
A
3726 switch (pd->af) {
3727#if INET
3728 case AF_INET:
3729 if (r->src.addr.p.dyn->
3730 pfid_acnt4 < 1)
3731 return (NULL);
3e170ce0 3732 PF_POOLMASK(ndaddr,
b0d623f7
A
3733 &r->src.addr.p.dyn->
3734 pfid_addr4,
3735 &r->src.addr.p.dyn->
3736 pfid_mask4,
3737 daddr, AF_INET);
3738 break;
3739#endif /* INET */
3740#if INET6
3741 case AF_INET6:
3742 if (r->src.addr.p.dyn->
3743 pfid_acnt6 < 1)
3744 return (NULL);
3e170ce0 3745 PF_POOLMASK(ndaddr,
b0d623f7
A
3746 &r->src.addr.p.dyn->
3747 pfid_addr6,
3748 &r->src.addr.p.dyn->
3749 pfid_mask6,
3750 daddr, AF_INET6);
3751 break;
3752#endif /* INET6 */
3753 }
3754 } else
3e170ce0 3755 PF_POOLMASK(ndaddr,
b0d623f7
A
3756 &r->src.addr.v.a.addr,
3757 &r->src.addr.v.a.mask, daddr,
3758 pd->af);
3759 break;
3760 }
3761 break;
3762 case PF_RDR: {
b0d623f7
A
3763 switch (direction) {
3764 case PF_OUT:
3765 if (r->dst.addr.type == PF_ADDR_DYNIFTL) {
39236c6e
A
3766 if (r->dst.addr.p.dyn == NULL)
3767 return (NULL);
b0d623f7
A
3768 switch (pd->af) {
3769#if INET
3770 case AF_INET:
3771 if (r->dst.addr.p.dyn->
3772 pfid_acnt4 < 1)
3773 return (NULL);
3e170ce0 3774 PF_POOLMASK(nsaddr,
b0d623f7
A
3775 &r->dst.addr.p.dyn->
3776 pfid_addr4,
3777 &r->dst.addr.p.dyn->
3778 pfid_mask4,
3779 daddr, AF_INET);
3780 break;
3781#endif /* INET */
3782#if INET6
3783 case AF_INET6:
3784 if (r->dst.addr.p.dyn->
3785 pfid_acnt6 < 1)
3786 return (NULL);
3e170ce0 3787 PF_POOLMASK(nsaddr,
b0d623f7
A
3788 &r->dst.addr.p.dyn->
3789 pfid_addr6,
3790 &r->dst.addr.p.dyn->
3791 pfid_mask6,
3792 daddr, AF_INET6);
3793 break;
3794#endif /* INET6 */
3795 }
3796 } else {
3e170ce0 3797 PF_POOLMASK(nsaddr,
b0d623f7
A
3798 &r->dst.addr.v.a.addr,
3799 &r->dst.addr.v.a.mask,
3800 daddr, pd->af);
3801 }
3e170ce0
A
3802 if (nsxport && r->dst.xport.range.port[0])
3803 nsxport->port =
d1ecb069 3804 r->dst.xport.range.port[0];
b0d623f7
A
3805 break;
3806 case PF_IN:
3807 if (pf_map_addr(pd->af, r, saddr,
3e170ce0 3808 ndaddr, NULL, sn))
b0d623f7
A
3809 return (NULL);
3810 if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
3811 PF_POOL_BITMASK)
3e170ce0 3812 PF_POOLMASK(ndaddr, ndaddr,
b0d623f7
A
3813 &r->rpool.cur->addr.v.a.mask, daddr,
3814 pd->af);
3815
3e170ce0 3816 if (nsxport && dxport) {
b0d623f7
A
3817 if (r->rpool.proxy_port[1]) {
3818 u_int32_t tmp_nport;
3819
3820 tmp_nport =
3821 ((ntohs(dxport->port) -
3822 ntohs(r->dst.xport.range.
3823 port[0])) %
3824 (r->rpool.proxy_port[1] -
3825 r->rpool.proxy_port[0] +
3826 1)) + r->rpool.proxy_port[0];
3827
3828 /* wrap around if necessary */
3829 if (tmp_nport > 65535)
3830 tmp_nport -= 65535;
3e170ce0 3831 nsxport->port =
b0d623f7
A
3832 htons((u_int16_t)tmp_nport);
3833 } else if (r->rpool.proxy_port[0]) {
3e170ce0 3834 nsxport->port = htons(r->rpool.
b0d623f7
A
3835 proxy_port[0]);
3836 }
3837 }
3838 break;
3839 }
b0d623f7
A
3840 break;
3841 }
3842 default:
3843 return (NULL);
3844 }
3845 }
3846
3847 return (r);
3848}
3849
3850int
3851pf_socket_lookup(int direction, struct pf_pdesc *pd)
3852{
3853 struct pf_addr *saddr, *daddr;
3854 u_int16_t sport, dport;
6d2010ae
A
3855 struct inpcbinfo *pi;
3856 int inp = 0;
b0d623f7
A
3857
3858 if (pd == NULL)
3859 return (-1);
3860 pd->lookup.uid = UID_MAX;
3861 pd->lookup.gid = GID_MAX;
3862 pd->lookup.pid = NO_PID;
3863
3864 switch (pd->proto) {
3865 case IPPROTO_TCP:
3866 if (pd->hdr.tcp == NULL)
3867 return (-1);
3868 sport = pd->hdr.tcp->th_sport;
3869 dport = pd->hdr.tcp->th_dport;
3870 pi = &tcbinfo;
3871 break;
3872 case IPPROTO_UDP:
3873 if (pd->hdr.udp == NULL)
3874 return (-1);
3875 sport = pd->hdr.udp->uh_sport;
3876 dport = pd->hdr.udp->uh_dport;
3877 pi = &udbinfo;
3878 break;
3879 default:
3880 return (-1);
3881 }
3882 if (direction == PF_IN) {
3883 saddr = pd->src;
3884 daddr = pd->dst;
3885 } else {
3886 u_int16_t p;
3887
3888 p = sport;
3889 sport = dport;
3890 dport = p;
3891 saddr = pd->dst;
3892 daddr = pd->src;
3893 }
3894 switch (pd->af) {
3895#if INET
3896 case AF_INET:
6d2010ae
A
3897 inp = in_pcblookup_hash_exists(pi, saddr->v4, sport, daddr->v4, dport,
3898 0, &pd->lookup.uid, &pd->lookup.gid, NULL);
b7266188 3899#if INET6
6d2010ae 3900 if (inp == 0) {
b7266188
A
3901 struct in6_addr s6, d6;
3902
3903 memset(&s6, 0, sizeof (s6));
3904 s6.s6_addr16[5] = htons(0xffff);
3905 memcpy(&s6.s6_addr32[3], &saddr->v4,
3906 sizeof (saddr->v4));
3907
3908 memset(&d6, 0, sizeof (d6));
3909 d6.s6_addr16[5] = htons(0xffff);
3910 memcpy(&d6.s6_addr32[3], &daddr->v4,
3911 sizeof (daddr->v4));
3912
6d2010ae
A
3913 inp = in6_pcblookup_hash_exists(pi, &s6, sport,
3914 &d6, dport, 0, &pd->lookup.uid, &pd->lookup.gid, NULL);
3915 if (inp == 0) {
3916 inp = in_pcblookup_hash_exists(pi, saddr->v4, sport,
3917 daddr->v4, dport, INPLOOKUP_WILDCARD, &pd->lookup.uid, &pd->lookup.gid, NULL);
3918 if (inp == 0) {
3919 inp = in6_pcblookup_hash_exists(pi, &s6, sport,
b7266188 3920 &d6, dport, INPLOOKUP_WILDCARD,
6d2010ae
A
3921 &pd->lookup.uid, &pd->lookup.gid, NULL);
3922 if (inp == 0)
b7266188
A
3923 return (-1);
3924 }
3925 }
3926 }
3927#else
6d2010ae
A
3928 if (inp == 0) {
3929 inp = in_pcblookup_hash_exists(pi, saddr->v4, sport,
3930 daddr->v4, dport, INPLOOKUP_WILDCARD,
3931 &pd->lookup.uid, &pd->lookup.gid, NULL);
3932 if (inp == 0)
b0d623f7
A
3933 return (-1);
3934 }
b7266188 3935#endif /* !INET6 */
b0d623f7
A
3936 break;
3937#endif /* INET */
3938#if INET6
3939 case AF_INET6:
6d2010ae
A
3940 inp = in6_pcblookup_hash_exists(pi, &saddr->v6, sport, &daddr->v6,
3941 dport, 0, &pd->lookup.uid, &pd->lookup.gid, NULL);
3942 if (inp == 0) {
3943 inp = in6_pcblookup_hash_exists(pi, &saddr->v6, sport,
3944 &daddr->v6, dport, INPLOOKUP_WILDCARD,
3945 &pd->lookup.uid, &pd->lookup.gid, NULL);
3946 if (inp == 0)
b0d623f7
A
3947 return (-1);
3948 }
3949 break;
3950#endif /* INET6 */
6d2010ae 3951
b0d623f7
A
3952 default:
3953 return (-1);
3954 }
3955
b0d623f7
A
3956 return (1);
3957}
3958
3959static u_int8_t
3960pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
3961{
3962 int hlen;
3963 u_int8_t hdr[60];
3964 u_int8_t *opt, optlen;
3965 u_int8_t wscale = 0;
3966
3967 hlen = th_off << 2; /* hlen <= sizeof (hdr) */
3968 if (hlen <= (int)sizeof (struct tcphdr))
3969 return (0);
3970 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
3971 return (0);
3972 opt = hdr + sizeof (struct tcphdr);
3973 hlen -= sizeof (struct tcphdr);
3974 while (hlen >= 3) {
3975 switch (*opt) {
3976 case TCPOPT_EOL:
3977 case TCPOPT_NOP:
3978 ++opt;
3979 --hlen;
3980 break;
3981 case TCPOPT_WINDOW:
3982 wscale = opt[2];
3983 if (wscale > TCP_MAX_WINSHIFT)
3984 wscale = TCP_MAX_WINSHIFT;
3985 wscale |= PF_WSCALE_FLAG;
3986 /* FALLTHROUGH */
3987 default:
3988 optlen = opt[1];
3989 if (optlen < 2)
3990 optlen = 2;
3991 hlen -= optlen;
3992 opt += optlen;
3993 break;
3994 }
3995 }
3996 return (wscale);
3997}
3998
3999static u_int16_t
4000pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
4001{
4002 int hlen;
4003 u_int8_t hdr[60];
4004 u_int8_t *opt, optlen;
4005 u_int16_t mss = tcp_mssdflt;
4006
4007 hlen = th_off << 2; /* hlen <= sizeof (hdr) */
4008 if (hlen <= (int)sizeof (struct tcphdr))
4009 return (0);
4010 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
4011 return (0);
4012 opt = hdr + sizeof (struct tcphdr);
4013 hlen -= sizeof (struct tcphdr);
4014 while (hlen >= TCPOLEN_MAXSEG) {
4015 switch (*opt) {
4016 case TCPOPT_EOL:
4017 case TCPOPT_NOP:
4018 ++opt;
4019 --hlen;
4020 break;
4021 case TCPOPT_MAXSEG:
4022 bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2);
4023#if BYTE_ORDER != BIG_ENDIAN
4024 NTOHS(mss);
4025#endif
4026 /* FALLTHROUGH */
4027 default:
4028 optlen = opt[1];
4029 if (optlen < 2)
4030 optlen = 2;
4031 hlen -= optlen;
4032 opt += optlen;
4033 break;
4034 }
4035 }
4036 return (mss);
4037}
4038
4039static u_int16_t
4040pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer)
4041{
4042#if INET
4043 struct sockaddr_in *dst;
4044 struct route ro;
4045#endif /* INET */
4046#if INET6
4047 struct sockaddr_in6 *dst6;
4048 struct route_in6 ro6;
4049#endif /* INET6 */
4050 struct rtentry *rt = NULL;
4051 int hlen;
4052 u_int16_t mss = tcp_mssdflt;
4053
4054 switch (af) {
4055#if INET
4056 case AF_INET:
4057 hlen = sizeof (struct ip);
4058 bzero(&ro, sizeof (ro));
316670eb 4059 dst = (struct sockaddr_in *)(void *)&ro.ro_dst;
b0d623f7
A
4060 dst->sin_family = AF_INET;
4061 dst->sin_len = sizeof (*dst);
4062 dst->sin_addr = addr->v4;
4063 rtalloc(&ro);
4064 rt = ro.ro_rt;
4065 break;
4066#endif /* INET */
4067#if INET6
4068 case AF_INET6:
4069 hlen = sizeof (struct ip6_hdr);
4070 bzero(&ro6, sizeof (ro6));
316670eb 4071 dst6 = (struct sockaddr_in6 *)(void *)&ro6.ro_dst;
b0d623f7
A
4072 dst6->sin6_family = AF_INET6;
4073 dst6->sin6_len = sizeof (*dst6);
4074 dst6->sin6_addr = addr->v6;
4075 rtalloc((struct route *)&ro);
4076 rt = ro6.ro_rt;
4077 break;
4078#endif /* INET6 */
4079 default:
4080 panic("pf_calc_mss: not AF_INET or AF_INET6!");
4081 return (0);
4082 }
4083
4084 if (rt && rt->rt_ifp) {
4085 mss = rt->rt_ifp->if_mtu - hlen - sizeof (struct tcphdr);
4086 mss = max(tcp_mssdflt, mss);
39236c6e 4087 rtfree(rt);
b0d623f7
A
4088 }
4089 mss = min(mss, offer);
4090 mss = max(mss, 64); /* sanity - at least max opt space */
4091 return (mss);
4092}
4093
4094static void
3e170ce0 4095pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr, sa_family_t af)
b0d623f7
A
4096{
4097 struct pf_rule *r = s->rule.ptr;
4098
4099 s->rt_kif = NULL;
3e170ce0 4100
b0d623f7
A
4101 if (!r->rt || r->rt == PF_FASTROUTE)
4102 return;
3e170ce0
A
4103 if ((af == AF_INET) || (af == AF_INET6)) {
4104 pf_map_addr(af, r, saddr, &s->rt_addr, NULL,
b0d623f7
A
4105 &s->nat_src_node);
4106 s->rt_kif = r->rpool.cur->kif;
b0d623f7 4107 }
3e170ce0
A
4108
4109 return;
b0d623f7
A
4110}
4111
4112static void
4113pf_attach_state(struct pf_state_key *sk, struct pf_state *s, int tail)
4114{
4115 s->state_key = sk;
4116 sk->refcnt++;
4117
4118 /* list is sorted, if-bound states before floating */
4119 if (tail)
4120 TAILQ_INSERT_TAIL(&sk->states, s, next);
4121 else
4122 TAILQ_INSERT_HEAD(&sk->states, s, next);
4123}
4124
4125static void
4126pf_detach_state(struct pf_state *s, int flags)
4127{
4128 struct pf_state_key *sk = s->state_key;
4129
4130 if (sk == NULL)
4131 return;
4132
4133 s->state_key = NULL;
4134 TAILQ_REMOVE(&sk->states, s, next);
4135 if (--sk->refcnt == 0) {
4136 if (!(flags & PF_DT_SKIP_EXTGWY))
4137 RB_REMOVE(pf_state_tree_ext_gwy,
4138 &pf_statetbl_ext_gwy, sk);
4139 if (!(flags & PF_DT_SKIP_LANEXT))
4140 RB_REMOVE(pf_state_tree_lan_ext,
4141 &pf_statetbl_lan_ext, sk);
b0d623f7
A
4142 if (sk->app_state)
4143 pool_put(&pf_app_state_pl, sk->app_state);
b0d623f7
A
4144 pool_put(&pf_state_key_pl, sk);
4145 }
4146}
4147
4148struct pf_state_key *
316670eb 4149pf_alloc_state_key(struct pf_state *s, struct pf_state_key *psk)
b0d623f7
A
4150{
4151 struct pf_state_key *sk;
4152
4153 if ((sk = pool_get(&pf_state_key_pl, PR_WAITOK)) == NULL)
4154 return (NULL);
4155 bzero(sk, sizeof (*sk));
4156 TAILQ_INIT(&sk->states);
4157 pf_attach_state(sk, s, 0);
4158
316670eb
A
4159 /* initialize state key from psk, if provided */
4160 if (psk != NULL) {
4161 bcopy(&psk->lan, &sk->lan, sizeof (sk->lan));
4162 bcopy(&psk->gwy, &sk->gwy, sizeof (sk->gwy));
3e170ce0
A
4163 bcopy(&psk->ext_lan, &sk->ext_lan, sizeof (sk->ext_lan));
4164 bcopy(&psk->ext_gwy, &sk->ext_gwy, sizeof (sk->ext_gwy));
4165 sk->af_lan = psk->af_lan;
4166 sk->af_gwy = psk->af_gwy;
316670eb
A
4167 sk->proto = psk->proto;
4168 sk->direction = psk->direction;
4169 sk->proto_variant = psk->proto_variant;
4170 VERIFY(psk->app_state == NULL);
39236c6e 4171 sk->flowsrc = psk->flowsrc;
316670eb
A
4172 sk->flowhash = psk->flowhash;
4173 /* don't touch tree entries, states and refcnt on sk */
4174 }
4175
b0d623f7
A
4176 return (sk);
4177}
4178
4179static u_int32_t
4180pf_tcp_iss(struct pf_pdesc *pd)
4181{
4182 MD5_CTX ctx;
4183 u_int32_t digest[4];
4184
4185 if (pf_tcp_secret_init == 0) {
4186 read_random(pf_tcp_secret, sizeof (pf_tcp_secret));
4187 MD5Init(&pf_tcp_secret_ctx);
4188 MD5Update(&pf_tcp_secret_ctx, pf_tcp_secret,
4189 sizeof (pf_tcp_secret));
4190 pf_tcp_secret_init = 1;
4191 }
4192 ctx = pf_tcp_secret_ctx;
4193
4194 MD5Update(&ctx, (char *)&pd->hdr.tcp->th_sport, sizeof (u_short));
4195 MD5Update(&ctx, (char *)&pd->hdr.tcp->th_dport, sizeof (u_short));
4196 if (pd->af == AF_INET6) {
4197 MD5Update(&ctx, (char *)&pd->src->v6, sizeof (struct in6_addr));
4198 MD5Update(&ctx, (char *)&pd->dst->v6, sizeof (struct in6_addr));
4199 } else {
4200 MD5Update(&ctx, (char *)&pd->src->v4, sizeof (struct in_addr));
4201 MD5Update(&ctx, (char *)&pd->dst->v4, sizeof (struct in_addr));
4202 }
4203 MD5Final((u_char *)digest, &ctx);
4204 pf_tcp_iss_off += 4096;
4205 return (digest[0] + random() + pf_tcp_iss_off);
4206}
4207
3e170ce0
A
4208/*
4209 * This routine is called to perform address family translation on the
4210 * inner IP header (that may come as payload) of an ICMP(v4/6) error
4211 * response.
4212 */
4213static int
4214pf_change_icmp_af(struct mbuf *m, int off,
4215 struct pf_pdesc *pd, struct pf_pdesc *pd2, struct pf_addr *src,
4216 struct pf_addr *dst, sa_family_t af, sa_family_t naf)
4217{
4218 struct mbuf *n = NULL;
4219 struct ip *ip4 = NULL;
4220 struct ip6_hdr *ip6 = NULL;
4221 int hlen, olen, mlen;
4222
4223 if (af == naf || (af != AF_INET && af != AF_INET6) ||
4224 (naf != AF_INET && naf != AF_INET6))
4225 return (-1);
4226
4227 /* split the mbuf chain on the inner ip/ip6 header boundary */
4228 if ((n = m_split(m, off, M_DONTWAIT)) == NULL)
4229 return (-1);
4230
4231 /* old header */
4232 olen = pd2->off - off;
4233 /* new header */
4234 hlen = naf == AF_INET ? sizeof(*ip4) : sizeof(*ip6);
4235
4236 /* trim old header */
4237 m_adj(n, olen);
4238
4239 /* prepend a new one */
4240 if (M_PREPEND(n, hlen, M_DONTWAIT, 0) == NULL)
4241 return (-1);
4242
4243 /* translate inner ip/ip6 header */
4244 switch (naf) {
4245 case AF_INET:
4246 ip4 = mtod(n, struct ip *);
4247 bzero(ip4, sizeof(*ip4));
4248 ip4->ip_v = IPVERSION;
4249 ip4->ip_hl = sizeof(*ip4) >> 2;
4250 ip4->ip_len = htons(sizeof(*ip4) + pd2->tot_len - olen);
4251 ip4->ip_id = htons(ip_randomid());
4252 ip4->ip_off = htons(IP_DF);
4253 ip4->ip_ttl = pd2->ttl;
4254 if (pd2->proto == IPPROTO_ICMPV6)
4255 ip4->ip_p = IPPROTO_ICMP;
4256 else
4257 ip4->ip_p = pd2->proto;
4258 ip4->ip_src = src->v4;
4259 ip4->ip_dst = dst->v4;
4260 ip4->ip_sum = in_cksum(n, ip4->ip_hl << 2);
4261 break;
4262 case AF_INET6:
4263 ip6 = mtod(n, struct ip6_hdr *);
4264 bzero(ip6, sizeof(*ip6));
4265 ip6->ip6_vfc = IPV6_VERSION;
4266 ip6->ip6_plen = htons(pd2->tot_len - olen);
4267 if (pd2->proto == IPPROTO_ICMP)
4268 ip6->ip6_nxt = IPPROTO_ICMPV6;
4269 else
4270 ip6->ip6_nxt = pd2->proto;
4271 if (!pd2->ttl || pd2->ttl > IPV6_DEFHLIM)
4272 ip6->ip6_hlim = IPV6_DEFHLIM;
4273 else
4274 ip6->ip6_hlim = pd2->ttl;
4275 ip6->ip6_src = src->v6;
4276 ip6->ip6_dst = dst->v6;
4277 break;
4278 }
4279
4280 /* adjust payload offset and total packet length */
4281 pd2->off += hlen - olen;
4282 pd->tot_len += hlen - olen;
4283
4284 /* merge modified inner packet with the original header */
4285 mlen = n->m_pkthdr.len;
4286 m_cat(m, n);
4287 m->m_pkthdr.len += mlen;
4288
4289 return (0);
4290}
4291
4292#define PTR_IP(field) ((int32_t)offsetof(struct ip, field))
4293#define PTR_IP6(field) ((int32_t)offsetof(struct ip6_hdr, field))
4294
4295static int
4296pf_translate_icmp_af(int af, void *arg)
4297{
4298 struct icmp *icmp4;
4299 struct icmp6_hdr *icmp6;
4300 u_int32_t mtu;
4301 int32_t ptr = -1;
4302 u_int8_t type;
4303 u_int8_t code;
4304
4305 switch (af) {
4306 case AF_INET:
4307 icmp6 = arg;
4308 type = icmp6->icmp6_type;
4309 code = icmp6->icmp6_code;
4310 mtu = ntohl(icmp6->icmp6_mtu);
4311
4312 switch (type) {
4313 case ICMP6_ECHO_REQUEST:
4314 type = ICMP_ECHO;
4315 break;
4316 case ICMP6_ECHO_REPLY:
4317 type = ICMP_ECHOREPLY;
4318 break;
4319 case ICMP6_DST_UNREACH:
4320 type = ICMP_UNREACH;
4321 switch (code) {
4322 case ICMP6_DST_UNREACH_NOROUTE:
4323 case ICMP6_DST_UNREACH_BEYONDSCOPE:
4324 case ICMP6_DST_UNREACH_ADDR:
4325 code = ICMP_UNREACH_HOST;
4326 break;
4327 case ICMP6_DST_UNREACH_ADMIN:
4328 code = ICMP_UNREACH_HOST_PROHIB;
4329 break;
4330 case ICMP6_DST_UNREACH_NOPORT:
4331 code = ICMP_UNREACH_PORT;
4332 break;
4333 default:
4334 return (-1);
4335 }
4336 break;
4337 case ICMP6_PACKET_TOO_BIG:
4338 type = ICMP_UNREACH;
4339 code = ICMP_UNREACH_NEEDFRAG;
4340 mtu -= 20;
4341 break;
4342 case ICMP6_TIME_EXCEEDED:
4343 type = ICMP_TIMXCEED;
4344 break;
4345 case ICMP6_PARAM_PROB:
4346 switch (code) {
4347 case ICMP6_PARAMPROB_HEADER:
4348 type = ICMP_PARAMPROB;
4349 code = ICMP_PARAMPROB_ERRATPTR;
4350 ptr = ntohl(icmp6->icmp6_pptr);
4351
4352 if (ptr == PTR_IP6(ip6_vfc))
4353 ; /* preserve */
4354 else if (ptr == PTR_IP6(ip6_vfc) + 1)
4355 ptr = PTR_IP(ip_tos);
4356 else if (ptr == PTR_IP6(ip6_plen) ||
4357 ptr == PTR_IP6(ip6_plen) + 1)
4358 ptr = PTR_IP(ip_len);
4359 else if (ptr == PTR_IP6(ip6_nxt))
4360 ptr = PTR_IP(ip_p);
4361 else if (ptr == PTR_IP6(ip6_hlim))
4362 ptr = PTR_IP(ip_ttl);
4363 else if (ptr >= PTR_IP6(ip6_src) &&
4364 ptr < PTR_IP6(ip6_dst))
4365 ptr = PTR_IP(ip_src);
4366 else if (ptr >= PTR_IP6(ip6_dst) &&
4367 ptr < (int32_t)sizeof(struct ip6_hdr))
4368 ptr = PTR_IP(ip_dst);
4369 else {
4370 return (-1);
4371 }
4372 break;
4373 case ICMP6_PARAMPROB_NEXTHEADER:
4374 type = ICMP_UNREACH;
4375 code = ICMP_UNREACH_PROTOCOL;
4376 break;
4377 default:
4378 return (-1);
4379 }
4380 break;
4381 default:
4382 return (-1);
4383 }
4384 icmp6->icmp6_type = type;
4385 icmp6->icmp6_code = code;
4386 /* aligns well with a icmpv4 nextmtu */
4387 icmp6->icmp6_mtu = htonl(mtu);
4388 /* icmpv4 pptr is a one most significant byte */
4389 if (ptr >= 0)
4390 icmp6->icmp6_pptr = htonl(ptr << 24);
4391 break;
4392
4393 case AF_INET6:
4394 icmp4 = arg;
4395 type = icmp4->icmp_type;
4396 code = icmp4->icmp_code;
4397 mtu = ntohs(icmp4->icmp_nextmtu);
4398
4399 switch (type) {
4400 case ICMP_ECHO:
4401 type = ICMP6_ECHO_REQUEST;
4402 break;
4403 case ICMP_ECHOREPLY:
4404 type = ICMP6_ECHO_REPLY;
4405 break;
4406 case ICMP_UNREACH:
4407 type = ICMP6_DST_UNREACH;
4408 switch (code) {
4409 case ICMP_UNREACH_NET:
4410 case ICMP_UNREACH_HOST:
4411 case ICMP_UNREACH_NET_UNKNOWN:
4412 case ICMP_UNREACH_HOST_UNKNOWN:
4413 case ICMP_UNREACH_ISOLATED:
4414 case ICMP_UNREACH_TOSNET:
4415 case ICMP_UNREACH_TOSHOST:
4416 code = ICMP6_DST_UNREACH_NOROUTE;
4417 break;
4418 case ICMP_UNREACH_PORT:
4419 code = ICMP6_DST_UNREACH_NOPORT;
4420 break;
4421 case ICMP_UNREACH_NET_PROHIB:
4422 case ICMP_UNREACH_HOST_PROHIB:
4423 case ICMP_UNREACH_FILTER_PROHIB:
4424 case ICMP_UNREACH_PRECEDENCE_CUTOFF:
4425 code = ICMP6_DST_UNREACH_ADMIN;
4426 break;
4427 case ICMP_UNREACH_PROTOCOL:
4428 type = ICMP6_PARAM_PROB;
4429 code = ICMP6_PARAMPROB_NEXTHEADER;
4430 ptr = offsetof(struct ip6_hdr, ip6_nxt);
4431 break;
4432 case ICMP_UNREACH_NEEDFRAG:
4433 type = ICMP6_PACKET_TOO_BIG;
4434 code = 0;
4435 mtu += 20;
4436 break;
4437 default:
4438 return (-1);
4439 }
4440 break;
4441 case ICMP_TIMXCEED:
4442 type = ICMP6_TIME_EXCEEDED;
4443 break;
4444 case ICMP_PARAMPROB:
4445 type = ICMP6_PARAM_PROB;
4446 switch (code) {
4447 case ICMP_PARAMPROB_ERRATPTR:
4448 code = ICMP6_PARAMPROB_HEADER;
4449 break;
4450 case ICMP_PARAMPROB_LENGTH:
4451 code = ICMP6_PARAMPROB_HEADER;
4452 break;
4453 default:
4454 return (-1);
4455 }
4456
4457 ptr = icmp4->icmp_pptr;
4458 if (ptr == 0 || ptr == PTR_IP(ip_tos))
4459 ; /* preserve */
4460 else if (ptr == PTR_IP(ip_len) ||
4461 ptr == PTR_IP(ip_len) + 1)
4462 ptr = PTR_IP6(ip6_plen);
4463 else if (ptr == PTR_IP(ip_ttl))
4464 ptr = PTR_IP6(ip6_hlim);
4465 else if (ptr == PTR_IP(ip_p))
4466 ptr = PTR_IP6(ip6_nxt);
4467 else if (ptr >= PTR_IP(ip_src) &&
4468 ptr < PTR_IP(ip_dst))
4469 ptr = PTR_IP6(ip6_src);
4470 else if (ptr >= PTR_IP(ip_dst) &&
4471 ptr < (int32_t)sizeof(struct ip))
4472 ptr = PTR_IP6(ip6_dst);
4473 else {
4474 return (-1);
4475 }
4476 break;
4477 default:
4478 return (-1);
4479 }
4480 icmp4->icmp_type = type;
4481 icmp4->icmp_code = code;
4482 icmp4->icmp_nextmtu = htons(mtu);
4483 if (ptr >= 0)
4484 icmp4->icmp_void = htonl(ptr);
4485 break;
4486 }
4487
4488 return (0);
4489}
4490
4491static int
4492pf_nat64_ipv6(struct mbuf *m, int off, struct pf_pdesc *pd)
4493{
4494 struct ip *ip4;
4495
4496 /*
4497 * ip_input asserts for rcvif to be not NULL
4498 * That may not be true for two corner cases
4499 * 1. If for some reason a local app sends DNS
4500 * AAAA query to local host
4501 * 2. If IPv6 stack in kernel internally generates a
4502 * message destined for a synthesized IPv6 end-point.
4503 */
4504 if (m->m_pkthdr.rcvif == NULL)
4505 return (PF_DROP);
4506
4507 /* trim the old header */
4508 m_adj(m, off);
4509
4510 /* prepend the new one */
4511 if (M_PREPEND(m, sizeof(*ip4), M_DONTWAIT, 0) == NULL)
4512 return (PF_DROP);
4513
4514 ip4 = mtod(m, struct ip *);
4515 ip4->ip_v = 4;
4516 ip4->ip_hl = 5;
4517 ip4->ip_tos = pd->tos & htonl(0x0ff00000);
4518 ip4->ip_len = htons(sizeof(*ip4) + (pd->tot_len - off));
4519 ip4->ip_id = 0;
4520 ip4->ip_off = htons(IP_DF);
4521 ip4->ip_ttl = pd->ttl;
4522 ip4->ip_p = pd->proto;
4523 ip4->ip_sum = 0;
4524 ip4->ip_src = pd->naddr.v4;
4525 ip4->ip_dst = pd->ndaddr.v4;
4526 ip4->ip_sum = in_cksum(m, ip4->ip_hl << 2);
4527
4528 /* recalculate icmp checksums */
4529 if (pd->proto == IPPROTO_ICMP) {
4530 struct mbuf *mp;
4531 struct icmp *icmp;
4532 int moff, hlen = sizeof(*ip4);
4533
4534 if ((mp = m_pulldown(m, hlen, ICMP_MINLEN, &moff)) == NULL)
4535 return (PF_NAT64);
4536
4537 icmp = (struct icmp *)(void *)(mtod(mp, char *) + moff);
4538 icmp->icmp_cksum = 0;
4539 icmp->icmp_cksum = inet_cksum(m, 0, hlen,
4540 ntohs(ip4->ip_len) - hlen);
4541 }
4542
4543 ip_input(m);
4544 return (PF_NAT64);
4545}
4546
4547static int
4548pf_nat64_ipv4(struct mbuf *m, int off, struct pf_pdesc *pd)
4549{
4550 struct ip6_hdr *ip6;
4551
4552 if (m->m_pkthdr.rcvif == NULL)
4553 return (PF_DROP);
4554
4555 m_adj(m, off);
4556 if (M_PREPEND(m, sizeof(*ip6), M_DONTWAIT, 0) == NULL)
4557 return (PF_DROP);
4558
4559 ip6 = mtod(m, struct ip6_hdr *);
4560 ip6->ip6_vfc = htonl((6 << 28) | (pd->tos << 20));
4561 ip6->ip6_plen = htons(pd->tot_len - off);
4562 ip6->ip6_nxt = pd->proto;
4563 ip6->ip6_hlim = pd->ttl;
4564 ip6->ip6_src = pd->naddr.v6;
4565 ip6->ip6_dst = pd->ndaddr.v6;
4566
4567 /* recalculate icmp6 checksums */
4568 if (pd->proto == IPPROTO_ICMPV6) {
4569 struct mbuf *mp;
4570 struct icmp6_hdr *icmp6;
4571 int moff, hlen = sizeof(*ip6);
4572
4573 if ((mp = m_pulldown(m, hlen, sizeof(*icmp6), &moff)) == NULL)
4574 return (PF_NAT64);
4575
4576 icmp6 = (struct icmp6_hdr *)(void *)(mtod(mp, char *) + moff);
4577 icmp6->icmp6_cksum = 0;
4578 icmp6->icmp6_cksum = inet6_cksum(m, IPPROTO_ICMPV6, hlen,
4579 ntohs(ip6->ip6_plen));
4580 }
4581 ip6_input(m);
4582 return (PF_NAT64);
4583}
4584
b0d623f7
A
4585static int
4586pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
4587 struct pfi_kif *kif, struct mbuf *m, int off, void *h,
4588 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
4589 struct ifqueue *ifq)
4590{
4591#pragma unused(h)
4592 struct pf_rule *nr = NULL;
4593 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
b0d623f7
A
4594 sa_family_t af = pd->af;
4595 struct pf_rule *r, *a = NULL;
4596 struct pf_ruleset *ruleset = NULL;
4597 struct pf_src_node *nsn = NULL;
4598 struct tcphdr *th = pd->hdr.tcp;
3e170ce0 4599 struct udphdr *uh = pd->hdr.udp;
b0d623f7
A
4600 u_short reason;
4601 int rewrite = 0, hdrlen = 0;
4602 int tag = -1;
4603 unsigned int rtableid = IFSCOPE_NONE;
4604 int asd = 0;
4605 int match = 0;
4606 int state_icmp = 0;
4607 u_int16_t mss = tcp_mssdflt;
b0d623f7
A
4608 u_int8_t icmptype = 0, icmpcode = 0;
4609
b0d623f7 4610 struct pf_grev1_hdr *grev1 = pd->hdr.grev1;
3e170ce0 4611 union pf_state_xport bxport, bdxport, nxport, sxport, dxport;
316670eb 4612 struct pf_state_key psk;
b0d623f7
A
4613
4614 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
4615
4616 if (direction == PF_IN && pf_check_congestion(ifq)) {
4617 REASON_SET(&reason, PFRES_CONGEST);
4618 return (PF_DROP);
4619 }
4620
b0d623f7
A
4621 hdrlen = 0;
4622 sxport.spi = 0;
4623 dxport.spi = 0;
4624 nxport.spi = 0;
b0d623f7
A
4625
4626 switch (pd->proto) {
4627 case IPPROTO_TCP:
b0d623f7
A
4628 sxport.port = th->th_sport;
4629 dxport.port = th->th_dport;
b0d623f7
A
4630 hdrlen = sizeof (*th);
4631 break;
4632 case IPPROTO_UDP:
3e170ce0
A
4633 sxport.port = uh->uh_sport;
4634 dxport.port = uh->uh_dport;
4635 hdrlen = sizeof (*uh);
b0d623f7
A
4636 break;
4637#if INET
4638 case IPPROTO_ICMP:
4639 if (pd->af != AF_INET)
4640 break;
b0d623f7
A
4641 sxport.port = dxport.port = pd->hdr.icmp->icmp_id;
4642 hdrlen = ICMP_MINLEN;
b0d623f7
A
4643 icmptype = pd->hdr.icmp->icmp_type;
4644 icmpcode = pd->hdr.icmp->icmp_code;
4645
4646 if (icmptype == ICMP_UNREACH ||
4647 icmptype == ICMP_SOURCEQUENCH ||
4648 icmptype == ICMP_REDIRECT ||
4649 icmptype == ICMP_TIMXCEED ||
4650 icmptype == ICMP_PARAMPROB)
4651 state_icmp++;
4652 break;
4653#endif /* INET */
4654#if INET6
4655 case IPPROTO_ICMPV6:
4656 if (pd->af != AF_INET6)
4657 break;
b0d623f7 4658 sxport.port = dxport.port = pd->hdr.icmp6->icmp6_id;
b0d623f7
A
4659 hdrlen = sizeof (*pd->hdr.icmp6);
4660 icmptype = pd->hdr.icmp6->icmp6_type;
4661 icmpcode = pd->hdr.icmp6->icmp6_code;
4662
4663 if (icmptype == ICMP6_DST_UNREACH ||
4664 icmptype == ICMP6_PACKET_TOO_BIG ||
4665 icmptype == ICMP6_TIME_EXCEEDED ||
4666 icmptype == ICMP6_PARAM_PROB)
4667 state_icmp++;
4668 break;
4669#endif /* INET6 */
b0d623f7
A
4670 case IPPROTO_GRE:
4671 if (pd->proto_variant == PF_GRE_PPTP_VARIANT) {
4672 sxport.call_id = dxport.call_id =
4673 pd->hdr.grev1->call_id;
4674 hdrlen = sizeof (*pd->hdr.grev1);
4675 }
4676 break;
4677 case IPPROTO_ESP:
4678 sxport.spi = 0;
4679 dxport.spi = pd->hdr.esp->spi;
4680 hdrlen = sizeof (*pd->hdr.esp);
4681 break;
b0d623f7
A
4682 }
4683
4684 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
4685
3e170ce0
A
4686 bxport = sxport;
4687 bdxport = dxport;
4688
4689 if (direction == PF_OUT)
4690 nxport = sxport;
4691 else
4692 nxport = dxport;
4693
4694 /* check packet for BINAT/NAT/RDR */
4695 if ((nr = pf_get_translation_aux(pd, m, off, direction, kif, &nsn,
4696 saddr, &sxport, daddr, &dxport, &nxport)) !=
b0d623f7 4697 NULL) {
3e170ce0
A
4698 int ua;
4699 u_int16_t dport;
4700
4701 if (pd->af != pd->naf)
4702 ua = 0;
4703 else
4704 ua = 1;
4705
4706 PF_ACPY(&pd->baddr, saddr, af);
4707 PF_ACPY(&pd->bdaddr, daddr, af);
4708
4709 switch (pd->proto) {
4710 case IPPROTO_TCP:
4711 if (pd->af != pd->naf ||
4712 PF_ANEQ(saddr, &pd->naddr, pd->af)) {
b0d623f7 4713 pf_change_ap(direction, pd->mp, saddr,
3e170ce0
A
4714 &th->th_sport, pd->ip_sum, &th->th_sum,
4715 &pd->naddr, nxport.port, 0, af,
4716 pd->naf, ua);
b0d623f7 4717 sxport.port = th->th_sport;
3e170ce0
A
4718 }
4719
4720 if (pd->af != pd->naf ||
4721 PF_ANEQ(daddr, &pd->ndaddr, pd->af) ||
4722 (nr && (nr->action == PF_RDR) &&
4723 (th->th_dport != nxport.port))) {
4724 if (nr && nr->action == PF_RDR)
4725 dport = nxport.port;
4726 else
4727 dport = th->th_dport;
4728 pf_change_ap(direction, pd->mp, daddr,
4729 &th->th_dport, pd->ip_sum,
4730 &th->th_sum, &pd->ndaddr,
4731 dport, 0, af, pd->naf, ua);
4732 dxport.port = th->th_dport;
4733 }
4734 rewrite++;
4735 break;
4736
4737 case IPPROTO_UDP:
4738 if (pd->af != pd->naf ||
4739 PF_ANEQ(saddr, &pd->naddr, pd->af)) {
b0d623f7 4740 pf_change_ap(direction, pd->mp, saddr,
3e170ce0
A
4741 &uh->uh_sport, pd->ip_sum,
4742 &uh->uh_sum, &pd->naddr,
4743 nxport.port, 1, af, pd->naf, ua);
4744 sxport.port = uh->uh_sport;
4745 }
4746
4747 if (pd->af != pd->naf ||
4748 PF_ANEQ(daddr, &pd->ndaddr, pd->af) ||
4749 (nr && (nr->action == PF_RDR) &&
4750 (uh->uh_dport != nxport.port))) {
4751 if (nr && nr->action == PF_RDR)
4752 dport = nxport.port;
4753 else
4754 dport = uh->uh_dport;
4755 pf_change_ap(direction, pd->mp, daddr,
4756 &uh->uh_dport, pd->ip_sum,
4757 &uh->uh_sum, &pd->ndaddr,
4758 dport, 0, af, pd->naf, ua);
4759 dxport.port = uh->uh_dport;
4760 }
4761 rewrite++;
4762 break;
b0d623f7 4763#if INET
3e170ce0
A
4764 case IPPROTO_ICMP:
4765 if (pd->af != AF_INET)
b0d623f7 4766 break;
3e170ce0
A
4767 /*
4768 * TODO:
4769 * pd->af != pd->naf not handled yet here and would be
4770 * needed for NAT46 needed to support XLAT.
4771 * Will cross the bridge when it comes.
4772 */
4773 if (PF_ANEQ(saddr, &pd->naddr, pd->af)) {
4774 pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
4775 pd->naddr.v4.s_addr, 0);
4776 pd->hdr.icmp->icmp_cksum = pf_cksum_fixup(
4777 pd->hdr.icmp->icmp_cksum, sxport.port,
4778 nxport.port, 0);
4779 pd->hdr.icmp->icmp_id = nxport.port;
4780 }
4781
4782 if (PF_ANEQ(daddr, &pd->ndaddr, pd->af)) {
4783 pf_change_a(&daddr->v4.s_addr, pd->ip_sum,
4784 pd->ndaddr.v4.s_addr, 0);
4785 }
4786 ++rewrite;
4787 break;
b0d623f7
A
4788#endif /* INET */
4789#if INET6
3e170ce0
A
4790 case IPPROTO_ICMPV6:
4791 if (pd->af != AF_INET6)
b0d623f7 4792 break;
3e170ce0
A
4793
4794 if (pd->af != pd->naf ||
4795 PF_ANEQ(saddr, &pd->naddr, pd->af)) {
4796 pf_change_addr(saddr,
4797 &pd->hdr.icmp6->icmp6_cksum,
4798 &pd->naddr, 0, pd->af, pd->naf);
b0d623f7
A
4799 }
4800
3e170ce0
A
4801 if (pd->af != pd->naf ||
4802 PF_ANEQ(daddr, &pd->ndaddr, pd->af)) {
4803 pf_change_addr(daddr,
4804 &pd->hdr.icmp6->icmp6_cksum,
4805 &pd->ndaddr, 0, pd->af, pd->naf);
4806 }
4807
4808 if (pd->af != pd->naf) {
4809 if (pf_translate_icmp_af(AF_INET,
4810 pd->hdr.icmp6))
4811 return (PF_DROP);
4812 pd->proto = IPPROTO_ICMP;
4813 }
4814 rewrite++;
4815 break;
4816#endif /* INET */
4817 case IPPROTO_GRE:
4818 if ((direction == PF_IN) &&
4819 (pd->proto_variant == PF_GRE_PPTP_VARIANT))
4820 grev1->call_id = nxport.call_id;
4821
4822 switch (pd->af) {
b0d623f7 4823#if INET
3e170ce0
A
4824 case AF_INET:
4825 if (PF_ANEQ(saddr, &pd->naddr, pd->af)) {
4826 pf_change_a(&saddr->v4.s_addr,
4827 pd->ip_sum,
4828 pd->naddr.v4.s_addr, 0);
4829 }
4830 if (PF_ANEQ(daddr, &pd->ndaddr, pd->af)) {
4831 pf_change_a(&daddr->v4.s_addr,
4832 pd->ip_sum,
4833 pd->ndaddr.v4.s_addr, 0);
316670eb 4834 }
b0d623f7
A
4835 break;
4836#endif /* INET */
4837#if INET6
3e170ce0
A
4838 case AF_INET6:
4839 if (PF_ANEQ(saddr, &pd->naddr, pd->af))
4840 PF_ACPY(saddr, &pd->naddr, AF_INET6);
4841 if (PF_ANEQ(daddr, &pd->ndaddr, pd->af))
4842 PF_ACPY(daddr, &pd->ndaddr, AF_INET6);
b0d623f7
A
4843 break;
4844#endif /* INET6 */
3e170ce0
A
4845 }
4846 ++rewrite;
4847 break;
4848 case IPPROTO_ESP:
4849 if (direction == PF_OUT)
4850 bxport.spi = 0;
b0d623f7 4851
3e170ce0 4852 switch (pd->af) {
b0d623f7 4853#if INET
3e170ce0
A
4854 case AF_INET:
4855 if (PF_ANEQ(saddr, &pd->naddr, pd->af)) {
4856 pf_change_a(&saddr->v4.s_addr,
4857 pd->ip_sum, pd->naddr.v4.s_addr, 0);
4858 }
4859 if (PF_ANEQ(daddr, &pd->ndaddr, pd->af)) {
b0d623f7 4860 pf_change_a(&daddr->v4.s_addr,
3e170ce0
A
4861 pd->ip_sum,
4862 pd->ndaddr.v4.s_addr, 0);
b0d623f7 4863 }
b0d623f7 4864 break;
b0d623f7
A
4865#endif /* INET */
4866#if INET6
3e170ce0
A
4867 case AF_INET6:
4868 if (PF_ANEQ(saddr, &pd->naddr, pd->af))
4869 PF_ACPY(saddr, &pd->naddr, AF_INET6);
4870 if (PF_ANEQ(daddr, &pd->ndaddr, pd->af))
4871 PF_ACPY(daddr, &pd->ndaddr, AF_INET6);
4872 break;
b0d623f7 4873#endif /* INET6 */
3e170ce0
A
4874 }
4875 break;
4876 default:
4877 switch (pd->af) {
4878#if INET
4879 case AF_INET:
4880 if ((pd->naf != AF_INET) ||
4881 (PF_ANEQ(saddr, &pd->naddr, pd->af))) {
4882 pf_change_addr(saddr, pd->ip_sum,
4883 &pd->naddr, 0, af, pd->naf);
4884 }
4885
4886 if ((pd->naf != AF_INET) ||
4887 (PF_ANEQ(daddr, &pd->ndaddr, pd->af))) {
4888 pf_change_addr(daddr, pd->ip_sum,
4889 &pd->ndaddr, 0, af, pd->naf);
b0d623f7
A
4890 }
4891 break;
b0d623f7
A
4892#endif /* INET */
4893#if INET6
3e170ce0
A
4894 case AF_INET6:
4895 if (PF_ANEQ(saddr, &pd->naddr, pd->af))
4896 PF_ACPY(saddr, &pd->naddr, af);
4897 if (PF_ANEQ(daddr, &pd->ndaddr, pd->af))
4898 PF_ACPY(daddr, &pd->ndaddr, af);
b0d623f7 4899 break;
3e170ce0 4900#endif /* INET */
b0d623f7 4901 }
3e170ce0 4902 break;
b0d623f7 4903 }
3e170ce0
A
4904
4905 if (nr->natpass)
4906 r = NULL;
4907 pd->nat_rule = nr;
4908 pd->af = pd->naf;
b0d623f7
A
4909 }
4910
b0d623f7
A
4911 if (nr && nr->tag > 0)
4912 tag = nr->tag;
b0d623f7
A
4913
4914 while (r != NULL) {
4915 r->evaluations++;
4916 if (pfi_kif_match(r->kif, kif) == r->ifnot)
4917 r = r->skip[PF_SKIP_IFP].ptr;
4918 else if (r->direction && r->direction != direction)
4919 r = r->skip[PF_SKIP_DIR].ptr;
3e170ce0 4920 else if (r->af && r->af != pd->af)
b0d623f7
A
4921 r = r->skip[PF_SKIP_AF].ptr;
4922 else if (r->proto && r->proto != pd->proto)
4923 r = r->skip[PF_SKIP_PROTO].ptr;
3e170ce0 4924 else if (PF_MISMATCHAW(&r->src.addr, saddr, pd->af,
b0d623f7
A
4925 r->src.neg, kif))
4926 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
4927 /* tcp/udp only. port_op always 0 in other cases */
b0d623f7
A
4928 else if (r->proto == pd->proto &&
4929 (r->proto == IPPROTO_TCP || r->proto == IPPROTO_UDP) &&
4930 r->src.xport.range.op &&
4931 !pf_match_port(r->src.xport.range.op,
4932 r->src.xport.range.port[0], r->src.xport.range.port[1],
4933 th->th_sport))
b0d623f7 4934 r = r->skip[PF_SKIP_SRC_PORT].ptr;
3e170ce0 4935 else if (PF_MISMATCHAW(&r->dst.addr, daddr, pd->af,
b0d623f7
A
4936 r->dst.neg, NULL))
4937 r = r->skip[PF_SKIP_DST_ADDR].ptr;
4938 /* tcp/udp only. port_op always 0 in other cases */
b0d623f7
A
4939 else if (r->proto == pd->proto &&
4940 (r->proto == IPPROTO_TCP || r->proto == IPPROTO_UDP) &&
4941 r->dst.xport.range.op &&
4942 !pf_match_port(r->dst.xport.range.op,
4943 r->dst.xport.range.port[0], r->dst.xport.range.port[1],
4944 th->th_dport))
b0d623f7
A
4945 r = r->skip[PF_SKIP_DST_PORT].ptr;
4946 /* icmp only. type always 0 in other cases */
4947 else if (r->type && r->type != icmptype + 1)
4948 r = TAILQ_NEXT(r, entries);
4949 /* icmp only. type always 0 in other cases */
4950 else if (r->code && r->code != icmpcode + 1)
4951 r = TAILQ_NEXT(r, entries);
316670eb
A
4952 else if ((r->rule_flag & PFRULE_TOS) && r->tos &&
4953 !(r->tos & pd->tos))
4954 r = TAILQ_NEXT(r, entries);
4955 else if ((r->rule_flag & PFRULE_DSCP) && r->tos &&
4956 !(r->tos & (pd->tos & DSCP_MASK)))
4957 r = TAILQ_NEXT(r, entries);
4958 else if ((r->rule_flag & PFRULE_SC) && r->tos &&
4959 ((r->tos & SCIDX_MASK) != pd->sc))
b0d623f7
A
4960 r = TAILQ_NEXT(r, entries);
4961 else if (r->rule_flag & PFRULE_FRAGMENT)
4962 r = TAILQ_NEXT(r, entries);
4963 else if (pd->proto == IPPROTO_TCP &&
4964 (r->flagset & th->th_flags) != r->flags)
4965 r = TAILQ_NEXT(r, entries);
4966 /* tcp/udp only. uid.op always 0 in other cases */
4967 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done =
4968 pf_socket_lookup(direction, pd), 1)) &&
4969 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
4970 pd->lookup.uid))
4971 r = TAILQ_NEXT(r, entries);
4972 /* tcp/udp only. gid.op always 0 in other cases */
4973 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done =
4974 pf_socket_lookup(direction, pd), 1)) &&
4975 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
4976 pd->lookup.gid))
4977 r = TAILQ_NEXT(r, entries);
39236c6e 4978 else if (r->prob && r->prob <= (RandomULong() % (UINT_MAX - 1) + 1))
b0d623f7
A
4979 r = TAILQ_NEXT(r, entries);
4980 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
4981 r = TAILQ_NEXT(r, entries);
4982 else if (r->os_fingerprint != PF_OSFP_ANY &&
4983 (pd->proto != IPPROTO_TCP || !pf_osfp_match(
4984 pf_osfp_fingerprint(pd, m, off, th),
4985 r->os_fingerprint)))
4986 r = TAILQ_NEXT(r, entries);
4987 else {
4988 if (r->tag)
4989 tag = r->tag;
4990 if (PF_RTABLEID_IS_VALID(r->rtableid))
4991 rtableid = r->rtableid;
4992 if (r->anchor == NULL) {
4993 match = 1;
4994 *rm = r;
4995 *am = a;
4996 *rsm = ruleset;
4997 if ((*rm)->quick)
4998 break;
4999 r = TAILQ_NEXT(r, entries);
5000 } else
5001 pf_step_into_anchor(&asd, &ruleset,
5002 PF_RULESET_FILTER, &r, &a, &match);
5003 }
5004 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
5005 PF_RULESET_FILTER, &r, &a, &match))
5006 break;
5007 }
5008 r = *rm;
5009 a = *am;
5010 ruleset = *rsm;
5011
5012 REASON_SET(&reason, PFRES_MATCH);
5013
5014 if (r->log || (nr != NULL && nr->log)) {
b0d623f7
A
5015 if (rewrite > 0) {
5016 if (rewrite < off + hdrlen)
5017 rewrite = off + hdrlen;
5018
5019 m = pf_lazy_makewritable(pd, m, rewrite);
5020 if (!m) {
5021 REASON_SET(&reason, PFRES_MEMORY);
5022 return (PF_DROP);
5023 }
5024
5025 m_copyback(m, off, hdrlen, pd->hdr.any);
5026 }
3e170ce0
A
5027 PFLOG_PACKET(kif, h, m, pd->af, direction, reason,
5028 r->log ? r : nr, a, ruleset, pd);
b0d623f7
A
5029 }
5030
5031 if ((r->action == PF_DROP) &&
5032 ((r->rule_flag & PFRULE_RETURNRST) ||
5033 (r->rule_flag & PFRULE_RETURNICMP) ||
5034 (r->rule_flag & PFRULE_RETURN))) {
5035 /* undo NAT changes, if they have taken place */
3e170ce0
A
5036 /* XXX For NAT64 we are not reverting the changes */
5037 if (nr != NULL && nr->action != PF_NAT64) {
b0d623f7 5038 if (direction == PF_OUT) {
3e170ce0 5039 pd->af = af;
b0d623f7
A
5040 switch (pd->proto) {
5041 case IPPROTO_TCP:
b0d623f7
A
5042 pf_change_ap(direction, pd->mp, saddr,
5043 &th->th_sport, pd->ip_sum,
5044 &th->th_sum, &pd->baddr,
3e170ce0 5045 bxport.port, 0, af, pd->af, 1);
b0d623f7 5046 sxport.port = th->th_sport;
b0d623f7
A
5047 rewrite++;
5048 break;
5049 case IPPROTO_UDP:
b0d623f7
A
5050 pf_change_ap(direction, pd->mp, saddr,
5051 &pd->hdr.udp->uh_sport, pd->ip_sum,
5052 &pd->hdr.udp->uh_sum, &pd->baddr,
3e170ce0 5053 bxport.port, 1, af, pd->af, 1);
b0d623f7 5054 sxport.port = pd->hdr.udp->uh_sport;
b0d623f7
A
5055 rewrite++;
5056 break;
5057 case IPPROTO_ICMP:
5058#if INET6
5059 case IPPROTO_ICMPV6:
5060#endif
5061 /* nothing! */
5062 break;
b0d623f7
A
5063 case IPPROTO_GRE:
5064 PF_ACPY(&pd->baddr, saddr, af);
5065 ++rewrite;
5066 switch (af) {
5067#if INET
5068 case AF_INET:
5069 pf_change_a(&saddr->v4.s_addr,
5070 pd->ip_sum,
5071 pd->baddr.v4.s_addr, 0);
5072 break;
5073#endif /* INET */
5074#if INET6
5075 case AF_INET6:
5076 PF_ACPY(saddr, &pd->baddr,
5077 AF_INET6);
5078 break;
5079#endif /* INET6 */
5080 }
5081 break;
5082 case IPPROTO_ESP:
5083 PF_ACPY(&pd->baddr, saddr, af);
5084 switch (af) {
5085#if INET
5086 case AF_INET:
5087 pf_change_a(&saddr->v4.s_addr,
5088 pd->ip_sum,
5089 pd->baddr.v4.s_addr, 0);
5090 break;
5091#endif /* INET */
5092#if INET6
5093 case AF_INET6:
5094 PF_ACPY(saddr, &pd->baddr,
5095 AF_INET6);
5096 break;
5097#endif /* INET6 */
5098 }
5099 break;
b0d623f7
A
5100 default:
5101 switch (af) {
5102 case AF_INET:
5103 pf_change_a(&saddr->v4.s_addr,
5104 pd->ip_sum,
5105 pd->baddr.v4.s_addr, 0);
5106 break;
5107 case AF_INET6:
5108 PF_ACPY(saddr, &pd->baddr, af);
5109 break;
5110 }
5111 }
5112 } else {
5113 switch (pd->proto) {
5114 case IPPROTO_TCP:
b0d623f7
A
5115 pf_change_ap(direction, pd->mp, daddr,
5116 &th->th_dport, pd->ip_sum,
3e170ce0
A
5117 &th->th_sum, &pd->bdaddr,
5118 bdxport.port, 0, af, pd->af, 1);
b0d623f7 5119 dxport.port = th->th_dport;
b0d623f7
A
5120 rewrite++;
5121 break;
5122 case IPPROTO_UDP:
b0d623f7
A
5123 pf_change_ap(direction, pd->mp, daddr,
5124 &pd->hdr.udp->uh_dport, pd->ip_sum,
3e170ce0
A
5125 &pd->hdr.udp->uh_sum, &pd->bdaddr,
5126 bdxport.port, 1, af, pd->af, 1);
b0d623f7 5127 dxport.port = pd->hdr.udp->uh_dport;
b0d623f7
A
5128 rewrite++;
5129 break;
5130 case IPPROTO_ICMP:
5131#if INET6
5132 case IPPROTO_ICMPV6:
5133#endif
5134 /* nothing! */
5135 break;
b0d623f7
A
5136 case IPPROTO_GRE:
5137 if (pd->proto_variant ==
5138 PF_GRE_PPTP_VARIANT)
3e170ce0
A
5139 grev1->call_id =
5140 bdxport.call_id;
b0d623f7
A
5141 ++rewrite;
5142 switch (af) {
5143#if INET
5144 case AF_INET:
5145 pf_change_a(&daddr->v4.s_addr,
5146 pd->ip_sum,
3e170ce0 5147 pd->bdaddr.v4.s_addr, 0);
b0d623f7
A
5148 break;
5149#endif /* INET */
5150#if INET6
5151 case AF_INET6:
3e170ce0 5152 PF_ACPY(daddr, &pd->bdaddr,
b0d623f7
A
5153 AF_INET6);
5154 break;
5155#endif /* INET6 */
5156 }
5157 break;
5158 case IPPROTO_ESP:
5159 switch (af) {
5160#if INET
5161 case AF_INET:
5162 pf_change_a(&daddr->v4.s_addr,
5163 pd->ip_sum,
3e170ce0 5164 pd->bdaddr.v4.s_addr, 0);
b0d623f7
A
5165 break;
5166#endif /* INET */
5167#if INET6
5168 case AF_INET6:
3e170ce0 5169 PF_ACPY(daddr, &pd->bdaddr,
b0d623f7
A
5170 AF_INET6);
5171 break;
5172#endif /* INET6 */
5173 }
5174 break;
b0d623f7
A
5175 default:
5176 switch (af) {
5177 case AF_INET:
5178 pf_change_a(&daddr->v4.s_addr,
5179 pd->ip_sum,
3e170ce0 5180 pd->bdaddr.v4.s_addr, 0);
b0d623f7
A
5181 break;
5182#if INET6
5183 case AF_INET6:
3e170ce0 5184 PF_ACPY(daddr, &pd->bdaddr, af);
b0d623f7
A
5185 break;
5186#endif /* INET6 */
5187 }
5188 }
5189 }
5190 }
5191 if (pd->proto == IPPROTO_TCP &&
5192 ((r->rule_flag & PFRULE_RETURNRST) ||
5193 (r->rule_flag & PFRULE_RETURN)) &&
5194 !(th->th_flags & TH_RST)) {
5195 u_int32_t ack = ntohl(th->th_seq) + pd->p_len;
5196 int len = 0;
5197 struct ip *h4;
5198#if INET6
5199 struct ip6_hdr *h6;
5200#endif /* INET6 */
5201
3e170ce0 5202 switch (pd->af) {
b0d623f7
A
5203 case AF_INET:
5204 h4 = mtod(m, struct ip *);
5205 len = ntohs(h4->ip_len) - off;
5206 break;
5207#if INET6
5208 case AF_INET6:
5209 h6 = mtod(m, struct ip6_hdr *);
5210 len = ntohs(h6->ip6_plen) -
5211 (off - sizeof (*h6));
5212 break;
5213#endif /* INET6 */
5214 }
5215
3e170ce0
A
5216 if (pf_check_proto_cksum(m, off, len, IPPROTO_TCP,
5217 pd->af))
b0d623f7
A
5218 REASON_SET(&reason, PFRES_PROTCKSUM);
5219 else {
5220 if (th->th_flags & TH_SYN)
5221 ack++;
5222 if (th->th_flags & TH_FIN)
5223 ack++;
3e170ce0 5224 pf_send_tcp(r, pd->af, pd->dst,
b0d623f7
A
5225 pd->src, th->th_dport, th->th_sport,
5226 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
5227 r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp);
5228 }
3e170ce0 5229 } else if (pd->proto != IPPROTO_ICMP && pd->af == AF_INET &&
b0d623f7 5230 pd->proto != IPPROTO_ESP && pd->proto != IPPROTO_AH &&
b0d623f7
A
5231 r->return_icmp)
5232 pf_send_icmp(m, r->return_icmp >> 8,
3e170ce0 5233 r->return_icmp & 255, pd->af, r);
b0d623f7 5234 else if (pd->proto != IPPROTO_ICMPV6 && af == AF_INET6 &&
b0d623f7 5235 pd->proto != IPPROTO_ESP && pd->proto != IPPROTO_AH &&
b0d623f7
A
5236 r->return_icmp6)
5237 pf_send_icmp(m, r->return_icmp6 >> 8,
3e170ce0 5238 r->return_icmp6 & 255, pd->af, r);
b0d623f7
A
5239 }
5240
5241 if (r->action == PF_DROP)
5242 return (PF_DROP);
5243
316670eb
A
5244 /* prepare state key, for flowhash and/or the state (if created) */
5245 bzero(&psk, sizeof (psk));
5246 psk.proto = pd->proto;
5247 psk.direction = direction;
316670eb
A
5248 if (pd->proto == IPPROTO_UDP) {
5249 if (ntohs(pd->hdr.udp->uh_sport) == PF_IKE_PORT &&
5250 ntohs(pd->hdr.udp->uh_dport) == PF_IKE_PORT) {
5251 psk.proto_variant = PF_EXTFILTER_APD;
5252 } else {
5253 psk.proto_variant = nr ? nr->extfilter : r->extfilter;
5254 if (psk.proto_variant < PF_EXTFILTER_APD)
5255 psk.proto_variant = PF_EXTFILTER_APD;
5256 }
5257 } else if (pd->proto == IPPROTO_GRE) {
5258 psk.proto_variant = pd->proto_variant;
5259 }
5260 if (direction == PF_OUT) {
3e170ce0 5261 psk.af_gwy = af;
316670eb 5262 PF_ACPY(&psk.gwy.addr, saddr, af);
3e170ce0 5263 PF_ACPY(&psk.ext_gwy.addr, daddr, af);
316670eb 5264 switch (pd->proto) {
316670eb
A
5265 case IPPROTO_ESP:
5266 psk.gwy.xport.spi = 0;
3e170ce0 5267 psk.ext_gwy.xport.spi = pd->hdr.esp->spi;
316670eb
A
5268 break;
5269 case IPPROTO_ICMP:
5270#if INET6
5271 case IPPROTO_ICMPV6:
5272#endif
3e170ce0
A
5273 /*
5274 * NAT64 requires protocol translation between ICMPv4
5275 * and ICMPv6. TCP and UDP do not require protocol
5276 * translation. To avoid adding complexity just to
5277 * handle ICMP(v4/v6), we always lookup for
5278 * proto = IPPROTO_ICMP on both LAN and WAN side
5279 */
5280 psk.proto = IPPROTO_ICMP;
316670eb 5281 psk.gwy.xport.port = nxport.port;
3e170ce0 5282 psk.ext_gwy.xport.spi = 0;
316670eb
A
5283 break;
5284 default:
5285 psk.gwy.xport = sxport;
3e170ce0 5286 psk.ext_gwy.xport = dxport;
316670eb
A
5287 break;
5288 }
3e170ce0 5289 psk.af_lan = af;
316670eb
A
5290 if (nr != NULL) {
5291 PF_ACPY(&psk.lan.addr, &pd->baddr, af);
5292 psk.lan.xport = bxport;
3e170ce0
A
5293 PF_ACPY(&psk.ext_lan.addr, &pd->bdaddr, af);
5294 psk.ext_lan.xport = bdxport;
316670eb
A
5295 } else {
5296 PF_ACPY(&psk.lan.addr, &psk.gwy.addr, af);
5297 psk.lan.xport = psk.gwy.xport;
3e170ce0
A
5298 PF_ACPY(&psk.ext_lan.addr, &psk.ext_gwy.addr, af);
5299 psk.ext_lan.xport = psk.ext_gwy.xport;
316670eb
A
5300 }
5301 } else {
3e170ce0
A
5302 psk.af_lan = af;
5303 if (nr && nr->action == PF_NAT64) {
5304 PF_ACPY(&psk.lan.addr, &pd->baddr, af);
5305 PF_ACPY(&psk.ext_lan.addr, &pd->bdaddr, af);
5306 } else {
5307 PF_ACPY(&psk.lan.addr, daddr, af);
5308 PF_ACPY(&psk.ext_lan.addr, saddr, af);
5309 }
316670eb
A
5310 switch (pd->proto) {
5311 case IPPROTO_ICMP:
5312#if INET6
5313 case IPPROTO_ICMPV6:
5314#endif
3e170ce0
A
5315 /*
5316 * NAT64 requires protocol translation between ICMPv4
5317 * and ICMPv6. TCP and UDP do not require protocol
5318 * translation. To avoid adding complexity just to
5319 * handle ICMP(v4/v6), we always lookup for
5320 * proto = IPPROTO_ICMP on both LAN and WAN side
5321 */
5322 psk.proto = IPPROTO_ICMP;
5323 if (nr && nr->action == PF_NAT64) {
5324 psk.lan.xport = bxport;
5325 psk.ext_lan.xport = bxport;
5326 } else {
5327 psk.lan.xport = nxport;
5328 psk.ext_lan.xport.spi = 0;
5329 }
316670eb
A
5330 break;
5331 case IPPROTO_ESP:
3e170ce0 5332 psk.ext_lan.xport.spi = 0;
316670eb
A
5333 psk.lan.xport.spi = pd->hdr.esp->spi;
5334 break;
5335 default:
3e170ce0
A
5336 if (nr != NULL) {
5337 if (nr->action == PF_NAT64) {
5338 psk.lan.xport = bxport;
5339 psk.ext_lan.xport = bdxport;
5340 } else {
5341 psk.lan.xport = dxport;
5342 psk.ext_lan.xport = sxport;
5343 }
5344 } else {
5345 psk.lan.xport = dxport;
5346 psk.ext_lan.xport = sxport;
5347 }
316670eb
A
5348 break;
5349 }
3e170ce0 5350 psk.af_gwy = pd->naf;
316670eb 5351 if (nr != NULL) {
3e170ce0
A
5352 if (nr->action == PF_NAT64) {
5353 PF_ACPY(&psk.gwy.addr, &pd->naddr, pd->naf);
5354 PF_ACPY(&psk.ext_gwy.addr, &pd->ndaddr,
5355 pd->naf);
5356 if ((pd->proto == IPPROTO_ICMPV6) ||
5357 (pd->proto == IPPROTO_ICMP)) {
5358 psk.gwy.xport = nxport;
5359 psk.ext_gwy.xport = nxport;
5360 } else {
5361 psk.gwy.xport = sxport;
5362 psk.ext_gwy.xport = dxport;
5363 }
5364 } else {
5365 PF_ACPY(&psk.gwy.addr, &pd->bdaddr, af);
5366 psk.gwy.xport = bdxport;
5367 PF_ACPY(&psk.ext_gwy.addr, saddr, af);
5368 psk.ext_gwy.xport = sxport;
5369 }
316670eb
A
5370 } else {
5371 PF_ACPY(&psk.gwy.addr, &psk.lan.addr, af);
5372 psk.gwy.xport = psk.lan.xport;
3e170ce0
A
5373 PF_ACPY(&psk.ext_gwy.addr, &psk.ext_lan.addr, af);
5374 psk.ext_gwy.xport = psk.ext_lan.xport;
316670eb
A
5375 }
5376 }
39236c6e
A
5377 if (pd->pktflags & PKTF_FLOW_ID) {
5378 /* flow hash was already computed outside of PF */
5379 psk.flowsrc = pd->flowsrc;
316670eb
A
5380 psk.flowhash = pd->flowhash;
5381 } else {
39236c6e
A
5382 /* compute flow hash and store it in state key */
5383 psk.flowsrc = FLOWSRC_PF;
316670eb 5384 psk.flowhash = pf_calc_state_key_flowhash(&psk);
39236c6e 5385 pd->flowsrc = psk.flowsrc;
316670eb 5386 pd->flowhash = psk.flowhash;
39236c6e
A
5387 pd->pktflags |= PKTF_FLOW_ID;
5388 pd->pktflags &= ~PKTF_FLOW_ADV;
316670eb
A
5389 }
5390
5391 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid, pd)) {
b0d623f7
A
5392 REASON_SET(&reason, PFRES_MEMORY);
5393 return (PF_DROP);
5394 }
5395
5396 if (!state_icmp && (r->keep_state || nr != NULL ||
5397 (pd->flags & PFDESC_TCP_NORM))) {
5398 /* create new state */
5399 struct pf_state *s = NULL;
5400 struct pf_state_key *sk = NULL;
5401 struct pf_src_node *sn = NULL;
b0d623f7
A
5402 struct pf_ike_hdr ike;
5403
5404 if (pd->proto == IPPROTO_UDP) {
b0d623f7
A
5405 size_t plen = m->m_pkthdr.len - off - sizeof (*uh);
5406
b7266188
A
5407 if (ntohs(uh->uh_sport) == PF_IKE_PORT &&
5408 ntohs(uh->uh_dport) == PF_IKE_PORT &&
b0d623f7
A
5409 plen >= PF_IKE_PACKET_MINSIZE) {
5410 if (plen > PF_IKE_PACKET_MINSIZE)
5411 plen = PF_IKE_PACKET_MINSIZE;
5412 m_copydata(m, off + sizeof (*uh), plen, &ike);
5413 }
5414 }
5415
5416 if (nr != NULL && pd->proto == IPPROTO_ESP &&
5417 direction == PF_OUT) {
5418 struct pf_state_key_cmp sk0;
5419 struct pf_state *s0;
5420
5421 /*
5422 * <jhw@apple.com>
5423 * This squelches state creation if the external
5424 * address matches an existing incomplete state with a
5425 * different internal address. Only one 'blocking'
5426 * partial state is allowed for each external address.
5427 */
5428 memset(&sk0, 0, sizeof (sk0));
3e170ce0 5429 sk0.af_gwy = pd->af;
b0d623f7 5430 sk0.proto = IPPROTO_ESP;
3e170ce0
A
5431 PF_ACPY(&sk0.gwy.addr, saddr, sk0.af_gwy);
5432 PF_ACPY(&sk0.ext_gwy.addr, daddr, sk0.af_gwy);
b0d623f7
A
5433 s0 = pf_find_state(kif, &sk0, PF_IN);
5434
5435 if (s0 && PF_ANEQ(&s0->state_key->lan.addr,
5436 pd->src, pd->af)) {
5437 nsn = 0;
5438 goto cleanup;
5439 }
5440 }
b0d623f7
A
5441
5442 /* check maximums */
5443 if (r->max_states && (r->states >= r->max_states)) {
5444 pf_status.lcounters[LCNT_STATES]++;
5445 REASON_SET(&reason, PFRES_MAXSTATES);
5446 goto cleanup;
5447 }
5448 /* src node for filter rule */
5449 if ((r->rule_flag & PFRULE_SRCTRACK ||
5450 r->rpool.opts & PF_POOL_STICKYADDR) &&
5451 pf_insert_src_node(&sn, r, saddr, af) != 0) {
5452 REASON_SET(&reason, PFRES_SRCLIMIT);
5453 goto cleanup;
5454 }
5455 /* src node for translation rule */
5456 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
5457 ((direction == PF_OUT &&
b0d623f7 5458 nr->action != PF_RDR &&
b0d623f7
A
5459 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
5460 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
5461 REASON_SET(&reason, PFRES_SRCLIMIT);
5462 goto cleanup;
5463 }
5464 s = pool_get(&pf_state_pl, PR_WAITOK);
5465 if (s == NULL) {
5466 REASON_SET(&reason, PFRES_MEMORY);
5467cleanup:
5468 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
5469 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
5470 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
5471 pf_status.src_nodes--;
5472 pool_put(&pf_src_tree_pl, sn);
5473 }
5474 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
5475 nsn->expire == 0) {
5476 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
5477 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
5478 pf_status.src_nodes--;
5479 pool_put(&pf_src_tree_pl, nsn);
5480 }
5481 if (sk != NULL) {
b0d623f7
A
5482 if (sk->app_state)
5483 pool_put(&pf_app_state_pl,
5484 sk->app_state);
b0d623f7
A
5485 pool_put(&pf_state_key_pl, sk);
5486 }
5487 return (PF_DROP);
5488 }
5489 bzero(s, sizeof (*s));
b0d623f7 5490 TAILQ_INIT(&s->unlink_hooks);
b0d623f7
A
5491 s->rule.ptr = r;
5492 s->nat_rule.ptr = nr;
d1ecb069 5493 s->anchor.ptr = a;
b0d623f7
A
5494 STATE_INC_COUNTERS(s);
5495 s->allow_opts = r->allow_opts;
5496 s->log = r->log & PF_LOG_ALL;
5497 if (nr != NULL)
5498 s->log |= nr->log & PF_LOG_ALL;
5499 switch (pd->proto) {
5500 case IPPROTO_TCP:
5501 s->src.seqlo = ntohl(th->th_seq);
5502 s->src.seqhi = s->src.seqlo + pd->p_len + 1;
5503 if ((th->th_flags & (TH_SYN|TH_ACK)) ==
5504 TH_SYN && r->keep_state == PF_STATE_MODULATE) {
5505 /* Generate sequence number modulator */
5506 if ((s->src.seqdiff = pf_tcp_iss(pd) -
5507 s->src.seqlo) == 0)
5508 s->src.seqdiff = 1;
5509 pf_change_a(&th->th_seq, &th->th_sum,
5510 htonl(s->src.seqlo + s->src.seqdiff), 0);
5511 rewrite = off + sizeof (*th);
5512 } else
5513 s->src.seqdiff = 0;
5514 if (th->th_flags & TH_SYN) {
5515 s->src.seqhi++;
5516 s->src.wscale = pf_get_wscale(m, off,
5517 th->th_off, af);
5518 }
5519 s->src.max_win = MAX(ntohs(th->th_win), 1);
5520 if (s->src.wscale & PF_WSCALE_MASK) {
5521 /* Remove scale factor from initial window */
5522 int win = s->src.max_win;
5523 win += 1 << (s->src.wscale & PF_WSCALE_MASK);
5524 s->src.max_win = (win - 1) >>
5525 (s->src.wscale & PF_WSCALE_MASK);
5526 }
5527 if (th->th_flags & TH_FIN)
5528 s->src.seqhi++;
5529 s->dst.seqhi = 1;
5530 s->dst.max_win = 1;
5531 s->src.state = TCPS_SYN_SENT;
5532 s->dst.state = TCPS_CLOSED;
5533 s->timeout = PFTM_TCP_FIRST_PACKET;
5534 break;
5535 case IPPROTO_UDP:
5536 s->src.state = PFUDPS_SINGLE;
5537 s->dst.state = PFUDPS_NO_TRAFFIC;
5538 s->timeout = PFTM_UDP_FIRST_PACKET;
5539 break;
5540 case IPPROTO_ICMP:
5541#if INET6
5542 case IPPROTO_ICMPV6:
5543#endif
5544 s->timeout = PFTM_ICMP_FIRST_PACKET;
5545 break;
b0d623f7
A
5546 case IPPROTO_GRE:
5547 s->src.state = PFGRE1S_INITIATING;
5548 s->dst.state = PFGRE1S_NO_TRAFFIC;
5549 s->timeout = PFTM_GREv1_INITIATING;
5550 break;
5551 case IPPROTO_ESP:
5552 s->src.state = PFESPS_INITIATING;
5553 s->dst.state = PFESPS_NO_TRAFFIC;
5554 s->timeout = PFTM_ESP_FIRST_PACKET;
5555 break;
b0d623f7
A
5556 default:
5557 s->src.state = PFOTHERS_SINGLE;
5558 s->dst.state = PFOTHERS_NO_TRAFFIC;
5559 s->timeout = PFTM_OTHER_FIRST_PACKET;
5560 }
5561
5562 s->creation = pf_time_second();
5563 s->expire = pf_time_second();
5564
5565 if (sn != NULL) {
5566 s->src_node = sn;
5567 s->src_node->states++;
b7266188 5568 VERIFY(s->src_node->states != 0);
b0d623f7
A
5569 }
5570 if (nsn != NULL) {
5571 PF_ACPY(&nsn->raddr, &pd->naddr, af);
5572 s->nat_src_node = nsn;
5573 s->nat_src_node->states++;
b7266188 5574 VERIFY(s->nat_src_node->states != 0);
b0d623f7
A
5575 }
5576 if (pd->proto == IPPROTO_TCP) {
5577 if ((pd->flags & PFDESC_TCP_NORM) &&
5578 pf_normalize_tcp_init(m, off, pd, th, &s->src,
5579 &s->dst)) {
5580 REASON_SET(&reason, PFRES_MEMORY);
5581 pf_src_tree_remove_state(s);
5582 STATE_DEC_COUNTERS(s);
5583 pool_put(&pf_state_pl, s);
5584 return (PF_DROP);
5585 }
5586 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub &&
5587 pf_normalize_tcp_stateful(m, off, pd, &reason,
5588 th, s, &s->src, &s->dst, &rewrite)) {
5589 /* This really shouldn't happen!!! */
5590 DPFPRINTF(PF_DEBUG_URGENT,
5591 ("pf_normalize_tcp_stateful failed on "
5592 "first pkt"));
5593 pf_normalize_tcp_cleanup(s);
5594 pf_src_tree_remove_state(s);
5595 STATE_DEC_COUNTERS(s);
5596 pool_put(&pf_state_pl, s);
5597 return (PF_DROP);
5598 }
5599 }
5600
316670eb
A
5601 /* allocate state key and import values from psk */
5602 if ((sk = pf_alloc_state_key(s, &psk)) == NULL) {
b0d623f7
A
5603 REASON_SET(&reason, PFRES_MEMORY);
5604 goto cleanup;
5605 }
5606
3e170ce0 5607 pf_set_rt_ifp(s, saddr, af); /* needs s->state_key set */
b0d623f7 5608
b0d623f7
A
5609 m = pd->mp;
5610
5611 if (sk->app_state == 0) {
5612 switch (pd->proto) {
5613 case IPPROTO_TCP: {
5614 u_int16_t dport = (direction == PF_OUT) ?
3e170ce0 5615 sk->ext_gwy.xport.port : sk->gwy.xport.port;
b0d623f7 5616
b7266188
A
5617 if (nr != NULL &&
5618 ntohs(dport) == PF_PPTP_PORT) {
b0d623f7
A
5619 struct pf_app_state *as;
5620
5621 as = pool_get(&pf_app_state_pl,
5622 PR_WAITOK);
5623 if (!as) {
5624 REASON_SET(&reason,
5625 PFRES_MEMORY);
5626 goto cleanup;
5627 }
5628
5629 bzero(as, sizeof (*as));
5630 as->handler = pf_pptp_handler;
5631 as->compare_lan_ext = 0;
5632 as->compare_ext_gwy = 0;
5633 as->u.pptp.grev1_state = 0;
5634 sk->app_state = as;
5635 (void) hook_establish(&s->unlink_hooks,
5636 0, (hook_fn_t) pf_pptp_unlink, s);
5637 }
5638 break;
5639 }
5640
5641 case IPPROTO_UDP: {
b7266188
A
5642 if (nr != NULL &&
5643 ntohs(uh->uh_sport) == PF_IKE_PORT &&
5644 ntohs(uh->uh_dport) == PF_IKE_PORT) {
b0d623f7
A
5645 struct pf_app_state *as;
5646
5647 as = pool_get(&pf_app_state_pl,
5648 PR_WAITOK);
5649 if (!as) {
5650 REASON_SET(&reason,
5651 PFRES_MEMORY);
5652 goto cleanup;
5653 }
5654
5655 bzero(as, sizeof (*as));
5656 as->compare_lan_ext = pf_ike_compare;
5657 as->compare_ext_gwy = pf_ike_compare;
5658 as->u.ike.cookie = ike.initiator_cookie;
5659 sk->app_state = as;
5660 }
5661 break;
5662 }
5663
5664 default:
5665 break;
5666 }
5667 }
b0d623f7
A
5668
5669 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
5670 if (pd->proto == IPPROTO_TCP)
5671 pf_normalize_tcp_cleanup(s);
5672 REASON_SET(&reason, PFRES_STATEINS);
5673 pf_src_tree_remove_state(s);
5674 STATE_DEC_COUNTERS(s);
5675 pool_put(&pf_state_pl, s);
5676 return (PF_DROP);
5677 } else
5678 *sm = s;
5679 if (tag > 0) {
5680 pf_tag_ref(tag);
5681 s->tag = tag;
5682 }
5683 if (pd->proto == IPPROTO_TCP &&
5684 (th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
5685 r->keep_state == PF_STATE_SYNPROXY) {
3e170ce0 5686 int ua = (sk->af_lan == sk->af_gwy) ? 1 : 0;
b0d623f7
A
5687 s->src.state = PF_TCPS_PROXY_SRC;
5688 if (nr != NULL) {
b0d623f7
A
5689 if (direction == PF_OUT) {
5690 pf_change_ap(direction, pd->mp, saddr,
5691 &th->th_sport, pd->ip_sum,
5692 &th->th_sum, &pd->baddr,
3e170ce0 5693 bxport.port, 0, af, pd->af, ua);
b0d623f7
A
5694 sxport.port = th->th_sport;
5695 } else {
5696 pf_change_ap(direction, pd->mp, daddr,
5697 &th->th_dport, pd->ip_sum,
5698 &th->th_sum, &pd->baddr,
3e170ce0 5699 bxport.port, 0, af, pd->af, ua);
b0d623f7
A
5700 sxport.port = th->th_dport;
5701 }
b0d623f7
A
5702 }
5703 s->src.seqhi = htonl(random());
5704 /* Find mss option */
5705 mss = pf_get_mss(m, off, th->th_off, af);
5706 mss = pf_calc_mss(saddr, af, mss);
5707 mss = pf_calc_mss(daddr, af, mss);
5708 s->src.mss = mss;
5709 pf_send_tcp(r, af, daddr, saddr, th->th_dport,
5710 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
5711 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL);
5712 REASON_SET(&reason, PFRES_SYNPROXY);
5713 return (PF_SYNPROXY_DROP);
5714 }
5715
b0d623f7
A
5716 if (sk->app_state && sk->app_state->handler) {
5717 int offx = off;
5718
5719 switch (pd->proto) {
5720 case IPPROTO_TCP:
5721 offx += th->th_off << 2;
5722 break;
5723 case IPPROTO_UDP:
5724 offx += pd->hdr.udp->uh_ulen << 2;
5725 break;
5726 default:
5727 /* ALG handlers only apply to TCP and UDP rules */
5728 break;
5729 }
5730
5731 if (offx > off) {
5732 sk->app_state->handler(s, direction, offx,
5733 pd, kif);
5734 if (pd->lmw < 0) {
5735 REASON_SET(&reason, PFRES_MEMORY);
5736 return (PF_DROP);
5737 }
5738 m = pd->mp;
5739 }
5740 }
b0d623f7
A
5741 }
5742
5743 /* copy back packet headers if we performed NAT operations */
b0d623f7
A
5744 if (rewrite) {
5745 if (rewrite < off + hdrlen)
5746 rewrite = off + hdrlen;
5747
5748 m = pf_lazy_makewritable(pd, pd->mp, rewrite);
5749 if (!m) {
5750 REASON_SET(&reason, PFRES_MEMORY);
5751 return (PF_DROP);
5752 }
5753
5754 m_copyback(m, off, hdrlen, pd->hdr.any);
3e170ce0
A
5755 if (af == AF_INET6 && pd->naf == AF_INET)
5756 return pf_nat64_ipv6(m, off, pd);
5757 else if (af == AF_INET && pd->naf == AF_INET6)
5758 return pf_nat64_ipv4(m, off, pd);
5759
b0d623f7 5760 }
b0d623f7
A
5761
5762 return (PF_PASS);
5763}
5764
316670eb
A
5765#if DUMMYNET
5766/*
5767 * When pf_test_dummynet() returns PF_PASS, the rule matching parameter "rm"
5768 * remains unchanged, meaning the packet did not match a dummynet rule.
5769 * when the packet does match a dummynet rule, pf_test_dummynet() returns
5770 * PF_PASS and zero out the mbuf rule as the packet is effectively siphoned
5771 * out by dummynet.
5772 */
5773static int
5774pf_test_dummynet(struct pf_rule **rm, int direction, struct pfi_kif *kif,
5775 struct mbuf **m0, struct pf_pdesc *pd, struct ip_fw_args *fwa)
5776{
5777 struct mbuf *m = *m0;
5778 struct pf_rule *am = NULL;
5779 struct pf_ruleset *rsm = NULL;
5780 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
5781 sa_family_t af = pd->af;
5782 struct pf_rule *r, *a = NULL;
5783 struct pf_ruleset *ruleset = NULL;
5784 struct tcphdr *th = pd->hdr.tcp;
5785 u_short reason;
5786 int hdrlen = 0;
5787 int tag = -1;
5788 unsigned int rtableid = IFSCOPE_NONE;
5789 int asd = 0;
5790 int match = 0;
5791 u_int8_t icmptype = 0, icmpcode = 0;
316670eb
A
5792 struct ip_fw_args dnflow;
5793 struct pf_rule *prev_matching_rule = fwa ? fwa->fwa_pf_rule : NULL;
5794 int found_prev_rule = (prev_matching_rule) ? 0 : 1;
5795
5796 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
5797
5798 if (!DUMMYNET_LOADED)
5799 return (PF_PASS);
5800
4b17d6b6 5801 if (TAILQ_EMPTY(pf_main_ruleset.rules[PF_RULESET_DUMMYNET].active.ptr))
316670eb 5802 return (PF_PASS);
4b17d6b6 5803
316670eb
A
5804 bzero(&dnflow, sizeof(dnflow));
5805
5806 hdrlen = 0;
316670eb
A
5807
5808 /* Fragments don't gave protocol headers */
5809 if (!(pd->flags & PFDESC_IP_FRAG))
5810 switch (pd->proto) {
5811 case IPPROTO_TCP:
5812 dnflow.fwa_id.flags = pd->hdr.tcp->th_flags;
4b17d6b6
A
5813 dnflow.fwa_id.dst_port = ntohs(pd->hdr.tcp->th_dport);
5814 dnflow.fwa_id.src_port = ntohs(pd->hdr.tcp->th_sport);
316670eb
A
5815 hdrlen = sizeof (*th);
5816 break;
5817 case IPPROTO_UDP:
4b17d6b6
A
5818 dnflow.fwa_id.dst_port = ntohs(pd->hdr.udp->uh_dport);
5819 dnflow.fwa_id.src_port = ntohs(pd->hdr.udp->uh_sport);
316670eb
A
5820 hdrlen = sizeof (*pd->hdr.udp);
5821 break;
5822#if INET
5823 case IPPROTO_ICMP:
4b17d6b6 5824 if (af != AF_INET)
316670eb 5825 break;
316670eb
A
5826 hdrlen = ICMP_MINLEN;
5827 icmptype = pd->hdr.icmp->icmp_type;
5828 icmpcode = pd->hdr.icmp->icmp_code;
5829 break;
5830#endif /* INET */
5831#if INET6
5832 case IPPROTO_ICMPV6:
4b17d6b6 5833 if (af != AF_INET6)
316670eb 5834 break;
316670eb
A
5835 hdrlen = sizeof (*pd->hdr.icmp6);
5836 icmptype = pd->hdr.icmp6->icmp6_type;
5837 icmpcode = pd->hdr.icmp6->icmp6_code;
5838 break;
5839#endif /* INET6 */
5840 case IPPROTO_GRE:
4b17d6b6 5841 if (pd->proto_variant == PF_GRE_PPTP_VARIANT)
316670eb 5842 hdrlen = sizeof (*pd->hdr.grev1);
316670eb
A
5843 break;
5844 case IPPROTO_ESP:
316670eb
A
5845 hdrlen = sizeof (*pd->hdr.esp);
5846 break;
5847 }
5848
5849 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_DUMMYNET].active.ptr);
5850
5851 while (r != NULL) {
5852 r->evaluations++;
5853 if (pfi_kif_match(r->kif, kif) == r->ifnot)
5854 r = r->skip[PF_SKIP_IFP].ptr;
5855 else if (r->direction && r->direction != direction)
5856 r = r->skip[PF_SKIP_DIR].ptr;
5857 else if (r->af && r->af != af)
5858 r = r->skip[PF_SKIP_AF].ptr;
5859 else if (r->proto && r->proto != pd->proto)
5860 r = r->skip[PF_SKIP_PROTO].ptr;
5861 else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
5862 r->src.neg, kif))
5863 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
5864 /* tcp/udp only. port_op always 0 in other cases */
5865 else if (r->proto == pd->proto &&
5866 (r->proto == IPPROTO_TCP || r->proto == IPPROTO_UDP) &&
5867 ((pd->flags & PFDESC_IP_FRAG) ||
5868 ((r->src.xport.range.op &&
5869 !pf_match_port(r->src.xport.range.op,
5870 r->src.xport.range.port[0], r->src.xport.range.port[1],
5871 th->th_sport)))))
5872 r = r->skip[PF_SKIP_SRC_PORT].ptr;
5873 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
5874 r->dst.neg, NULL))
5875 r = r->skip[PF_SKIP_DST_ADDR].ptr;
5876 /* tcp/udp only. port_op always 0 in other cases */
5877 else if (r->proto == pd->proto &&
5878 (r->proto == IPPROTO_TCP || r->proto == IPPROTO_UDP) &&
5879 r->dst.xport.range.op &&
5880 ((pd->flags & PFDESC_IP_FRAG) ||
5881 !pf_match_port(r->dst.xport.range.op,
5882 r->dst.xport.range.port[0], r->dst.xport.range.port[1],
5883 th->th_dport)))
5884 r = r->skip[PF_SKIP_DST_PORT].ptr;
5885 /* icmp only. type always 0 in other cases */
5886 else if (r->type &&
5887 ((pd->flags & PFDESC_IP_FRAG) ||
5888 r->type != icmptype + 1))
5889 r = TAILQ_NEXT(r, entries);
5890 /* icmp only. type always 0 in other cases */
5891 else if (r->code &&
5892 ((pd->flags & PFDESC_IP_FRAG) ||
5893 r->code != icmpcode + 1))
5894 r = TAILQ_NEXT(r, entries);
5895 else if (r->tos && !(r->tos == pd->tos))
5896 r = TAILQ_NEXT(r, entries);
5897 else if (r->rule_flag & PFRULE_FRAGMENT)
5898 r = TAILQ_NEXT(r, entries);
5899 else if (pd->proto == IPPROTO_TCP &&
5900 ((pd->flags & PFDESC_IP_FRAG) ||
5901 (r->flagset & th->th_flags) != r->flags))
5902 r = TAILQ_NEXT(r, entries);
39236c6e
A
5903 else if (r->prob && r->prob <= (RandomULong() % (UINT_MAX - 1) + 1))
5904 r = TAILQ_NEXT(r, entries);
316670eb
A
5905 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
5906 r = TAILQ_NEXT(r, entries);
5907 else {
5908 /*
5909 * Need to go past the previous dummynet matching rule
5910 */
5911 if (r->anchor == NULL) {
5912 if (found_prev_rule) {
5913 if (r->tag)
5914 tag = r->tag;
5915 if (PF_RTABLEID_IS_VALID(r->rtableid))
5916 rtableid = r->rtableid;
5917 match = 1;
5918 *rm = r;
5919 am = a;
5920 rsm = ruleset;
5921 if ((*rm)->quick)
5922 break;
5923 } else if (r == prev_matching_rule) {
5924 found_prev_rule = 1;
5925 }
5926 r = TAILQ_NEXT(r, entries);
5927 } else {
5928 pf_step_into_anchor(&asd, &ruleset,
5929 PF_RULESET_DUMMYNET, &r, &a, &match);
5930 }
5931 }
5932 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
5933 PF_RULESET_DUMMYNET, &r, &a, &match))
5934 break;
5935 }
5936 r = *rm;
5937 a = am;
5938 ruleset = rsm;
5939
5940 if (!match)
5941 return (PF_PASS);
5942
5943 REASON_SET(&reason, PFRES_DUMMYNET);
5944
5945 if (r->log) {
5946 PFLOG_PACKET(kif, h, m, af, direction, reason, r,
5947 a, ruleset, pd);
5948 }
5949
5950 if (r->action == PF_NODUMMYNET) {
5951 int dirndx = (direction == PF_OUT);
5952
5953 r->packets[dirndx]++;
5954 r->bytes[dirndx] += pd->tot_len;
5955
5956 return (PF_PASS);
5957 }
5958 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid, pd)) {
5959 REASON_SET(&reason, PFRES_MEMORY);
5960
5961 return (PF_DROP);
5962 }
5963
5964 if (r->dnpipe && ip_dn_io_ptr != NULL) {
5965 int dirndx = (direction == PF_OUT);
5966
5967 r->packets[dirndx]++;
5968 r->bytes[dirndx] += pd->tot_len;
5969
5970 dnflow.fwa_cookie = r->dnpipe;
5971 dnflow.fwa_pf_rule = r;
316670eb
A
5972 dnflow.fwa_id.proto = pd->proto;
5973 dnflow.fwa_flags = r->dntype;
4b17d6b6
A
5974 switch (af) {
5975 case AF_INET:
5976 dnflow.fwa_id.addr_type = 4;
5977 dnflow.fwa_id.src_ip = ntohl(saddr->v4.s_addr);
5978 dnflow.fwa_id.dst_ip = ntohl(daddr->v4.s_addr);
5979 break;
5980 case AF_INET6:
5981 dnflow.fwa_id.addr_type = 6;
5982 dnflow.fwa_id.src_ip6 = saddr->v6;
5983 dnflow.fwa_id.dst_ip6 = saddr->v6;
5984 break;
5985 }
5986
316670eb
A
5987 if (fwa != NULL) {
5988 dnflow.fwa_oif = fwa->fwa_oif;
5989 dnflow.fwa_oflags = fwa->fwa_oflags;
5990 /*
5991 * Note that fwa_ro, fwa_dst and fwa_ipoa are
5992 * actually in a union so the following does work
5993 * for both IPv4 and IPv6
5994 */
5995 dnflow.fwa_ro = fwa->fwa_ro;
5996 dnflow.fwa_dst = fwa->fwa_dst;
5997 dnflow.fwa_ipoa = fwa->fwa_ipoa;
5998 dnflow.fwa_ro6_pmtu = fwa->fwa_ro6_pmtu;
5999 dnflow.fwa_origifp = fwa->fwa_origifp;
6000 dnflow.fwa_mtu = fwa->fwa_mtu;
6001 dnflow.fwa_alwaysfrag = fwa->fwa_alwaysfrag;
6002 dnflow.fwa_unfragpartlen = fwa->fwa_unfragpartlen;
6003 dnflow.fwa_exthdrs = fwa->fwa_exthdrs;
6004 }
6005
6006 if (af == AF_INET) {
6007 struct ip *iphdr = mtod(m, struct ip *);
6008 NTOHS(iphdr->ip_len);
6009 NTOHS(iphdr->ip_off);
6010 }
3e170ce0 6011 /*
316670eb
A
6012 * Don't need to unlock pf_lock as NET_THREAD_HELD_PF
6013 * allows for recursive behavior
6014 */
6015 ip_dn_io_ptr(m,
6016 dnflow.fwa_cookie,
6017 af == AF_INET ?
6018 direction == PF_IN ? DN_TO_IP_IN : DN_TO_IP_OUT :
6019 direction == PF_IN ? DN_TO_IP6_IN : DN_TO_IP6_OUT,
6020 &dnflow, DN_CLIENT_PF);
6021
6022 /*
6023 * The packet is siphoned out by dummynet so return a NULL
6024 * mbuf so the caller can still return success.
6025 */
6026 *m0 = NULL;
6027
6028 return (PF_PASS);
6029 }
6030
6031 return (PF_PASS);
6032}
6033#endif /* DUMMYNET */
6034
b0d623f7
A
6035static int
6036pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
6037 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am,
6038 struct pf_ruleset **rsm)
6039{
6040#pragma unused(h)
6041 struct pf_rule *r, *a = NULL;
6042 struct pf_ruleset *ruleset = NULL;
6043 sa_family_t af = pd->af;
6044 u_short reason;
6045 int tag = -1;
6046 int asd = 0;
6047 int match = 0;
6048
6049 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
6050 while (r != NULL) {
6051 r->evaluations++;
6052 if (pfi_kif_match(r->kif, kif) == r->ifnot)
6053 r = r->skip[PF_SKIP_IFP].ptr;
6054 else if (r->direction && r->direction != direction)
6055 r = r->skip[PF_SKIP_DIR].ptr;
6056 else if (r->af && r->af != af)
6057 r = r->skip[PF_SKIP_AF].ptr;
6058 else if (r->proto && r->proto != pd->proto)
6059 r = r->skip[PF_SKIP_PROTO].ptr;
6060 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
6061 r->src.neg, kif))
6062 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
6063 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
6064 r->dst.neg, NULL))
6065 r = r->skip[PF_SKIP_DST_ADDR].ptr;
316670eb
A
6066 else if ((r->rule_flag & PFRULE_TOS) && r->tos &&
6067 !(r->tos & pd->tos))
6068 r = TAILQ_NEXT(r, entries);
6069 else if ((r->rule_flag & PFRULE_DSCP) && r->tos &&
6070 !(r->tos & (pd->tos & DSCP_MASK)))
6071 r = TAILQ_NEXT(r, entries);
6072 else if ((r->rule_flag & PFRULE_SC) && r->tos &&
6073 ((r->tos & SCIDX_MASK) != pd->sc))
b0d623f7
A
6074 r = TAILQ_NEXT(r, entries);
6075 else if (r->os_fingerprint != PF_OSFP_ANY)
6076 r = TAILQ_NEXT(r, entries);
b0d623f7
A
6077 else if (pd->proto == IPPROTO_UDP &&
6078 (r->src.xport.range.op || r->dst.xport.range.op))
6079 r = TAILQ_NEXT(r, entries);
6080 else if (pd->proto == IPPROTO_TCP &&
6081 (r->src.xport.range.op || r->dst.xport.range.op ||
6082 r->flagset))
6083 r = TAILQ_NEXT(r, entries);
b0d623f7
A
6084 else if ((pd->proto == IPPROTO_ICMP ||
6085 pd->proto == IPPROTO_ICMPV6) &&
6086 (r->type || r->code))
6087 r = TAILQ_NEXT(r, entries);
39236c6e 6088 else if (r->prob && r->prob <= (RandomULong() % (UINT_MAX - 1) + 1))
b0d623f7
A
6089 r = TAILQ_NEXT(r, entries);
6090 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
6091 r = TAILQ_NEXT(r, entries);
6092 else {
6093 if (r->anchor == NULL) {
6094 match = 1;
6095 *rm = r;
6096 *am = a;
6097 *rsm = ruleset;
6098 if ((*rm)->quick)
6099 break;
6100 r = TAILQ_NEXT(r, entries);
6101 } else
6102 pf_step_into_anchor(&asd, &ruleset,
6103 PF_RULESET_FILTER, &r, &a, &match);
6104 }
6105 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
6106 PF_RULESET_FILTER, &r, &a, &match))
6107 break;
6108 }
6109 r = *rm;
6110 a = *am;
6111 ruleset = *rsm;
6112
6113 REASON_SET(&reason, PFRES_MATCH);
6114
6115 if (r->log)
6116 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset,
6117 pd);
6118
6119 if (r->action != PF_PASS)
6120 return (PF_DROP);
6121
316670eb 6122 if (pf_tag_packet(m, pd->pf_mtag, tag, -1, NULL)) {
b0d623f7
A
6123 REASON_SET(&reason, PFRES_MEMORY);
6124 return (PF_DROP);
6125 }
6126
6127 return (PF_PASS);
6128}
6129
b0d623f7
A
6130static void
6131pf_pptp_handler(struct pf_state *s, int direction, int off,
6132 struct pf_pdesc *pd, struct pfi_kif *kif)
6133{
6134#pragma unused(direction)
6135 struct tcphdr *th;
d1ecb069 6136 struct pf_pptp_state *pptps;
b0d623f7
A
6137 struct pf_pptp_ctrl_msg cm;
6138 size_t plen;
6139 struct pf_state *gs;
6140 u_int16_t ct;
6141 u_int16_t *pac_call_id;
6142 u_int16_t *pns_call_id;
6143 u_int16_t *spoof_call_id;
6144 u_int8_t *pac_state;
6145 u_int8_t *pns_state;
6146 enum { PF_PPTP_PASS, PF_PPTP_INSERT_GRE, PF_PPTP_REMOVE_GRE } op;
6147 struct mbuf *m;
6148 struct pf_state_key *sk;
6149 struct pf_state_key *gsk;
d1ecb069
A
6150 struct pf_app_state *gas;
6151
6152 sk = s->state_key;
6153 pptps = &sk->app_state->u.pptp;
6154 gs = pptps->grev1_state;
6155
6156 if (gs)
6157 gs->expire = pf_time_second();
b0d623f7
A
6158
6159 m = pd->mp;
6160 plen = min(sizeof (cm), m->m_pkthdr.len - off);
6161 if (plen < PF_PPTP_CTRL_MSG_MINSIZE)
6162 return;
6163
b0d623f7
A
6164 m_copydata(m, off, plen, &cm);
6165
b7266188 6166 if (ntohl(cm.hdr.magic) != PF_PPTP_MAGIC_NUMBER)
b0d623f7 6167 return;
b7266188 6168 if (ntohs(cm.hdr.type) != 1)
b0d623f7
A
6169 return;
6170
b0d623f7
A
6171 if (!gs) {
6172 gs = pool_get(&pf_state_pl, PR_WAITOK);
6173 if (!gs)
6174 return;
6175
6176 memcpy(gs, s, sizeof (*gs));
6177
6178 memset(&gs->entry_id, 0, sizeof (gs->entry_id));
6179 memset(&gs->entry_list, 0, sizeof (gs->entry_list));
6180
6181 TAILQ_INIT(&gs->unlink_hooks);
6182 gs->rt_kif = NULL;
6183 gs->creation = 0;
6184 gs->pfsync_time = 0;
6185 gs->packets[0] = gs->packets[1] = 0;
6186 gs->bytes[0] = gs->bytes[1] = 0;
6187 gs->timeout = PFTM_UNLINKED;
6188 gs->id = gs->creatorid = 0;
6189 gs->src.state = gs->dst.state = PFGRE1S_NO_TRAFFIC;
6190 gs->src.scrub = gs->dst.scrub = 0;
6191
d1ecb069
A
6192 gas = pool_get(&pf_app_state_pl, PR_NOWAIT);
6193 if (!gas) {
6194 pool_put(&pf_state_pl, gs);
6195 return;
6196 }
6197
316670eb 6198 gsk = pf_alloc_state_key(gs, NULL);
b0d623f7 6199 if (!gsk) {
d1ecb069 6200 pool_put(&pf_app_state_pl, gas);
b0d623f7
A
6201 pool_put(&pf_state_pl, gs);
6202 return;
6203 }
6204
6205 memcpy(&gsk->lan, &sk->lan, sizeof (gsk->lan));
6206 memcpy(&gsk->gwy, &sk->gwy, sizeof (gsk->gwy));
3e170ce0
A
6207 memcpy(&gsk->ext_lan, &sk->ext_lan, sizeof (gsk->ext_lan));
6208 memcpy(&gsk->ext_gwy, &sk->ext_gwy, sizeof (gsk->ext_gwy));
6209 gsk->af_lan = sk->af_lan;
6210 gsk->af_gwy = sk->af_gwy;
b0d623f7
A
6211 gsk->proto = IPPROTO_GRE;
6212 gsk->proto_variant = PF_GRE_PPTP_VARIANT;
d1ecb069 6213 gsk->app_state = gas;
b0d623f7
A
6214 gsk->lan.xport.call_id = 0;
6215 gsk->gwy.xport.call_id = 0;
3e170ce0
A
6216 gsk->ext_lan.xport.call_id = 0;
6217 gsk->ext_gwy.xport.call_id = 0;
39236c6e 6218 gsk->flowsrc = FLOWSRC_PF;
316670eb 6219 gsk->flowhash = pf_calc_state_key_flowhash(gsk);
d1ecb069
A
6220 memset(gas, 0, sizeof (*gas));
6221 gas->u.grev1.pptp_state = s;
b7266188 6222 STATE_INC_COUNTERS(gs);
d1ecb069
A
6223 pptps->grev1_state = gs;
6224 (void) hook_establish(&gs->unlink_hooks, 0,
6225 (hook_fn_t) pf_grev1_unlink, gs);
b0d623f7
A
6226 } else {
6227 gsk = gs->state_key;
6228 }
6229
6230 switch (sk->direction) {
6231 case PF_IN:
3e170ce0 6232 pns_call_id = &gsk->ext_lan.xport.call_id;
b0d623f7
A
6233 pns_state = &gs->dst.state;
6234 pac_call_id = &gsk->lan.xport.call_id;
6235 pac_state = &gs->src.state;
6236 break;
6237
6238 case PF_OUT:
6239 pns_call_id = &gsk->lan.xport.call_id;
6240 pns_state = &gs->src.state;
3e170ce0 6241 pac_call_id = &gsk->ext_lan.xport.call_id;
b0d623f7
A
6242 pac_state = &gs->dst.state;
6243 break;
6244
6245 default:
6246 DPFPRINTF(PF_DEBUG_URGENT,
6247 ("pf_pptp_handler: bad directional!\n"));
6248 return;
6249 }
6250
6251 spoof_call_id = 0;
6252 op = PF_PPTP_PASS;
6253
6254 ct = ntohs(cm.ctrl.type);
6255
6256 switch (ct) {
6257 case PF_PPTP_CTRL_TYPE_CALL_OUT_REQ:
6258 *pns_call_id = cm.msg.call_out_req.call_id;
6259 *pns_state = PFGRE1S_INITIATING;
6260 if (s->nat_rule.ptr && pns_call_id == &gsk->lan.xport.call_id)
6261 spoof_call_id = &cm.msg.call_out_req.call_id;
6262 break;
6263
6264 case PF_PPTP_CTRL_TYPE_CALL_OUT_RPY:
6265 *pac_call_id = cm.msg.call_out_rpy.call_id;
6266 if (s->nat_rule.ptr)
6267 spoof_call_id =
6268 (pac_call_id == &gsk->lan.xport.call_id) ?
6269 &cm.msg.call_out_rpy.call_id :
6270 &cm.msg.call_out_rpy.peer_call_id;
6271 if (gs->timeout == PFTM_UNLINKED) {
6272 *pac_state = PFGRE1S_INITIATING;
6273 op = PF_PPTP_INSERT_GRE;
6274 }
6275 break;
6276
6277 case PF_PPTP_CTRL_TYPE_CALL_IN_1ST:
6278 *pns_call_id = cm.msg.call_in_1st.call_id;
6279 *pns_state = PFGRE1S_INITIATING;
6280 if (s->nat_rule.ptr && pns_call_id == &gsk->lan.xport.call_id)
6281 spoof_call_id = &cm.msg.call_in_1st.call_id;
6282 break;
6283
6284 case PF_PPTP_CTRL_TYPE_CALL_IN_2ND:
6285 *pac_call_id = cm.msg.call_in_2nd.call_id;
6286 *pac_state = PFGRE1S_INITIATING;
6287 if (s->nat_rule.ptr)
6288 spoof_call_id =
6289 (pac_call_id == &gsk->lan.xport.call_id) ?
6290 &cm.msg.call_in_2nd.call_id :
6291 &cm.msg.call_in_2nd.peer_call_id;
6292 break;
6293
6294 case PF_PPTP_CTRL_TYPE_CALL_IN_3RD:
6295 if (s->nat_rule.ptr && pns_call_id == &gsk->lan.xport.call_id)
6296 spoof_call_id = &cm.msg.call_in_3rd.call_id;
6297 if (cm.msg.call_in_3rd.call_id != *pns_call_id) {
6298 break;
6299 }
6300 if (gs->timeout == PFTM_UNLINKED)
6301 op = PF_PPTP_INSERT_GRE;
6302 break;
6303
6304 case PF_PPTP_CTRL_TYPE_CALL_CLR:
6305 if (cm.msg.call_clr.call_id != *pns_call_id)
6306 op = PF_PPTP_REMOVE_GRE;
6307 break;
6308
6309 case PF_PPTP_CTRL_TYPE_CALL_DISC:
6310 if (cm.msg.call_clr.call_id != *pac_call_id)
6311 op = PF_PPTP_REMOVE_GRE;
6312 break;
6313
6314 case PF_PPTP_CTRL_TYPE_ERROR:
6315 if (s->nat_rule.ptr && pns_call_id == &gsk->lan.xport.call_id)
6316 spoof_call_id = &cm.msg.error.peer_call_id;
6317 break;
6318
6319 case PF_PPTP_CTRL_TYPE_SET_LINKINFO:
6320 if (s->nat_rule.ptr && pac_call_id == &gsk->lan.xport.call_id)
6321 spoof_call_id = &cm.msg.set_linkinfo.peer_call_id;
6322 break;
6323
6324 default:
6325 op = PF_PPTP_PASS;
6326 break;
6327 }
6328
6329 if (!gsk->gwy.xport.call_id && gsk->lan.xport.call_id) {
6330 gsk->gwy.xport.call_id = gsk->lan.xport.call_id;
6331 if (spoof_call_id) {
6332 u_int16_t call_id = 0;
6333 int n = 0;
6334 struct pf_state_key_cmp key;
6335
3e170ce0 6336 key.af_gwy = gsk->af_gwy;
b0d623f7
A
6337 key.proto = IPPROTO_GRE;
6338 key.proto_variant = PF_GRE_PPTP_VARIANT;
3e170ce0
A
6339 PF_ACPY(&key.gwy.addr, &gsk->gwy.addr, key.af_gwy);
6340 PF_ACPY(&key.ext_gwy.addr, &gsk->ext_gwy.addr, key.af_gwy);
b0d623f7 6341 key.gwy.xport.call_id = gsk->gwy.xport.call_id;
3e170ce0 6342 key.ext_gwy.xport.call_id = gsk->ext_gwy.xport.call_id;
b0d623f7
A
6343 do {
6344 call_id = htonl(random());
6345 } while (!call_id);
6346
6347 while (pf_find_state_all(&key, PF_IN, 0)) {
6348 call_id = ntohs(call_id);
6349 --call_id;
6350 if (--call_id == 0) call_id = 0xffff;
6351 call_id = htons(call_id);
6352
6353 key.gwy.xport.call_id = call_id;
6354
6355 if (++n > 65535) {
6356 DPFPRINTF(PF_DEBUG_URGENT,
6357 ("pf_pptp_handler: failed to spoof "
6358 "call id\n"));
6359 key.gwy.xport.call_id = 0;
6360 break;
6361 }
6362 }
6363
6364 gsk->gwy.xport.call_id = call_id;
6365 }
6366 }
6367
6368 th = pd->hdr.tcp;
6369
6370 if (spoof_call_id && gsk->lan.xport.call_id != gsk->gwy.xport.call_id) {
6371 if (*spoof_call_id == gsk->gwy.xport.call_id) {
6372 *spoof_call_id = gsk->lan.xport.call_id;
6373 th->th_sum = pf_cksum_fixup(th->th_sum,
6374 gsk->gwy.xport.call_id, gsk->lan.xport.call_id, 0);
6375 } else {
6376 *spoof_call_id = gsk->gwy.xport.call_id;
6377 th->th_sum = pf_cksum_fixup(th->th_sum,
6378 gsk->lan.xport.call_id, gsk->gwy.xport.call_id, 0);
6379 }
6380
6381 m = pf_lazy_makewritable(pd, m, off + plen);
b7266188 6382 if (!m) {
d1ecb069 6383 pptps->grev1_state = NULL;
b7266188
A
6384 STATE_DEC_COUNTERS(gs);
6385 pool_put(&pf_state_pl, gs);
b0d623f7 6386 return;
b7266188 6387 }
b0d623f7
A
6388 m_copyback(m, off, plen, &cm);
6389 }
6390
6391 switch (op) {
6392 case PF_PPTP_REMOVE_GRE:
6393 gs->timeout = PFTM_PURGE;
6394 gs->src.state = gs->dst.state = PFGRE1S_NO_TRAFFIC;
6395 gsk->lan.xport.call_id = 0;
6396 gsk->gwy.xport.call_id = 0;
3e170ce0
A
6397 gsk->ext_lan.xport.call_id = 0;
6398 gsk->ext_gwy.xport.call_id = 0;
b0d623f7
A
6399 gs->id = gs->creatorid = 0;
6400 break;
6401
6402 case PF_PPTP_INSERT_GRE:
6403 gs->creation = pf_time_second();
6404 gs->expire = pf_time_second();
d1ecb069 6405 gs->timeout = PFTM_TCP_ESTABLISHED;
b7266188
A
6406 if (gs->src_node != NULL) {
6407 ++gs->src_node->states;
6408 VERIFY(gs->src_node->states != 0);
6409 }
6410 if (gs->nat_src_node != NULL) {
6411 ++gs->nat_src_node->states;
6412 VERIFY(gs->nat_src_node->states != 0);
6413 }
3e170ce0 6414 pf_set_rt_ifp(gs, &sk->lan.addr, sk->af_lan);
b0d623f7
A
6415 if (pf_insert_state(BOUND_IFACE(s->rule.ptr, kif), gs)) {
6416
6417 /*
6418 * <jhw@apple.com>
6419 * FIX ME: insertion can fail when multiple PNS
6420 * behind the same NAT open calls to the same PAC
6421 * simultaneously because spoofed call ID numbers
6422 * are chosen before states are inserted. This is
6423 * hard to fix and happens infrequently enough that
6424 * users will normally try again and this ALG will
6425 * succeed. Failures are expected to be rare enough
6426 * that fixing this is a low priority.
6427 */
d1ecb069
A
6428 pptps->grev1_state = NULL;
6429 pd->lmw = -1; /* Force PF_DROP on PFRES_MEMORY */
b0d623f7
A
6430 pf_src_tree_remove_state(gs);
6431 STATE_DEC_COUNTERS(gs);
6432 pool_put(&pf_state_pl, gs);
6433 DPFPRINTF(PF_DEBUG_URGENT, ("pf_pptp_handler: error "
6434 "inserting GREv1 state.\n"));
6435 }
6436 break;
6437
6438 default:
6439 break;
6440 }
6441}
6442
6443static void
6444pf_pptp_unlink(struct pf_state *s)
6445{
6446 struct pf_app_state *as = s->state_key->app_state;
d1ecb069
A
6447 struct pf_state *grev1s = as->u.pptp.grev1_state;
6448
6449 if (grev1s) {
6450 struct pf_app_state *gas = grev1s->state_key->app_state;
b0d623f7 6451
d1ecb069
A
6452 if (grev1s->timeout < PFTM_MAX)
6453 grev1s->timeout = PFTM_PURGE;
6454 gas->u.grev1.pptp_state = NULL;
6455 as->u.pptp.grev1_state = NULL;
6456 }
6457}
6458
6459static void
6460pf_grev1_unlink(struct pf_state *s)
6461{
6462 struct pf_app_state *as = s->state_key->app_state;
6463 struct pf_state *pptps = as->u.grev1.pptp_state;
6464
6465 if (pptps) {
6466 struct pf_app_state *pas = pptps->state_key->app_state;
6467
6468 pas->u.pptp.grev1_state = NULL;
6469 as->u.grev1.pptp_state = NULL;
b0d623f7
A
6470 }
6471}
6472
6473static int
6474pf_ike_compare(struct pf_app_state *a, struct pf_app_state *b)
6475{
6476 int64_t d = a->u.ike.cookie - b->u.ike.cookie;
6477 return ((d > 0) ? 1 : ((d < 0) ? -1 : 0));
6478}
b0d623f7 6479
3e170ce0
A
6480static int
6481pf_do_nat64(struct pf_state_key *sk, struct pf_pdesc *pd, struct mbuf *m,
6482 int off)
6483{
6484 if (pd->af == AF_INET) {
6485 if (pd->af != sk->af_lan) {
6486 pd->ndaddr = sk->lan.addr;
6487 pd->naddr = sk->ext_lan.addr;
6488 } else {
6489 pd->naddr = sk->gwy.addr;
6490 pd->ndaddr = sk->ext_gwy.addr;
6491 }
6492 return (pf_nat64_ipv4(m, off, pd));
6493 }
6494 else if (pd->af == AF_INET6) {
6495 if (pd->af != sk->af_lan) {
6496 pd->ndaddr = sk->lan.addr;
6497 pd->naddr = sk->ext_lan.addr;
6498 } else {
6499 pd->naddr = sk->gwy.addr;
6500 pd->ndaddr = sk->ext_gwy.addr;
6501 }
6502 return (pf_nat64_ipv6(m, off, pd));
6503 }
6504 return (PF_DROP);
6505}
6506
b0d623f7
A
6507static int
6508pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
6509 struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
6510 u_short *reason)
6511{
6512#pragma unused(h)
6513 struct pf_state_key_cmp key;
6514 struct tcphdr *th = pd->hdr.tcp;
6515 u_int16_t win = ntohs(th->th_win);
6516 u_int32_t ack, end, seq, orig_seq;
6517 u_int8_t sws, dws;
6518 int ackskew;
6519 int copyback = 0;
6520 struct pf_state_peer *src, *dst;
3e170ce0 6521 struct pf_state_key *sk;
b0d623f7 6522
b0d623f7 6523 key.app_state = 0;
b0d623f7 6524 key.proto = IPPROTO_TCP;
3e170ce0
A
6525 key.af_lan = key.af_gwy = pd->af;
6526
6527 /*
6528 * For NAT64 the first time rule search and state creation
6529 * is done on the incoming side only.
6530 * Once the state gets created, NAT64's LAN side (ipv6) will
6531 * not be able to find the state in ext-gwy tree as that normally
6532 * is intended to be looked up for incoming traffic from the
6533 * WAN side.
6534 * Therefore to handle NAT64 case we init keys here for both
6535 * lan-ext as well as ext-gwy trees.
6536 * In the state lookup we attempt a lookup on both trees if
6537 * first one does not return any result and return a match if
6538 * the match state's was created by NAT64 rule.
6539 */
6540 PF_ACPY(&key.ext_gwy.addr, pd->src, key.af_gwy);
6541 PF_ACPY(&key.gwy.addr, pd->dst, key.af_gwy);
6542 key.ext_gwy.xport.port = th->th_sport;
6543 key.gwy.xport.port = th->th_dport;
6544
6545 PF_ACPY(&key.lan.addr, pd->src, key.af_lan);
6546 PF_ACPY(&key.ext_lan.addr, pd->dst, key.af_lan);
6547 key.lan.xport.port = th->th_sport;
6548 key.ext_lan.xport.port = th->th_dport;
b0d623f7
A
6549
6550 STATE_LOOKUP();
6551
3e170ce0
A
6552 sk = (*state)->state_key;
6553 /*
6554 * In case of NAT64 the translation is first applied on the LAN
6555 * side. Therefore for stack's address family comparison
6556 * we use sk->af_lan.
6557 */
6558 if ((direction == sk->direction) && (pd->af == sk->af_lan)) {
b0d623f7
A
6559 src = &(*state)->src;
6560 dst = &(*state)->dst;
6561 } else {
6562 src = &(*state)->dst;
6563 dst = &(*state)->src;
6564 }
6565
3e170ce0
A
6566 if (src->state == PF_TCPS_PROXY_SRC) {
6567 if (direction != sk->direction) {
b0d623f7
A
6568 REASON_SET(reason, PFRES_SYNPROXY);
6569 return (PF_SYNPROXY_DROP);
6570 }
6571 if (th->th_flags & TH_SYN) {
3e170ce0 6572 if (ntohl(th->th_seq) != src->seqlo) {
b0d623f7
A
6573 REASON_SET(reason, PFRES_SYNPROXY);
6574 return (PF_DROP);
6575 }
6576 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
6577 pd->src, th->th_dport, th->th_sport,
3e170ce0
A
6578 src->seqhi, ntohl(th->th_seq) + 1,
6579 TH_SYN|TH_ACK, 0, src->mss, 0, 1,
b0d623f7
A
6580 0, NULL, NULL);
6581 REASON_SET(reason, PFRES_SYNPROXY);
6582 return (PF_SYNPROXY_DROP);
6583 } else if (!(th->th_flags & TH_ACK) ||
3e170ce0
A
6584 (ntohl(th->th_ack) != src->seqhi + 1) ||
6585 (ntohl(th->th_seq) != src->seqlo + 1)) {
b0d623f7
A
6586 REASON_SET(reason, PFRES_SYNPROXY);
6587 return (PF_DROP);
6588 } else if ((*state)->src_node != NULL &&
6589 pf_src_connlimit(state)) {
6590 REASON_SET(reason, PFRES_SRCLIMIT);
6591 return (PF_DROP);
6592 } else
3e170ce0 6593 src->state = PF_TCPS_PROXY_DST;
b0d623f7 6594 }
3e170ce0 6595 if (src->state == PF_TCPS_PROXY_DST) {
b0d623f7
A
6596 struct pf_state_host *psrc, *pdst;
6597
6598 if (direction == PF_OUT) {
3e170ce0
A
6599 psrc = &sk->gwy;
6600 pdst = &sk->ext_gwy;
b0d623f7 6601 } else {
3e170ce0
A
6602 psrc = &sk->ext_lan;
6603 pdst = &sk->lan;
b0d623f7 6604 }
3e170ce0 6605 if (direction == sk->direction) {
b0d623f7 6606 if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) ||
3e170ce0
A
6607 (ntohl(th->th_ack) != src->seqhi + 1) ||
6608 (ntohl(th->th_seq) != src->seqlo + 1)) {
b0d623f7
A
6609 REASON_SET(reason, PFRES_SYNPROXY);
6610 return (PF_DROP);
6611 }
3e170ce0
A
6612 src->max_win = MAX(ntohs(th->th_win), 1);
6613 if (dst->seqhi == 1)
6614 dst->seqhi = htonl(random());
b0d623f7 6615 pf_send_tcp((*state)->rule.ptr, pd->af, &psrc->addr,
b0d623f7 6616 &pdst->addr, psrc->xport.port, pdst->xport.port,
3e170ce0
A
6617 dst->seqhi, 0, TH_SYN, 0,
6618 src->mss, 0, 0, (*state)->tag, NULL, NULL);
b0d623f7
A
6619 REASON_SET(reason, PFRES_SYNPROXY);
6620 return (PF_SYNPROXY_DROP);
6621 } else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
6622 (TH_SYN|TH_ACK)) ||
3e170ce0 6623 (ntohl(th->th_ack) != dst->seqhi + 1)) {
b0d623f7
A
6624 REASON_SET(reason, PFRES_SYNPROXY);
6625 return (PF_DROP);
6626 } else {
3e170ce0
A
6627 dst->max_win = MAX(ntohs(th->th_win), 1);
6628 dst->seqlo = ntohl(th->th_seq);
b0d623f7
A
6629 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
6630 pd->src, th->th_dport, th->th_sport,
6631 ntohl(th->th_ack), ntohl(th->th_seq) + 1,
3e170ce0 6632 TH_ACK, src->max_win, 0, 0, 0,
b0d623f7
A
6633 (*state)->tag, NULL, NULL);
6634 pf_send_tcp((*state)->rule.ptr, pd->af, &psrc->addr,
b0d623f7 6635 &pdst->addr, psrc->xport.port, pdst->xport.port,
3e170ce0
A
6636 src->seqhi + 1, src->seqlo + 1,
6637 TH_ACK, dst->max_win, 0, 0, 1,
b0d623f7 6638 0, NULL, NULL);
3e170ce0
A
6639 src->seqdiff = dst->seqhi -
6640 src->seqlo;
6641 dst->seqdiff = src->seqhi -
6642 dst->seqlo;
6643 src->seqhi = src->seqlo +
6644 dst->max_win;
6645 dst->seqhi = dst->seqlo +
6646 src->max_win;
6647 src->wscale = dst->wscale = 0;
6648 src->state = dst->state =
b0d623f7
A
6649 TCPS_ESTABLISHED;
6650 REASON_SET(reason, PFRES_SYNPROXY);
6651 return (PF_SYNPROXY_DROP);
6652 }
6653 }
6654
6655 if (((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) &&
6656 dst->state >= TCPS_FIN_WAIT_2 &&
6657 src->state >= TCPS_FIN_WAIT_2) {
6658 if (pf_status.debug >= PF_DEBUG_MISC) {
6659 printf("pf: state reuse ");
6660 pf_print_state(*state);
6661 pf_print_flags(th->th_flags);
6662 printf("\n");
6663 }
6664 /* XXX make sure it's the same direction ?? */
3e170ce0 6665 src->state = dst->state = TCPS_CLOSED;
b0d623f7
A
6666 pf_unlink_state(*state);
6667 *state = NULL;
6668 return (PF_DROP);
6669 }
6670
39236c6e
A
6671 if ((th->th_flags & TH_SYN) == 0) {
6672 sws = (src->wscale & PF_WSCALE_FLAG) ?
6673 (src->wscale & PF_WSCALE_MASK) : TCP_MAX_WINSHIFT;
6674 dws = (dst->wscale & PF_WSCALE_FLAG) ?
6675 (dst->wscale & PF_WSCALE_MASK) : TCP_MAX_WINSHIFT;
6676 }
6677 else
b0d623f7
A
6678 sws = dws = 0;
6679
6680 /*
6681 * Sequence tracking algorithm from Guido van Rooij's paper:
6682 * http://www.madison-gurkha.com/publications/tcp_filtering/
6683 * tcp_filtering.ps
6684 */
6685
6686 orig_seq = seq = ntohl(th->th_seq);
6687 if (src->seqlo == 0) {
6688 /* First packet from this end. Set its state */
6689
6690 if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) &&
6691 src->scrub == NULL) {
6692 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) {
6693 REASON_SET(reason, PFRES_MEMORY);
6694 return (PF_DROP);
6695 }
6696 }
6697
6698 /* Deferred generation of sequence number modulator */
6699 if (dst->seqdiff && !src->seqdiff) {
6700 /* use random iss for the TCP server */
6701 while ((src->seqdiff = random() - seq) == 0)
6702 ;
6703 ack = ntohl(th->th_ack) - dst->seqdiff;
6704 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
6705 src->seqdiff), 0);
6706 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
6707 copyback = off + sizeof (*th);
6708 } else {
6709 ack = ntohl(th->th_ack);
6710 }
6711
6712 end = seq + pd->p_len;
6713 if (th->th_flags & TH_SYN) {
6714 end++;
6715 if (dst->wscale & PF_WSCALE_FLAG) {
6716 src->wscale = pf_get_wscale(m, off, th->th_off,
6717 pd->af);
6718 if (src->wscale & PF_WSCALE_FLAG) {
6719 /*
6720 * Remove scale factor from initial
6721 * window
6722 */
6723 sws = src->wscale & PF_WSCALE_MASK;
6724 win = ((u_int32_t)win + (1 << sws) - 1)
6725 >> sws;
6726 dws = dst->wscale & PF_WSCALE_MASK;
6727 } else {
b7266188 6728 /*
b7266188
A
6729 * Window scale negotiation has failed,
6730 * therefore we must restore the window
6731 * scale in the state record that we
6732 * optimistically removed in
6733 * pf_test_rule(). Care is required to
6734 * prevent arithmetic overflow from
6735 * zeroing the window when it's
316670eb 6736 * truncated down to 16-bits.
b7266188 6737 */
d1ecb069
A
6738 u_int32_t max_win = dst->max_win;
6739 max_win <<=
6740 dst->wscale & PF_WSCALE_MASK;
6741 dst->max_win = MIN(0xffff, max_win);
b0d623f7
A
6742 /* in case of a retrans SYN|ACK */
6743 dst->wscale = 0;
6744 }
6745 }
6746 }
6747 if (th->th_flags & TH_FIN)
6748 end++;
6749
6750 src->seqlo = seq;
6751 if (src->state < TCPS_SYN_SENT)
6752 src->state = TCPS_SYN_SENT;
6753
6754 /*
6755 * May need to slide the window (seqhi may have been set by
6756 * the crappy stack check or if we picked up the connection
6757 * after establishment)
6758 */
b7266188
A
6759 if (src->seqhi == 1 ||
6760 SEQ_GEQ(end + MAX(1, (u_int32_t)dst->max_win << dws),
6761 src->seqhi))
6762 src->seqhi = end + MAX(1, (u_int32_t)dst->max_win << dws);
b0d623f7
A
6763 if (win > src->max_win)
6764 src->max_win = win;
6765
6766 } else {
6767 ack = ntohl(th->th_ack) - dst->seqdiff;
6768 if (src->seqdiff) {
6769 /* Modulate sequence numbers */
6770 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
6771 src->seqdiff), 0);
6772 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
6773 copyback = off+ sizeof (*th);
6774 }
6775 end = seq + pd->p_len;
6776 if (th->th_flags & TH_SYN)
6777 end++;
6778 if (th->th_flags & TH_FIN)
6779 end++;
6780 }
6781
6782 if ((th->th_flags & TH_ACK) == 0) {
6783 /* Let it pass through the ack skew check */
6784 ack = dst->seqlo;
6785 } else if ((ack == 0 &&
6786 (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) ||
6787 /* broken tcp stacks do not set ack */
6788 (dst->state < TCPS_SYN_SENT)) {
6789 /*
6790 * Many stacks (ours included) will set the ACK number in an
6791 * FIN|ACK if the SYN times out -- no sequence to ACK.
6792 */
6793 ack = dst->seqlo;
6794 }
6795
6796 if (seq == end) {
6797 /* Ease sequencing restrictions on no data packets */
6798 seq = src->seqlo;
6799 end = seq;
6800 }
6801
6802 ackskew = dst->seqlo - ack;
6803
6804
6805 /*
6806 * Need to demodulate the sequence numbers in any TCP SACK options
6807 * (Selective ACK). We could optionally validate the SACK values
6808 * against the current ACK window, either forwards or backwards, but
6809 * I'm not confident that SACK has been implemented properly
6810 * everywhere. It wouldn't surprise me if several stacks accidently
6811 * SACK too far backwards of previously ACKed data. There really aren't
6812 * any security implications of bad SACKing unless the target stack
6813 * doesn't validate the option length correctly. Someone trying to
6814 * spoof into a TCP connection won't bother blindly sending SACK
6815 * options anyway.
6816 */
6817 if (dst->seqdiff && (th->th_off << 2) > (int)sizeof (struct tcphdr)) {
b0d623f7
A
6818 copyback = pf_modulate_sack(m, off, pd, th, dst);
6819 if (copyback == -1) {
6820 REASON_SET(reason, PFRES_MEMORY);
6821 return (PF_DROP);
6822 }
6823
6824 m = pd->mp;
b0d623f7
A
6825 }
6826
6827
6828#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */
6829 if (SEQ_GEQ(src->seqhi, end) &&
6830 /* Last octet inside other's window space */
b7266188 6831 SEQ_GEQ(seq, src->seqlo - ((u_int32_t)dst->max_win << dws)) &&
b0d623f7
A
6832 /* Retrans: not more than one window back */
6833 (ackskew >= -MAXACKWINDOW) &&
6834 /* Acking not more than one reassembled fragment backwards */
6835 (ackskew <= (MAXACKWINDOW << sws)) &&
6836 /* Acking not more than one window forward */
6837 ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
6838 (orig_seq == src->seqlo + 1) || (orig_seq + 1 == src->seqlo) ||
6839 (pd->flags & PFDESC_IP_REAS) == 0)) {
6840 /* Require an exact/+1 sequence match on resets when possible */
6841
6842 if (dst->scrub || src->scrub) {
6843 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
6844 *state, src, dst, &copyback))
6845 return (PF_DROP);
6846
b0d623f7 6847 m = pd->mp;
b0d623f7
A
6848 }
6849
6850 /* update max window */
6851 if (src->max_win < win)
6852 src->max_win = win;
6853 /* synchronize sequencing */
6854 if (SEQ_GT(end, src->seqlo))
6855 src->seqlo = end;
6856 /* slide the window of what the other end can send */
b7266188
A
6857 if (SEQ_GEQ(ack + ((u_int32_t)win << sws), dst->seqhi))
6858 dst->seqhi = ack + MAX(((u_int32_t)win << sws), 1);
b0d623f7
A
6859
6860 /* update states */
6861 if (th->th_flags & TH_SYN)
6862 if (src->state < TCPS_SYN_SENT)
6863 src->state = TCPS_SYN_SENT;
6864 if (th->th_flags & TH_FIN)
6865 if (src->state < TCPS_CLOSING)
6866 src->state = TCPS_CLOSING;
6867 if (th->th_flags & TH_ACK) {
6868 if (dst->state == TCPS_SYN_SENT) {
6869 dst->state = TCPS_ESTABLISHED;
6870 if (src->state == TCPS_ESTABLISHED &&
6871 (*state)->src_node != NULL &&
6872 pf_src_connlimit(state)) {
6873 REASON_SET(reason, PFRES_SRCLIMIT);
6874 return (PF_DROP);
6875 }
6876 } else if (dst->state == TCPS_CLOSING)
6877 dst->state = TCPS_FIN_WAIT_2;
6878 }
6879 if (th->th_flags & TH_RST)
6880 src->state = dst->state = TCPS_TIME_WAIT;
6881
6882 /* update expire time */
6883 (*state)->expire = pf_time_second();
6884 if (src->state >= TCPS_FIN_WAIT_2 &&
6885 dst->state >= TCPS_FIN_WAIT_2)
6886 (*state)->timeout = PFTM_TCP_CLOSED;
6887 else if (src->state >= TCPS_CLOSING &&
6888 dst->state >= TCPS_CLOSING)
6889 (*state)->timeout = PFTM_TCP_FIN_WAIT;
6890 else if (src->state < TCPS_ESTABLISHED ||
6891 dst->state < TCPS_ESTABLISHED)
6892 (*state)->timeout = PFTM_TCP_OPENING;
6893 else if (src->state >= TCPS_CLOSING ||
6894 dst->state >= TCPS_CLOSING)
6895 (*state)->timeout = PFTM_TCP_CLOSING;
6896 else
6897 (*state)->timeout = PFTM_TCP_ESTABLISHED;
6898
6899 /* Fall through to PASS packet */
6900
6901 } else if ((dst->state < TCPS_SYN_SENT ||
6902 dst->state >= TCPS_FIN_WAIT_2 || src->state >= TCPS_FIN_WAIT_2) &&
6903 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) &&
6904 /* Within a window forward of the originating packet */
6905 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) {
6906 /* Within a window backward of the originating packet */
6907
6908 /*
6909 * This currently handles three situations:
6910 * 1) Stupid stacks will shotgun SYNs before their peer
6911 * replies.
6912 * 2) When PF catches an already established stream (the
6913 * firewall rebooted, the state table was flushed, routes
6914 * changed...)
6915 * 3) Packets get funky immediately after the connection
6916 * closes (this should catch Solaris spurious ACK|FINs
6917 * that web servers like to spew after a close)
6918 *
6919 * This must be a little more careful than the above code
6920 * since packet floods will also be caught here. We don't
6921 * update the TTL here to mitigate the damage of a packet
6922 * flood and so the same code can handle awkward establishment
6923 * and a loosened connection close.
6924 * In the establishment case, a correct peer response will
6925 * validate the connection, go through the normal state code
6926 * and keep updating the state TTL.
6927 */
6928
6929 if (pf_status.debug >= PF_DEBUG_MISC) {
6930 printf("pf: loose state match: ");
6931 pf_print_state(*state);
6932 pf_print_flags(th->th_flags);
6933 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
6934 "pkts=%llu:%llu dir=%s,%s\n", seq, orig_seq, ack,
6935 pd->p_len, ackskew, (*state)->packets[0],
6936 (*state)->packets[1],
6937 direction == PF_IN ? "in" : "out",
3e170ce0 6938 direction == sk->direction ?
b0d623f7
A
6939 "fwd" : "rev");
6940 }
6941
6942 if (dst->scrub || src->scrub) {
6943 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
6944 *state, src, dst, &copyback))
6945 return (PF_DROP);
b0d623f7 6946 m = pd->mp;
b0d623f7
A
6947 }
6948
6949 /* update max window */
6950 if (src->max_win < win)
6951 src->max_win = win;
6952 /* synchronize sequencing */
6953 if (SEQ_GT(end, src->seqlo))
6954 src->seqlo = end;
6955 /* slide the window of what the other end can send */
b7266188
A
6956 if (SEQ_GEQ(ack + ((u_int32_t)win << sws), dst->seqhi))
6957 dst->seqhi = ack + MAX(((u_int32_t)win << sws), 1);
b0d623f7
A
6958
6959 /*
6960 * Cannot set dst->seqhi here since this could be a shotgunned
6961 * SYN and not an already established connection.
6962 */
6963
6964 if (th->th_flags & TH_FIN)
6965 if (src->state < TCPS_CLOSING)
6966 src->state = TCPS_CLOSING;
6967 if (th->th_flags & TH_RST)
6968 src->state = dst->state = TCPS_TIME_WAIT;
6969
6970 /* Fall through to PASS packet */
6971
6972 } else {
3e170ce0
A
6973 if (dst->state == TCPS_SYN_SENT &&
6974 src->state == TCPS_SYN_SENT) {
b0d623f7
A
6975 /* Send RST for state mismatches during handshake */
6976 if (!(th->th_flags & TH_RST))
6977 pf_send_tcp((*state)->rule.ptr, pd->af,
6978 pd->dst, pd->src, th->th_dport,
6979 th->th_sport, ntohl(th->th_ack), 0,
6980 TH_RST, 0, 0,
6981 (*state)->rule.ptr->return_ttl, 1, 0,
6982 pd->eh, kif->pfik_ifp);
6983 src->seqlo = 0;
6984 src->seqhi = 1;
6985 src->max_win = 1;
6986 } else if (pf_status.debug >= PF_DEBUG_MISC) {
6987 printf("pf: BAD state: ");
6988 pf_print_state(*state);
6989 pf_print_flags(th->th_flags);
39236c6e
A
6990 printf("\n seq=%u (%u) ack=%u len=%u ackskew=%d "
6991 "sws=%u dws=%u pkts=%llu:%llu dir=%s,%s\n",
b0d623f7 6992 seq, orig_seq, ack, pd->p_len, ackskew,
39236c6e 6993 (unsigned int)sws, (unsigned int)dws,
b0d623f7
A
6994 (*state)->packets[0], (*state)->packets[1],
6995 direction == PF_IN ? "in" : "out",
3e170ce0 6996 direction == sk->direction ?
b0d623f7
A
6997 "fwd" : "rev");
6998 printf("pf: State failure on: %c %c %c %c | %c %c\n",
6999 SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
b7266188
A
7000 SEQ_GEQ(seq,
7001 src->seqlo - ((u_int32_t)dst->max_win << dws)) ?
b0d623f7
A
7002 ' ': '2',
7003 (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
7004 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',
7005 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5',
7006 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6');
7007 }
7008 REASON_SET(reason, PFRES_BADSTATE);
7009 return (PF_DROP);
7010 }
7011
7012 /* Any packets which have gotten here are to be passed */
7013
3e170ce0
A
7014 if (sk->app_state &&
7015 sk->app_state->handler) {
7016 sk->app_state->handler(*state, direction,
b0d623f7
A
7017 off + (th->th_off << 2), pd, kif);
7018 if (pd->lmw < 0) {
7019 REASON_SET(reason, PFRES_MEMORY);
7020 return (PF_DROP);
7021 }
7022 m = pd->mp;
7023 }
7024
7025 /* translate source/destination address, if necessary */
3e170ce0
A
7026 if (STATE_TRANSLATE(sk)) {
7027 pd->naf = (pd->af == sk->af_lan) ? sk->af_gwy : sk->af_lan;
7028
7029 if (direction == PF_OUT) {
b0d623f7 7030 pf_change_ap(direction, pd->mp, pd->src, &th->th_sport,
3e170ce0
A
7031 pd->ip_sum, &th->th_sum, &sk->gwy.addr,
7032 sk->gwy.xport.port, 0, pd->af, pd->naf, 1);
7033 } else {
7034 if (pd->af != pd->naf) {
7035 if (pd->af == sk->af_gwy) {
7036 pf_change_ap(direction, pd->mp, pd->dst,
7037 &th->th_dport, pd->ip_sum,
7038 &th->th_sum, &sk->lan.addr,
7039 sk->lan.xport.port, 0,
7040 pd->af, pd->naf, 0);
7041
7042 pf_change_ap(direction, pd->mp, pd->src,
7043 &th->th_sport, pd->ip_sum,
7044 &th->th_sum, &sk->ext_lan.addr,
7045 th->th_sport, 0, pd->af,
7046 pd->naf, 0);
7047
7048 } else {
7049 pf_change_ap(direction, pd->mp, pd->dst,
7050 &th->th_dport, pd->ip_sum,
7051 &th->th_sum, &sk->ext_gwy.addr,
7052 th->th_dport, 0, pd->af,
7053 pd->naf, 0);
7054
7055 pf_change_ap(direction, pd->mp, pd->src,
7056 &th->th_sport, pd->ip_sum,
7057 &th->th_sum, &sk->gwy.addr,
7058 sk->gwy.xport.port, 0, pd->af,
7059 pd->naf, 0);
7060 }
7061 } else {
7062 pf_change_ap(direction, pd->mp, pd->dst,
7063 &th->th_dport, pd->ip_sum,
7064 &th->th_sum, &sk->lan.addr,
7065 sk->lan.xport.port, 0, pd->af,
7066 pd->naf, 1);
7067 }
7068 }
7069
b0d623f7
A
7070 copyback = off + sizeof (*th);
7071 }
7072
7073 if (copyback) {
7074 m = pf_lazy_makewritable(pd, m, copyback);
7075 if (!m) {
7076 REASON_SET(reason, PFRES_MEMORY);
7077 return (PF_DROP);
7078 }
7079
7080 /* Copyback sequence modulation or stateful scrub changes */
7081 m_copyback(m, off, sizeof (*th), th);
b0d623f7 7082
3e170ce0
A
7083 if (sk->af_lan != sk->af_gwy)
7084 return (pf_do_nat64(sk, pd, m, off));
7085 }
b0d623f7
A
7086 return (PF_PASS);
7087}
7088
7089static int
7090pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
b7266188 7091 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason)
b0d623f7
A
7092{
7093#pragma unused(h)
7094 struct pf_state_peer *src, *dst;
7095 struct pf_state_key_cmp key;
3e170ce0 7096 struct pf_state_key *sk;
b0d623f7 7097 struct udphdr *uh = pd->hdr.udp;
b0d623f7 7098 struct pf_app_state as;
3e170ce0 7099 int action, extfilter;
b0d623f7
A
7100 key.app_state = 0;
7101 key.proto_variant = PF_EXTFILTER_APD;
b0d623f7 7102
b0d623f7 7103 key.proto = IPPROTO_UDP;
3e170ce0
A
7104 key.af_lan = key.af_gwy = pd->af;
7105
7106 /*
7107 * For NAT64 the first time rule search and state creation
7108 * is done on the incoming side only.
7109 * Once the state gets created, NAT64's LAN side (ipv6) will
7110 * not be able to find the state in ext-gwy tree as that normally
7111 * is intended to be looked up for incoming traffic from the
7112 * WAN side.
7113 * Therefore to handle NAT64 case we init keys here for both
7114 * lan-ext as well as ext-gwy trees.
7115 * In the state lookup we attempt a lookup on both trees if
7116 * first one does not return any result and return a match if
7117 * the match state's was created by NAT64 rule.
7118 */
7119 PF_ACPY(&key.ext_gwy.addr, pd->src, key.af_gwy);
7120 PF_ACPY(&key.gwy.addr, pd->dst, key.af_gwy);
7121 key.ext_gwy.xport.port = uh->uh_sport;
7122 key.gwy.xport.port = uh->uh_dport;
7123
7124 PF_ACPY(&key.lan.addr, pd->src, key.af_lan);
7125 PF_ACPY(&key.ext_lan.addr, pd->dst, key.af_lan);
7126 key.lan.xport.port = uh->uh_sport;
7127 key.ext_lan.xport.port = uh->uh_dport;
b0d623f7 7128
b7266188
A
7129 if (ntohs(uh->uh_sport) == PF_IKE_PORT &&
7130 ntohs(uh->uh_dport) == PF_IKE_PORT) {
b0d623f7
A
7131 struct pf_ike_hdr ike;
7132 size_t plen = m->m_pkthdr.len - off - sizeof (*uh);
7133 if (plen < PF_IKE_PACKET_MINSIZE) {
7134 DPFPRINTF(PF_DEBUG_MISC,
7135 ("pf: IKE message too small.\n"));
7136 return (PF_DROP);
7137 }
7138
7139 if (plen > sizeof (ike))
7140 plen = sizeof (ike);
7141 m_copydata(m, off + sizeof (*uh), plen, &ike);
7142
7143 if (ike.initiator_cookie) {
7144 key.app_state = &as;
7145 as.compare_lan_ext = pf_ike_compare;
7146 as.compare_ext_gwy = pf_ike_compare;
7147 as.u.ike.cookie = ike.initiator_cookie;
7148 } else {
7149 /*
7150 * <http://tools.ietf.org/html/\
7151 * draft-ietf-ipsec-nat-t-ike-01>
7152 * Support non-standard NAT-T implementations that
7153 * push the ESP packet over the top of the IKE packet.
7154 * Do not drop packet.
7155 */
7156 DPFPRINTF(PF_DEBUG_MISC,
7157 ("pf: IKE initiator cookie = 0.\n"));
7158 }
7159 }
7160
3e170ce0 7161 *state = pf_find_state(kif, &key, direction);
b0d623f7
A
7162
7163 if (!key.app_state && *state == 0) {
7164 key.proto_variant = PF_EXTFILTER_AD;
3e170ce0 7165 *state = pf_find_state(kif, &key, direction);
b0d623f7
A
7166 }
7167
7168 if (!key.app_state && *state == 0) {
7169 key.proto_variant = PF_EXTFILTER_EI;
3e170ce0 7170 *state = pf_find_state(kif, &key, direction);
b0d623f7
A
7171 }
7172
39236c6e
A
7173 /* similar to STATE_LOOKUP() */
7174 if (*state != NULL && pd != NULL && !(pd->pktflags & PKTF_FLOW_ID)) {
7175 pd->flowsrc = (*state)->state_key->flowsrc;
316670eb 7176 pd->flowhash = (*state)->state_key->flowhash;
39236c6e
A
7177 if (pd->flowhash != 0) {
7178 pd->pktflags |= PKTF_FLOW_ID;
7179 pd->pktflags &= ~PKTF_FLOW_ADV;
7180 }
7181 }
316670eb 7182
b0d623f7
A
7183 if (pf_state_lookup_aux(state, kif, direction, &action))
7184 return (action);
b0d623f7 7185
3e170ce0
A
7186 sk = (*state)->state_key;
7187
7188 /*
7189 * In case of NAT64 the translation is first applied on the LAN
7190 * side. Therefore for stack's address family comparison
7191 * we use sk->af_lan.
7192 */
7193 if ((direction == sk->direction) && (pd->af == sk->af_lan)) {
b0d623f7
A
7194 src = &(*state)->src;
7195 dst = &(*state)->dst;
7196 } else {
7197 src = &(*state)->dst;
7198 dst = &(*state)->src;
7199 }
7200
7201 /* update states */
7202 if (src->state < PFUDPS_SINGLE)
7203 src->state = PFUDPS_SINGLE;
7204 if (dst->state == PFUDPS_SINGLE)
7205 dst->state = PFUDPS_MULTIPLE;
7206
7207 /* update expire time */
7208 (*state)->expire = pf_time_second();
7209 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE)
7210 (*state)->timeout = PFTM_UDP_MULTIPLE;
7211 else
7212 (*state)->timeout = PFTM_UDP_SINGLE;
7213
3e170ce0 7214 extfilter = sk->proto_variant;
b0d623f7 7215 if (extfilter > PF_EXTFILTER_APD) {
3e170ce0
A
7216 if (direction == PF_OUT) {
7217 sk->ext_lan.xport.port = key.ext_lan.xport.port;
7218 if (extfilter > PF_EXTFILTER_AD)
7219 PF_ACPY(&sk->ext_lan.addr, &key.ext_lan.addr,
7220 key.af_lan);
7221 } else {
7222 sk->ext_gwy.xport.port = key.ext_gwy.xport.port;
7223 if (extfilter > PF_EXTFILTER_AD)
7224 PF_ACPY(&sk->ext_gwy.addr, &key.ext_gwy.addr,
7225 key.af_gwy);
7226 }
b0d623f7
A
7227 }
7228
3e170ce0
A
7229 if (sk->app_state && sk->app_state->handler) {
7230 sk->app_state->handler(*state, direction, off + uh->uh_ulen,
7231 pd, kif);
b7266188
A
7232 if (pd->lmw < 0) {
7233 REASON_SET(reason, PFRES_MEMORY);
7234 return (PF_DROP);
7235 }
b0d623f7
A
7236 m = pd->mp;
7237 }
b0d623f7
A
7238
7239 /* translate source/destination address, if necessary */
3e170ce0 7240 if (STATE_TRANSLATE(sk)) {
b0d623f7 7241 m = pf_lazy_makewritable(pd, m, off + sizeof (*uh));
d1ecb069
A
7242 if (!m) {
7243 REASON_SET(reason, PFRES_MEMORY);
b0d623f7 7244 return (PF_DROP);
d1ecb069 7245 }
b0d623f7 7246
3e170ce0
A
7247 pd->naf = (pd->af == sk->af_lan) ? sk->af_gwy : sk->af_lan;
7248
7249 if (direction == PF_OUT) {
b0d623f7 7250 pf_change_ap(direction, pd->mp, pd->src, &uh->uh_sport,
3e170ce0
A
7251 pd->ip_sum, &uh->uh_sum, &sk->gwy.addr,
7252 sk->gwy.xport.port, 1, pd->af, pd->naf, 1);
7253 } else {
7254 if (pd->af != pd->naf) {
7255
7256 if (pd->af == sk->af_gwy) {
7257 pf_change_ap(direction, pd->mp, pd->dst,
7258 &uh->uh_dport, pd->ip_sum,
7259 &uh->uh_sum, &sk->lan.addr,
7260 sk->lan.xport.port, 1,
7261 pd->af, pd->naf, 0);
7262
7263 pf_change_ap(direction, pd->mp, pd->src,
7264 &uh->uh_sport, pd->ip_sum,
7265 &uh->uh_sum, &sk->ext_lan.addr,
7266 uh->uh_sport, 1, pd->af,
7267 pd->naf, 0);
7268
7269 } else {
7270 pf_change_ap(direction, pd->mp, pd->dst,
7271 &uh->uh_dport, pd->ip_sum,
7272 &uh->uh_sum, &sk->ext_gwy.addr,
7273 uh->uh_dport, 1, pd->af,
7274 pd->naf, 0);
7275
7276 pf_change_ap(direction, pd->mp, pd->src,
7277 &uh->uh_sport, pd->ip_sum,
7278 &uh->uh_sum, &sk->gwy.addr,
7279 sk->gwy.xport.port, 1, pd->af,
7280 pd->naf, 0);
7281 }
7282 } else {
7283 pf_change_ap(direction, pd->mp, pd->dst,
7284 &uh->uh_dport, pd->ip_sum,
7285 &uh->uh_sum, &sk->lan.addr,
7286 sk->lan.xport.port, 1,
7287 pd->af, pd->naf, 1);
7288 }
7289 }
7290
b0d623f7 7291 m_copyback(m, off, sizeof (*uh), uh);
3e170ce0
A
7292 if (sk->af_lan != sk->af_gwy)
7293 return (pf_do_nat64(sk, pd, m, off));
b0d623f7 7294 }
b0d623f7
A
7295 return (PF_PASS);
7296}
7297
7298static int
7299pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
7300 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason)
7301{
7302#pragma unused(h)
7303 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3e170ce0 7304 struct in_addr srcv4_inaddr = saddr->v4;
b0d623f7
A
7305 u_int16_t icmpid = 0, *icmpsum;
7306 u_int8_t icmptype;
7307 int state_icmp = 0;
7308 struct pf_state_key_cmp key;
3e170ce0 7309 struct pf_state_key *sk;
b0d623f7 7310
b0d623f7
A
7311 struct pf_app_state as;
7312 key.app_state = 0;
b0d623f7 7313
3e170ce0
A
7314 pd->off = off;
7315
b0d623f7
A
7316 switch (pd->proto) {
7317#if INET
7318 case IPPROTO_ICMP:
7319 icmptype = pd->hdr.icmp->icmp_type;
7320 icmpid = pd->hdr.icmp->icmp_id;
7321 icmpsum = &pd->hdr.icmp->icmp_cksum;
7322
7323 if (icmptype == ICMP_UNREACH ||
7324 icmptype == ICMP_SOURCEQUENCH ||
7325 icmptype == ICMP_REDIRECT ||
7326 icmptype == ICMP_TIMXCEED ||
7327 icmptype == ICMP_PARAMPROB)
7328 state_icmp++;
7329 break;
7330#endif /* INET */
7331#if INET6
7332 case IPPROTO_ICMPV6:
7333 icmptype = pd->hdr.icmp6->icmp6_type;
7334 icmpid = pd->hdr.icmp6->icmp6_id;
7335 icmpsum = &pd->hdr.icmp6->icmp6_cksum;
7336
7337 if (icmptype == ICMP6_DST_UNREACH ||
7338 icmptype == ICMP6_PACKET_TOO_BIG ||
7339 icmptype == ICMP6_TIME_EXCEEDED ||
7340 icmptype == ICMP6_PARAM_PROB)
7341 state_icmp++;
7342 break;
7343#endif /* INET6 */
7344 }
7345
7346 if (!state_icmp) {
7347
7348 /*
7349 * ICMP query/reply message not related to a TCP/UDP packet.
7350 * Search for an ICMP state.
7351 */
3e170ce0
A
7352 /*
7353 * NAT64 requires protocol translation between ICMPv4
7354 * and ICMPv6. TCP and UDP do not require protocol
7355 * translation. To avoid adding complexity just to
7356 * handle ICMP(v4/v6), we always lookup for
7357 * proto = IPPROTO_ICMP on both LAN and WAN side
7358 */
7359 key.proto = IPPROTO_ICMP;
7360 key.af_lan = key.af_gwy = pd->af;
7361
7362 PF_ACPY(&key.ext_gwy.addr, pd->src, key.af_gwy);
7363 PF_ACPY(&key.gwy.addr, pd->dst, key.af_gwy);
7364 key.ext_gwy.xport.port = 0;
7365 key.gwy.xport.port = icmpid;
7366
7367 PF_ACPY(&key.lan.addr, pd->src, key.af_lan);
7368 PF_ACPY(&key.ext_lan.addr, pd->dst, key.af_lan);
7369 key.lan.xport.port = icmpid;
7370 key.ext_lan.xport.port = 0;
b0d623f7
A
7371
7372 STATE_LOOKUP();
7373
3e170ce0 7374 sk = (*state)->state_key;
b0d623f7
A
7375 (*state)->expire = pf_time_second();
7376 (*state)->timeout = PFTM_ICMP_ERROR_REPLY;
7377
7378 /* translate source/destination address, if necessary */
3e170ce0
A
7379 if (STATE_TRANSLATE(sk)) {
7380 pd->naf = (pd->af == sk->af_lan) ?
7381 sk->af_gwy : sk->af_lan;
b0d623f7
A
7382 if (direction == PF_OUT) {
7383 switch (pd->af) {
7384#if INET
7385 case AF_INET:
7386 pf_change_a(&saddr->v4.s_addr,
7387 pd->ip_sum,
3e170ce0 7388 sk->gwy.addr.v4.s_addr, 0);
b0d623f7
A
7389 pd->hdr.icmp->icmp_cksum =
7390 pf_cksum_fixup(
7391 pd->hdr.icmp->icmp_cksum, icmpid,
3e170ce0 7392 sk->gwy.xport.port, 0);
b0d623f7 7393 pd->hdr.icmp->icmp_id =
3e170ce0 7394 sk->gwy.xport.port;
b0d623f7 7395 m = pf_lazy_makewritable(pd, m,
3e170ce0 7396 off + ICMP_MINLEN);
b0d623f7
A
7397 if (!m)
7398 return (PF_DROP);
b0d623f7
A
7399 m_copyback(m, off, ICMP_MINLEN,
7400 pd->hdr.icmp);
7401 break;
7402#endif /* INET */
7403#if INET6
7404 case AF_INET6:
7405 pf_change_a6(saddr,
7406 &pd->hdr.icmp6->icmp6_cksum,
3e170ce0 7407 &sk->gwy.addr, 0);
b0d623f7
A
7408 m = pf_lazy_makewritable(pd, m,
7409 off + sizeof (struct icmp6_hdr));
7410 if (!m)
7411 return (PF_DROP);
b0d623f7
A
7412 m_copyback(m, off,
7413 sizeof (struct icmp6_hdr),
7414 pd->hdr.icmp6);
7415 break;
7416#endif /* INET6 */
7417 }
7418 } else {
7419 switch (pd->af) {
7420#if INET
7421 case AF_INET:
3e170ce0
A
7422 if (pd->naf != AF_INET) {
7423 if (pf_translate_icmp_af(
7424 AF_INET6, pd->hdr.icmp))
7425 return (PF_DROP);
7426
7427 pd->proto = IPPROTO_ICMPV6;
7428
7429 } else {
7430
7431 pf_change_a(&daddr->v4.s_addr,
7432 pd->ip_sum,
7433 sk->lan.addr.v4.s_addr, 0);
7434
7435 pd->hdr.icmp->icmp_cksum =
7436 pf_cksum_fixup(
7437 pd->hdr.icmp->icmp_cksum,
7438 icmpid, sk->lan.xport.port, 0);
7439
7440 pd->hdr.icmp->icmp_id =
7441 sk->lan.xport.port;
7442 }
7443
b0d623f7
A
7444 m = pf_lazy_makewritable(pd, m,
7445 off + ICMP_MINLEN);
7446 if (!m)
7447 return (PF_DROP);
b0d623f7 7448 m_copyback(m, off, ICMP_MINLEN,
3e170ce0
A
7449 pd->hdr.icmp);
7450 if (sk->af_lan != sk->af_gwy)
7451 return (pf_do_nat64(sk, pd, m,
7452 off));
b0d623f7
A
7453 break;
7454#endif /* INET */
7455#if INET6
7456 case AF_INET6:
3e170ce0
A
7457 if (pd->naf != AF_INET6) {
7458 if (pf_translate_icmp_af(
7459 AF_INET, pd->hdr.icmp6))
7460 return (PF_DROP);
7461
7462 pd->proto = IPPROTO_ICMP;
7463 } else {
7464 pf_change_a6(daddr,
7465 &pd->hdr.icmp6->icmp6_cksum,
7466 &sk->lan.addr, 0);
7467 }
b0d623f7
A
7468 m = pf_lazy_makewritable(pd, m,
7469 off + sizeof (struct icmp6_hdr));
7470 if (!m)
7471 return (PF_DROP);
b0d623f7 7472 m_copyback(m, off,
3e170ce0
A
7473 sizeof (struct icmp6_hdr),
7474 pd->hdr.icmp6);
7475 if (sk->af_lan != sk->af_gwy)
7476 return (pf_do_nat64(sk, pd, m,
7477 off));
b0d623f7
A
7478 break;
7479#endif /* INET6 */
7480 }
7481 }
7482 }
7483
7484 return (PF_PASS);
7485
7486 } else {
7487 /*
7488 * ICMP error message in response to a TCP/UDP packet.
7489 * Extract the inner TCP/UDP header and search for that state.
7490 */
3e170ce0 7491 struct pf_pdesc pd2; /* For inner (original) header */
b0d623f7
A
7492#if INET
7493 struct ip h2;
7494#endif /* INET */
7495#if INET6
7496 struct ip6_hdr h2_6;
7497 int terminal = 0;
7498#endif /* INET6 */
7499 int ipoff2 = 0;
7500 int off2 = 0;
7501
7502 memset(&pd2, 0, sizeof (pd2));
7503
7504 pd2.af = pd->af;
7505 switch (pd->af) {
7506#if INET
7507 case AF_INET:
7508 /* offset of h2 in mbuf chain */
7509 ipoff2 = off + ICMP_MINLEN;
7510
7511 if (!pf_pull_hdr(m, ipoff2, &h2, sizeof (h2),
7512 NULL, reason, pd2.af)) {
7513 DPFPRINTF(PF_DEBUG_MISC,
7514 ("pf: ICMP error message too short "
7515 "(ip)\n"));
7516 return (PF_DROP);
7517 }
7518 /*
7519 * ICMP error messages don't refer to non-first
7520 * fragments
7521 */
7522 if (h2.ip_off & htons(IP_OFFMASK)) {
7523 REASON_SET(reason, PFRES_FRAG);
7524 return (PF_DROP);
7525 }
7526
7527 /* offset of protocol header that follows h2 */
7528 off2 = ipoff2 + (h2.ip_hl << 2);
3e170ce0
A
7529 /* TODO */
7530 pd2.off = ipoff2 + (h2.ip_hl << 2);
b0d623f7
A
7531
7532 pd2.proto = h2.ip_p;
7533 pd2.src = (struct pf_addr *)&h2.ip_src;
7534 pd2.dst = (struct pf_addr *)&h2.ip_dst;
7535 pd2.ip_sum = &h2.ip_sum;
7536 break;
7537#endif /* INET */
7538#if INET6
7539 case AF_INET6:
7540 ipoff2 = off + sizeof (struct icmp6_hdr);
7541
7542 if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof (h2_6),
7543 NULL, reason, pd2.af)) {
7544 DPFPRINTF(PF_DEBUG_MISC,
7545 ("pf: ICMP error message too short "
7546 "(ip6)\n"));
7547 return (PF_DROP);
7548 }
7549 pd2.proto = h2_6.ip6_nxt;
7550 pd2.src = (struct pf_addr *)&h2_6.ip6_src;
7551 pd2.dst = (struct pf_addr *)&h2_6.ip6_dst;
7552 pd2.ip_sum = NULL;
7553 off2 = ipoff2 + sizeof (h2_6);
7554 do {
7555 switch (pd2.proto) {
7556 case IPPROTO_FRAGMENT:
7557 /*
7558 * ICMPv6 error messages for
7559 * non-first fragments
7560 */
7561 REASON_SET(reason, PFRES_FRAG);
7562 return (PF_DROP);
7563 case IPPROTO_AH:
7564 case IPPROTO_HOPOPTS:
7565 case IPPROTO_ROUTING:
7566 case IPPROTO_DSTOPTS: {
7567 /* get next header and header length */
7568 struct ip6_ext opt6;
7569
7570 if (!pf_pull_hdr(m, off2, &opt6,
7571 sizeof (opt6), NULL, reason,
7572 pd2.af)) {
7573 DPFPRINTF(PF_DEBUG_MISC,
7574 ("pf: ICMPv6 short opt\n"));
7575 return (PF_DROP);
7576 }
7577 if (pd2.proto == IPPROTO_AH)
7578 off2 += (opt6.ip6e_len + 2) * 4;
7579 else
7580 off2 += (opt6.ip6e_len + 1) * 8;
7581 pd2.proto = opt6.ip6e_nxt;
7582 /* goto the next header */
7583 break;
7584 }
7585 default:
7586 terminal++;
7587 break;
7588 }
7589 } while (!terminal);
3e170ce0
A
7590 /* TODO */
7591 pd2.off = ipoff2;
b0d623f7
A
7592 break;
7593#endif /* INET6 */
7594 }
7595
7596 switch (pd2.proto) {
7597 case IPPROTO_TCP: {
7598 struct tcphdr th;
7599 u_int32_t seq;
7600 struct pf_state_peer *src, *dst;
7601 u_int8_t dws;
7602 int copyback = 0;
7603
7604 /*
7605 * Only the first 8 bytes of the TCP header can be
7606 * expected. Don't access any TCP header fields after
7607 * th_seq, an ackskew test is not possible.
7608 */
7609 if (!pf_pull_hdr(m, off2, &th, 8, NULL, reason,
7610 pd2.af)) {
7611 DPFPRINTF(PF_DEBUG_MISC,
7612 ("pf: ICMP error message too short "
7613 "(tcp)\n"));
7614 return (PF_DROP);
7615 }
7616
b0d623f7 7617 key.proto = IPPROTO_TCP;
3e170ce0
A
7618 key.af_gwy = pd2.af;
7619 PF_ACPY(&key.ext_gwy.addr, pd2.dst, key.af_gwy);
7620 PF_ACPY(&key.gwy.addr, pd2.src, key.af_gwy);
7621 key.ext_gwy.xport.port = th.th_dport;
7622 key.gwy.xport.port = th.th_sport;
7623
7624 key.af_lan = pd2.af;
7625 PF_ACPY(&key.lan.addr, pd2.dst, key.af_lan);
7626 PF_ACPY(&key.ext_lan.addr, pd2.src, key.af_lan);
7627 key.lan.xport.port = th.th_dport;
7628 key.ext_lan.xport.port = th.th_sport;
b0d623f7
A
7629
7630 STATE_LOOKUP();
7631
3e170ce0
A
7632 sk = (*state)->state_key;
7633 if ((direction == sk->direction) &&
7634 ((sk->af_lan == sk->af_gwy) ||
7635 (pd2.af == sk->af_lan))) {
b0d623f7
A
7636 src = &(*state)->dst;
7637 dst = &(*state)->src;
7638 } else {
7639 src = &(*state)->src;
7640 dst = &(*state)->dst;
7641 }
7642
39236c6e 7643 if (src->wscale && (dst->wscale & PF_WSCALE_FLAG))
b0d623f7
A
7644 dws = dst->wscale & PF_WSCALE_MASK;
7645 else
39236c6e 7646 dws = TCP_MAX_WINSHIFT;
b0d623f7
A
7647
7648 /* Demodulate sequence number */
7649 seq = ntohl(th.th_seq) - src->seqdiff;
7650 if (src->seqdiff) {
7651 pf_change_a(&th.th_seq, icmpsum,
7652 htonl(seq), 0);
7653 copyback = 1;
7654 }
7655
7656 if (!SEQ_GEQ(src->seqhi, seq) ||
b7266188
A
7657 !SEQ_GEQ(seq,
7658 src->seqlo - ((u_int32_t)dst->max_win << dws))) {
b0d623f7
A
7659 if (pf_status.debug >= PF_DEBUG_MISC) {
7660 printf("pf: BAD ICMP %d:%d ",
7661 icmptype, pd->hdr.icmp->icmp_code);
7662 pf_print_host(pd->src, 0, pd->af);
7663 printf(" -> ");
7664 pf_print_host(pd->dst, 0, pd->af);
7665 printf(" state: ");
7666 pf_print_state(*state);
7667 printf(" seq=%u\n", seq);
7668 }
7669 REASON_SET(reason, PFRES_BADSTATE);
7670 return (PF_DROP);
7671 }
7672
3e170ce0
A
7673 pd->naf = pd2.naf = (pd2.af == sk->af_lan) ?
7674 sk->af_gwy : sk->af_lan;
7675
7676 if (STATE_TRANSLATE(sk)) {
7677 /* NAT64 case */
7678 if (sk->af_lan != sk->af_gwy) {
7679 struct pf_state_host *saddr2, *daddr2;
7680
7681 if (pd2.naf == sk->af_lan) {
7682 saddr2 = &sk->lan;
7683 daddr2 = &sk->ext_lan;
7684 } else {
7685 saddr2 = &sk->ext_gwy;
7686 daddr2 = &sk->gwy;
7687 }
7688
7689 /* translate ICMP message types and codes */
7690 if (pf_translate_icmp_af(pd->naf,
7691 pd->hdr.icmp))
7692 return (PF_DROP);
7693 m =
7694 pf_lazy_makewritable(pd, m, off2 + 8);
7695 if (!m)
7696 return (PF_DROP);
7697
7698 m_copyback(m, pd->off,
7699 sizeof(struct icmp6_hdr),
7700 pd->hdr.icmp6);
7701
7702 /*
7703 * translate inner ip header within the
7704 * ICMP message
7705 */
7706 if (pf_change_icmp_af(m, ipoff2, pd,
7707 &pd2, &saddr2->addr, &daddr2->addr,
7708 pd->af, pd->naf))
7709 return (PF_DROP);
7710
7711 if (pd->naf == AF_INET)
7712 pd->proto = IPPROTO_ICMP;
7713 else
7714 pd->proto = IPPROTO_ICMPV6;
7715
7716 /*
7717 * translate inner tcp header within
7718 * the ICMP message
7719 */
7720 pf_change_ap(direction, NULL, pd2.src,
7721 &th.th_sport, pd2.ip_sum,
7722 &th.th_sum, &daddr2->addr,
7723 saddr2->xport.port, 0, pd2.af,
7724 pd2.naf, 0);
7725
7726 pf_change_ap(direction, NULL, pd2.dst,
7727 &th.th_dport, pd2.ip_sum,
7728 &th.th_sum, &saddr2->addr,
7729 daddr2->xport.port, 0, pd2.af,
7730 pd2.naf, 0);
7731
7732 m_copyback(m, pd2.off, 8, &th);
7733
7734 /* translate outer ip header */
7735 PF_ACPY(&pd->naddr, &daddr2->addr,
7736 pd->naf);
7737 PF_ACPY(&pd->ndaddr, &saddr2->addr,
7738 pd->naf);
7739 if (pd->af == AF_INET) {
7740 memcpy(&pd->naddr.addr32[3],
7741 &srcv4_inaddr,
7742 sizeof(pd->naddr.addr32[3]));
7743 return (pf_nat64_ipv4(m, off,
7744 pd));
7745 } else {
7746 return (pf_nat64_ipv6(m, off,
7747 pd));
7748 }
7749 }
b0d623f7
A
7750 if (direction == PF_IN) {
7751 pf_change_icmp(pd2.src, &th.th_sport,
3e170ce0
A
7752 daddr, &sk->lan.addr,
7753 sk->lan.xport.port, NULL,
b0d623f7
A
7754 pd2.ip_sum, icmpsum,
7755 pd->ip_sum, 0, pd2.af);
7756 } else {
7757 pf_change_icmp(pd2.dst, &th.th_dport,
3e170ce0
A
7758 saddr, &sk->gwy.addr,
7759 sk->gwy.xport.port, NULL,
b0d623f7
A
7760 pd2.ip_sum, icmpsum,
7761 pd->ip_sum, 0, pd2.af);
7762 }
7763 copyback = 1;
7764 }
7765
7766 if (copyback) {
b0d623f7
A
7767 m = pf_lazy_makewritable(pd, m, off2 + 8);
7768 if (!m)
7769 return (PF_DROP);
b0d623f7
A
7770 switch (pd2.af) {
7771#if INET
7772 case AF_INET:
7773 m_copyback(m, off, ICMP_MINLEN,
7774 pd->hdr.icmp);
7775 m_copyback(m, ipoff2, sizeof (h2),
7776 &h2);
7777 break;
7778#endif /* INET */
7779#if INET6
7780 case AF_INET6:
7781 m_copyback(m, off,
7782 sizeof (struct icmp6_hdr),
7783 pd->hdr.icmp6);
7784 m_copyback(m, ipoff2, sizeof (h2_6),
7785 &h2_6);
7786 break;
7787#endif /* INET6 */
7788 }
7789 m_copyback(m, off2, 8, &th);
7790 }
7791
7792 return (PF_PASS);
7793 break;
7794 }
7795 case IPPROTO_UDP: {
3e170ce0 7796 struct udphdr uh;
b0d623f7 7797 int dx, action;
b0d623f7
A
7798 if (!pf_pull_hdr(m, off2, &uh, sizeof (uh),
7799 NULL, reason, pd2.af)) {
7800 DPFPRINTF(PF_DEBUG_MISC,
7801 ("pf: ICMP error message too short "
7802 "(udp)\n"));
7803 return (PF_DROP);
7804 }
7805
3e170ce0
A
7806 key.af_gwy = pd2.af;
7807 PF_ACPY(&key.ext_gwy.addr, pd2.dst, key.af_gwy);
7808 PF_ACPY(&key.gwy.addr, pd2.src, key.af_gwy);
7809 key.ext_gwy.xport.port = uh.uh_dport;
7810 key.gwy.xport.port = uh.uh_sport;
b0d623f7 7811
3e170ce0
A
7812 key.af_lan = pd2.af;
7813 PF_ACPY(&key.lan.addr, pd2.dst, key.af_lan);
7814 PF_ACPY(&key.ext_lan.addr, pd2.src, key.af_lan);
7815 key.lan.xport.port = uh.uh_dport;
7816 key.ext_lan.xport.port = uh.uh_sport;
7817
7818 key.proto = IPPROTO_UDP;
b0d623f7 7819 key.proto_variant = PF_EXTFILTER_APD;
3e170ce0 7820 dx = direction;
b0d623f7 7821
b7266188
A
7822 if (ntohs(uh.uh_sport) == PF_IKE_PORT &&
7823 ntohs(uh.uh_dport) == PF_IKE_PORT) {
b0d623f7
A
7824 struct pf_ike_hdr ike;
7825 size_t plen =
7826 m->m_pkthdr.len - off2 - sizeof (uh);
7827 if (direction == PF_IN &&
7828 plen < 8 /* PF_IKE_PACKET_MINSIZE */) {
7829 DPFPRINTF(PF_DEBUG_MISC, ("pf: "
7830 "ICMP error, embedded IKE message "
7831 "too small.\n"));
7832 return (PF_DROP);
7833 }
7834
7835 if (plen > sizeof (ike))
7836 plen = sizeof (ike);
7837 m_copydata(m, off + sizeof (uh), plen, &ike);
7838
7839 key.app_state = &as;
7840 as.compare_lan_ext = pf_ike_compare;
7841 as.compare_ext_gwy = pf_ike_compare;
7842 as.u.ike.cookie = ike.initiator_cookie;
7843 }
7844
7845 *state = pf_find_state(kif, &key, dx);
7846
7847 if (key.app_state && *state == 0) {
7848 key.app_state = 0;
7849 *state = pf_find_state(kif, &key, dx);
7850 }
7851
7852 if (*state == 0) {
7853 key.proto_variant = PF_EXTFILTER_AD;
7854 *state = pf_find_state(kif, &key, dx);
7855 }
7856
7857 if (*state == 0) {
7858 key.proto_variant = PF_EXTFILTER_EI;
7859 *state = pf_find_state(kif, &key, dx);
7860 }
7861
39236c6e 7862 /* similar to STATE_LOOKUP() */
316670eb 7863 if (*state != NULL && pd != NULL &&
39236c6e
A
7864 !(pd->pktflags & PKTF_FLOW_ID)) {
7865 pd->flowsrc = (*state)->state_key->flowsrc;
316670eb 7866 pd->flowhash = (*state)->state_key->flowhash;
39236c6e
A
7867 if (pd->flowhash != 0) {
7868 pd->pktflags |= PKTF_FLOW_ID;
7869 pd->pktflags &= ~PKTF_FLOW_ADV;
7870 }
7871 }
316670eb 7872
b0d623f7
A
7873 if (pf_state_lookup_aux(state, kif, direction, &action))
7874 return (action);
b0d623f7 7875
3e170ce0
A
7876 sk = (*state)->state_key;
7877 pd->naf = pd2.naf = (pd2.af == sk->af_lan) ?
7878 sk->af_gwy : sk->af_lan;
7879
7880 if (STATE_TRANSLATE(sk)) {
7881 /* NAT64 case */
7882 if (sk->af_lan != sk->af_gwy) {
7883 struct pf_state_host *saddr2, *daddr2;
7884
7885 if (pd2.naf == sk->af_lan) {
7886 saddr2 = &sk->lan;
7887 daddr2 = &sk->ext_lan;
7888 } else {
7889 saddr2 = &sk->ext_gwy;
7890 daddr2 = &sk->gwy;
7891 }
7892
7893 /* translate ICMP message */
7894 if (pf_translate_icmp_af(pd->naf,
7895 pd->hdr.icmp))
7896 return (PF_DROP);
7897 m =
7898 pf_lazy_makewritable(pd, m, off2 + 8);
7899 if (!m)
7900 return (PF_DROP);
7901
7902 m_copyback(m, pd->off,
7903 sizeof(struct icmp6_hdr),
7904 pd->hdr.icmp6);
7905
7906 /*
7907 * translate inner ip header within the
7908 * ICMP message
7909 */
7910 if (pf_change_icmp_af(m, ipoff2, pd,
7911 &pd2, &saddr2->addr, &daddr2->addr,
7912 pd->af, pd->naf))
7913 return (PF_DROP);
7914
7915 if (pd->naf == AF_INET)
7916 pd->proto = IPPROTO_ICMP;
7917 else
7918 pd->proto = IPPROTO_ICMPV6;
7919
7920 /*
7921 * translate inner udp header within
7922 * the ICMP message
7923 */
7924 pf_change_ap(direction, NULL, pd2.src,
7925 &uh.uh_sport, pd2.ip_sum,
7926 &uh.uh_sum, &daddr2->addr,
7927 saddr2->xport.port, 0, pd2.af,
7928 pd2.naf, 0);
7929
7930 pf_change_ap(direction, NULL, pd2.dst,
7931 &uh.uh_dport, pd2.ip_sum,
7932 &uh.uh_sum, &saddr2->addr,
7933 daddr2->xport.port, 0, pd2.af,
7934 pd2.naf, 0);
7935
7936 m_copyback(m, pd2.off, sizeof(uh), &uh);
7937
7938 /* translate outer ip header */
7939 PF_ACPY(&pd->naddr, &daddr2->addr,
7940 pd->naf);
7941 PF_ACPY(&pd->ndaddr, &saddr2->addr,
7942 pd->naf);
7943 if (pd->af == AF_INET) {
7944 memcpy(&pd->naddr.addr32[3],
7945 &srcv4_inaddr,
7946 sizeof(pd->naddr.addr32[3]));
7947 return (pf_nat64_ipv4(m, off,
7948 pd));
7949 } else {
7950 return (pf_nat64_ipv6(m, off,
7951 pd));
7952 }
7953 }
b0d623f7
A
7954 if (direction == PF_IN) {
7955 pf_change_icmp(pd2.src, &uh.uh_sport,
3e170ce0
A
7956 daddr, &sk->lan.addr,
7957 sk->lan.xport.port, &uh.uh_sum,
b0d623f7
A
7958 pd2.ip_sum, icmpsum,
7959 pd->ip_sum, 1, pd2.af);
7960 } else {
7961 pf_change_icmp(pd2.dst, &uh.uh_dport,
3e170ce0
A
7962 saddr, &sk->gwy.addr,
7963 sk->gwy.xport.port, &uh.uh_sum,
b0d623f7
A
7964 pd2.ip_sum, icmpsum,
7965 pd->ip_sum, 1, pd2.af);
7966 }
b0d623f7
A
7967 m = pf_lazy_makewritable(pd, m,
7968 off2 + sizeof (uh));
7969 if (!m)
7970 return (PF_DROP);
b0d623f7
A
7971 switch (pd2.af) {
7972#if INET
7973 case AF_INET:
7974 m_copyback(m, off, ICMP_MINLEN,
7975 pd->hdr.icmp);
7976 m_copyback(m, ipoff2, sizeof (h2), &h2);
7977 break;
7978#endif /* INET */
7979#if INET6
7980 case AF_INET6:
7981 m_copyback(m, off,
7982 sizeof (struct icmp6_hdr),
7983 pd->hdr.icmp6);
7984 m_copyback(m, ipoff2, sizeof (h2_6),
7985 &h2_6);
7986 break;
7987#endif /* INET6 */
7988 }
7989 m_copyback(m, off2, sizeof (uh), &uh);
7990 }
7991
7992 return (PF_PASS);
7993 break;
7994 }
7995#if INET
7996 case IPPROTO_ICMP: {
7997 struct icmp iih;
7998
7999 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN,
8000 NULL, reason, pd2.af)) {
8001 DPFPRINTF(PF_DEBUG_MISC,
8002 ("pf: ICMP error message too short i"
8003 "(icmp)\n"));
8004 return (PF_DROP);
8005 }
8006
b0d623f7
A
8007 key.proto = IPPROTO_ICMP;
8008 if (direction == PF_IN) {
3e170ce0
A
8009 key.af_gwy = pd2.af;
8010 PF_ACPY(&key.ext_gwy.addr, pd2.dst, key.af_gwy);
8011 PF_ACPY(&key.gwy.addr, pd2.src, key.af_gwy);
8012 key.ext_gwy.xport.port = 0;
b0d623f7 8013 key.gwy.xport.port = iih.icmp_id;
b0d623f7 8014 } else {
3e170ce0
A
8015 key.af_lan = pd2.af;
8016 PF_ACPY(&key.lan.addr, pd2.dst, key.af_lan);
8017 PF_ACPY(&key.ext_lan.addr, pd2.src, key.af_lan);
b0d623f7 8018 key.lan.xport.port = iih.icmp_id;
3e170ce0 8019 key.ext_lan.xport.port = 0;
b0d623f7
A
8020 }
8021
8022 STATE_LOOKUP();
8023
3e170ce0
A
8024 sk = (*state)->state_key;
8025 if (STATE_TRANSLATE(sk)) {
b0d623f7
A
8026 if (direction == PF_IN) {
8027 pf_change_icmp(pd2.src, &iih.icmp_id,
3e170ce0
A
8028 daddr, &sk->lan.addr,
8029 sk->lan.xport.port, NULL,
b0d623f7
A
8030 pd2.ip_sum, icmpsum,
8031 pd->ip_sum, 0, AF_INET);
8032 } else {
8033 pf_change_icmp(pd2.dst, &iih.icmp_id,
3e170ce0
A
8034 saddr, &sk->gwy.addr,
8035 sk->gwy.xport.port, NULL,
b0d623f7
A
8036 pd2.ip_sum, icmpsum,
8037 pd->ip_sum, 0, AF_INET);
8038 }
3e170ce0
A
8039 m = pf_lazy_makewritable(pd, m,
8040 off2 + ICMP_MINLEN);
b0d623f7
A
8041 if (!m)
8042 return (PF_DROP);
b0d623f7
A
8043 m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp);
8044 m_copyback(m, ipoff2, sizeof (h2), &h2);
8045 m_copyback(m, off2, ICMP_MINLEN, &iih);
8046 }
8047
8048 return (PF_PASS);
8049 break;
8050 }
8051#endif /* INET */
8052#if INET6
8053 case IPPROTO_ICMPV6: {
8054 struct icmp6_hdr iih;
8055
8056 if (!pf_pull_hdr(m, off2, &iih,
8057 sizeof (struct icmp6_hdr), NULL, reason, pd2.af)) {
8058 DPFPRINTF(PF_DEBUG_MISC,
8059 ("pf: ICMP error message too short "
8060 "(icmp6)\n"));
8061 return (PF_DROP);
8062 }
8063
b0d623f7
A
8064 key.proto = IPPROTO_ICMPV6;
8065 if (direction == PF_IN) {
3e170ce0
A
8066 key.af_gwy = pd2.af;
8067 PF_ACPY(&key.ext_gwy.addr, pd2.dst, key.af_gwy);
8068 PF_ACPY(&key.gwy.addr, pd2.src, key.af_gwy);
8069 key.ext_gwy.xport.port = 0;
b0d623f7 8070 key.gwy.xport.port = iih.icmp6_id;
b0d623f7 8071 } else {
3e170ce0
A
8072 key.af_lan = pd2.af;
8073 PF_ACPY(&key.lan.addr, pd2.dst, key.af_lan);
8074 PF_ACPY(&key.ext_lan.addr, pd2.src, key.af_lan);
b0d623f7 8075 key.lan.xport.port = iih.icmp6_id;
3e170ce0 8076 key.ext_lan.xport.port = 0;
b0d623f7
A
8077 }
8078
8079 STATE_LOOKUP();
8080
3e170ce0
A
8081 sk = (*state)->state_key;
8082 if (STATE_TRANSLATE(sk)) {
b0d623f7
A
8083 if (direction == PF_IN) {
8084 pf_change_icmp(pd2.src, &iih.icmp6_id,
3e170ce0
A
8085 daddr, &sk->lan.addr,
8086 sk->lan.xport.port, NULL,
b0d623f7
A
8087 pd2.ip_sum, icmpsum,
8088 pd->ip_sum, 0, AF_INET6);
8089 } else {
8090 pf_change_icmp(pd2.dst, &iih.icmp6_id,
3e170ce0
A
8091 saddr, &sk->gwy.addr,
8092 sk->gwy.xport.port, NULL,
b0d623f7
A
8093 pd2.ip_sum, icmpsum,
8094 pd->ip_sum, 0, AF_INET6);
8095 }
b0d623f7
A
8096 m = pf_lazy_makewritable(pd, m, off2 +
8097 sizeof (struct icmp6_hdr));
8098 if (!m)
8099 return (PF_DROP);
b0d623f7
A
8100 m_copyback(m, off, sizeof (struct icmp6_hdr),
8101 pd->hdr.icmp6);
8102 m_copyback(m, ipoff2, sizeof (h2_6), &h2_6);
8103 m_copyback(m, off2, sizeof (struct icmp6_hdr),
8104 &iih);
8105 }
8106
8107 return (PF_PASS);
8108 break;
8109 }
8110#endif /* INET6 */
8111 default: {
b0d623f7
A
8112 key.proto = pd2.proto;
8113 if (direction == PF_IN) {
3e170ce0
A
8114 key.af_gwy = pd2.af;
8115 PF_ACPY(&key.ext_gwy.addr, pd2.dst, key.af_gwy);
8116 PF_ACPY(&key.gwy.addr, pd2.src, key.af_gwy);
8117 key.ext_gwy.xport.port = 0;
b0d623f7 8118 key.gwy.xport.port = 0;
b0d623f7 8119 } else {
3e170ce0
A
8120 key.af_lan = pd2.af;
8121 PF_ACPY(&key.lan.addr, pd2.dst, key.af_lan);
8122 PF_ACPY(&key.ext_lan.addr, pd2.src, key.af_lan);
b0d623f7 8123 key.lan.xport.port = 0;
3e170ce0 8124 key.ext_lan.xport.port = 0;
b0d623f7
A
8125 }
8126
8127 STATE_LOOKUP();
8128
3e170ce0
A
8129 sk = (*state)->state_key;
8130 if (STATE_TRANSLATE(sk)) {
b0d623f7 8131 if (direction == PF_IN) {
3e170ce0
A
8132 pf_change_icmp(pd2.src, NULL, daddr,
8133 &sk->lan.addr, 0, NULL,
8134 pd2.ip_sum, icmpsum,
8135 pd->ip_sum, 0, pd2.af);
b0d623f7 8136 } else {
3e170ce0
A
8137 pf_change_icmp(pd2.dst, NULL, saddr,
8138 &sk->gwy.addr, 0, NULL,
8139 pd2.ip_sum, icmpsum,
8140 pd->ip_sum, 0, pd2.af);
b0d623f7
A
8141 }
8142 switch (pd2.af) {
8143#if INET
8144 case AF_INET:
b0d623f7
A
8145 m = pf_lazy_makewritable(pd, m,
8146 ipoff2 + sizeof (h2));
8147 if (!m)
8148 return (PF_DROP);
b0d623f7
A
8149#endif /* INET */
8150#if INET6
8151 case AF_INET6:
b0d623f7 8152 m = pf_lazy_makewritable(pd, m,
3e170ce0 8153 ipoff2 + sizeof (h2_6));
b0d623f7
A
8154 if (!m)
8155 return (PF_DROP);
b0d623f7 8156 m_copyback(m, off,
3e170ce0
A
8157 sizeof (struct icmp6_hdr),
8158 pd->hdr.icmp6);
b0d623f7 8159 m_copyback(m, ipoff2, sizeof (h2_6),
3e170ce0 8160 &h2_6);
b0d623f7
A
8161 break;
8162#endif /* INET6 */
8163 }
8164 }
8165
8166 return (PF_PASS);
8167 break;
8168 }
8169 }
8170 }
8171}
8172
b0d623f7
A
8173static int
8174pf_test_state_grev1(struct pf_state **state, int direction,
8175 struct pfi_kif *kif, int off, struct pf_pdesc *pd)
8176{
8177 struct pf_state_peer *src;
8178 struct pf_state_peer *dst;
8179 struct pf_state_key_cmp key;
8180 struct pf_grev1_hdr *grev1 = pd->hdr.grev1;
8181 struct mbuf *m;
8182
b0d623f7 8183 key.app_state = 0;
b0d623f7
A
8184 key.proto = IPPROTO_GRE;
8185 key.proto_variant = PF_GRE_PPTP_VARIANT;
8186 if (direction == PF_IN) {
3e170ce0
A
8187 key.af_gwy = pd->af;
8188 PF_ACPY(&key.ext_gwy.addr, pd->src, key.af_gwy);
8189 PF_ACPY(&key.gwy.addr, pd->dst, key.af_gwy);
b0d623f7
A
8190 key.gwy.xport.call_id = grev1->call_id;
8191 } else {
3e170ce0
A
8192 key.af_lan = pd->af;
8193 PF_ACPY(&key.lan.addr, pd->src, key.af_lan);
8194 PF_ACPY(&key.ext_lan.addr, pd->dst, key.af_lan);
8195 key.ext_lan.xport.call_id = grev1->call_id;
b0d623f7
A
8196 }
8197
8198 STATE_LOOKUP();
8199
8200 if (direction == (*state)->state_key->direction) {
8201 src = &(*state)->src;
8202 dst = &(*state)->dst;
8203 } else {
8204 src = &(*state)->dst;
8205 dst = &(*state)->src;
8206 }
8207
8208 /* update states */
8209 if (src->state < PFGRE1S_INITIATING)
8210 src->state = PFGRE1S_INITIATING;
8211
8212 /* update expire time */
8213 (*state)->expire = pf_time_second();
8214 if (src->state >= PFGRE1S_INITIATING &&
8215 dst->state >= PFGRE1S_INITIATING) {
d1ecb069
A
8216 if ((*state)->timeout != PFTM_TCP_ESTABLISHED)
8217 (*state)->timeout = PFTM_GREv1_ESTABLISHED;
b0d623f7
A
8218 src->state = PFGRE1S_ESTABLISHED;
8219 dst->state = PFGRE1S_ESTABLISHED;
8220 } else {
8221 (*state)->timeout = PFTM_GREv1_INITIATING;
8222 }
d1ecb069
A
8223
8224 if ((*state)->state_key->app_state)
8225 (*state)->state_key->app_state->u.grev1.pptp_state->expire =
8226 pf_time_second();
8227
b0d623f7
A
8228 /* translate source/destination address, if necessary */
8229 if (STATE_GRE_TRANSLATE((*state)->state_key)) {
8230 if (direction == PF_OUT) {
8231 switch (pd->af) {
8232#if INET
8233 case AF_INET:
8234 pf_change_a(&pd->src->v4.s_addr,
8235 pd->ip_sum,
8236 (*state)->state_key->gwy.addr.v4.s_addr, 0);
8237 break;
8238#endif /* INET */
8239#if INET6
8240 case AF_INET6:
8241 PF_ACPY(pd->src, &(*state)->state_key->gwy.addr,
8242 pd->af);
8243 break;
8244#endif /* INET6 */
8245 }
8246 } else {
8247 grev1->call_id = (*state)->state_key->lan.xport.call_id;
8248
8249 switch (pd->af) {
8250#if INET
8251 case AF_INET:
8252 pf_change_a(&pd->dst->v4.s_addr,
8253 pd->ip_sum,
8254 (*state)->state_key->lan.addr.v4.s_addr, 0);
8255 break;
8256#endif /* INET */
8257#if INET6
8258 case AF_INET6:
8259 PF_ACPY(pd->dst, &(*state)->state_key->lan.addr,
8260 pd->af);
8261 break;
8262#endif /* INET6 */
8263 }
8264 }
8265
8266 m = pf_lazy_makewritable(pd, pd->mp, off + sizeof (*grev1));
8267 if (!m)
8268 return (PF_DROP);
8269 m_copyback(m, off, sizeof (*grev1), grev1);
8270 }
8271
8272 return (PF_PASS);
8273}
8274
316670eb 8275static int
b0d623f7
A
8276pf_test_state_esp(struct pf_state **state, int direction, struct pfi_kif *kif,
8277 int off, struct pf_pdesc *pd)
8278{
8279#pragma unused(off)
8280 struct pf_state_peer *src;
8281 struct pf_state_peer *dst;
8282 struct pf_state_key_cmp key;
8283 struct pf_esp_hdr *esp = pd->hdr.esp;
8284 int action;
8285
8286 memset(&key, 0, sizeof (key));
b0d623f7
A
8287 key.proto = IPPROTO_ESP;
8288 if (direction == PF_IN) {
3e170ce0
A
8289 key.af_gwy = pd->af;
8290 PF_ACPY(&key.ext_gwy.addr, pd->src, key.af_gwy);
8291 PF_ACPY(&key.gwy.addr, pd->dst, key.af_gwy);
b0d623f7
A
8292 key.gwy.xport.spi = esp->spi;
8293 } else {
3e170ce0
A
8294 key.af_lan = pd->af;
8295 PF_ACPY(&key.lan.addr, pd->src, key.af_lan);
8296 PF_ACPY(&key.ext_lan.addr, pd->dst, key.af_lan);
8297 key.ext_lan.xport.spi = esp->spi;
b0d623f7
A
8298 }
8299
8300 *state = pf_find_state(kif, &key, direction);
8301
8302 if (*state == 0) {
8303 struct pf_state *s;
8304
8305 /*
8306 * <jhw@apple.com>
8307 * No matching state. Look for a blocking state. If we find
8308 * one, then use that state and move it so that it's keyed to
8309 * the SPI in the current packet.
8310 */
8311 if (direction == PF_IN) {
8312 key.gwy.xport.spi = 0;
8313
8314 s = pf_find_state(kif, &key, direction);
8315 if (s) {
8316 struct pf_state_key *sk = s->state_key;
8317
8318 RB_REMOVE(pf_state_tree_ext_gwy,
8319 &pf_statetbl_ext_gwy, sk);
8320 sk->lan.xport.spi = sk->gwy.xport.spi =
8321 esp->spi;
8322
8323 if (RB_INSERT(pf_state_tree_ext_gwy,
8324 &pf_statetbl_ext_gwy, sk))
8325 pf_detach_state(s, PF_DT_SKIP_EXTGWY);
8326 else
8327 *state = s;
8328 }
8329 } else {
3e170ce0 8330 key.ext_lan.xport.spi = 0;
b0d623f7
A
8331
8332 s = pf_find_state(kif, &key, direction);
8333 if (s) {
8334 struct pf_state_key *sk = s->state_key;
8335
8336 RB_REMOVE(pf_state_tree_lan_ext,
8337 &pf_statetbl_lan_ext, sk);
3e170ce0 8338 sk->ext_lan.xport.spi = esp->spi;
b0d623f7
A
8339
8340 if (RB_INSERT(pf_state_tree_lan_ext,
8341 &pf_statetbl_lan_ext, sk))
8342 pf_detach_state(s, PF_DT_SKIP_LANEXT);
8343 else
8344 *state = s;
8345 }
8346 }
8347
8348 if (s) {
8349 if (*state == 0) {
8350#if NPFSYNC
8351 if (s->creatorid == pf_status.hostid)
8352 pfsync_delete_state(s);
8353#endif
8354 s->timeout = PFTM_UNLINKED;
8355 hook_runloop(&s->unlink_hooks,
8356 HOOK_REMOVE|HOOK_FREE);
8357 pf_src_tree_remove_state(s);
8358 pf_free_state(s);
8359 return (PF_DROP);
8360 }
8361 }
8362 }
8363
39236c6e
A
8364 /* similar to STATE_LOOKUP() */
8365 if (*state != NULL && pd != NULL && !(pd->pktflags & PKTF_FLOW_ID)) {
8366 pd->flowsrc = (*state)->state_key->flowsrc;
316670eb 8367 pd->flowhash = (*state)->state_key->flowhash;
39236c6e
A
8368 if (pd->flowhash != 0) {
8369 pd->pktflags |= PKTF_FLOW_ID;
8370 pd->pktflags &= ~PKTF_FLOW_ADV;
8371 }
316670eb
A
8372 }
8373
b0d623f7
A
8374 if (pf_state_lookup_aux(state, kif, direction, &action))
8375 return (action);
8376
8377 if (direction == (*state)->state_key->direction) {
8378 src = &(*state)->src;
8379 dst = &(*state)->dst;
8380 } else {
8381 src = &(*state)->dst;
8382 dst = &(*state)->src;
8383 }
8384
8385 /* update states */
8386 if (src->state < PFESPS_INITIATING)
8387 src->state = PFESPS_INITIATING;
8388
8389 /* update expire time */
8390 (*state)->expire = pf_time_second();
8391 if (src->state >= PFESPS_INITIATING &&
8392 dst->state >= PFESPS_INITIATING) {
8393 (*state)->timeout = PFTM_ESP_ESTABLISHED;
8394 src->state = PFESPS_ESTABLISHED;
8395 dst->state = PFESPS_ESTABLISHED;
8396 } else {
8397 (*state)->timeout = PFTM_ESP_INITIATING;
8398 }
8399 /* translate source/destination address, if necessary */
8400 if (STATE_ADDR_TRANSLATE((*state)->state_key)) {
8401 if (direction == PF_OUT) {
8402 switch (pd->af) {
8403#if INET
8404 case AF_INET:
8405 pf_change_a(&pd->src->v4.s_addr,
8406 pd->ip_sum,
8407 (*state)->state_key->gwy.addr.v4.s_addr, 0);
8408 break;
8409#endif /* INET */
8410#if INET6
8411 case AF_INET6:
8412 PF_ACPY(pd->src, &(*state)->state_key->gwy.addr,
8413 pd->af);
8414 break;
8415#endif /* INET6 */
8416 }
8417 } else {
8418 switch (pd->af) {
8419#if INET
8420 case AF_INET:
8421 pf_change_a(&pd->dst->v4.s_addr,
8422 pd->ip_sum,
8423 (*state)->state_key->lan.addr.v4.s_addr, 0);
8424 break;
8425#endif /* INET */
8426#if INET6
8427 case AF_INET6:
8428 PF_ACPY(pd->dst, &(*state)->state_key->lan.addr,
8429 pd->af);
8430 break;
8431#endif /* INET6 */
8432 }
8433 }
8434 }
8435
8436 return (PF_PASS);
8437}
b0d623f7
A
8438
8439static int
8440pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
8441 struct pf_pdesc *pd)
8442{
8443 struct pf_state_peer *src, *dst;
8444 struct pf_state_key_cmp key;
8445
b0d623f7 8446 key.app_state = 0;
b0d623f7
A
8447 key.proto = pd->proto;
8448 if (direction == PF_IN) {
3e170ce0
A
8449 key.af_gwy = pd->af;
8450 PF_ACPY(&key.ext_gwy.addr, pd->src, key.af_gwy);
8451 PF_ACPY(&key.gwy.addr, pd->dst, key.af_gwy);
8452 key.ext_gwy.xport.port = 0;
b0d623f7 8453 key.gwy.xport.port = 0;
b0d623f7 8454 } else {
3e170ce0
A
8455 key.af_lan = pd->af;
8456 PF_ACPY(&key.lan.addr, pd->src, key.af_lan);
8457 PF_ACPY(&key.ext_lan.addr, pd->dst, key.af_lan);
b0d623f7 8458 key.lan.xport.port = 0;
3e170ce0 8459 key.ext_lan.xport.port = 0;
b0d623f7
A
8460 }
8461
8462 STATE_LOOKUP();
8463
8464 if (direction == (*state)->state_key->direction) {
8465 src = &(*state)->src;
8466 dst = &(*state)->dst;
8467 } else {
8468 src = &(*state)->dst;
8469 dst = &(*state)->src;
8470 }
8471
8472 /* update states */
8473 if (src->state < PFOTHERS_SINGLE)
8474 src->state = PFOTHERS_SINGLE;
8475 if (dst->state == PFOTHERS_SINGLE)
8476 dst->state = PFOTHERS_MULTIPLE;
8477
8478 /* update expire time */
8479 (*state)->expire = pf_time_second();
8480 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE)
8481 (*state)->timeout = PFTM_OTHER_MULTIPLE;
8482 else
8483 (*state)->timeout = PFTM_OTHER_SINGLE;
8484
8485 /* translate source/destination address, if necessary */
b0d623f7 8486 if (STATE_ADDR_TRANSLATE((*state)->state_key)) {
b0d623f7
A
8487 if (direction == PF_OUT) {
8488 switch (pd->af) {
8489#if INET
8490 case AF_INET:
8491 pf_change_a(&pd->src->v4.s_addr,
8492 pd->ip_sum,
8493 (*state)->state_key->gwy.addr.v4.s_addr,
8494 0);
8495 break;
8496#endif /* INET */
8497#if INET6
8498 case AF_INET6:
8499 PF_ACPY(pd->src,
8500 &(*state)->state_key->gwy.addr, pd->af);
8501 break;
8502#endif /* INET6 */
8503 }
8504 } else {
8505 switch (pd->af) {
8506#if INET
8507 case AF_INET:
8508 pf_change_a(&pd->dst->v4.s_addr,
8509 pd->ip_sum,
8510 (*state)->state_key->lan.addr.v4.s_addr,
8511 0);
8512 break;
8513#endif /* INET */
8514#if INET6
8515 case AF_INET6:
8516 PF_ACPY(pd->dst,
8517 &(*state)->state_key->lan.addr, pd->af);
8518 break;
8519#endif /* INET6 */
8520 }
8521 }
8522 }
8523
8524 return (PF_PASS);
8525}
8526
8527/*
8528 * ipoff and off are measured from the start of the mbuf chain.
8529 * h must be at "ipoff" on the mbuf chain.
8530 */
8531void *
8532pf_pull_hdr(struct mbuf *m, int off, void *p, int len,
8533 u_short *actionp, u_short *reasonp, sa_family_t af)
8534{
8535 switch (af) {
8536#if INET
8537 case AF_INET: {
8538 struct ip *h = mtod(m, struct ip *);
8539 u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
8540
8541 if (fragoff) {
8542 if (fragoff >= len) {
8543 ACTION_SET(actionp, PF_PASS);
8544 } else {
8545 ACTION_SET(actionp, PF_DROP);
8546 REASON_SET(reasonp, PFRES_FRAG);
8547 }
8548 return (NULL);
8549 }
8550 if (m->m_pkthdr.len < off + len ||
8551 ntohs(h->ip_len) < off + len) {
8552 ACTION_SET(actionp, PF_DROP);
8553 REASON_SET(reasonp, PFRES_SHORT);
8554 return (NULL);
8555 }
8556 break;
8557 }
8558#endif /* INET */
8559#if INET6
8560 case AF_INET6: {
8561 struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
8562
8563 if (m->m_pkthdr.len < off + len ||
8564 (ntohs(h->ip6_plen) + sizeof (struct ip6_hdr)) <
8565 (unsigned)(off + len)) {
8566 ACTION_SET(actionp, PF_DROP);
8567 REASON_SET(reasonp, PFRES_SHORT);
8568 return (NULL);
8569 }
8570 break;
8571 }
8572#endif /* INET6 */
8573 }
8574 m_copydata(m, off, len, p);
8575 return (p);
8576}
8577
8578int
8579pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif)
8580{
8581#pragma unused(kif)
8582 struct sockaddr_in *dst;
8583 int ret = 1;
8584#if INET6
8585 struct sockaddr_in6 *dst6;
8586 struct route_in6 ro;
8587#else
8588 struct route ro;
8589#endif
8590
8591 bzero(&ro, sizeof (ro));
8592 switch (af) {
8593 case AF_INET:
8594 dst = satosin(&ro.ro_dst);
8595 dst->sin_family = AF_INET;
8596 dst->sin_len = sizeof (*dst);
8597 dst->sin_addr = addr->v4;
8598 break;
8599#if INET6
8600 case AF_INET6:
8601 dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
8602 dst6->sin6_family = AF_INET6;
8603 dst6->sin6_len = sizeof (*dst6);
8604 dst6->sin6_addr = addr->v6;
8605 break;
8606#endif /* INET6 */
8607 default:
8608 return (0);
8609 }
8610
8611 /* XXX: IFT_ENC is not currently used by anything*/
8612 /* Skip checks for ipsec interfaces */
8613 if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC)
8614 goto out;
8615
39236c6e 8616 /* XXX: what is the point of this? */
b0d623f7
A
8617 rtalloc((struct route *)&ro);
8618
8619out:
39236c6e 8620 ROUTE_RELEASE(&ro);
b0d623f7
A
8621 return (ret);
8622}
8623
8624int
8625pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw)
8626{
8627#pragma unused(aw)
8628 struct sockaddr_in *dst;
8629#if INET6
8630 struct sockaddr_in6 *dst6;
8631 struct route_in6 ro;
8632#else
8633 struct route ro;
8634#endif
8635 int ret = 0;
8636
8637 bzero(&ro, sizeof (ro));
8638 switch (af) {
8639 case AF_INET:
8640 dst = satosin(&ro.ro_dst);
8641 dst->sin_family = AF_INET;
8642 dst->sin_len = sizeof (*dst);
8643 dst->sin_addr = addr->v4;
8644 break;
8645#if INET6
8646 case AF_INET6:
8647 dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
8648 dst6->sin6_family = AF_INET6;
8649 dst6->sin6_len = sizeof (*dst6);
8650 dst6->sin6_addr = addr->v6;
8651 break;
8652#endif /* INET6 */
8653 default:
8654 return (0);
8655 }
8656
39236c6e 8657 /* XXX: what is the point of this? */
b0d623f7
A
8658 rtalloc((struct route *)&ro);
8659
39236c6e 8660 ROUTE_RELEASE(&ro);
b0d623f7
A
8661
8662 return (ret);
8663}
8664
8665#if INET
8666static void
8667pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
8668 struct pf_state *s, struct pf_pdesc *pd)
8669{
8670#pragma unused(pd)
8671 struct mbuf *m0, *m1;
8672 struct route iproute;
39236c6e 8673 struct route *ro = &iproute;
b0d623f7
A
8674 struct sockaddr_in *dst;
8675 struct ip *ip;
8676 struct ifnet *ifp = NULL;
8677 struct pf_addr naddr;
8678 struct pf_src_node *sn = NULL;
8679 int error = 0;
39236c6e
A
8680 uint32_t sw_csum;
8681
8682 bzero(&iproute, sizeof (iproute));
b0d623f7
A
8683
8684 if (m == NULL || *m == NULL || r == NULL ||
8685 (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
8686 panic("pf_route: invalid parameters");
8687
316670eb 8688 if (pd->pf_mtag->pftag_routed++ > 3) {
b0d623f7
A
8689 m0 = *m;
8690 *m = NULL;
8691 goto bad;
8692 }
8693
8694 if (r->rt == PF_DUPTO) {
8695 if ((m0 = m_copym(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
8696 return;
8697 } else {
8698 if ((r->rt == PF_REPLYTO) == (r->direction == dir))
8699 return;
8700 m0 = *m;
8701 }
8702
8703 if (m0->m_len < (int)sizeof (struct ip)) {
8704 DPFPRINTF(PF_DEBUG_URGENT,
8705 ("pf_route: m0->m_len < sizeof (struct ip)\n"));
8706 goto bad;
8707 }
8708
8709 ip = mtod(m0, struct ip *);
8710
316670eb 8711 dst = satosin((void *)&ro->ro_dst);
b0d623f7
A
8712 dst->sin_family = AF_INET;
8713 dst->sin_len = sizeof (*dst);
8714 dst->sin_addr = ip->ip_dst;
8715
8716 if (r->rt == PF_FASTROUTE) {
8717 rtalloc(ro);
39236c6e 8718 if (ro->ro_rt == NULL) {
b0d623f7
A
8719 ipstat.ips_noroute++;
8720 goto bad;
8721 }
8722
8723 ifp = ro->ro_rt->rt_ifp;
6d2010ae 8724 RT_LOCK(ro->ro_rt);
b0d623f7
A
8725 ro->ro_rt->rt_use++;
8726
8727 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
316670eb 8728 dst = satosin((void *)ro->ro_rt->rt_gateway);
6d2010ae 8729 RT_UNLOCK(ro->ro_rt);
b0d623f7
A
8730 } else {
8731 if (TAILQ_EMPTY(&r->rpool.list)) {
8732 DPFPRINTF(PF_DEBUG_URGENT,
8733 ("pf_route: TAILQ_EMPTY(&r->rpool.list)\n"));
8734 goto bad;
8735 }
8736 if (s == NULL) {
8737 pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
8738 &naddr, NULL, &sn);
8739 if (!PF_AZERO(&naddr, AF_INET))
8740 dst->sin_addr.s_addr = naddr.v4.s_addr;
8741 ifp = r->rpool.cur->kif ?
8742 r->rpool.cur->kif->pfik_ifp : NULL;
8743 } else {
8744 if (!PF_AZERO(&s->rt_addr, AF_INET))
8745 dst->sin_addr.s_addr =
8746 s->rt_addr.v4.s_addr;
8747 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
8748 }
8749 }
8750 if (ifp == NULL)
8751 goto bad;
8752
8753 if (oifp != ifp) {
316670eb 8754 if (pf_test(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS)
b0d623f7
A
8755 goto bad;
8756 else if (m0 == NULL)
8757 goto done;
8758 if (m0->m_len < (int)sizeof (struct ip)) {
8759 DPFPRINTF(PF_DEBUG_URGENT,
8760 ("pf_route: m0->m_len < sizeof (struct ip)\n"));
8761 goto bad;
8762 }
8763 ip = mtod(m0, struct ip *);
8764 }
8765
b0d623f7 8766 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */
39236c6e
A
8767 ip_output_checksum(ifp, m0, ((ip->ip_hl) << 2), ntohs(ip->ip_len),
8768 &sw_csum);
b0d623f7 8769
39236c6e
A
8770 if (ntohs(ip->ip_len) <= ifp->if_mtu || TSO_IPV4_OK(ifp, m0) ||
8771 (!(ip->ip_off & htons(IP_DF)) &&
8772 (ifp->if_hwassist & CSUM_FRAGMENT))) {
b0d623f7 8773 ip->ip_sum = 0;
39236c6e 8774 if (sw_csum & CSUM_DELAY_IP) {
b0d623f7 8775 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
39236c6e
A
8776 sw_csum &= ~CSUM_DELAY_IP;
8777 m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_IP;
8778 }
316670eb 8779 error = ifnet_output(ifp, PF_INET, m0, ro->ro_rt, sintosa(dst));
b0d623f7
A
8780 goto done;
8781 }
8782
8783 /*
8784 * Too large for interface; fragment if possible.
8785 * Must be able to put at least 8 bytes per fragment.
39236c6e 8786 * Balk when DF bit is set or the interface didn't support TSO.
b0d623f7 8787 */
39236c6e
A
8788 if ((ip->ip_off & htons(IP_DF)) ||
8789 (m0->m_pkthdr.csum_flags & CSUM_TSO_IPV4)) {
b0d623f7
A
8790 ipstat.ips_cantfrag++;
8791 if (r->rt != PF_DUPTO) {
8792 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
8793 ifp->if_mtu);
8794 goto done;
8795 } else
8796 goto bad;
8797 }
8798
8799 m1 = m0;
6d2010ae
A
8800
8801 /* PR-8933605: send ip_len,ip_off to ip_fragment in host byte order */
316670eb 8802#if BYTE_ORDER != BIG_ENDIAN
6d2010ae
A
8803 NTOHS(ip->ip_off);
8804 NTOHS(ip->ip_len);
8805#endif
b0d623f7 8806 error = ip_fragment(m0, ifp, ifp->if_mtu, sw_csum);
316670eb 8807
b0d623f7
A
8808 if (error) {
8809 m0 = NULL;
8810 goto bad;
8811 }
8812
8813 for (m0 = m1; m0; m0 = m1) {
8814 m1 = m0->m_nextpkt;
8815 m0->m_nextpkt = 0;
8816 if (error == 0)
316670eb 8817 error = ifnet_output(ifp, PF_INET, m0, ro->ro_rt,
b0d623f7
A
8818 sintosa(dst));
8819 else
8820 m_freem(m0);
8821 }
8822
8823 if (error == 0)
8824 ipstat.ips_fragmented++;
8825
8826done:
8827 if (r->rt != PF_DUPTO)
8828 *m = NULL;
39236c6e
A
8829
8830 ROUTE_RELEASE(&iproute);
b0d623f7
A
8831 return;
8832
8833bad:
8834 m_freem(m0);
8835 goto done;
8836}
8837#endif /* INET */
8838
8839#if INET6
8840static void
8841pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
8842 struct pf_state *s, struct pf_pdesc *pd)
8843{
8844#pragma unused(pd)
8845 struct mbuf *m0;
8846 struct route_in6 ip6route;
8847 struct route_in6 *ro;
8848 struct sockaddr_in6 *dst;
8849 struct ip6_hdr *ip6;
8850 struct ifnet *ifp = NULL;
8851 struct pf_addr naddr;
8852 struct pf_src_node *sn = NULL;
8853 int error = 0;
8854
8855 if (m == NULL || *m == NULL || r == NULL ||
8856 (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
8857 panic("pf_route6: invalid parameters");
8858
316670eb 8859 if (pd->pf_mtag->pftag_routed++ > 3) {
b0d623f7
A
8860 m0 = *m;
8861 *m = NULL;
8862 goto bad;
8863 }
8864
8865 if (r->rt == PF_DUPTO) {
8866 if ((m0 = m_copym(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
8867 return;
8868 } else {
8869 if ((r->rt == PF_REPLYTO) == (r->direction == dir))
8870 return;
8871 m0 = *m;
8872 }
8873
8874 if (m0->m_len < (int)sizeof (struct ip6_hdr)) {
8875 DPFPRINTF(PF_DEBUG_URGENT,
8876 ("pf_route6: m0->m_len < sizeof (struct ip6_hdr)\n"));
8877 goto bad;
8878 }
8879 ip6 = mtod(m0, struct ip6_hdr *);
8880
8881 ro = &ip6route;
8882 bzero((caddr_t)ro, sizeof (*ro));
8883 dst = (struct sockaddr_in6 *)&ro->ro_dst;
8884 dst->sin6_family = AF_INET6;
8885 dst->sin6_len = sizeof (*dst);
8886 dst->sin6_addr = ip6->ip6_dst;
8887
8888 /* Cheat. XXX why only in the v6 case??? */
8889 if (r->rt == PF_FASTROUTE) {
8890 struct pf_mtag *pf_mtag;
8891
8892 if ((pf_mtag = pf_get_mtag(m0)) == NULL)
8893 goto bad;
316670eb 8894 pf_mtag->pftag_flags |= PF_TAG_GENERATED;
6d2010ae 8895 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
b0d623f7
A
8896 return;
8897 }
8898
8899 if (TAILQ_EMPTY(&r->rpool.list)) {
8900 DPFPRINTF(PF_DEBUG_URGENT,
8901 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n"));
8902 goto bad;
8903 }
8904 if (s == NULL) {
8905 pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
8906 &naddr, NULL, &sn);
8907 if (!PF_AZERO(&naddr, AF_INET6))
8908 PF_ACPY((struct pf_addr *)&dst->sin6_addr,
8909 &naddr, AF_INET6);
8910 ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
8911 } else {
8912 if (!PF_AZERO(&s->rt_addr, AF_INET6))
8913 PF_ACPY((struct pf_addr *)&dst->sin6_addr,
8914 &s->rt_addr, AF_INET6);
8915 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
8916 }
8917 if (ifp == NULL)
8918 goto bad;
8919
8920 if (oifp != ifp) {
316670eb 8921 if (pf_test6(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS)
b0d623f7
A
8922 goto bad;
8923 else if (m0 == NULL)
8924 goto done;
8925 if (m0->m_len < (int)sizeof (struct ip6_hdr)) {
8926 DPFPRINTF(PF_DEBUG_URGENT, ("pf_route6: m0->m_len "
8927 "< sizeof (struct ip6_hdr)\n"));
8928 goto bad;
8929 }
8930 ip6 = mtod(m0, struct ip6_hdr *);
8931 }
8932
8933 /*
8934 * If the packet is too large for the outgoing interface,
8935 * send back an icmp6 error.
8936 */
8937 if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr))
8938 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
8939 if ((unsigned)m0->m_pkthdr.len <= ifp->if_mtu) {
316670eb 8940 error = nd6_output(ifp, ifp, m0, dst, NULL, NULL);
b0d623f7
A
8941 } else {
8942 in6_ifstat_inc(ifp, ifs6_in_toobig);
8943 if (r->rt != PF_DUPTO)
8944 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
8945 else
8946 goto bad;
8947 }
8948
8949done:
8950 if (r->rt != PF_DUPTO)
8951 *m = NULL;
8952 return;
8953
8954bad:
8955 m_freem(m0);
8956 goto done;
8957}
8958#endif /* INET6 */
8959
8960
8961/*
8962 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag
8963 * off is the offset where the protocol header starts
8964 * len is the total length of protocol header plus payload
8965 * returns 0 when the checksum is valid, otherwise returns 1.
8966 */
8967static int
8968pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,
8969 sa_family_t af)
8970{
8971 u_int16_t sum;
8972
8973 switch (p) {
8974 case IPPROTO_TCP:
8975 case IPPROTO_UDP:
8976 /*
8977 * Optimize for the common case; if the hardware calculated
8978 * value doesn't include pseudo-header checksum, or if it
8979 * is partially-computed (only 16-bit summation), do it in
8980 * software below.
8981 */
39236c6e
A
8982 if ((m->m_pkthdr.csum_flags &
8983 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) ==
8984 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR) &&
b0d623f7
A
8985 (m->m_pkthdr.csum_data ^ 0xffff) == 0) {
8986 return (0);
8987 }
8988 break;
8989 case IPPROTO_ICMP:
8990#if INET6
8991 case IPPROTO_ICMPV6:
8992#endif /* INET6 */
8993 break;
8994 default:
8995 return (1);
8996 }
8997 if (off < (int)sizeof (struct ip) || len < (int)sizeof (struct udphdr))
8998 return (1);
8999 if (m->m_pkthdr.len < off + len)
9000 return (1);
9001 switch (af) {
9002#if INET
9003 case AF_INET:
9004 if (p == IPPROTO_ICMP) {
9005 if (m->m_len < off)
9006 return (1);
9007 m->m_data += off;
9008 m->m_len -= off;
9009 sum = in_cksum(m, len);
9010 m->m_data -= off;
9011 m->m_len += off;
9012 } else {
9013 if (m->m_len < (int)sizeof (struct ip))
9014 return (1);
9015 sum = inet_cksum(m, p, off, len);
9016 }
9017 break;
9018#endif /* INET */
9019#if INET6
9020 case AF_INET6:
9021 if (m->m_len < (int)sizeof (struct ip6_hdr))
9022 return (1);
9023 sum = inet6_cksum(m, p, off, len);
9024 break;
9025#endif /* INET6 */
9026 default:
9027 return (1);
9028 }
9029 if (sum) {
9030 switch (p) {
9031 case IPPROTO_TCP:
9032 tcpstat.tcps_rcvbadsum++;
9033 break;
9034 case IPPROTO_UDP:
9035 udpstat.udps_badsum++;
9036 break;
9037 case IPPROTO_ICMP:
9038 icmpstat.icps_checksum++;
9039 break;
9040#if INET6
9041 case IPPROTO_ICMPV6:
9042 icmp6stat.icp6s_checksum++;
9043 break;
9044#endif /* INET6 */
9045 }
9046 return (1);
9047 }
9048 return (0);
9049}
9050
9051#if INET
b0d623f7
A
9052#define PF_APPLE_UPDATE_PDESC_IPv4() \
9053 do { \
9054 if (m && pd.mp && m != pd.mp) { \
9055 m = pd.mp; \
9056 h = mtod(m, struct ip *); \
316670eb 9057 pd.pf_mtag = pf_get_mtag(m); \
b0d623f7
A
9058 } \
9059 } while (0)
b0d623f7
A
9060
9061int
9062pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
316670eb 9063 struct ether_header *eh, struct ip_fw_args *fwa)
b0d623f7 9064{
316670eb
A
9065#if !DUMMYNET
9066#pragma unused(fwa)
9067#endif
b0d623f7 9068 struct pfi_kif *kif;
316670eb 9069 u_short action = PF_PASS, reason = 0, log = 0;
b0d623f7
A
9070 struct mbuf *m = *m0;
9071 struct ip *h = 0;
9072 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
9073 struct pf_state *s = NULL;
9074 struct pf_state_key *sk = NULL;
9075 struct pf_ruleset *ruleset = NULL;
9076 struct pf_pdesc pd;
9077 int off, dirndx, pqid = 0;
9078
9079 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
9080
9081 if (!pf_status.running)
9082 return (PF_PASS);
9083
9084 memset(&pd, 0, sizeof (pd));
9085
9086 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) {
9087 DPFPRINTF(PF_DEBUG_URGENT,
9088 ("pf_test: pf_get_mtag returned NULL\n"));
9089 return (PF_DROP);
9090 }
9091
316670eb 9092 if (pd.pf_mtag->pftag_flags & PF_TAG_GENERATED)
b0d623f7
A
9093 return (PF_PASS);
9094
9095 kif = (struct pfi_kif *)ifp->if_pf_kif;
9096
9097 if (kif == NULL) {
9098 DPFPRINTF(PF_DEBUG_URGENT,
9099 ("pf_test: kif == NULL, if_name %s\n", ifp->if_name));
9100 return (PF_DROP);
9101 }
9102 if (kif->pfik_flags & PFI_IFLAG_SKIP)
9103 return (PF_PASS);
9104
39236c6e 9105 VERIFY(m->m_flags & M_PKTHDR);
b0d623f7 9106
316670eb
A
9107 /* initialize enough of pd for the done label */
9108 h = mtod(m, struct ip *);
9109 pd.mp = m;
9110 pd.lmw = 0;
9111 pd.pf_mtag = pf_get_mtag(m);
9112 pd.src = (struct pf_addr *)&h->ip_src;
9113 pd.dst = (struct pf_addr *)&h->ip_dst;
3e170ce0
A
9114 PF_ACPY(&pd.baddr, pd.src, AF_INET);
9115 PF_ACPY(&pd.bdaddr, pd.dst, AF_INET);
316670eb
A
9116 pd.ip_sum = &h->ip_sum;
9117 pd.proto = h->ip_p;
9118 pd.proto_variant = 0;
9119 pd.af = AF_INET;
9120 pd.tos = h->ip_tos;
3e170ce0 9121 pd.ttl = h->ip_ttl;
316670eb
A
9122 pd.tot_len = ntohs(h->ip_len);
9123 pd.eh = eh;
9124
b0d623f7
A
9125 if (m->m_pkthdr.len < (int)sizeof (*h)) {
9126 action = PF_DROP;
9127 REASON_SET(&reason, PFRES_SHORT);
9128 log = 1;
9129 goto done;
9130 }
9131
316670eb
A
9132#if DUMMYNET
9133 if (fwa != NULL && fwa->fwa_pf_rule != NULL)
9134 goto nonormalize;
9135#endif /* DUMMYNET */
9136
b0d623f7 9137 /* We do IP header normalization and packet reassembly here */
316670eb
A
9138 action = pf_normalize_ip(m0, dir, kif, &reason, &pd);
9139 pd.mp = m = *m0;
9140 if (action != PF_PASS || pd.lmw < 0) {
b0d623f7
A
9141 action = PF_DROP;
9142 goto done;
9143 }
316670eb
A
9144
9145#if DUMMYNET
9146nonormalize:
9147#endif /* DUMMYNET */
b0d623f7
A
9148 m = *m0; /* pf_normalize messes with m0 */
9149 h = mtod(m, struct ip *);
9150
9151 off = h->ip_hl << 2;
9152 if (off < (int)sizeof (*h)) {
9153 action = PF_DROP;
9154 REASON_SET(&reason, PFRES_SHORT);
9155 log = 1;
9156 goto done;
9157 }
9158
9159 pd.src = (struct pf_addr *)&h->ip_src;
9160 pd.dst = (struct pf_addr *)&h->ip_dst;
3e170ce0
A
9161 PF_ACPY(&pd.baddr, pd.src, AF_INET);
9162 PF_ACPY(&pd.bdaddr, pd.dst, AF_INET);
b0d623f7
A
9163 pd.ip_sum = &h->ip_sum;
9164 pd.proto = h->ip_p;
b0d623f7
A
9165 pd.proto_variant = 0;
9166 pd.mp = m;
9167 pd.lmw = 0;
316670eb 9168 pd.pf_mtag = pf_get_mtag(m);
b0d623f7
A
9169 pd.af = AF_INET;
9170 pd.tos = h->ip_tos;
3e170ce0 9171 pd.ttl = h->ip_ttl;
316670eb 9172 pd.sc = MBUF_SCIDX(mbuf_get_service_class(m));
b0d623f7
A
9173 pd.tot_len = ntohs(h->ip_len);
9174 pd.eh = eh;
39236c6e
A
9175
9176 if (m->m_pkthdr.pkt_flags & PKTF_FLOW_ID) {
9177 pd.flowsrc = m->m_pkthdr.pkt_flowsrc;
9178 pd.flowhash = m->m_pkthdr.pkt_flowid;
9179 pd.pktflags = (m->m_pkthdr.pkt_flags & PKTF_FLOW_MASK);
316670eb 9180 }
b0d623f7
A
9181
9182 /* handle fragments that didn't get reassembled by normalization */
9183 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) {
316670eb
A
9184 pd.flags |= PFDESC_IP_FRAG;
9185#if DUMMYNET
9186 /* Traffic goes through dummynet first */
9187 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9188 if (action == PF_DROP || m == NULL) {
9189 *m0 = NULL;
9190 return (action);
9191 }
9192#endif /* DUMMYNET */
b0d623f7
A
9193 action = pf_test_fragment(&r, dir, kif, m, h,
9194 &pd, &a, &ruleset);
9195 goto done;
9196 }
9197
9198 switch (h->ip_p) {
9199
9200 case IPPROTO_TCP: {
9201 struct tcphdr th;
9202 pd.hdr.tcp = &th;
9203 if (!pf_pull_hdr(m, off, &th, sizeof (th),
9204 &action, &reason, AF_INET)) {
9205 log = action != PF_PASS;
9206 goto done;
9207 }
9208 pd.p_len = pd.tot_len - off - (th.th_off << 2);
9209 if ((th.th_flags & TH_ACK) && pd.p_len == 0)
9210 pqid = 1;
316670eb
A
9211#if DUMMYNET
9212 /* Traffic goes through dummynet first */
9213 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9214 if (action == PF_DROP || m == NULL) {
9215 *m0 = NULL;
9216 return (action);
9217 }
9218#endif /* DUMMYNET */
b0d623f7 9219 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
b7266188 9220 if (pd.lmw < 0)
b0d623f7
A
9221 goto done;
9222 PF_APPLE_UPDATE_PDESC_IPv4();
b7266188
A
9223 if (action == PF_DROP)
9224 goto done;
b0d623f7
A
9225 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
9226 &reason);
3e170ce0
A
9227 if (action == PF_NAT64)
9228 goto done;
b0d623f7
A
9229 if (pd.lmw < 0)
9230 goto done;
9231 PF_APPLE_UPDATE_PDESC_IPv4();
b0d623f7
A
9232 if (action == PF_PASS) {
9233#if NPFSYNC
9234 pfsync_update_state(s);
9235#endif /* NPFSYNC */
9236 r = s->rule.ptr;
9237 a = s->anchor.ptr;
9238 log = s->log;
9239 } else if (s == NULL)
9240 action = pf_test_rule(&r, &s, dir, kif,
39236c6e 9241 m, off, h, &pd, &a, &ruleset, NULL);
b0d623f7
A
9242 break;
9243 }
9244
9245 case IPPROTO_UDP: {
9246 struct udphdr uh;
9247
9248 pd.hdr.udp = &uh;
9249 if (!pf_pull_hdr(m, off, &uh, sizeof (uh),
9250 &action, &reason, AF_INET)) {
9251 log = action != PF_PASS;
9252 goto done;
9253 }
9254 if (uh.uh_dport == 0 ||
9255 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
9256 ntohs(uh.uh_ulen) < sizeof (struct udphdr)) {
9257 action = PF_DROP;
9258 REASON_SET(&reason, PFRES_SHORT);
9259 goto done;
9260 }
316670eb
A
9261#if DUMMYNET
9262 /* Traffic goes through dummynet first */
9263 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9264 if (action == PF_DROP || m == NULL) {
9265 *m0 = NULL;
9266 return (action);
9267 }
9268#endif /* DUMMYNET */
b7266188
A
9269 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd,
9270 &reason);
3e170ce0
A
9271 if (action == PF_NAT64)
9272 goto done;
b0d623f7
A
9273 if (pd.lmw < 0)
9274 goto done;
9275 PF_APPLE_UPDATE_PDESC_IPv4();
b0d623f7
A
9276 if (action == PF_PASS) {
9277#if NPFSYNC
9278 pfsync_update_state(s);
9279#endif /* NPFSYNC */
9280 r = s->rule.ptr;
9281 a = s->anchor.ptr;
9282 log = s->log;
9283 } else if (s == NULL)
9284 action = pf_test_rule(&r, &s, dir, kif,
39236c6e 9285 m, off, h, &pd, &a, &ruleset, NULL);
b0d623f7
A
9286 break;
9287 }
9288
9289 case IPPROTO_ICMP: {
9290 struct icmp ih;
9291
9292 pd.hdr.icmp = &ih;
9293 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN,
9294 &action, &reason, AF_INET)) {
9295 log = action != PF_PASS;
9296 goto done;
9297 }
316670eb
A
9298#if DUMMYNET
9299 /* Traffic goes through dummynet first */
9300 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9301 if (action == PF_DROP || m == NULL) {
9302 *m0 = NULL;
9303 return (action);
9304 }
9305#endif /* DUMMYNET */
b0d623f7
A
9306 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd,
9307 &reason);
3e170ce0
A
9308 if (action == PF_NAT64)
9309 goto done;
b0d623f7
A
9310 if (pd.lmw < 0)
9311 goto done;
9312 PF_APPLE_UPDATE_PDESC_IPv4();
b0d623f7
A
9313 if (action == PF_PASS) {
9314#if NPFSYNC
9315 pfsync_update_state(s);
9316#endif /* NPFSYNC */
9317 r = s->rule.ptr;
9318 a = s->anchor.ptr;
9319 log = s->log;
3e170ce0 9320 } else if (s == NULL)
b0d623f7 9321 action = pf_test_rule(&r, &s, dir, kif,
39236c6e 9322 m, off, h, &pd, &a, &ruleset, NULL);
b0d623f7
A
9323 break;
9324 }
9325
b0d623f7
A
9326 case IPPROTO_ESP: {
9327 struct pf_esp_hdr esp;
9328
9329 pd.hdr.esp = &esp;
9330 if (!pf_pull_hdr(m, off, &esp, sizeof (esp), &action, &reason,
9331 AF_INET)) {
9332 log = action != PF_PASS;
9333 goto done;
9334 }
316670eb
A
9335#if DUMMYNET
9336 /* Traffic goes through dummynet first */
9337 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9338 if (action == PF_DROP || m == NULL) {
9339 *m0 = NULL;
9340 return (action);
9341 }
9342#endif /* DUMMYNET */
b0d623f7
A
9343 action = pf_test_state_esp(&s, dir, kif, off, &pd);
9344 if (pd.lmw < 0)
9345 goto done;
9346 PF_APPLE_UPDATE_PDESC_IPv4();
9347 if (action == PF_PASS) {
9348#if NPFSYNC
9349 pfsync_update_state(s);
9350#endif /* NPFSYNC */
9351 r = s->rule.ptr;
9352 a = s->anchor.ptr;
9353 log = s->log;
9354 } else if (s == NULL)
9355 action = pf_test_rule(&r, &s, dir, kif,
39236c6e 9356 m, off, h, &pd, &a, &ruleset, NULL);
b0d623f7
A
9357 break;
9358 }
9359
9360 case IPPROTO_GRE: {
9361 struct pf_grev1_hdr grev1;
9362 pd.hdr.grev1 = &grev1;
9363 if (!pf_pull_hdr(m, off, &grev1, sizeof (grev1), &action,
9364 &reason, AF_INET)) {
9365 log = (action != PF_PASS);
9366 goto done;
9367 }
316670eb
A
9368#if DUMMYNET
9369 /* Traffic goes through dummynet first */
9370 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9371 if (action == PF_DROP || m == NULL) {
9372 *m0 = NULL;
9373 return (action);
9374 }
9375#endif /* DUMMYNET */
b0d623f7
A
9376 if ((ntohs(grev1.flags) & PF_GRE_FLAG_VERSION_MASK) == 1 &&
9377 ntohs(grev1.protocol_type) == PF_GRE_PPP_ETHERTYPE) {
9378 if (ntohs(grev1.payload_length) >
9379 m->m_pkthdr.len - off) {
9380 action = PF_DROP;
9381 REASON_SET(&reason, PFRES_SHORT);
9382 goto done;
9383 }
9384 pd.proto_variant = PF_GRE_PPTP_VARIANT;
9385 action = pf_test_state_grev1(&s, dir, kif, off, &pd);
9386 if (pd.lmw < 0) goto done;
9387 PF_APPLE_UPDATE_PDESC_IPv4();
9388 if (action == PF_PASS) {
9389#if NPFSYNC
9390 pfsync_update_state(s);
9391#endif /* NPFSYNC */
9392 r = s->rule.ptr;
9393 a = s->anchor.ptr;
9394 log = s->log;
9395 break;
9396 } else if (s == NULL) {
9397 action = pf_test_rule(&r, &s, dir, kif, m, off,
39236c6e 9398 h, &pd, &a, &ruleset, NULL);
b0d623f7
A
9399 if (action == PF_PASS)
9400 break;
9401 }
9402 }
9403
9404 /* not GREv1/PPTP, so treat as ordinary GRE... */
9405 }
b0d623f7
A
9406
9407 default:
316670eb
A
9408#if DUMMYNET
9409 /* Traffic goes through dummynet first */
9410 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9411 if (action == PF_DROP || m == NULL) {
9412 *m0 = NULL;
9413 return (action);
9414 }
9415#endif /* DUMMYNET */
b0d623f7 9416 action = pf_test_state_other(&s, dir, kif, &pd);
b0d623f7
A
9417 if (pd.lmw < 0)
9418 goto done;
9419 PF_APPLE_UPDATE_PDESC_IPv4();
b0d623f7
A
9420 if (action == PF_PASS) {
9421#if NPFSYNC
9422 pfsync_update_state(s);
9423#endif /* NPFSYNC */
9424 r = s->rule.ptr;
9425 a = s->anchor.ptr;
9426 log = s->log;
9427 } else if (s == NULL)
9428 action = pf_test_rule(&r, &s, dir, kif, m, off, h,
39236c6e 9429 &pd, &a, &ruleset, NULL);
b0d623f7
A
9430 break;
9431 }
9432
9433done:
3e170ce0
A
9434 if (action == PF_NAT64) {
9435 *m0 = NULL;
9436 return (action);
9437 }
9438
b7266188 9439 *m0 = pd.mp;
b0d623f7
A
9440 PF_APPLE_UPDATE_PDESC_IPv4();
9441
9442 if (action == PF_PASS && h->ip_hl > 5 &&
9443 !((s && s->allow_opts) || r->allow_opts)) {
9444 action = PF_DROP;
9445 REASON_SET(&reason, PFRES_IPOPTIONS);
9446 log = 1;
9447 DPFPRINTF(PF_DEBUG_MISC,
9448 ("pf: dropping packet with ip options [hlen=%u]\n",
9449 (unsigned int) h->ip_hl));
9450 }
9451
316670eb 9452 if ((s && s->tag) || PF_RTABLEID_IS_VALID(r->rtableid) ||
39236c6e 9453 (pd.pktflags & PKTF_FLOW_ID))
b0d623f7 9454 (void) pf_tag_packet(m, pd.pf_mtag, s ? s->tag : 0,
316670eb 9455 r->rtableid, &pd);
b0d623f7 9456
316670eb
A
9457 if (action == PF_PASS) {
9458#if PF_ALTQ
9459 if (altq_allowed && r->qid) {
9460 if (pqid || (pd.tos & IPTOS_LOWDELAY))
9461 pd.pf_mtag->pftag_qid = r->pqid;
9462 else
9463 pd.pf_mtag->pftag_qid = r->qid;
9464 }
9465#endif /* PF_ALTQ */
39236c6e 9466#if PF_ECN
b0d623f7 9467 /* add hints for ecn */
316670eb
A
9468 pd.pf_mtag->pftag_hdr = h;
9469 /* record address family */
9470 pd.pf_mtag->pftag_flags &= ~PF_TAG_HDR_INET6;
9471 pd.pf_mtag->pftag_flags |= PF_TAG_HDR_INET;
39236c6e
A
9472#endif /* PF_ECN */
9473 /* record protocol */
9474 m->m_pkthdr.pkt_proto = pd.proto;
b0d623f7 9475 }
b0d623f7
A
9476
9477 /*
9478 * connections redirected to loopback should not match sockets
9479 * bound specifically to loopback due to security implications,
9480 * see tcp_input() and in_pcblookup_listen().
9481 */
9482 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
9483 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
9484 (s->nat_rule.ptr->action == PF_RDR ||
9485 s->nat_rule.ptr->action == PF_BINAT) &&
9486 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
316670eb 9487 pd.pf_mtag->pftag_flags |= PF_TAG_TRANSLATE_LOCALHOST;
b0d623f7
A
9488
9489 if (log) {
9490 struct pf_rule *lr;
9491
9492 if (s != NULL && s->nat_rule.ptr != NULL &&
9493 s->nat_rule.ptr->log & PF_LOG_ALL)
9494 lr = s->nat_rule.ptr;
9495 else
9496 lr = r;
9497 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, lr, a, ruleset,
9498 &pd);
9499 }
9500
9501 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
9502 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++;
9503
9504 if (action == PF_PASS || r->action == PF_DROP) {
9505 dirndx = (dir == PF_OUT);
9506 r->packets[dirndx]++;
9507 r->bytes[dirndx] += pd.tot_len;
9508 if (a != NULL) {
9509 a->packets[dirndx]++;
9510 a->bytes[dirndx] += pd.tot_len;
9511 }
9512 if (s != NULL) {
9513 sk = s->state_key;
9514 if (s->nat_rule.ptr != NULL) {
9515 s->nat_rule.ptr->packets[dirndx]++;
9516 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
9517 }
9518 if (s->src_node != NULL) {
9519 s->src_node->packets[dirndx]++;
9520 s->src_node->bytes[dirndx] += pd.tot_len;
9521 }
9522 if (s->nat_src_node != NULL) {
9523 s->nat_src_node->packets[dirndx]++;
9524 s->nat_src_node->bytes[dirndx] += pd.tot_len;
9525 }
9526 dirndx = (dir == sk->direction) ? 0 : 1;
9527 s->packets[dirndx]++;
9528 s->bytes[dirndx] += pd.tot_len;
9529 }
9530 tr = r;
9531 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
9532 if (nr != NULL) {
9533 struct pf_addr *x;
9534 /*
9535 * XXX: we need to make sure that the addresses
9536 * passed to pfr_update_stats() are the same than
9537 * the addresses used during matching (pfr_match)
9538 */
9539 if (r == &pf_default_rule) {
9540 tr = nr;
9541 x = (sk == NULL || sk->direction == dir) ?
9542 &pd.baddr : &pd.naddr;
9543 } else
9544 x = (sk == NULL || sk->direction == dir) ?
9545 &pd.naddr : &pd.baddr;
9546 if (x == &pd.baddr || s == NULL) {
9547 /* we need to change the address */
9548 if (dir == PF_OUT)
9549 pd.src = x;
9550 else
9551 pd.dst = x;
9552 }
9553 }
9554 if (tr->src.addr.type == PF_ADDR_TABLE)
9555 pfr_update_stats(tr->src.addr.p.tbl, (sk == NULL ||
9556 sk->direction == dir) ?
9557 pd.src : pd.dst, pd.af,
9558 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
9559 tr->src.neg);
9560 if (tr->dst.addr.type == PF_ADDR_TABLE)
9561 pfr_update_stats(tr->dst.addr.p.tbl, (sk == NULL ||
9562 sk->direction == dir) ? pd.dst : pd.src, pd.af,
9563 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
9564 tr->dst.neg);
9565 }
9566
b7266188
A
9567 VERIFY(m == NULL || pd.mp == NULL || pd.mp == m);
9568
b0d623f7
A
9569 if (*m0) {
9570 if (pd.lmw < 0) {
b7266188
A
9571 REASON_SET(&reason, PFRES_MEMORY);
9572 action = PF_DROP;
9573 }
9574
9575 if (action == PF_DROP) {
b0d623f7
A
9576 m_freem(*m0);
9577 *m0 = NULL;
9578 return (PF_DROP);
9579 }
9580
9581 *m0 = m;
9582 }
b0d623f7
A
9583
9584 if (action == PF_SYNPROXY_DROP) {
9585 m_freem(*m0);
9586 *m0 = NULL;
9587 action = PF_PASS;
9588 } else if (r->rt)
9589 /* pf_route can free the mbuf causing *m0 to become NULL */
9590 pf_route(m0, r, dir, kif->pfik_ifp, s, &pd);
9591
9592 return (action);
9593}
9594#endif /* INET */
9595
9596#if INET6
b0d623f7
A
9597#define PF_APPLE_UPDATE_PDESC_IPv6() \
9598 do { \
9599 if (m && pd.mp && m != pd.mp) { \
9600 if (n == m) \
9601 n = pd.mp; \
9602 m = pd.mp; \
9603 h = mtod(m, struct ip6_hdr *); \
9604 } \
9605 } while (0)
b0d623f7
A
9606
9607int
9608pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
316670eb 9609 struct ether_header *eh, struct ip_fw_args *fwa)
b0d623f7 9610{
316670eb
A
9611#if !DUMMYNET
9612#pragma unused(fwa)
9613#endif
b0d623f7 9614 struct pfi_kif *kif;
316670eb 9615 u_short action = PF_PASS, reason = 0, log = 0;
b0d623f7
A
9616 struct mbuf *m = *m0, *n = NULL;
9617 struct ip6_hdr *h;
9618 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
9619 struct pf_state *s = NULL;
9620 struct pf_state_key *sk = NULL;
9621 struct pf_ruleset *ruleset = NULL;
9622 struct pf_pdesc pd;
9623 int off, terminal = 0, dirndx, rh_cnt = 0;
316670eb 9624 u_int8_t nxt;
b0d623f7
A
9625
9626 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
9627
9628 if (!pf_status.running)
9629 return (PF_PASS);
9630
9631 memset(&pd, 0, sizeof (pd));
9632
9633 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) {
9634 DPFPRINTF(PF_DEBUG_URGENT,
9635 ("pf_test6: pf_get_mtag returned NULL\n"));
9636 return (PF_DROP);
9637 }
9638
316670eb 9639 if (pd.pf_mtag->pftag_flags & PF_TAG_GENERATED)
b0d623f7
A
9640 return (PF_PASS);
9641
9642 kif = (struct pfi_kif *)ifp->if_pf_kif;
9643
9644 if (kif == NULL) {
9645 DPFPRINTF(PF_DEBUG_URGENT,
9646 ("pf_test6: kif == NULL, if_name %s\n", ifp->if_name));
9647 return (PF_DROP);
9648 }
9649 if (kif->pfik_flags & PFI_IFLAG_SKIP)
9650 return (PF_PASS);
9651
39236c6e 9652 VERIFY(m->m_flags & M_PKTHDR);
b0d623f7
A
9653
9654 h = mtod(m, struct ip6_hdr *);
9655
316670eb
A
9656 nxt = h->ip6_nxt;
9657 off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr);
9658 pd.mp = m;
9659 pd.lmw = 0;
9660 pd.pf_mtag = pf_get_mtag(m);
9661 pd.src = (struct pf_addr *)&h->ip6_src;
9662 pd.dst = (struct pf_addr *)&h->ip6_dst;
3e170ce0
A
9663 PF_ACPY(&pd.baddr, pd.src, AF_INET6);
9664 PF_ACPY(&pd.bdaddr, pd.dst, AF_INET6);
316670eb
A
9665 pd.ip_sum = NULL;
9666 pd.af = AF_INET6;
9667 pd.proto = nxt;
9668 pd.proto_variant = 0;
9669 pd.tos = 0;
3e170ce0 9670 pd.ttl = h->ip6_hlim;
316670eb
A
9671 pd.sc = MBUF_SCIDX(mbuf_get_service_class(m));
9672 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
9673 pd.eh = eh;
9674
39236c6e
A
9675 if (m->m_pkthdr.pkt_flags & PKTF_FLOW_ID) {
9676 pd.flowsrc = m->m_pkthdr.pkt_flowsrc;
9677 pd.flowhash = m->m_pkthdr.pkt_flowid;
9678 pd.pktflags = (m->m_pkthdr.pkt_flags & PKTF_FLOW_MASK);
316670eb
A
9679 }
9680
b0d623f7
A
9681 if (m->m_pkthdr.len < (int)sizeof (*h)) {
9682 action = PF_DROP;
9683 REASON_SET(&reason, PFRES_SHORT);
9684 log = 1;
9685 goto done;
9686 }
9687
316670eb
A
9688#if DUMMYNET
9689 if (fwa != NULL && fwa->fwa_pf_rule != NULL)
9690 goto nonormalize;
9691#endif /* DUMMYNET */
9692
b0d623f7 9693 /* We do IP header normalization and packet reassembly here */
316670eb
A
9694 action = pf_normalize_ip6(m0, dir, kif, &reason, &pd);
9695 pd.mp = m = *m0;
9696 if (action != PF_PASS || pd.lmw < 0) {
b0d623f7
A
9697 action = PF_DROP;
9698 goto done;
9699 }
316670eb
A
9700
9701#if DUMMYNET
9702nonormalize:
9703#endif /* DUMMYNET */
b0d623f7
A
9704 h = mtod(m, struct ip6_hdr *);
9705
9706#if 1
9707 /*
9708 * we do not support jumbogram yet. if we keep going, zero ip6_plen
9709 * will do something bad, so drop the packet for now.
9710 */
9711 if (htons(h->ip6_plen) == 0) {
9712 action = PF_DROP;
9713 REASON_SET(&reason, PFRES_NORM); /*XXX*/
9714 goto done;
9715 }
9716#endif
9717
9718 pd.src = (struct pf_addr *)&h->ip6_src;
9719 pd.dst = (struct pf_addr *)&h->ip6_dst;
3e170ce0
A
9720 PF_ACPY(&pd.baddr, pd.src, AF_INET6);
9721 PF_ACPY(&pd.bdaddr, pd.dst, AF_INET6);
b0d623f7
A
9722 pd.ip_sum = NULL;
9723 pd.af = AF_INET6;
9724 pd.tos = 0;
3e170ce0 9725 pd.ttl = h->ip6_hlim;
b0d623f7
A
9726 pd.tot_len = ntohs(h->ip6_plen) + sizeof (struct ip6_hdr);
9727 pd.eh = eh;
9728
9729 off = ((caddr_t)h - m->m_data) + sizeof (struct ip6_hdr);
9730 pd.proto = h->ip6_nxt;
b0d623f7
A
9731 pd.proto_variant = 0;
9732 pd.mp = m;
9733 pd.lmw = 0;
316670eb 9734 pd.pf_mtag = pf_get_mtag(m);
b0d623f7 9735
316670eb
A
9736 do {
9737 switch (nxt) {
9738 case IPPROTO_FRAGMENT: {
9739 struct ip6_frag ip6f;
39236c6e 9740
316670eb
A
9741 pd.flags |= PFDESC_IP_FRAG;
9742 if (!pf_pull_hdr(m, off, &ip6f, sizeof ip6f, NULL,
b0d623f7
A
9743 &reason, pd.af)) {
9744 DPFPRINTF(PF_DEBUG_MISC,
316670eb 9745 ("pf: IPv6 short fragment header\n"));
b0d623f7
A
9746 action = PF_DROP;
9747 REASON_SET(&reason, PFRES_SHORT);
9748 log = 1;
9749 goto done;
9750 }
316670eb
A
9751 pd.proto = nxt = ip6f.ip6f_nxt;
9752#if DUMMYNET
9753 /* Traffic goes through dummynet first */
9754 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9755 if (action == PF_DROP || m == NULL) {
9756 *m0 = NULL;
9757 return (action);
9758 }
9759#endif /* DUMMYNET */
9760 action = pf_test_fragment(&r, dir, kif, m, h, &pd, &a,
9761 &ruleset);
9762 if (action == PF_DROP) {
9763 REASON_SET(&reason, PFRES_FRAG);
b0d623f7 9764 log = 1;
b0d623f7 9765 }
316670eb 9766 goto done;
b0d623f7 9767 }
316670eb
A
9768 case IPPROTO_ROUTING:
9769 ++rh_cnt;
9770 /* FALL THROUGH */
9771
b0d623f7
A
9772 case IPPROTO_AH:
9773 case IPPROTO_HOPOPTS:
9774 case IPPROTO_DSTOPTS: {
9775 /* get next header and header length */
9776 struct ip6_ext opt6;
9777
316670eb 9778 if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6),
b0d623f7
A
9779 NULL, &reason, pd.af)) {
9780 DPFPRINTF(PF_DEBUG_MISC,
9781 ("pf: IPv6 short opt\n"));
9782 action = PF_DROP;
9783 log = 1;
9784 goto done;
9785 }
9786 if (pd.proto == IPPROTO_AH)
9787 off += (opt6.ip6e_len + 2) * 4;
9788 else
9789 off += (opt6.ip6e_len + 1) * 8;
316670eb 9790 nxt = opt6.ip6e_nxt;
b0d623f7
A
9791 /* goto the next header */
9792 break;
9793 }
9794 default:
9795 terminal++;
9796 break;
9797 }
9798 } while (!terminal);
9799
9800 /* if there's no routing header, use unmodified mbuf for checksumming */
9801 if (!n)
9802 n = m;
9803
9804 switch (pd.proto) {
9805
9806 case IPPROTO_TCP: {
9807 struct tcphdr th;
9808
9809 pd.hdr.tcp = &th;
9810 if (!pf_pull_hdr(m, off, &th, sizeof (th),
9811 &action, &reason, AF_INET6)) {
9812 log = action != PF_PASS;
9813 goto done;
9814 }
9815 pd.p_len = pd.tot_len - off - (th.th_off << 2);
316670eb
A
9816#if DUMMYNET
9817 /* Traffic goes through dummynet first */
9818 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9819 if (action == PF_DROP || m == NULL) {
9820 *m0 = NULL;
9821 return (action);
9822 }
9823#endif /* DUMMYNET */
b0d623f7 9824 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
b7266188 9825 if (pd.lmw < 0)
b0d623f7
A
9826 goto done;
9827 PF_APPLE_UPDATE_PDESC_IPv6();
b7266188
A
9828 if (action == PF_DROP)
9829 goto done;
b0d623f7
A
9830 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
9831 &reason);
3e170ce0
A
9832 if (action == PF_NAT64)
9833 goto done;
b0d623f7
A
9834 if (pd.lmw < 0)
9835 goto done;
9836 PF_APPLE_UPDATE_PDESC_IPv6();
b0d623f7
A
9837 if (action == PF_PASS) {
9838#if NPFSYNC
9839 pfsync_update_state(s);
9840#endif /* NPFSYNC */
9841 r = s->rule.ptr;
9842 a = s->anchor.ptr;
9843 log = s->log;
3e170ce0 9844 } else if (s == NULL)
b0d623f7 9845 action = pf_test_rule(&r, &s, dir, kif,
39236c6e 9846 m, off, h, &pd, &a, &ruleset, NULL);
b0d623f7
A
9847 break;
9848 }
9849
9850 case IPPROTO_UDP: {
9851 struct udphdr uh;
9852
9853 pd.hdr.udp = &uh;
9854 if (!pf_pull_hdr(m, off, &uh, sizeof (uh),
9855 &action, &reason, AF_INET6)) {
9856 log = action != PF_PASS;
9857 goto done;
9858 }
9859 if (uh.uh_dport == 0 ||
9860 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
9861 ntohs(uh.uh_ulen) < sizeof (struct udphdr)) {
9862 action = PF_DROP;
9863 REASON_SET(&reason, PFRES_SHORT);
9864 goto done;
9865 }
316670eb
A
9866#if DUMMYNET
9867 /* Traffic goes through dummynet first */
9868 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9869 if (action == PF_DROP || m == NULL) {
9870 *m0 = NULL;
9871 return (action);
9872 }
9873#endif /* DUMMYNET */
b7266188
A
9874 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd,
9875 &reason);
3e170ce0
A
9876 if (action == PF_NAT64)
9877 goto done;
b0d623f7
A
9878 if (pd.lmw < 0)
9879 goto done;
9880 PF_APPLE_UPDATE_PDESC_IPv6();
b0d623f7
A
9881 if (action == PF_PASS) {
9882#if NPFSYNC
9883 pfsync_update_state(s);
9884#endif /* NPFSYNC */
9885 r = s->rule.ptr;
9886 a = s->anchor.ptr;
9887 log = s->log;
3e170ce0 9888 } else if (s == NULL)
b0d623f7 9889 action = pf_test_rule(&r, &s, dir, kif,
39236c6e 9890 m, off, h, &pd, &a, &ruleset, NULL);
b0d623f7
A
9891 break;
9892 }
9893
9894 case IPPROTO_ICMPV6: {
9895 struct icmp6_hdr ih;
9896
9897 pd.hdr.icmp6 = &ih;
9898 if (!pf_pull_hdr(m, off, &ih, sizeof (ih),
9899 &action, &reason, AF_INET6)) {
9900 log = action != PF_PASS;
9901 goto done;
9902 }
316670eb
A
9903#if DUMMYNET
9904 /* Traffic goes through dummynet first */
9905 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9906 if (action == PF_DROP || m == NULL) {
9907 *m0 = NULL;
9908 return (action);
9909 }
9910#endif /* DUMMYNET */
b0d623f7
A
9911 action = pf_test_state_icmp(&s, dir, kif,
9912 m, off, h, &pd, &reason);
3e170ce0
A
9913 if (action == PF_NAT64)
9914 goto done;
b0d623f7
A
9915 if (pd.lmw < 0)
9916 goto done;
9917 PF_APPLE_UPDATE_PDESC_IPv6();
b0d623f7
A
9918 if (action == PF_PASS) {
9919#if NPFSYNC
9920 pfsync_update_state(s);
9921#endif /* NPFSYNC */
9922 r = s->rule.ptr;
9923 a = s->anchor.ptr;
9924 log = s->log;
9925 } else if (s == NULL)
9926 action = pf_test_rule(&r, &s, dir, kif,
39236c6e 9927 m, off, h, &pd, &a, &ruleset, NULL);
b0d623f7
A
9928 break;
9929 }
9930
b0d623f7
A
9931 case IPPROTO_ESP: {
9932 struct pf_esp_hdr esp;
9933
9934 pd.hdr.esp = &esp;
9935 if (!pf_pull_hdr(m, off, &esp, sizeof (esp), &action, &reason,
9936 AF_INET6)) {
9937 log = action != PF_PASS;
9938 goto done;
9939 }
316670eb
A
9940#if DUMMYNET
9941 /* Traffic goes through dummynet first */
9942 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9943 if (action == PF_DROP || m == NULL) {
9944 *m0 = NULL;
9945 return (action);
9946 }
9947#endif /* DUMMYNET */
b0d623f7
A
9948 action = pf_test_state_esp(&s, dir, kif, off, &pd);
9949 if (pd.lmw < 0)
9950 goto done;
9951 PF_APPLE_UPDATE_PDESC_IPv6();
9952 if (action == PF_PASS) {
9953#if NPFSYNC
9954 pfsync_update_state(s);
9955#endif /* NPFSYNC */
9956 r = s->rule.ptr;
9957 a = s->anchor.ptr;
9958 log = s->log;
9959 } else if (s == NULL)
9960 action = pf_test_rule(&r, &s, dir, kif,
39236c6e 9961 m, off, h, &pd, &a, &ruleset, NULL);
b0d623f7
A
9962 break;
9963 }
9964
9965 case IPPROTO_GRE: {
9966 struct pf_grev1_hdr grev1;
9967
9968 pd.hdr.grev1 = &grev1;
9969 if (!pf_pull_hdr(m, off, &grev1, sizeof (grev1), &action,
9970 &reason, AF_INET6)) {
9971 log = (action != PF_PASS);
9972 goto done;
9973 }
316670eb
A
9974#if DUMMYNET
9975 /* Traffic goes through dummynet first */
9976 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
9977 if (action == PF_DROP || m == NULL) {
9978 *m0 = NULL;
9979 return (action);
9980 }
9981#endif /* DUMMYNET */
b0d623f7
A
9982 if ((ntohs(grev1.flags) & PF_GRE_FLAG_VERSION_MASK) == 1 &&
9983 ntohs(grev1.protocol_type) == PF_GRE_PPP_ETHERTYPE) {
9984 if (ntohs(grev1.payload_length) >
9985 m->m_pkthdr.len - off) {
9986 action = PF_DROP;
9987 REASON_SET(&reason, PFRES_SHORT);
9988 goto done;
9989 }
9990 action = pf_test_state_grev1(&s, dir, kif, off, &pd);
9991 if (pd.lmw < 0)
9992 goto done;
9993 PF_APPLE_UPDATE_PDESC_IPv6();
9994 if (action == PF_PASS) {
9995#if NPFSYNC
9996 pfsync_update_state(s);
9997#endif /* NPFSYNC */
9998 r = s->rule.ptr;
9999 a = s->anchor.ptr;
10000 log = s->log;
10001 break;
10002 } else if (s == NULL) {
10003 action = pf_test_rule(&r, &s, dir, kif, m, off,
39236c6e 10004 h, &pd, &a, &ruleset, NULL);
b0d623f7
A
10005 if (action == PF_PASS)
10006 break;
10007 }
10008 }
10009
10010 /* not GREv1/PPTP, so treat as ordinary GRE... */
10011 }
b0d623f7
A
10012
10013 default:
316670eb
A
10014#if DUMMYNET
10015 /* Traffic goes through dummynet first */
10016 action = pf_test_dummynet(&r, dir, kif, &m, &pd, fwa);
10017 if (action == PF_DROP || m == NULL) {
10018 *m0 = NULL;
10019 return (action);
10020 }
10021#endif /* DUMMYNET */
b0d623f7 10022 action = pf_test_state_other(&s, dir, kif, &pd);
b0d623f7
A
10023 if (pd.lmw < 0)
10024 goto done;
10025 PF_APPLE_UPDATE_PDESC_IPv6();
b0d623f7
A
10026 if (action == PF_PASS) {
10027#if NPFSYNC
10028 pfsync_update_state(s);
10029#endif /* NPFSYNC */
10030 r = s->rule.ptr;
10031 a = s->anchor.ptr;
10032 log = s->log;
10033 } else if (s == NULL)
10034 action = pf_test_rule(&r, &s, dir, kif, m, off, h,
39236c6e 10035 &pd, &a, &ruleset, NULL);
b0d623f7
A
10036 break;
10037 }
10038
10039done:
3e170ce0
A
10040 if (action == PF_NAT64) {
10041 *m0 = NULL;
10042 return (action);
10043 }
10044
b7266188 10045 *m0 = pd.mp;
b0d623f7
A
10046 PF_APPLE_UPDATE_PDESC_IPv6();
10047
10048 if (n != m) {
10049 m_freem(n);
10050 n = NULL;
10051 }
10052
10053 /* handle dangerous IPv6 extension headers. */
10054 if (action == PF_PASS && rh_cnt &&
10055 !((s && s->allow_opts) || r->allow_opts)) {
10056 action = PF_DROP;
10057 REASON_SET(&reason, PFRES_IPOPTIONS);
10058 log = 1;
10059 DPFPRINTF(PF_DEBUG_MISC,
10060 ("pf: dropping packet with dangerous v6 headers\n"));
10061 }
10062
39236c6e
A
10063 if ((s && s->tag) || PF_RTABLEID_IS_VALID(r->rtableid) ||
10064 (pd.pktflags & PKTF_FLOW_ID))
b0d623f7 10065 (void) pf_tag_packet(m, pd.pf_mtag, s ? s->tag : 0,
316670eb 10066 r->rtableid, &pd);
b0d623f7 10067
316670eb
A
10068 if (action == PF_PASS) {
10069#if PF_ALTQ
10070 if (altq_allowed && r->qid) {
10071 if (pd.tos & IPTOS_LOWDELAY)
10072 pd.pf_mtag->pftag_qid = r->pqid;
10073 else
10074 pd.pf_mtag->pftag_qid = r->qid;
10075 }
10076#endif /* PF_ALTQ */
39236c6e 10077#if PF_ECN
b0d623f7 10078 /* add hints for ecn */
316670eb
A
10079 pd.pf_mtag->pftag_hdr = h;
10080 /* record address family */
10081 pd.pf_mtag->pftag_flags &= ~PF_TAG_HDR_INET;
10082 pd.pf_mtag->pftag_flags |= PF_TAG_HDR_INET6;
39236c6e
A
10083#endif /* PF_ECN */
10084 /* record protocol */
10085 m->m_pkthdr.pkt_proto = pd.proto;
b0d623f7 10086 }
b0d623f7
A
10087
10088 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
10089 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
10090 (s->nat_rule.ptr->action == PF_RDR ||
10091 s->nat_rule.ptr->action == PF_BINAT) &&
10092 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6))
316670eb 10093 pd.pf_mtag->pftag_flags |= PF_TAG_TRANSLATE_LOCALHOST;
b0d623f7
A
10094
10095 if (log) {
10096 struct pf_rule *lr;
10097
10098 if (s != NULL && s->nat_rule.ptr != NULL &&
10099 s->nat_rule.ptr->log & PF_LOG_ALL)
10100 lr = s->nat_rule.ptr;
10101 else
10102 lr = r;
10103 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, lr, a, ruleset,
10104 &pd);
10105 }
10106
10107 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
10108 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++;
10109
10110 if (action == PF_PASS || r->action == PF_DROP) {
10111 dirndx = (dir == PF_OUT);
10112 r->packets[dirndx]++;
10113 r->bytes[dirndx] += pd.tot_len;
10114 if (a != NULL) {
10115 a->packets[dirndx]++;
10116 a->bytes[dirndx] += pd.tot_len;
10117 }
10118 if (s != NULL) {
10119 sk = s->state_key;
10120 if (s->nat_rule.ptr != NULL) {
10121 s->nat_rule.ptr->packets[dirndx]++;
10122 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
10123 }
10124 if (s->src_node != NULL) {
10125 s->src_node->packets[dirndx]++;
10126 s->src_node->bytes[dirndx] += pd.tot_len;
10127 }
10128 if (s->nat_src_node != NULL) {
10129 s->nat_src_node->packets[dirndx]++;
10130 s->nat_src_node->bytes[dirndx] += pd.tot_len;
10131 }
10132 dirndx = (dir == sk->direction) ? 0 : 1;
10133 s->packets[dirndx]++;
10134 s->bytes[dirndx] += pd.tot_len;
10135 }
10136 tr = r;
10137 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
10138 if (nr != NULL) {
10139 struct pf_addr *x;
10140 /*
10141 * XXX: we need to make sure that the addresses
10142 * passed to pfr_update_stats() are the same than
10143 * the addresses used during matching (pfr_match)
10144 */
10145 if (r == &pf_default_rule) {
10146 tr = nr;
10147 x = (s == NULL || sk->direction == dir) ?
10148 &pd.baddr : &pd.naddr;
10149 } else {
10150 x = (s == NULL || sk->direction == dir) ?
10151 &pd.naddr : &pd.baddr;
10152 }
10153 if (x == &pd.baddr || s == NULL) {
10154 if (dir == PF_OUT)
10155 pd.src = x;
10156 else
10157 pd.dst = x;
10158 }
10159 }
10160 if (tr->src.addr.type == PF_ADDR_TABLE)
10161 pfr_update_stats(tr->src.addr.p.tbl, (sk == NULL ||
10162 sk->direction == dir) ? pd.src : pd.dst, pd.af,
10163 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
10164 tr->src.neg);
10165 if (tr->dst.addr.type == PF_ADDR_TABLE)
10166 pfr_update_stats(tr->dst.addr.p.tbl, (sk == NULL ||
10167 sk->direction == dir) ? pd.dst : pd.src, pd.af,
10168 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
10169 tr->dst.neg);
10170 }
10171
10172#if 0
10173 if (action == PF_SYNPROXY_DROP) {
10174 m_freem(*m0);
10175 *m0 = NULL;
10176 action = PF_PASS;
10177 } else if (r->rt)
10178 /* pf_route6 can free the mbuf causing *m0 to become NULL */
10179 pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd);
10180#else
b7266188
A
10181 VERIFY(m == NULL || pd.mp == NULL || pd.mp == m);
10182
b0d623f7
A
10183 if (*m0) {
10184 if (pd.lmw < 0) {
b7266188
A
10185 REASON_SET(&reason, PFRES_MEMORY);
10186 action = PF_DROP;
10187 }
10188
10189 if (action == PF_DROP) {
b0d623f7
A
10190 m_freem(*m0);
10191 *m0 = NULL;
10192 return (PF_DROP);
10193 }
10194
10195 *m0 = m;
10196 }
10197
10198 if (action == PF_SYNPROXY_DROP) {
10199 m_freem(*m0);
10200 *m0 = NULL;
10201 action = PF_PASS;
10202 } else if (r->rt) {
10203 if (action == PF_PASS) {
10204 m = *m0;
10205 h = mtod(m, struct ip6_hdr *);
10206 }
10207
10208 /* pf_route6 can free the mbuf causing *m0 to become NULL */
10209 pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd);
10210 }
316670eb 10211#endif /* 0 */
b0d623f7
A
10212
10213 return (action);
10214}
10215#endif /* INET6 */
10216
10217static int
10218pf_check_congestion(struct ifqueue *ifq)
10219{
10220#pragma unused(ifq)
10221 return (0);
10222}
10223
10224void
10225pool_init(struct pool *pp, size_t size, unsigned int align, unsigned int ioff,
10226 int flags, const char *wchan, void *palloc)
10227{
10228#pragma unused(align, ioff, flags, palloc)
10229 bzero(pp, sizeof (*pp));
10230 pp->pool_zone = zinit(size, 1024 * size, PAGE_SIZE, wchan);
10231 if (pp->pool_zone != NULL) {
10232 zone_change(pp->pool_zone, Z_EXPAND, TRUE);
6d2010ae 10233 zone_change(pp->pool_zone, Z_CALLERACCT, FALSE);
b0d623f7
A
10234 pp->pool_hiwat = pp->pool_limit = (unsigned int)-1;
10235 pp->pool_name = wchan;
10236 }
10237}
10238
10239/* Zones cannot be currently destroyed */
10240void
10241pool_destroy(struct pool *pp)
10242{
10243#pragma unused(pp)
10244}
10245
10246void
10247pool_sethiwat(struct pool *pp, int n)
10248{
10249 pp->pool_hiwat = n; /* Currently unused */
10250}
10251
10252void
10253pool_sethardlimit(struct pool *pp, int n, const char *warnmess, int ratecap)
10254{
10255#pragma unused(warnmess, ratecap)
10256 pp->pool_limit = n;
10257}
10258
10259void *
10260pool_get(struct pool *pp, int flags)
10261{
10262 void *buf;
10263
10264 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
10265
10266 if (pp->pool_count > pp->pool_limit) {
10267 DPFPRINTF(PF_DEBUG_NOISY,
10268 ("pf: pool %s hard limit reached (%d)\n",
10269 pp->pool_name != NULL ? pp->pool_name : "unknown",
10270 pp->pool_limit));
10271 pp->pool_fails++;
10272 return (NULL);
10273 }
10274
10275 buf = zalloc_canblock(pp->pool_zone, (flags & (PR_NOWAIT | PR_WAITOK)));
10276 if (buf != NULL) {
10277 pp->pool_count++;
10278 VERIFY(pp->pool_count != 0);
10279 }
10280 return (buf);
10281}
10282
10283void
10284pool_put(struct pool *pp, void *v)
10285{
10286 lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);
10287
10288 zfree(pp->pool_zone, v);
10289 VERIFY(pp->pool_count != 0);
10290 pp->pool_count--;
10291}
10292
10293struct pf_mtag *
10294pf_find_mtag(struct mbuf *m)
10295{
b0d623f7
A
10296 if (!(m->m_flags & M_PKTHDR))
10297 return (NULL);
10298
316670eb 10299 return (m_pftag(m));
b0d623f7
A
10300}
10301
10302struct pf_mtag *
10303pf_get_mtag(struct mbuf *m)
10304{
b0d623f7 10305 return (pf_find_mtag(m));
b0d623f7
A
10306}
10307
10308uint64_t
10309pf_time_second(void)
10310{
10311 struct timeval t;
10312
b7266188
A
10313 microuptime(&t);
10314 return (t.tv_sec);
10315}
10316
10317uint64_t
10318pf_calendar_time_second(void)
10319{
10320 struct timeval t;
10321
39236c6e 10322 getmicrotime(&t);
b0d623f7
A
10323 return (t.tv_sec);
10324}
10325
10326static void *
10327hook_establish(struct hook_desc_head *head, int tail, hook_fn_t fn, void *arg)
10328{
10329 struct hook_desc *hd;
10330
10331 hd = _MALLOC(sizeof(*hd), M_DEVBUF, M_WAITOK);
10332 if (hd == NULL)
10333 return (NULL);
10334
10335 hd->hd_fn = fn;
10336 hd->hd_arg = arg;
10337 if (tail)
10338 TAILQ_INSERT_TAIL(head, hd, hd_list);
10339 else
10340 TAILQ_INSERT_HEAD(head, hd, hd_list);
10341
10342 return (hd);
10343}
10344
10345static void
10346hook_runloop(struct hook_desc_head *head, int flags)
10347{
10348 struct hook_desc *hd;
10349
10350 if (!(flags & HOOK_REMOVE)) {
10351 if (!(flags & HOOK_ABORT))
10352 TAILQ_FOREACH(hd, head, hd_list)
10353 hd->hd_fn(hd->hd_arg);
10354 } else {
10355 while (!!(hd = TAILQ_FIRST(head))) {
10356 TAILQ_REMOVE(head, hd, hd_list);
10357 if (!(flags & HOOK_ABORT))
10358 hd->hd_fn(hd->hd_arg);
10359 if (flags & HOOK_FREE)
10360 _FREE(hd, M_DEVBUF);
10361 }
10362 }
10363}