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