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