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