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