Sync usage with man page.
[netbsd-mini2440.git] / sys / dist / pf / net / pf.c
blob26251cb7db39ee7ea46f69672aa4524f1efde55b
1 /* $NetBSD: pf.c,v 1.59 2009/12/30 16:49:02 elad Exp $ */
2 /* $OpenBSD: pf.c,v 1.552.2.1 2007/11/27 16:37:57 henning Exp $ */
4 /*
5 * Copyright (c) 2001 Daniel Hartmeier
6 * Copyright (c) 2002,2003 Henning Brauer
7 * All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
13 * - Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
33 * Effort sponsored in part by the Defense Advanced Research Projects
34 * Agency (DARPA) and Air Force Research Laboratory, Air Force
35 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: pf.c,v 1.59 2009/12/30 16:49:02 elad Exp $");
42 #include "bpfilter.h"
43 #include "pflog.h"
45 #include "pfsync.h"
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/mbuf.h>
50 #include <sys/filio.h>
51 #include <sys/socket.h>
52 #include <sys/socketvar.h>
53 #include <sys/kernel.h>
54 #include <sys/time.h>
55 #include <sys/pool.h>
56 #include <sys/proc.h>
57 #include <sys/rwlock.h>
58 #ifdef __NetBSD__
59 #include <sys/kthread.h>
60 #include <sys/kauth.h>
61 #endif /* __NetBSD__ */
63 #include <net/if.h>
64 #include <net/if_types.h>
65 #include <net/bpf.h>
66 #include <net/route.h>
67 #ifndef __NetBSD__
68 #include <net/radix_mpath.h>
69 #endif /* !__NetBSD__ */
71 #include <netinet/in.h>
72 #ifdef __NetBSD__
73 #include <netinet/in_offload.h>
74 #endif /* __NetBSD__ */
75 #include <netinet/in_var.h>
76 #include <netinet/in_systm.h>
77 #include <netinet/ip.h>
78 #include <netinet/ip_var.h>
79 #include <netinet/tcp.h>
80 #include <netinet/tcp_seq.h>
81 #include <netinet/udp.h>
82 #include <netinet/ip_icmp.h>
83 #include <netinet/in_pcb.h>
84 #include <netinet/tcp_timer.h>
85 #include <netinet/tcp_var.h>
86 #include <netinet/udp_var.h>
87 #include <netinet/icmp_var.h>
88 #ifndef __NetBSD__
89 #include <netinet/if_ether.h>
90 #else
91 #include <net/if_ether.h>
92 #endif /* __NetBSD__ */
94 #ifndef __NetBSD__
95 #include <dev/rndvar.h>
96 #else
97 #include <sys/rnd.h>
98 #endif /* __NetBSD__ */
100 #include <net/pfvar.h>
101 #include <net/if_pflog.h>
103 #if NPFSYNC > 0
104 #include <net/if_pfsync.h>
105 #endif /* NPFSYNC > 0 */
107 #ifdef INET6
108 #include <netinet/ip6.h>
109 #include <netinet6/ip6_var.h>
110 #ifdef __NetBSD__
111 #include <netinet6/in6_pcb.h>
112 #endif /* __NetBSD__ */
113 #include <netinet/icmp6.h>
114 #include <netinet6/nd6.h>
115 #endif /* INET6 */
117 #ifdef __NetBSD__
118 #include <netinet/tcp_rndiss.h>
119 #endif /* __NetBSD__ */
122 #define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
125 * Global variables
128 /* state tables */
129 struct pf_state_tree_lan_ext pf_statetbl_lan_ext;
130 struct pf_state_tree_ext_gwy pf_statetbl_ext_gwy;
132 struct pf_altqqueue pf_altqs[2];
133 struct pf_palist pf_pabuf;
134 struct pf_altqqueue *pf_altqs_active;
135 struct pf_altqqueue *pf_altqs_inactive;
136 struct pf_status pf_status;
138 u_int32_t ticket_altqs_active;
139 u_int32_t ticket_altqs_inactive;
140 int altqs_inactive_open;
141 u_int32_t ticket_pabuf;
143 struct pf_anchor_stackframe {
144 struct pf_ruleset *rs;
145 struct pf_rule *r;
146 struct pf_anchor_node *parent;
147 struct pf_anchor *child;
148 } pf_anchor_stack[64];
150 struct pool pf_src_tree_pl, pf_rule_pl, pf_pooladdr_pl;
151 struct pool pf_state_pl, pf_state_key_pl;
152 struct pool pf_altq_pl;
154 void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
156 void pf_init_threshold(struct pf_threshold *, u_int32_t,
157 u_int32_t);
158 void pf_add_threshold(struct pf_threshold *);
159 int pf_check_threshold(struct pf_threshold *);
161 void pf_change_ap(struct pf_addr *, u_int16_t *,
162 u_int16_t *, u_int16_t *, struct pf_addr *,
163 u_int16_t, u_int8_t, sa_family_t);
164 int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *,
165 struct tcphdr *, struct pf_state_peer *);
166 #ifdef INET6
167 void pf_change_a6(struct pf_addr *, u_int16_t *,
168 struct pf_addr *, u_int8_t);
169 #endif /* INET6 */
170 void pf_change_icmp(struct pf_addr *, u_int16_t *,
171 struct pf_addr *, struct pf_addr *, u_int16_t,
172 u_int16_t *, u_int16_t *, u_int16_t *,
173 u_int16_t *, u_int8_t, sa_family_t);
174 void pf_send_tcp(const struct pf_rule *, sa_family_t,
175 const struct pf_addr *, const struct pf_addr *,
176 u_int16_t, u_int16_t, u_int32_t, u_int32_t,
177 u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
178 u_int16_t, struct ether_header *, struct ifnet *);
179 void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
180 sa_family_t, struct pf_rule *);
181 struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
182 int, int, struct pfi_kif *,
183 struct pf_addr *, u_int16_t, struct pf_addr *,
184 u_int16_t, int);
185 struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
186 int, int, struct pfi_kif *, struct pf_src_node **,
187 struct pf_addr *, u_int16_t,
188 struct pf_addr *, u_int16_t,
189 struct pf_addr *, u_int16_t *);
190 void pf_attach_state(struct pf_state_key *,
191 struct pf_state *, int);
192 void pf_detach_state(struct pf_state *, int);
193 int pf_test_rule(struct pf_rule **, struct pf_state **,
194 int, struct pfi_kif *, struct mbuf *, int,
195 void *, struct pf_pdesc *, struct pf_rule **,
196 struct pf_ruleset **, struct ifqueue *);
197 int pf_test_fragment(struct pf_rule **, int,
198 struct pfi_kif *, struct mbuf *, void *,
199 struct pf_pdesc *, struct pf_rule **,
200 struct pf_ruleset **);
201 int pf_test_state_tcp(struct pf_state **, int,
202 struct pfi_kif *, struct mbuf *, int,
203 void *, struct pf_pdesc *, u_short *);
204 int pf_test_state_udp(struct pf_state **, int,
205 struct pfi_kif *, struct mbuf *, int,
206 void *, struct pf_pdesc *);
207 int pf_test_state_icmp(struct pf_state **, int,
208 struct pfi_kif *, struct mbuf *, int,
209 void *, struct pf_pdesc *, u_short *);
210 int pf_test_state_other(struct pf_state **, int,
211 struct pfi_kif *, struct pf_pdesc *);
212 int pf_match_tag(struct mbuf *, struct pf_rule *, int *);
213 void pf_step_into_anchor(int *, struct pf_ruleset **, int,
214 struct pf_rule **, struct pf_rule **, int *);
215 int pf_step_out_of_anchor(int *, struct pf_ruleset **,
216 int, struct pf_rule **, struct pf_rule **,
217 int *);
218 void pf_hash(const struct pf_addr *, struct pf_addr *,
219 struct pf_poolhashkey *, sa_family_t);
220 int pf_map_addr(u_int8_t, struct pf_rule *,
221 const struct pf_addr *, struct pf_addr *,
222 struct pf_addr *, struct pf_src_node **);
223 int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
224 struct pf_addr *, struct pf_addr *, u_int16_t,
225 struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
226 struct pf_src_node **);
227 void pf_route(struct mbuf **, struct pf_rule *, int,
228 struct ifnet *, struct pf_state *,
229 struct pf_pdesc *);
230 void pf_route6(struct mbuf **, struct pf_rule *, int,
231 struct ifnet *, struct pf_state *,
232 struct pf_pdesc *);
233 int pf_socket_lookup(int, struct pf_pdesc *);
234 u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t,
235 sa_family_t);
236 u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
237 sa_family_t);
238 u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t,
239 u_int16_t);
240 void pf_set_rt_ifp(struct pf_state *,
241 struct pf_addr *);
242 #ifdef __NetBSD__
243 int pf_check_proto_cksum(struct mbuf *, int, int, int,
244 u_int8_t, sa_family_t);
245 #else
246 int pf_check_proto_cksum(struct mbuf *, int, int,
247 u_int8_t, sa_family_t);
248 #endif /* !__NetBSD__ */
249 int pf_addr_wrap_neq(struct pf_addr_wrap *,
250 struct pf_addr_wrap *);
251 struct pf_state *pf_find_state(struct pfi_kif *,
252 struct pf_state_key_cmp *, u_int8_t);
253 int pf_src_connlimit(struct pf_state **);
254 void pf_stateins_err(const char *, struct pf_state *,
255 struct pfi_kif *);
256 int pf_check_congestion(struct ifqueue *);
258 extern struct pool pfr_ktable_pl;
259 extern struct pool pfr_kentry_pl;
261 struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
262 { &pf_state_pl, PFSTATE_HIWAT },
263 { &pf_src_tree_pl, PFSNODE_HIWAT },
264 { &pf_frent_pl, PFFRAG_FRENT_HIWAT },
265 { &pfr_ktable_pl, PFR_KTABLE_HIWAT },
266 { &pfr_kentry_pl, PFR_KENTRY_HIWAT }
269 #define STATE_LOOKUP() \
270 do { \
271 if (direction == PF_IN) \
272 *state = pf_find_state(kif, &key, PF_EXT_GWY); \
273 else \
274 *state = pf_find_state(kif, &key, PF_LAN_EXT); \
275 if (*state == NULL || (*state)->timeout == PFTM_PURGE) \
276 return (PF_DROP); \
277 if (direction == PF_OUT && \
278 (((*state)->rule.ptr->rt == PF_ROUTETO && \
279 (*state)->rule.ptr->direction == PF_OUT) || \
280 ((*state)->rule.ptr->rt == PF_REPLYTO && \
281 (*state)->rule.ptr->direction == PF_IN)) && \
282 (*state)->rt_kif != NULL && \
283 (*state)->rt_kif != kif) \
284 return (PF_PASS); \
285 } while (0)
287 #define STATE_TRANSLATE(sk) \
288 (sk)->lan.addr.addr32[0] != (sk)->gwy.addr.addr32[0] || \
289 ((sk)->af == AF_INET6 && \
290 ((sk)->lan.addr.addr32[1] != (sk)->gwy.addr.addr32[1] || \
291 (sk)->lan.addr.addr32[2] != (sk)->gwy.addr.addr32[2] || \
292 (sk)->lan.addr.addr32[3] != (sk)->gwy.addr.addr32[3])) || \
293 (sk)->lan.port != (sk)->gwy.port
295 #define BOUND_IFACE(r, k) \
296 ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all
298 #define STATE_INC_COUNTERS(s) \
299 do { \
300 s->rule.ptr->states++; \
301 if (s->anchor.ptr != NULL) \
302 s->anchor.ptr->states++; \
303 if (s->nat_rule.ptr != NULL) \
304 s->nat_rule.ptr->states++; \
305 } while (0)
307 #define STATE_DEC_COUNTERS(s) \
308 do { \
309 if (s->nat_rule.ptr != NULL) \
310 s->nat_rule.ptr->states--; \
311 if (s->anchor.ptr != NULL) \
312 s->anchor.ptr->states--; \
313 s->rule.ptr->states--; \
314 } while (0)
316 static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
317 static __inline int pf_state_compare_lan_ext(struct pf_state_key *,
318 struct pf_state_key *);
319 static __inline int pf_state_compare_ext_gwy(struct pf_state_key *,
320 struct pf_state_key *);
321 static __inline int pf_state_compare_id(struct pf_state *,
322 struct pf_state *);
324 struct pf_src_tree tree_src_tracking;
326 struct pf_state_tree_id tree_id;
327 struct pf_state_queue state_list;
329 RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
330 RB_GENERATE(pf_state_tree_lan_ext, pf_state_key,
331 entry_lan_ext, pf_state_compare_lan_ext);
332 RB_GENERATE(pf_state_tree_ext_gwy, pf_state_key,
333 entry_ext_gwy, pf_state_compare_ext_gwy);
334 RB_GENERATE(pf_state_tree_id, pf_state,
335 entry_id, pf_state_compare_id);
337 #define PF_DT_SKIP_LANEXT 0x01
338 #define PF_DT_SKIP_EXTGWY 0x02
340 #ifdef __NetBSD__
341 static __inline struct pfi_kif *
342 bound_iface(const struct pf_rule *r, const struct pf_rule *nr,
343 struct pfi_kif *k)
345 uint32_t rule_flag;
347 rule_flag = r->rule_flag;
348 if (nr != NULL)
349 rule_flag |= nr->rule_flag;
351 return ((rule_flag & PFRULE_IFBOUND) != 0) ? k : pfi_all;
353 #endif /* __NetBSD__ */
355 static __inline int
356 pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
358 int diff;
360 if (a->rule.ptr > b->rule.ptr)
361 return (1);
362 if (a->rule.ptr < b->rule.ptr)
363 return (-1);
364 if ((diff = a->af - b->af) != 0)
365 return (diff);
366 switch (a->af) {
367 #ifdef INET
368 case AF_INET:
369 if (a->addr.addr32[0] > b->addr.addr32[0])
370 return (1);
371 if (a->addr.addr32[0] < b->addr.addr32[0])
372 return (-1);
373 break;
374 #endif /* INET */
375 #ifdef INET6
376 case AF_INET6:
377 if (a->addr.addr32[3] > b->addr.addr32[3])
378 return (1);
379 if (a->addr.addr32[3] < b->addr.addr32[3])
380 return (-1);
381 if (a->addr.addr32[2] > b->addr.addr32[2])
382 return (1);
383 if (a->addr.addr32[2] < b->addr.addr32[2])
384 return (-1);
385 if (a->addr.addr32[1] > b->addr.addr32[1])
386 return (1);
387 if (a->addr.addr32[1] < b->addr.addr32[1])
388 return (-1);
389 if (a->addr.addr32[0] > b->addr.addr32[0])
390 return (1);
391 if (a->addr.addr32[0] < b->addr.addr32[0])
392 return (-1);
393 break;
394 #endif /* INET6 */
396 return (0);
399 static __inline int
400 pf_state_compare_lan_ext(struct pf_state_key *a, struct pf_state_key *b)
402 int diff;
404 if ((diff = a->proto - b->proto) != 0)
405 return (diff);
406 if ((diff = a->af - b->af) != 0)
407 return (diff);
408 switch (a->af) {
409 #ifdef INET
410 case AF_INET:
411 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
412 return (1);
413 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
414 return (-1);
415 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
416 return (1);
417 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
418 return (-1);
419 break;
420 #endif /* INET */
421 #ifdef INET6
422 case AF_INET6:
423 if (a->lan.addr.addr32[3] > b->lan.addr.addr32[3])
424 return (1);
425 if (a->lan.addr.addr32[3] < b->lan.addr.addr32[3])
426 return (-1);
427 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
428 return (1);
429 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
430 return (-1);
431 if (a->lan.addr.addr32[2] > b->lan.addr.addr32[2])
432 return (1);
433 if (a->lan.addr.addr32[2] < b->lan.addr.addr32[2])
434 return (-1);
435 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
436 return (1);
437 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
438 return (-1);
439 if (a->lan.addr.addr32[1] > b->lan.addr.addr32[1])
440 return (1);
441 if (a->lan.addr.addr32[1] < b->lan.addr.addr32[1])
442 return (-1);
443 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
444 return (1);
445 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
446 return (-1);
447 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
448 return (1);
449 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
450 return (-1);
451 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
452 return (1);
453 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
454 return (-1);
455 break;
456 #endif /* INET6 */
459 if ((diff = a->lan.port - b->lan.port) != 0)
460 return (diff);
461 if ((diff = a->ext.port - b->ext.port) != 0)
462 return (diff);
464 return (0);
467 static __inline int
468 pf_state_compare_ext_gwy(struct pf_state_key *a, struct pf_state_key *b)
470 int diff;
472 if ((diff = a->proto - b->proto) != 0)
473 return (diff);
474 if ((diff = a->af - b->af) != 0)
475 return (diff);
476 switch (a->af) {
477 #ifdef INET
478 case AF_INET:
479 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
480 return (1);
481 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
482 return (-1);
483 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
484 return (1);
485 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
486 return (-1);
487 break;
488 #endif /* INET */
489 #ifdef INET6
490 case AF_INET6:
491 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
492 return (1);
493 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
494 return (-1);
495 if (a->gwy.addr.addr32[3] > b->gwy.addr.addr32[3])
496 return (1);
497 if (a->gwy.addr.addr32[3] < b->gwy.addr.addr32[3])
498 return (-1);
499 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
500 return (1);
501 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
502 return (-1);
503 if (a->gwy.addr.addr32[2] > b->gwy.addr.addr32[2])
504 return (1);
505 if (a->gwy.addr.addr32[2] < b->gwy.addr.addr32[2])
506 return (-1);
507 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
508 return (1);
509 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
510 return (-1);
511 if (a->gwy.addr.addr32[1] > b->gwy.addr.addr32[1])
512 return (1);
513 if (a->gwy.addr.addr32[1] < b->gwy.addr.addr32[1])
514 return (-1);
515 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
516 return (1);
517 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
518 return (-1);
519 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
520 return (1);
521 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
522 return (-1);
523 break;
524 #endif /* INET6 */
527 if ((diff = a->ext.port - b->ext.port) != 0)
528 return (diff);
529 if ((diff = a->gwy.port - b->gwy.port) != 0)
530 return (diff);
532 return (0);
535 static __inline int
536 pf_state_compare_id(struct pf_state *a, struct pf_state *b)
538 if (a->id > b->id)
539 return (1);
540 if (a->id < b->id)
541 return (-1);
542 if (a->creatorid > b->creatorid)
543 return (1);
544 if (a->creatorid < b->creatorid)
545 return (-1);
547 return (0);
550 #ifdef INET6
551 void
552 pf_addrcpy(struct pf_addr *dst, const struct pf_addr *src, sa_family_t af)
554 switch (af) {
555 #ifdef INET
556 case AF_INET:
557 dst->addr32[0] = src->addr32[0];
558 break;
559 #endif /* INET */
560 case AF_INET6:
561 dst->addr32[0] = src->addr32[0];
562 dst->addr32[1] = src->addr32[1];
563 dst->addr32[2] = src->addr32[2];
564 dst->addr32[3] = src->addr32[3];
565 break;
568 #endif /* INET6 */
570 struct pf_state *
571 pf_find_state_byid(struct pf_state_cmp *key)
573 pf_status.fcounters[FCNT_STATE_SEARCH]++;
575 return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key));
578 struct pf_state *
579 pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int8_t tree)
581 struct pf_state_key *sk;
582 struct pf_state *s;
584 pf_status.fcounters[FCNT_STATE_SEARCH]++;
586 switch (tree) {
587 case PF_LAN_EXT:
588 sk = RB_FIND(pf_state_tree_lan_ext, &pf_statetbl_lan_ext,
589 (struct pf_state_key *)key);
590 break;
591 case PF_EXT_GWY:
592 sk = RB_FIND(pf_state_tree_ext_gwy, &pf_statetbl_ext_gwy,
593 (struct pf_state_key *)key);
594 break;
595 default:
596 panic("pf_find_state");
599 /* list is sorted, if-bound states before floating ones */
600 if (sk != NULL)
601 TAILQ_FOREACH(s, &sk->states, next)
602 if (s->kif == pfi_all || s->kif == kif)
603 return (s);
605 return (NULL);
608 struct pf_state *
609 pf_find_state_all(struct pf_state_key_cmp *key, u_int8_t tree, int *more)
611 struct pf_state_key *sk;
612 struct pf_state *s, *ret = NULL;
614 pf_status.fcounters[FCNT_STATE_SEARCH]++;
616 switch (tree) {
617 case PF_LAN_EXT:
618 sk = RB_FIND(pf_state_tree_lan_ext,
619 &pf_statetbl_lan_ext, (struct pf_state_key *)key);
620 break;
621 case PF_EXT_GWY:
622 sk = RB_FIND(pf_state_tree_ext_gwy,
623 &pf_statetbl_ext_gwy, (struct pf_state_key *)key);
624 break;
625 default:
626 panic("pf_find_state_all");
629 if (sk != NULL) {
630 ret = TAILQ_FIRST(&sk->states);
631 if (more == NULL)
632 return (ret);
634 TAILQ_FOREACH(s, &sk->states, next)
635 (*more)++;
638 return (ret);
641 void
642 pf_init_threshold(struct pf_threshold *threshold,
643 u_int32_t limit, u_int32_t seconds)
645 threshold->limit = limit * PF_THRESHOLD_MULT;
646 threshold->seconds = seconds;
647 threshold->count = 0;
648 threshold->last = time_second;
651 void
652 pf_add_threshold(struct pf_threshold *threshold)
654 u_int32_t t = time_second, diff = t - threshold->last;
656 if (diff >= threshold->seconds)
657 threshold->count = 0;
658 else
659 threshold->count -= threshold->count * diff /
660 threshold->seconds;
661 threshold->count += PF_THRESHOLD_MULT;
662 threshold->last = t;
666 pf_check_threshold(struct pf_threshold *threshold)
668 return (threshold->count > threshold->limit);
672 pf_src_connlimit(struct pf_state **state)
674 int bad = 0;
676 (*state)->src_node->conn++;
677 (*state)->src.tcp_est = 1;
678 pf_add_threshold(&(*state)->src_node->conn_rate);
680 if ((*state)->rule.ptr->max_src_conn &&
681 (*state)->rule.ptr->max_src_conn <
682 (*state)->src_node->conn) {
683 pf_status.lcounters[LCNT_SRCCONN]++;
684 bad++;
687 if ((*state)->rule.ptr->max_src_conn_rate.limit &&
688 pf_check_threshold(&(*state)->src_node->conn_rate)) {
689 pf_status.lcounters[LCNT_SRCCONNRATE]++;
690 bad++;
693 if (!bad)
694 return (0);
696 if ((*state)->rule.ptr->overload_tbl) {
697 struct pfr_addr p;
698 u_int32_t killed = 0;
700 pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
701 if (pf_status.debug >= PF_DEBUG_MISC) {
702 printf("pf_src_connlimit: blocking address ");
703 pf_print_host(&(*state)->src_node->addr, 0,
704 (*state)->state_key->af);
707 bzero(&p, sizeof(p));
708 p.pfra_af = (*state)->state_key->af;
709 switch ((*state)->state_key->af) {
710 #ifdef INET
711 case AF_INET:
712 p.pfra_net = 32;
713 p.pfra_ip4addr = (*state)->src_node->addr.v4;
714 break;
715 #endif /* INET */
716 #ifdef INET6
717 case AF_INET6:
718 p.pfra_net = 128;
719 p.pfra_ip6addr = (*state)->src_node->addr.v6;
720 break;
721 #endif /* INET6 */
724 pfr_insert_kentry((*state)->rule.ptr->overload_tbl,
725 &p, time_second);
727 /* kill existing states if that's required. */
728 if ((*state)->rule.ptr->flush) {
729 struct pf_state_key *sk;
730 struct pf_state *st;
732 pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
733 RB_FOREACH(st, pf_state_tree_id, &tree_id) {
734 sk = st->state_key;
736 * Kill states from this source. (Only those
737 * from the same rule if PF_FLUSH_GLOBAL is not
738 * set)
740 if (sk->af ==
741 (*state)->state_key->af &&
742 (((*state)->state_key->direction ==
743 PF_OUT &&
744 PF_AEQ(&(*state)->src_node->addr,
745 &sk->lan.addr, sk->af)) ||
746 ((*state)->state_key->direction == PF_IN &&
747 PF_AEQ(&(*state)->src_node->addr,
748 &sk->ext.addr, sk->af))) &&
749 ((*state)->rule.ptr->flush &
750 PF_FLUSH_GLOBAL ||
751 (*state)->rule.ptr == st->rule.ptr)) {
752 st->timeout = PFTM_PURGE;
753 st->src.state = st->dst.state =
754 TCPS_CLOSED;
755 killed++;
758 if (pf_status.debug >= PF_DEBUG_MISC)
759 printf(", %u states killed", killed);
761 if (pf_status.debug >= PF_DEBUG_MISC)
762 printf("\n");
765 /* kill this state */
766 (*state)->timeout = PFTM_PURGE;
767 (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
768 return (1);
772 pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
773 struct pf_addr *src, sa_family_t af)
775 struct pf_src_node k;
777 if (*sn == NULL) {
778 k.af = af;
779 PF_ACPY(&k.addr, src, af);
780 if (rule->rule_flag & PFRULE_RULESRCTRACK ||
781 rule->rpool.opts & PF_POOL_STICKYADDR)
782 k.rule.ptr = rule;
783 else
784 k.rule.ptr = NULL;
785 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
786 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
788 if (*sn == NULL) {
789 if (!rule->max_src_nodes ||
790 rule->src_nodes < rule->max_src_nodes)
791 (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT);
792 else
793 pf_status.lcounters[LCNT_SRCNODES]++;
794 if ((*sn) == NULL)
795 return (-1);
796 bzero(*sn, sizeof(struct pf_src_node));
798 pf_init_threshold(&(*sn)->conn_rate,
799 rule->max_src_conn_rate.limit,
800 rule->max_src_conn_rate.seconds);
802 (*sn)->af = af;
803 if (rule->rule_flag & PFRULE_RULESRCTRACK ||
804 rule->rpool.opts & PF_POOL_STICKYADDR)
805 (*sn)->rule.ptr = rule;
806 else
807 (*sn)->rule.ptr = NULL;
808 PF_ACPY(&(*sn)->addr, src, af);
809 if (RB_INSERT(pf_src_tree,
810 &tree_src_tracking, *sn) != NULL) {
811 if (pf_status.debug >= PF_DEBUG_MISC) {
812 printf("pf: src_tree insert failed: ");
813 pf_print_host(&(*sn)->addr, 0, af);
814 printf("\n");
816 pool_put(&pf_src_tree_pl, *sn);
817 return (-1);
819 (*sn)->creation = time_second;
820 (*sn)->ruletype = rule->action;
821 if ((*sn)->rule.ptr != NULL)
822 (*sn)->rule.ptr->src_nodes++;
823 pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
824 pf_status.src_nodes++;
825 } else {
826 if (rule->max_src_states &&
827 (*sn)->states >= rule->max_src_states) {
828 pf_status.lcounters[LCNT_SRCSTATES]++;
829 return (-1);
832 return (0);
835 void
836 pf_stateins_err(const char *tree, struct pf_state *s, struct pfi_kif *kif)
838 struct pf_state_key *sk = s->state_key;
840 if (pf_status.debug >= PF_DEBUG_MISC) {
841 printf("pf: state insert failed: %s %s", tree, kif->pfik_name);
842 printf(" lan: ");
843 pf_print_host(&sk->lan.addr, sk->lan.port,
844 sk->af);
845 printf(" gwy: ");
846 pf_print_host(&sk->gwy.addr, sk->gwy.port,
847 sk->af);
848 printf(" ext: ");
849 pf_print_host(&sk->ext.addr, sk->ext.port,
850 sk->af);
851 if (s->sync_flags & PFSTATE_FROMSYNC)
852 printf(" (from sync)");
853 printf("\n");
858 pf_insert_state(struct pfi_kif *kif, struct pf_state *s)
860 struct pf_state_key *cur;
861 struct pf_state *sp;
863 KASSERT(s->state_key != NULL);
864 s->kif = kif;
866 if ((cur = RB_INSERT(pf_state_tree_lan_ext, &pf_statetbl_lan_ext,
867 s->state_key)) != NULL) {
868 /* key exists. check for same kif, if none, add to key */
869 TAILQ_FOREACH(sp, &cur->states, next)
870 if (sp->kif == kif) { /* collision! */
871 pf_stateins_err("tree_lan_ext", s, kif);
872 pf_detach_state(s,
873 PF_DT_SKIP_LANEXT|PF_DT_SKIP_EXTGWY);
874 return (-1);
876 pf_detach_state(s, PF_DT_SKIP_LANEXT|PF_DT_SKIP_EXTGWY);
877 pf_attach_state(cur, s, kif == pfi_all ? 1 : 0);
880 /* if cur != NULL, we already found a state key and attached to it */
881 if (cur == NULL && (cur = RB_INSERT(pf_state_tree_ext_gwy,
882 &pf_statetbl_ext_gwy, s->state_key)) != NULL) {
883 /* must not happen. we must have found the sk above! */
884 pf_stateins_err("tree_ext_gwy", s, kif);
885 pf_detach_state(s, PF_DT_SKIP_EXTGWY);
886 return (-1);
889 if (s->id == 0 && s->creatorid == 0) {
890 s->id = htobe64(pf_status.stateid++);
891 s->creatorid = pf_status.hostid;
893 if (RB_INSERT(pf_state_tree_id, &tree_id, s) != NULL) {
894 if (pf_status.debug >= PF_DEBUG_MISC) {
895 #ifdef __NetBSD__
896 printf("pf: state insert failed: "
897 "id: %016" PRIx64 " creatorid: %08x",
898 be64toh(s->id), ntohl(s->creatorid));
899 #else
900 printf("pf: state insert failed: "
901 "id: %016llx creatorid: %08x",
902 betoh64(s->id), ntohl(s->creatorid));
903 #endif /* !__NetBSD__ */
904 if (s->sync_flags & PFSTATE_FROMSYNC)
905 printf(" (from sync)");
906 printf("\n");
908 pf_detach_state(s, 0);
909 return (-1);
911 TAILQ_INSERT_TAIL(&state_list, s, entry_list);
912 pf_status.fcounters[FCNT_STATE_INSERT]++;
913 pf_status.states++;
914 pfi_kif_ref(kif, PFI_KIF_REF_STATE);
915 #if NPFSYNC
916 pfsync_insert_state(s);
917 #endif
918 return (0);
921 void
922 pf_purge_thread(void *v)
924 int nloops = 0, s;
926 for (;;) {
927 tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz);
929 s = splsoftnet();
931 /* process a fraction of the state table every second */
932 pf_purge_expired_states(1 + (pf_status.states
933 / pf_default_rule.timeout[PFTM_INTERVAL]));
935 /* purge other expired types every PFTM_INTERVAL seconds */
936 if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) {
937 pf_purge_expired_fragments();
938 pf_purge_expired_src_nodes(0);
939 nloops = 0;
942 splx(s);
946 u_int32_t
947 pf_state_expires(const struct pf_state *state)
949 u_int32_t timeout;
950 u_int32_t start;
951 u_int32_t end;
952 u_int32_t states;
954 /* handle all PFTM_* > PFTM_MAX here */
955 if (state->timeout == PFTM_PURGE)
956 return (time_second);
957 if (state->timeout == PFTM_UNTIL_PACKET)
958 return (0);
959 KASSERT(state->timeout != PFTM_UNLINKED);
960 KASSERT(state->timeout < PFTM_MAX);
961 timeout = state->rule.ptr->timeout[state->timeout];
962 if (!timeout)
963 timeout = pf_default_rule.timeout[state->timeout];
964 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
965 if (start) {
966 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];
967 states = state->rule.ptr->states;
968 } else {
969 start = pf_default_rule.timeout[PFTM_ADAPTIVE_START];
970 end = pf_default_rule.timeout[PFTM_ADAPTIVE_END];
971 states = pf_status.states;
973 if (end && states > start && start < end) {
974 if (states < end)
975 return (state->expire + timeout * (end - states) /
976 (end - start));
977 else
978 return (time_second);
980 return (state->expire + timeout);
983 void
984 pf_purge_expired_src_nodes(int waslocked)
986 struct pf_src_node *cur, *next;
987 int locked = waslocked;
989 for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
990 next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
992 if (cur->states <= 0 && cur->expire <= time_second) {
993 if (! locked) {
994 rw_enter_write(&pf_consistency_lock);
995 next = RB_NEXT(pf_src_tree,
996 &tree_src_tracking, cur);
997 locked = 1;
999 if (cur->rule.ptr != NULL) {
1000 cur->rule.ptr->src_nodes--;
1001 if (cur->rule.ptr->states <= 0 &&
1002 cur->rule.ptr->max_src_nodes <= 0)
1003 pf_rm_rule(NULL, cur->rule.ptr);
1005 RB_REMOVE(pf_src_tree, &tree_src_tracking, cur);
1006 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
1007 pf_status.src_nodes--;
1008 pool_put(&pf_src_tree_pl, cur);
1012 if (locked && !waslocked)
1013 rw_exit_write(&pf_consistency_lock);
1016 void
1017 pf_src_tree_remove_state(struct pf_state *s)
1019 u_int32_t timeout;
1021 if (s->src_node != NULL) {
1022 if (s->src.tcp_est)
1023 --s->src_node->conn;
1024 if (--s->src_node->states <= 0) {
1025 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1026 if (!timeout)
1027 timeout =
1028 pf_default_rule.timeout[PFTM_SRC_NODE];
1029 s->src_node->expire = time_second + timeout;
1032 if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
1033 if (--s->nat_src_node->states <= 0) {
1034 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1035 if (!timeout)
1036 timeout =
1037 pf_default_rule.timeout[PFTM_SRC_NODE];
1038 s->nat_src_node->expire = time_second + timeout;
1041 s->src_node = s->nat_src_node = NULL;
1044 /* callers should be at splsoftnet */
1045 void
1046 pf_unlink_state(struct pf_state *cur)
1048 if (cur->src.state == PF_TCPS_PROXY_DST) {
1049 pf_send_tcp(cur->rule.ptr, cur->state_key->af,
1050 &cur->state_key->ext.addr, &cur->state_key->lan.addr,
1051 cur->state_key->ext.port, cur->state_key->lan.port,
1052 cur->src.seqhi, cur->src.seqlo + 1,
1053 TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL);
1055 RB_REMOVE(pf_state_tree_id, &tree_id, cur);
1056 #if NPFSYNC
1057 if (cur->creatorid == pf_status.hostid)
1058 pfsync_delete_state(cur);
1059 #endif
1060 cur->timeout = PFTM_UNLINKED;
1061 pf_src_tree_remove_state(cur);
1062 pf_detach_state(cur, 0);
1065 /* callers should be at splsoftnet and hold the
1066 * write_lock on pf_consistency_lock */
1067 void
1068 pf_free_state(struct pf_state *cur)
1070 #if NPFSYNC
1071 if (pfsyncif != NULL &&
1072 (pfsyncif->sc_bulk_send_next == cur ||
1073 pfsyncif->sc_bulk_terminator == cur))
1074 return;
1075 #endif
1076 KASSERT(cur->timeout == PFTM_UNLINKED);
1077 if (--cur->rule.ptr->states <= 0 &&
1078 cur->rule.ptr->src_nodes <= 0)
1079 pf_rm_rule(NULL, cur->rule.ptr);
1080 if (cur->nat_rule.ptr != NULL)
1081 if (--cur->nat_rule.ptr->states <= 0 &&
1082 cur->nat_rule.ptr->src_nodes <= 0)
1083 pf_rm_rule(NULL, cur->nat_rule.ptr);
1084 if (cur->anchor.ptr != NULL)
1085 if (--cur->anchor.ptr->states <= 0)
1086 pf_rm_rule(NULL, cur->anchor.ptr);
1087 pf_normalize_tcp_cleanup(cur);
1088 pfi_kif_unref(cur->kif, PFI_KIF_REF_STATE);
1089 TAILQ_REMOVE(&state_list, cur, entry_list);
1090 if (cur->tag)
1091 pf_tag_unref(cur->tag);
1092 pool_put(&pf_state_pl, cur);
1093 pf_status.fcounters[FCNT_STATE_REMOVALS]++;
1094 pf_status.states--;
1097 void
1098 pf_purge_expired_states(u_int32_t maxcheck)
1100 static struct pf_state *cur = NULL;
1101 struct pf_state *next;
1102 int locked = 0;
1104 while (maxcheck--) {
1105 /* wrap to start of list when we hit the end */
1106 if (cur == NULL) {
1107 cur = TAILQ_FIRST(&state_list);
1108 if (cur == NULL)
1109 break; /* list empty */
1112 /* get next state, as cur may get deleted */
1113 next = TAILQ_NEXT(cur, entry_list);
1115 if (cur->timeout == PFTM_UNLINKED) {
1116 /* free unlinked state */
1117 if (! locked) {
1118 rw_enter_write(&pf_consistency_lock);
1119 locked = 1;
1121 pf_free_state(cur);
1122 } else if (pf_state_expires(cur) <= time_second) {
1123 /* unlink and free expired state */
1124 pf_unlink_state(cur);
1125 if (! locked) {
1126 rw_enter_write(&pf_consistency_lock);
1127 locked = 1;
1129 pf_free_state(cur);
1131 cur = next;
1134 if (locked)
1135 rw_exit_write(&pf_consistency_lock);
1139 pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
1141 if (aw->type != PF_ADDR_TABLE)
1142 return (0);
1143 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)
1144 return (1);
1145 return (0);
1148 void
1149 pf_tbladdr_remove(struct pf_addr_wrap *aw)
1151 if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL)
1152 return;
1153 pfr_detach_table(aw->p.tbl);
1154 aw->p.tbl = NULL;
1157 void
1158 pf_tbladdr_copyout(struct pf_addr_wrap *aw)
1160 struct pfr_ktable *kt = aw->p.tbl;
1162 if (aw->type != PF_ADDR_TABLE || kt == NULL)
1163 return;
1164 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
1165 kt = kt->pfrkt_root;
1166 aw->p.tbl = NULL;
1167 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
1168 kt->pfrkt_cnt : -1;
1171 void
1172 pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
1174 switch (af) {
1175 #ifdef INET
1176 case AF_INET: {
1177 u_int32_t a = ntohl(addr->addr32[0]);
1178 printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255,
1179 (a>>8)&255, a&255);
1180 if (p) {
1181 p = ntohs(p);
1182 printf(":%u", p);
1184 break;
1186 #endif /* INET */
1187 #ifdef INET6
1188 case AF_INET6: {
1189 u_int16_t b;
1190 u_int8_t i, curstart = 255, curend = 0,
1191 maxstart = 0, maxend = 0;
1192 for (i = 0; i < 8; i++) {
1193 if (!addr->addr16[i]) {
1194 if (curstart == 255)
1195 curstart = i;
1196 else
1197 curend = i;
1198 } else {
1199 if (curstart) {
1200 if ((curend - curstart) >
1201 (maxend - maxstart)) {
1202 maxstart = curstart;
1203 maxend = curend;
1204 curstart = 255;
1209 for (i = 0; i < 8; i++) {
1210 if (i >= maxstart && i <= maxend) {
1211 if (maxend != 7) {
1212 if (i == maxstart)
1213 printf(":");
1214 } else {
1215 if (i == maxend)
1216 printf(":");
1218 } else {
1219 b = ntohs(addr->addr16[i]);
1220 printf("%x", b);
1221 if (i < 7)
1222 printf(":");
1225 if (p) {
1226 p = ntohs(p);
1227 printf("[%u]", p);
1229 break;
1231 #endif /* INET6 */
1235 void
1236 pf_print_state(struct pf_state *s)
1238 struct pf_state_key *sk = s->state_key;
1239 switch (sk->proto) {
1240 case IPPROTO_TCP:
1241 printf("TCP ");
1242 break;
1243 case IPPROTO_UDP:
1244 printf("UDP ");
1245 break;
1246 case IPPROTO_ICMP:
1247 printf("ICMP ");
1248 break;
1249 case IPPROTO_ICMPV6:
1250 printf("ICMPV6 ");
1251 break;
1252 default:
1253 printf("%u ", sk->proto);
1254 break;
1256 pf_print_host(&sk->lan.addr, sk->lan.port, sk->af);
1257 printf(" ");
1258 pf_print_host(&sk->gwy.addr, sk->gwy.port, sk->af);
1259 printf(" ");
1260 pf_print_host(&sk->ext.addr, sk->ext.port, sk->af);
1261 printf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo,
1262 s->src.seqhi, s->src.max_win, s->src.seqdiff);
1263 if (s->src.wscale && s->dst.wscale)
1264 printf(" wscale=%u", s->src.wscale & PF_WSCALE_MASK);
1265 printf("]");
1266 printf(" [lo=%u high=%u win=%u modulator=%u", s->dst.seqlo,
1267 s->dst.seqhi, s->dst.max_win, s->dst.seqdiff);
1268 if (s->src.wscale && s->dst.wscale)
1269 printf(" wscale=%u", s->dst.wscale & PF_WSCALE_MASK);
1270 printf("]");
1271 printf(" %u:%u", s->src.state, s->dst.state);
1274 void
1275 pf_print_flags(u_int8_t f)
1277 if (f)
1278 printf(" ");
1279 if (f & TH_FIN)
1280 printf("F");
1281 if (f & TH_SYN)
1282 printf("S");
1283 if (f & TH_RST)
1284 printf("R");
1285 if (f & TH_PUSH)
1286 printf("P");
1287 if (f & TH_ACK)
1288 printf("A");
1289 if (f & TH_URG)
1290 printf("U");
1291 if (f & TH_ECE)
1292 printf("E");
1293 if (f & TH_CWR)
1294 printf("W");
1297 #define PF_SET_SKIP_STEPS(i) \
1298 do { \
1299 while (head[i] != cur) { \
1300 head[i]->skip[i].ptr = cur; \
1301 head[i] = TAILQ_NEXT(head[i], entries); \
1303 } while (0)
1305 void
1306 pf_calc_skip_steps(struct pf_rulequeue *rules)
1308 struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT];
1309 int i;
1311 cur = TAILQ_FIRST(rules);
1312 prev = cur;
1313 for (i = 0; i < PF_SKIP_COUNT; ++i)
1314 head[i] = cur;
1315 while (cur != NULL) {
1317 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
1318 PF_SET_SKIP_STEPS(PF_SKIP_IFP);
1319 if (cur->direction != prev->direction)
1320 PF_SET_SKIP_STEPS(PF_SKIP_DIR);
1321 if (cur->af != prev->af)
1322 PF_SET_SKIP_STEPS(PF_SKIP_AF);
1323 if (cur->proto != prev->proto)
1324 PF_SET_SKIP_STEPS(PF_SKIP_PROTO);
1325 if (cur->src.neg != prev->src.neg ||
1326 pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr))
1327 PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR);
1328 if (cur->src.port[0] != prev->src.port[0] ||
1329 cur->src.port[1] != prev->src.port[1] ||
1330 cur->src.port_op != prev->src.port_op)
1331 PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
1332 if (cur->dst.neg != prev->dst.neg ||
1333 pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
1334 PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
1335 if (cur->dst.port[0] != prev->dst.port[0] ||
1336 cur->dst.port[1] != prev->dst.port[1] ||
1337 cur->dst.port_op != prev->dst.port_op)
1338 PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
1340 prev = cur;
1341 cur = TAILQ_NEXT(cur, entries);
1343 for (i = 0; i < PF_SKIP_COUNT; ++i)
1344 PF_SET_SKIP_STEPS(i);
1348 pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
1350 if (aw1->type != aw2->type)
1351 return (1);
1352 switch (aw1->type) {
1353 case PF_ADDR_ADDRMASK:
1354 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
1355 return (1);
1356 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
1357 return (1);
1358 return (0);
1359 case PF_ADDR_DYNIFTL:
1360 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
1361 case PF_ADDR_NOROUTE:
1362 case PF_ADDR_URPFFAILED:
1363 return (0);
1364 case PF_ADDR_TABLE:
1365 return (aw1->p.tbl != aw2->p.tbl);
1366 case PF_ADDR_RTLABEL:
1367 return (aw1->v.rtlabel != aw2->v.rtlabel);
1368 default:
1369 printf("invalid address type: %d\n", aw1->type);
1370 return (1);
1374 u_int16_t
1375 pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp)
1377 u_int32_t l;
1379 if (udp && !cksum)
1380 return (0x0000);
1381 l = cksum + old - new;
1382 l = (l >> 16) + (l & 65535);
1383 l = l & 65535;
1384 if (udp && !l)
1385 return (0xFFFF);
1386 return (l);
1389 void
1390 pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc,
1391 struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af)
1393 struct pf_addr ao;
1394 u_int16_t po = *p;
1396 PF_ACPY(&ao, a, af);
1397 PF_ACPY(a, an, af);
1399 *p = pn;
1401 switch (af) {
1402 #ifdef INET
1403 case AF_INET:
1404 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
1405 ao.addr16[0], an->addr16[0], 0),
1406 ao.addr16[1], an->addr16[1], 0);
1407 *p = pn;
1408 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
1409 ao.addr16[0], an->addr16[0], u),
1410 ao.addr16[1], an->addr16[1], u),
1411 po, pn, u);
1412 break;
1413 #endif /* INET */
1414 #ifdef INET6
1415 case AF_INET6:
1416 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1417 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1418 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
1419 ao.addr16[0], an->addr16[0], u),
1420 ao.addr16[1], an->addr16[1], u),
1421 ao.addr16[2], an->addr16[2], u),
1422 ao.addr16[3], an->addr16[3], u),
1423 ao.addr16[4], an->addr16[4], u),
1424 ao.addr16[5], an->addr16[5], u),
1425 ao.addr16[6], an->addr16[6], u),
1426 ao.addr16[7], an->addr16[7], u),
1427 po, pn, u);
1428 break;
1429 #endif /* INET6 */
1434 /* Changes a u_int32_t. Uses a void * so there are no align restrictions */
1435 void
1436 pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u)
1438 u_int32_t ao;
1440 memcpy(&ao, a, sizeof(ao));
1441 memcpy(a, &an, sizeof(u_int32_t));
1442 *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u),
1443 ao % 65536, an % 65536, u);
1446 #ifdef INET6
1447 void
1448 pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u)
1450 struct pf_addr ao;
1452 PF_ACPY(&ao, a, AF_INET6);
1453 PF_ACPY(a, an, AF_INET6);
1455 *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1456 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1457 pf_cksum_fixup(pf_cksum_fixup(*c,
1458 ao.addr16[0], an->addr16[0], u),
1459 ao.addr16[1], an->addr16[1], u),
1460 ao.addr16[2], an->addr16[2], u),
1461 ao.addr16[3], an->addr16[3], u),
1462 ao.addr16[4], an->addr16[4], u),
1463 ao.addr16[5], an->addr16[5], u),
1464 ao.addr16[6], an->addr16[6], u),
1465 ao.addr16[7], an->addr16[7], u);
1467 #endif /* INET6 */
1469 void
1470 pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa,
1471 struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c,
1472 u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af)
1474 struct pf_addr oia, ooa;
1476 PF_ACPY(&oia, ia, af);
1477 PF_ACPY(&ooa, oa, af);
1479 /* Change inner protocol port, fix inner protocol checksum. */
1480 if (ip != NULL) {
1481 u_int16_t oip = *ip;
1482 u_int32_t opc = 0;
1484 if (pc != NULL)
1485 opc = *pc;
1486 *ip = np;
1487 if (pc != NULL)
1488 *pc = pf_cksum_fixup(*pc, oip, *ip, u);
1489 *ic = pf_cksum_fixup(*ic, oip, *ip, 0);
1490 if (pc != NULL)
1491 *ic = pf_cksum_fixup(*ic, opc, *pc, 0);
1493 /* Change inner ip address, fix inner ip and icmp checksums. */
1494 PF_ACPY(ia, na, af);
1495 switch (af) {
1496 #ifdef INET
1497 case AF_INET: {
1498 u_int32_t oh2c = *h2c;
1500 *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c,
1501 oia.addr16[0], ia->addr16[0], 0),
1502 oia.addr16[1], ia->addr16[1], 0);
1503 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
1504 oia.addr16[0], ia->addr16[0], 0),
1505 oia.addr16[1], ia->addr16[1], 0);
1506 *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0);
1507 break;
1509 #endif /* INET */
1510 #ifdef INET6
1511 case AF_INET6:
1512 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1513 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1514 pf_cksum_fixup(pf_cksum_fixup(*ic,
1515 oia.addr16[0], ia->addr16[0], u),
1516 oia.addr16[1], ia->addr16[1], u),
1517 oia.addr16[2], ia->addr16[2], u),
1518 oia.addr16[3], ia->addr16[3], u),
1519 oia.addr16[4], ia->addr16[4], u),
1520 oia.addr16[5], ia->addr16[5], u),
1521 oia.addr16[6], ia->addr16[6], u),
1522 oia.addr16[7], ia->addr16[7], u);
1523 break;
1524 #endif /* INET6 */
1526 /* Change outer ip address, fix outer ip or icmpv6 checksum. */
1527 PF_ACPY(oa, na, af);
1528 switch (af) {
1529 #ifdef INET
1530 case AF_INET:
1531 *hc = pf_cksum_fixup(pf_cksum_fixup(*hc,
1532 ooa.addr16[0], oa->addr16[0], 0),
1533 ooa.addr16[1], oa->addr16[1], 0);
1534 break;
1535 #endif /* INET */
1536 #ifdef INET6
1537 case AF_INET6:
1538 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1539 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1540 pf_cksum_fixup(pf_cksum_fixup(*ic,
1541 ooa.addr16[0], oa->addr16[0], u),
1542 ooa.addr16[1], oa->addr16[1], u),
1543 ooa.addr16[2], oa->addr16[2], u),
1544 ooa.addr16[3], oa->addr16[3], u),
1545 ooa.addr16[4], oa->addr16[4], u),
1546 ooa.addr16[5], oa->addr16[5], u),
1547 ooa.addr16[6], oa->addr16[6], u),
1548 ooa.addr16[7], oa->addr16[7], u);
1549 break;
1550 #endif /* INET6 */
1556 * Need to modulate the sequence numbers in the TCP SACK option
1557 * (credits to Krzysztof Pfaff for report and patch)
1560 pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd,
1561 struct tcphdr *th, struct pf_state_peer *dst)
1563 int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen;
1564 u_int8_t opts[MAX_TCPOPTLEN], *opt = opts;
1565 int copyback = 0, i, olen;
1566 struct sackblk sack;
1568 #ifdef __NetBSD__
1569 #define TCPOLEN_SACK (2 * sizeof(uint32_t))
1570 #endif
1572 #define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2)
1573 if (hlen < TCPOLEN_SACKLEN ||
1574 !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af))
1575 return 0;
1577 while (hlen >= TCPOLEN_SACKLEN) {
1578 olen = opt[1];
1579 switch (*opt) {
1580 case TCPOPT_EOL: /* FALLTHROUGH */
1581 case TCPOPT_NOP:
1582 opt++;
1583 hlen--;
1584 break;
1585 case TCPOPT_SACK:
1586 if (olen > hlen)
1587 olen = hlen;
1588 if (olen >= TCPOLEN_SACKLEN) {
1589 for (i = 2; i + TCPOLEN_SACK <= olen;
1590 i += TCPOLEN_SACK) {
1591 memcpy(&sack, &opt[i], sizeof(sack));
1592 #ifdef __NetBSD__
1593 #define SACK_START sack.left
1594 #define SACK_END sack.right
1595 #else
1596 #define SACK_START sack.start
1597 #define SACK_END sack.end
1598 #endif
1599 pf_change_a(&SACK_START, &th->th_sum,
1600 htonl(ntohl(SACK_START) -
1601 dst->seqdiff), 0);
1602 pf_change_a(&SACK_END, &th->th_sum,
1603 htonl(ntohl(SACK_END) -
1604 dst->seqdiff), 0);
1605 #undef SACK_START
1606 #undef SACK_END
1607 memcpy(&opt[i], &sack, sizeof(sack));
1609 copyback = 1;
1611 /* FALLTHROUGH */
1612 default:
1613 if (olen < 2)
1614 olen = 2;
1615 hlen -= olen;
1616 opt += olen;
1620 if (copyback)
1621 m_copyback(m, off + sizeof(*th), thoptlen, opts);
1622 return (copyback);
1625 void
1626 pf_send_tcp(const struct pf_rule *r, sa_family_t af,
1627 const struct pf_addr *saddr, const struct pf_addr *daddr,
1628 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
1629 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
1630 u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp)
1632 struct mbuf *m;
1633 int len, tlen;
1634 #ifdef INET
1635 struct ip *h = NULL;
1636 #endif /* INET */
1637 #ifdef INET6
1638 struct ip6_hdr *h6 = NULL;
1639 #endif /* INET6 */
1640 struct tcphdr *th;
1641 char *opt;
1642 #ifdef __NetBSD__
1643 struct pf_mtag *pf_mtag;
1644 #endif /* __NetBSD__ */
1646 /* maximum segment size tcp option */
1647 tlen = sizeof(struct tcphdr);
1648 if (mss)
1649 tlen += 4;
1651 switch (af) {
1652 #ifdef INET
1653 case AF_INET:
1654 len = sizeof(struct ip) + tlen;
1655 break;
1656 #endif /* INET */
1657 #ifdef INET6
1658 case AF_INET6:
1659 len = sizeof(struct ip6_hdr) + tlen;
1660 break;
1661 #endif /* INET6 */
1662 default:
1663 return;
1666 /* create outgoing mbuf */
1667 m = m_gethdr(M_DONTWAIT, MT_HEADER);
1668 if (m == NULL)
1669 return;
1670 #ifdef __NetBSD__
1671 if ((pf_mtag = pf_get_mtag(m)) == NULL) {
1672 m_freem(m);
1673 return;
1675 if (tag)
1676 pf_mtag->flags |= PF_TAG_GENERATED;
1677 pf_mtag->tag = rtag;
1679 if (r != NULL && r->rtableid >= 0)
1680 pf_mtag->rtableid = r->rtableid;
1681 #else
1682 if (tag)
1683 m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
1684 m->m_pkthdr.pf.tag = rtag;
1686 if (r != NULL && r->rtableid >= 0)
1687 m->m_pkthdr.pf.rtableid = m->m_pkthdr.pf.rtableid;
1688 #endif /* !__NetBSD__ */
1690 #ifdef ALTQ
1691 if (r != NULL && r->qid) {
1692 #ifdef __NetBSD__
1693 struct m_tag *mtag;
1694 struct altq_tag *atag;
1696 mtag = m_tag_get(PACKET_TAG_ALTQ_QID, sizeof(*atag), M_NOWAIT);
1697 if (mtag != NULL) {
1698 atag = (struct altq_tag *)(mtag + 1);
1699 atag->qid = r->qid;
1700 /* add hints for ecn */
1701 atag->af = af;
1702 atag->hdr = mtod(m, struct ip *);
1703 m_tag_prepend(m, mtag);
1705 #else
1706 m->m_pkthdr.pf.qid = r->qid;
1707 /* add hints for ecn */
1708 m->m_pkthdr.pf.hdr = mtod(m, struct ip *);
1709 #endif /* !__NetBSD__ */
1711 #endif /* ALTQ */
1712 m->m_data += max_linkhdr;
1713 m->m_pkthdr.len = m->m_len = len;
1714 m->m_pkthdr.rcvif = NULL;
1715 bzero(m->m_data, len);
1716 switch (af) {
1717 #ifdef INET
1718 case AF_INET:
1719 h = mtod(m, struct ip *);
1721 /* IP header fields included in the TCP checksum */
1722 h->ip_p = IPPROTO_TCP;
1723 h->ip_len = htons(tlen);
1724 h->ip_src.s_addr = saddr->v4.s_addr;
1725 h->ip_dst.s_addr = daddr->v4.s_addr;
1727 th = (struct tcphdr *)((char *)h + sizeof(struct ip));
1728 break;
1729 #endif /* INET */
1730 #ifdef INET6
1731 case AF_INET6:
1732 h6 = mtod(m, struct ip6_hdr *);
1734 /* IP header fields included in the TCP checksum */
1735 h6->ip6_nxt = IPPROTO_TCP;
1736 h6->ip6_plen = htons(tlen);
1737 memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr));
1738 memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr));
1740 th = (struct tcphdr *)((char *)h6 + sizeof(struct ip6_hdr));
1741 break;
1742 #endif /* INET6 */
1743 default:
1744 m_freem(m);
1745 return;
1748 /* TCP header */
1749 th->th_sport = sport;
1750 th->th_dport = dport;
1751 th->th_seq = htonl(seq);
1752 th->th_ack = htonl(ack);
1753 th->th_off = tlen >> 2;
1754 th->th_flags = flags;
1755 th->th_win = htons(win);
1757 if (mss) {
1758 opt = (char *)(th + 1);
1759 opt[0] = TCPOPT_MAXSEG;
1760 opt[1] = 4;
1761 HTONS(mss);
1762 bcopy((void *)&mss, (void *)(opt + 2), 2);
1765 switch (af) {
1766 #ifdef INET
1767 case AF_INET:
1768 /* TCP checksum */
1769 th->th_sum = in_cksum(m, len);
1771 /* Finish the IP header */
1772 h->ip_v = 4;
1773 h->ip_hl = sizeof(*h) >> 2;
1774 h->ip_tos = IPTOS_LOWDELAY;
1775 h->ip_len = htons(len);
1776 h->ip_off = htons(ip_mtudisc ? IP_DF : 0);
1777 h->ip_ttl = ttl ? ttl : ip_defttl;
1778 h->ip_sum = 0;
1779 if (eh == NULL) {
1780 ip_output(m, (void *)NULL, (void *)NULL, 0,
1781 (void *)NULL, (void *)NULL);
1782 } else {
1783 #ifdef __NetBSD__
1785 * On netbsd, pf_test and pf_test6 are always called
1786 * with eh == NULL.
1788 panic("pf_send_tcp: eh != NULL");
1789 #else
1790 struct route ro;
1791 struct rtentry rt;
1792 struct ether_header *e = (void *)ro.ro_dst.sa_data;
1794 if (ifp == NULL) {
1795 m_freem(m);
1796 return;
1798 rt.rt_ifp = ifp;
1799 ro.ro_rt = &rt;
1800 ro.ro_dst.sa_len = sizeof(ro.ro_dst);
1801 ro.ro_dst.sa_family = pseudo_AF_HDRCMPLT;
1802 bcopy(eh->ether_dhost, e->ether_shost, ETHER_ADDR_LEN);
1803 bcopy(eh->ether_shost, e->ether_dhost, ETHER_ADDR_LEN);
1804 e->ether_type = eh->ether_type;
1805 ip_output(m, (void *)NULL, &ro, IP_ROUTETOETHER,
1806 (void *)NULL, (void *)NULL);
1807 #endif /* !__NetBSD__ */
1809 break;
1810 #endif /* INET */
1811 #ifdef INET6
1812 case AF_INET6:
1813 /* TCP checksum */
1814 th->th_sum = in6_cksum(m, IPPROTO_TCP,
1815 sizeof(struct ip6_hdr), tlen);
1817 h6->ip6_vfc |= IPV6_VERSION;
1818 h6->ip6_hlim = IPV6_DEFHLIM;
1820 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
1821 break;
1822 #endif /* INET6 */
1826 void
1827 pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
1828 struct pf_rule *r)
1830 struct mbuf *m0;
1831 #ifdef __NetBSD__
1832 struct pf_mtag *pf_mtag;
1833 #endif /* __NetBSD__ */
1835 m0 = m_copy(m, 0, M_COPYALL);
1837 #ifdef __NetBSD__
1838 if ((pf_mtag = pf_get_mtag(m0)) == NULL)
1839 return;
1840 pf_mtag->flags |= PF_TAG_GENERATED;
1842 if (r->rtableid >= 0)
1843 pf_mtag->rtableid = r->rtableid;
1844 #else
1845 m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
1847 if (r->rtableid >= 0)
1848 m0->m_pkthdr.pf.rtableid = r->rtableid;
1849 #endif /* !__NetBSD__ */
1851 #ifdef ALTQ
1852 if (r->qid) {
1853 #ifdef __NetBSD__
1854 struct m_tag *mtag;
1855 struct altq_tag *atag;
1857 mtag = m_tag_get(PACKET_TAG_ALTQ_QID, sizeof(*atag), M_NOWAIT);
1858 if (mtag != NULL) {
1859 atag = (struct altq_tag *)(mtag + 1);
1860 atag->qid = r->qid;
1861 /* add hints for ecn */
1862 atag->af = af;
1863 atag->hdr = mtod(m0, struct ip *);
1864 m_tag_prepend(m0, mtag);
1866 #else
1867 m0->m_pkthdr.pf.qid = r->qid;
1868 /* add hints for ecn */
1869 m0->m_pkthdr.pf.hdr = mtod(m0, struct ip *);
1870 #endif /* !__NetBSD__ */
1872 #endif /* ALTQ */
1874 switch (af) {
1875 #ifdef INET
1876 case AF_INET:
1877 icmp_error(m0, type, code, 0, 0);
1878 break;
1879 #endif /* INET */
1880 #ifdef INET6
1881 case AF_INET6:
1882 icmp6_error(m0, type, code, 0);
1883 break;
1884 #endif /* INET6 */
1889 * Return 1 if the addresses a and b match (with mask m), otherwise return 0.
1890 * If n is 0, they match if they are equal. If n is != 0, they match if they
1891 * are different.
1894 pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
1895 struct pf_addr *b, sa_family_t af)
1897 int match = 0;
1899 switch (af) {
1900 #ifdef INET
1901 case AF_INET:
1902 if ((a->addr32[0] & m->addr32[0]) ==
1903 (b->addr32[0] & m->addr32[0]))
1904 match++;
1905 break;
1906 #endif /* INET */
1907 #ifdef INET6
1908 case AF_INET6:
1909 if (((a->addr32[0] & m->addr32[0]) ==
1910 (b->addr32[0] & m->addr32[0])) &&
1911 ((a->addr32[1] & m->addr32[1]) ==
1912 (b->addr32[1] & m->addr32[1])) &&
1913 ((a->addr32[2] & m->addr32[2]) ==
1914 (b->addr32[2] & m->addr32[2])) &&
1915 ((a->addr32[3] & m->addr32[3]) ==
1916 (b->addr32[3] & m->addr32[3])))
1917 match++;
1918 break;
1919 #endif /* INET6 */
1921 if (match) {
1922 if (n)
1923 return (0);
1924 else
1925 return (1);
1926 } else {
1927 if (n)
1928 return (1);
1929 else
1930 return (0);
1935 pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
1937 switch (op) {
1938 case PF_OP_IRG:
1939 return ((p > a1) && (p < a2));
1940 case PF_OP_XRG:
1941 return ((p < a1) || (p > a2));
1942 case PF_OP_RRG:
1943 return ((p >= a1) && (p <= a2));
1944 case PF_OP_EQ:
1945 return (p == a1);
1946 case PF_OP_NE:
1947 return (p != a1);
1948 case PF_OP_LT:
1949 return (p < a1);
1950 case PF_OP_LE:
1951 return (p <= a1);
1952 case PF_OP_GT:
1953 return (p > a1);
1954 case PF_OP_GE:
1955 return (p >= a1);
1957 return (0); /* never reached */
1961 pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
1963 NTOHS(a1);
1964 NTOHS(a2);
1965 NTOHS(p);
1966 return (pf_match(op, a1, a2, p));
1970 pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
1972 if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
1973 return (0);
1974 return (pf_match(op, a1, a2, u));
1978 pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
1980 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
1981 return (0);
1982 return (pf_match(op, a1, a2, g));
1986 pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag)
1988 #ifdef __NetBSD__
1989 if (*tag == -1) {
1990 struct pf_mtag *pf_mtag = pf_get_mtag(m);
1991 if (pf_mtag == NULL)
1992 return (0);
1994 *tag = pf_mtag->tag;
1996 #else
1997 if (*tag == -1)
1998 *tag = m->m_pkthdr.pf.tag;
1999 #endif /* !__NetBSD__ */
2001 return ((!r->match_tag_not && r->match_tag == *tag) ||
2002 (r->match_tag_not && r->match_tag != *tag));
2006 pf_tag_packet(struct mbuf *m, int tag, int rtableid)
2008 if (tag <= 0 && rtableid < 0)
2009 return (0);
2011 #ifdef __NetBSD__
2012 if (tag > 0 || rtableid > 0) {
2013 struct pf_mtag *pf_mtag = pf_get_mtag(m);
2014 if (pf_mtag == NULL)
2015 return (1);
2017 if (tag > 0)
2018 pf_mtag->tag = tag;
2019 if (rtableid > 0)
2020 pf_mtag->rtableid = rtableid;
2022 #else
2023 if (tag > 0)
2024 m->m_pkthdr.pf.tag = tag;
2025 if (rtableid >= 0)
2026 m->m_pkthdr.pf.rtableid = rtableid;
2027 #endif /* !__NetBSD__ */
2029 return (0);
2032 void
2033 pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n,
2034 struct pf_rule **r, struct pf_rule **a, int *match)
2036 struct pf_anchor_stackframe *f;
2038 (*r)->anchor->match = 0;
2039 if (match)
2040 *match = 0;
2041 if (*depth >= sizeof(pf_anchor_stack) /
2042 sizeof(pf_anchor_stack[0])) {
2043 printf("pf_step_into_anchor: stack overflow\n");
2044 *r = TAILQ_NEXT(*r, entries);
2045 return;
2046 } else if (*depth == 0 && a != NULL)
2047 *a = *r;
2048 f = pf_anchor_stack + (*depth)++;
2049 f->rs = *rs;
2050 f->r = *r;
2051 if ((*r)->anchor_wildcard) {
2052 f->parent = &(*r)->anchor->children;
2053 if ((f->child = RB_MIN(pf_anchor_node, f->parent)) ==
2054 NULL) {
2055 *r = NULL;
2056 return;
2058 *rs = &f->child->ruleset;
2059 } else {
2060 f->parent = NULL;
2061 f->child = NULL;
2062 *rs = &(*r)->anchor->ruleset;
2064 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2068 pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n,
2069 struct pf_rule **r, struct pf_rule **a, int *match)
2071 struct pf_anchor_stackframe *f;
2072 int quick = 0;
2074 do {
2075 if (*depth <= 0)
2076 break;
2077 f = pf_anchor_stack + *depth - 1;
2078 if (f->parent != NULL && f->child != NULL) {
2079 if (f->child->match ||
2080 (match != NULL && *match)) {
2081 f->r->anchor->match = 1;
2082 *match = 0;
2084 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child);
2085 if (f->child != NULL) {
2086 *rs = &f->child->ruleset;
2087 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2088 if (*r == NULL)
2089 continue;
2090 else
2091 break;
2094 (*depth)--;
2095 if (*depth == 0 && a != NULL)
2096 *a = NULL;
2097 *rs = f->rs;
2098 if (f->r->anchor->match || (match != NULL && *match))
2099 quick = f->r->quick;
2100 *r = TAILQ_NEXT(f->r, entries);
2101 } while (*r == NULL);
2103 return (quick);
2106 #ifdef INET6
2107 void
2108 pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
2109 struct pf_addr *rmask, const struct pf_addr *saddr, sa_family_t af)
2111 switch (af) {
2112 #ifdef INET
2113 case AF_INET:
2114 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
2115 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
2116 break;
2117 #endif /* INET */
2118 case AF_INET6:
2119 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
2120 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
2121 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) |
2122 ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]);
2123 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) |
2124 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]);
2125 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) |
2126 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]);
2127 break;
2131 void
2132 pf_addr_inc(struct pf_addr *addr, sa_family_t af)
2134 switch (af) {
2135 #ifdef INET
2136 case AF_INET:
2137 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1);
2138 break;
2139 #endif /* INET */
2140 case AF_INET6:
2141 if (addr->addr32[3] == 0xffffffff) {
2142 addr->addr32[3] = 0;
2143 if (addr->addr32[2] == 0xffffffff) {
2144 addr->addr32[2] = 0;
2145 if (addr->addr32[1] == 0xffffffff) {
2146 addr->addr32[1] = 0;
2147 addr->addr32[0] =
2148 htonl(ntohl(addr->addr32[0]) + 1);
2149 } else
2150 addr->addr32[1] =
2151 htonl(ntohl(addr->addr32[1]) + 1);
2152 } else
2153 addr->addr32[2] =
2154 htonl(ntohl(addr->addr32[2]) + 1);
2155 } else
2156 addr->addr32[3] =
2157 htonl(ntohl(addr->addr32[3]) + 1);
2158 break;
2161 #endif /* INET6 */
2163 #define mix(a,b,c) \
2164 do { \
2165 a -= b; a -= c; a ^= (c >> 13); \
2166 b -= c; b -= a; b ^= (a << 8); \
2167 c -= a; c -= b; c ^= (b >> 13); \
2168 a -= b; a -= c; a ^= (c >> 12); \
2169 b -= c; b -= a; b ^= (a << 16); \
2170 c -= a; c -= b; c ^= (b >> 5); \
2171 a -= b; a -= c; a ^= (c >> 3); \
2172 b -= c; b -= a; b ^= (a << 10); \
2173 c -= a; c -= b; c ^= (b >> 15); \
2174 } while (0)
2177 * hash function based on bridge_hash in if_bridge.c
2179 void
2180 pf_hash(const struct pf_addr *inaddr, struct pf_addr *hash,
2181 struct pf_poolhashkey *key, sa_family_t af)
2183 u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0];
2185 switch (af) {
2186 #ifdef INET
2187 case AF_INET:
2188 a += inaddr->addr32[0];
2189 b += key->key32[1];
2190 mix(a, b, c);
2191 hash->addr32[0] = c + key->key32[2];
2192 break;
2193 #endif /* INET */
2194 #ifdef INET6
2195 case AF_INET6:
2196 a += inaddr->addr32[0];
2197 b += inaddr->addr32[2];
2198 mix(a, b, c);
2199 hash->addr32[0] = c;
2200 a += inaddr->addr32[1];
2201 b += inaddr->addr32[3];
2202 c += key->key32[1];
2203 mix(a, b, c);
2204 hash->addr32[1] = c;
2205 a += inaddr->addr32[2];
2206 b += inaddr->addr32[1];
2207 c += key->key32[2];
2208 mix(a, b, c);
2209 hash->addr32[2] = c;
2210 a += inaddr->addr32[3];
2211 b += inaddr->addr32[0];
2212 c += key->key32[3];
2213 mix(a, b, c);
2214 hash->addr32[3] = c;
2215 break;
2216 #endif /* INET6 */
2221 pf_map_addr(sa_family_t af, struct pf_rule *r, const struct pf_addr *saddr,
2222 struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
2224 unsigned char hash[16];
2225 struct pf_pool *rpool = &r->rpool;
2226 struct pf_addr *raddr = &rpool->cur->addr.v.a.addr;
2227 struct pf_addr *rmask = &rpool->cur->addr.v.a.mask;
2228 struct pf_pooladdr *acur = rpool->cur;
2229 struct pf_src_node k;
2231 if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
2232 (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
2233 k.af = af;
2234 PF_ACPY(&k.addr, saddr, af);
2235 if (r->rule_flag & PFRULE_RULESRCTRACK ||
2236 r->rpool.opts & PF_POOL_STICKYADDR)
2237 k.rule.ptr = r;
2238 else
2239 k.rule.ptr = NULL;
2240 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
2241 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
2242 if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
2243 PF_ACPY(naddr, &(*sn)->raddr, af);
2244 if (pf_status.debug >= PF_DEBUG_MISC) {
2245 printf("pf_map_addr: src tracking maps ");
2246 pf_print_host(&k.addr, 0, af);
2247 printf(" to ");
2248 pf_print_host(naddr, 0, af);
2249 printf("\n");
2251 return (0);
2255 if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
2256 return (1);
2257 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2258 switch (af) {
2259 #ifdef INET
2260 case AF_INET:
2261 if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
2262 (rpool->opts & PF_POOL_TYPEMASK) !=
2263 PF_POOL_ROUNDROBIN)
2264 return (1);
2265 raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
2266 rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
2267 break;
2268 #endif /* INET */
2269 #ifdef INET6
2270 case AF_INET6:
2271 if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
2272 (rpool->opts & PF_POOL_TYPEMASK) !=
2273 PF_POOL_ROUNDROBIN)
2274 return (1);
2275 raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
2276 rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
2277 break;
2278 #endif /* INET6 */
2280 } else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2281 if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
2282 return (1); /* unsupported */
2283 } else {
2284 raddr = &rpool->cur->addr.v.a.addr;
2285 rmask = &rpool->cur->addr.v.a.mask;
2288 switch (rpool->opts & PF_POOL_TYPEMASK) {
2289 case PF_POOL_NONE:
2290 PF_ACPY(naddr, raddr, af);
2291 break;
2292 case PF_POOL_BITMASK:
2293 PF_POOLMASK(naddr, raddr, rmask, saddr, af);
2294 break;
2295 case PF_POOL_RANDOM:
2296 if (init_addr != NULL && PF_AZERO(init_addr, af)) {
2297 switch (af) {
2298 #ifdef INET
2299 case AF_INET:
2300 rpool->counter.addr32[0] = htonl(arc4random());
2301 break;
2302 #endif /* INET */
2303 #ifdef INET6
2304 case AF_INET6:
2305 if (rmask->addr32[3] != 0xffffffff)
2306 rpool->counter.addr32[3] =
2307 htonl(arc4random());
2308 else
2309 break;
2310 if (rmask->addr32[2] != 0xffffffff)
2311 rpool->counter.addr32[2] =
2312 htonl(arc4random());
2313 else
2314 break;
2315 if (rmask->addr32[1] != 0xffffffff)
2316 rpool->counter.addr32[1] =
2317 htonl(arc4random());
2318 else
2319 break;
2320 if (rmask->addr32[0] != 0xffffffff)
2321 rpool->counter.addr32[0] =
2322 htonl(arc4random());
2323 break;
2324 #endif /* INET6 */
2326 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
2327 PF_ACPY(init_addr, naddr, af);
2329 } else {
2330 PF_AINC(&rpool->counter, af);
2331 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
2333 break;
2334 case PF_POOL_SRCHASH:
2335 pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
2336 PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
2337 break;
2338 case PF_POOL_ROUNDROBIN:
2339 if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2340 if (!pfr_pool_get(rpool->cur->addr.p.tbl,
2341 &rpool->tblidx, &rpool->counter,
2342 &raddr, &rmask, af))
2343 goto get_addr;
2344 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2345 if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
2346 &rpool->tblidx, &rpool->counter,
2347 &raddr, &rmask, af))
2348 goto get_addr;
2349 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
2350 goto get_addr;
2352 try_next:
2353 if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL)
2354 rpool->cur = TAILQ_FIRST(&rpool->list);
2355 if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2356 rpool->tblidx = -1;
2357 if (pfr_pool_get(rpool->cur->addr.p.tbl,
2358 &rpool->tblidx, &rpool->counter,
2359 &raddr, &rmask, af)) {
2360 /* table contains no address of type 'af' */
2361 if (rpool->cur != acur)
2362 goto try_next;
2363 return (1);
2365 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2366 rpool->tblidx = -1;
2367 if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
2368 &rpool->tblidx, &rpool->counter,
2369 &raddr, &rmask, af)) {
2370 /* table contains no address of type 'af' */
2371 if (rpool->cur != acur)
2372 goto try_next;
2373 return (1);
2375 } else {
2376 raddr = &rpool->cur->addr.v.a.addr;
2377 rmask = &rpool->cur->addr.v.a.mask;
2378 PF_ACPY(&rpool->counter, raddr, af);
2381 get_addr:
2382 PF_ACPY(naddr, &rpool->counter, af);
2383 if (init_addr != NULL && PF_AZERO(init_addr, af))
2384 PF_ACPY(init_addr, naddr, af);
2385 PF_AINC(&rpool->counter, af);
2386 break;
2388 if (*sn != NULL)
2389 PF_ACPY(&(*sn)->raddr, naddr, af);
2391 if (pf_status.debug >= PF_DEBUG_MISC &&
2392 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
2393 printf("pf_map_addr: selected address ");
2394 pf_print_host(naddr, 0, af);
2395 printf("\n");
2398 return (0);
2402 pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
2403 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
2404 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
2405 struct pf_src_node **sn)
2407 struct pf_state_key_cmp key;
2408 struct pf_addr init_addr;
2409 u_int16_t cut;
2411 bzero(&init_addr, sizeof(init_addr));
2412 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
2413 return (1);
2415 if (proto == IPPROTO_ICMP) {
2416 low = 1;
2417 high = 65535;
2420 do {
2421 key.af = af;
2422 key.proto = proto;
2423 PF_ACPY(&key.ext.addr, daddr, key.af);
2424 PF_ACPY(&key.gwy.addr, naddr, key.af);
2425 key.ext.port = dport;
2428 * port search; start random, step;
2429 * similar 2 portloop in in_pcbbind
2431 if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
2432 proto == IPPROTO_ICMP)) {
2433 key.gwy.port = dport;
2434 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
2435 return (0);
2436 } else if (low == 0 && high == 0) {
2437 key.gwy.port = *nport;
2438 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
2439 return (0);
2440 } else if (low == high) {
2441 key.gwy.port = htons(low);
2442 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) {
2443 *nport = htons(low);
2444 return (0);
2446 } else {
2447 u_int16_t tmp;
2449 if (low > high) {
2450 tmp = low;
2451 low = high;
2452 high = tmp;
2454 /* low < high */
2455 cut = htonl(arc4random()) % (1 + high - low) + low;
2456 /* low <= cut <= high */
2457 for (tmp = cut; tmp <= high; ++(tmp)) {
2458 key.gwy.port = htons(tmp);
2459 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
2460 NULL) {
2461 *nport = htons(tmp);
2462 return (0);
2465 for (tmp = cut - 1; tmp >= low; --(tmp)) {
2466 key.gwy.port = htons(tmp);
2467 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
2468 NULL) {
2469 *nport = htons(tmp);
2470 return (0);
2475 switch (r->rpool.opts & PF_POOL_TYPEMASK) {
2476 case PF_POOL_RANDOM:
2477 case PF_POOL_ROUNDROBIN:
2478 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
2479 return (1);
2480 break;
2481 case PF_POOL_NONE:
2482 case PF_POOL_SRCHASH:
2483 case PF_POOL_BITMASK:
2484 default:
2485 return (1);
2487 } while (! PF_AEQ(&init_addr, naddr, af) );
2489 return (1); /* none available */
2492 struct pf_rule *
2493 pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
2494 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
2495 struct pf_addr *daddr, u_int16_t dport, int rs_num)
2497 struct pf_rule *r, *rm = NULL;
2498 struct pf_ruleset *ruleset = NULL;
2499 int tag = -1;
2500 int rtableid = -1;
2501 int asd = 0;
2503 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
2504 while (r && rm == NULL) {
2505 struct pf_rule_addr *src = NULL, *dst = NULL;
2506 struct pf_addr_wrap *xdst = NULL;
2508 if (r->action == PF_BINAT && direction == PF_IN) {
2509 src = &r->dst;
2510 if (r->rpool.cur != NULL)
2511 xdst = &r->rpool.cur->addr;
2512 } else {
2513 src = &r->src;
2514 dst = &r->dst;
2517 r->evaluations++;
2518 if (pfi_kif_match(r->kif, kif) == r->ifnot)
2519 r = r->skip[PF_SKIP_IFP].ptr;
2520 else if (r->direction && r->direction != direction)
2521 r = r->skip[PF_SKIP_DIR].ptr;
2522 else if (r->af && r->af != pd->af)
2523 r = r->skip[PF_SKIP_AF].ptr;
2524 else if (r->proto && r->proto != pd->proto)
2525 r = r->skip[PF_SKIP_PROTO].ptr;
2526 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af,
2527 src->neg, kif))
2528 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR :
2529 PF_SKIP_DST_ADDR].ptr;
2530 else if (src->port_op && !pf_match_port(src->port_op,
2531 src->port[0], src->port[1], sport))
2532 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
2533 PF_SKIP_DST_PORT].ptr;
2534 else if (dst != NULL &&
2535 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL))
2536 r = r->skip[PF_SKIP_DST_ADDR].ptr;
2537 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af,
2538 0, NULL))
2539 r = TAILQ_NEXT(r, entries);
2540 else if (dst != NULL && dst->port_op &&
2541 !pf_match_port(dst->port_op, dst->port[0],
2542 dst->port[1], dport))
2543 r = r->skip[PF_SKIP_DST_PORT].ptr;
2544 else if (r->match_tag && !pf_match_tag(m, r, &tag))
2545 r = TAILQ_NEXT(r, entries);
2546 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
2547 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
2548 off, pd->hdr.tcp), r->os_fingerprint)))
2549 r = TAILQ_NEXT(r, entries);
2550 else {
2551 if (r->tag)
2552 tag = r->tag;
2553 if (r->rtableid >= 0)
2554 rtableid = r->rtableid;
2555 if (r->anchor == NULL) {
2556 rm = r;
2557 } else
2558 pf_step_into_anchor(&asd, &ruleset, rs_num,
2559 &r, NULL, NULL);
2561 if (r == NULL)
2562 pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r,
2563 NULL, NULL);
2565 if (pf_tag_packet(m, tag, rtableid))
2566 return (NULL);
2567 if (rm != NULL && (rm->action == PF_NONAT ||
2568 rm->action == PF_NORDR || rm->action == PF_NOBINAT))
2569 return (NULL);
2570 return (rm);
2573 struct pf_rule *
2574 pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
2575 struct pfi_kif *kif, struct pf_src_node **sn,
2576 struct pf_addr *saddr, u_int16_t sport,
2577 struct pf_addr *daddr, u_int16_t dport,
2578 struct pf_addr *naddr, u_int16_t *nport)
2580 struct pf_rule *r = NULL;
2582 if (direction == PF_OUT) {
2583 r = pf_match_translation(pd, m, off, direction, kif, saddr,
2584 sport, daddr, dport, PF_RULESET_BINAT);
2585 if (r == NULL)
2586 r = pf_match_translation(pd, m, off, direction, kif,
2587 saddr, sport, daddr, dport, PF_RULESET_NAT);
2588 } else {
2589 r = pf_match_translation(pd, m, off, direction, kif, saddr,
2590 sport, daddr, dport, PF_RULESET_RDR);
2591 if (r == NULL)
2592 r = pf_match_translation(pd, m, off, direction, kif,
2593 saddr, sport, daddr, dport, PF_RULESET_BINAT);
2596 if (r != NULL) {
2597 switch (r->action) {
2598 case PF_NONAT:
2599 case PF_NOBINAT:
2600 case PF_NORDR:
2601 return (NULL);
2602 case PF_NAT:
2603 if (pf_get_sport(pd->af, pd->proto, r, saddr,
2604 daddr, dport, naddr, nport, r->rpool.proxy_port[0],
2605 r->rpool.proxy_port[1], sn)) {
2606 DPFPRINTF(PF_DEBUG_MISC,
2607 ("pf: NAT proxy port allocation "
2608 "(%u-%u) failed\n",
2609 r->rpool.proxy_port[0],
2610 r->rpool.proxy_port[1]));
2611 return (NULL);
2613 break;
2614 case PF_BINAT:
2615 switch (direction) {
2616 case PF_OUT:
2617 if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
2618 switch (pd->af) {
2619 #ifdef INET
2620 case AF_INET:
2621 if (r->rpool.cur->addr.p.dyn->
2622 pfid_acnt4 < 1)
2623 return (NULL);
2624 PF_POOLMASK(naddr,
2625 &r->rpool.cur->addr.p.dyn->
2626 pfid_addr4,
2627 &r->rpool.cur->addr.p.dyn->
2628 pfid_mask4,
2629 saddr, AF_INET);
2630 break;
2631 #endif /* INET */
2632 #ifdef INET6
2633 case AF_INET6:
2634 if (r->rpool.cur->addr.p.dyn->
2635 pfid_acnt6 < 1)
2636 return (NULL);
2637 PF_POOLMASK(naddr,
2638 &r->rpool.cur->addr.p.dyn->
2639 pfid_addr6,
2640 &r->rpool.cur->addr.p.dyn->
2641 pfid_mask6,
2642 saddr, AF_INET6);
2643 break;
2644 #endif /* INET6 */
2646 } else
2647 PF_POOLMASK(naddr,
2648 &r->rpool.cur->addr.v.a.addr,
2649 &r->rpool.cur->addr.v.a.mask,
2650 saddr, pd->af);
2651 break;
2652 case PF_IN:
2653 if (r->src.addr.type == PF_ADDR_DYNIFTL) {
2654 switch (pd->af) {
2655 #ifdef INET
2656 case AF_INET:
2657 if (r->src.addr.p.dyn->
2658 pfid_acnt4 < 1)
2659 return (NULL);
2660 PF_POOLMASK(naddr,
2661 &r->src.addr.p.dyn->
2662 pfid_addr4,
2663 &r->src.addr.p.dyn->
2664 pfid_mask4,
2665 daddr, AF_INET);
2666 break;
2667 #endif /* INET */
2668 #ifdef INET6
2669 case AF_INET6:
2670 if (r->src.addr.p.dyn->
2671 pfid_acnt6 < 1)
2672 return (NULL);
2673 PF_POOLMASK(naddr,
2674 &r->src.addr.p.dyn->
2675 pfid_addr6,
2676 &r->src.addr.p.dyn->
2677 pfid_mask6,
2678 daddr, AF_INET6);
2679 break;
2680 #endif /* INET6 */
2682 } else
2683 PF_POOLMASK(naddr,
2684 &r->src.addr.v.a.addr,
2685 &r->src.addr.v.a.mask, daddr,
2686 pd->af);
2687 break;
2689 break;
2690 case PF_RDR: {
2691 if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
2692 return (NULL);
2693 if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
2694 PF_POOL_BITMASK)
2695 PF_POOLMASK(naddr, naddr,
2696 &r->rpool.cur->addr.v.a.mask, daddr,
2697 pd->af);
2699 if (r->rpool.proxy_port[1]) {
2700 u_int32_t tmp_nport;
2702 tmp_nport = ((ntohs(dport) -
2703 ntohs(r->dst.port[0])) %
2704 (r->rpool.proxy_port[1] -
2705 r->rpool.proxy_port[0] + 1)) +
2706 r->rpool.proxy_port[0];
2708 /* wrap around if necessary */
2709 if (tmp_nport > 65535)
2710 tmp_nport -= 65535;
2711 *nport = htons((u_int16_t)tmp_nport);
2712 } else if (r->rpool.proxy_port[0])
2713 *nport = htons(r->rpool.proxy_port[0]);
2714 break;
2716 default:
2717 return (NULL);
2721 return (r);
2725 pf_socket_lookup(int direction, struct pf_pdesc *pd)
2727 struct pf_addr *saddr, *daddr;
2728 u_int16_t sport, dport;
2729 struct inpcbtable *tb;
2730 struct inpcb *inp = NULL;
2731 struct socket *so = NULL;
2732 #if defined(__NetBSD__) && defined(INET6)
2733 struct in6pcb *in6p = NULL;
2734 #else
2735 #define in6p inp
2736 #endif /* __NetBSD__ && INET6 */
2738 if (pd == NULL)
2739 return (-1);
2740 pd->lookup.uid = UID_MAX;
2741 pd->lookup.gid = GID_MAX;
2742 pd->lookup.pid = NO_PID;
2743 switch (pd->proto) {
2744 case IPPROTO_TCP:
2745 if (pd->hdr.tcp == NULL)
2746 return (-1);
2747 sport = pd->hdr.tcp->th_sport;
2748 dport = pd->hdr.tcp->th_dport;
2749 tb = &tcbtable;
2750 break;
2751 case IPPROTO_UDP:
2752 if (pd->hdr.udp == NULL)
2753 return (-1);
2754 sport = pd->hdr.udp->uh_sport;
2755 dport = pd->hdr.udp->uh_dport;
2756 tb = &udbtable;
2757 break;
2758 default:
2759 return (-1);
2761 if (direction == PF_IN) {
2762 saddr = pd->src;
2763 daddr = pd->dst;
2764 } else {
2765 u_int16_t p;
2767 p = sport;
2768 sport = dport;
2769 dport = p;
2770 saddr = pd->dst;
2771 daddr = pd->src;
2773 switch (pd->af) {
2775 #ifdef __NetBSD__
2776 #define in_pcbhashlookup(tbl, saddr, sport, daddr, dport) \
2777 in_pcblookup_connect(tbl, saddr, sport, daddr, dport)
2778 #define in6_pcbhashlookup(tbl, saddr, sport, daddr, dport) \
2779 in6_pcblookup_connect(tbl, saddr, sport, daddr, dport, 0)
2780 #define in_pcblookup_listen(tbl, addr, port, zero) \
2781 in_pcblookup_bind(tbl, addr, port)
2782 #define in6_pcblookup_listen(tbl, addr, port, zero) \
2783 in6_pcblookup_bind(tbl, addr, port, zero)
2784 #endif
2786 #ifdef INET
2787 case AF_INET:
2788 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport);
2789 if (inp == NULL) {
2790 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0);
2791 if (inp == NULL)
2792 return (-1);
2794 break;
2795 #endif /* INET */
2796 #ifdef INET6
2797 case AF_INET6:
2798 /*###2817 [cc] warning: assignment from incompatible pointer type%%%*/
2799 in6p = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6,
2800 dport);
2801 if (inp == NULL) {
2802 in6p = in6_pcblookup_listen(tb, &daddr->v6, dport, 0);
2803 if (inp == NULL)
2804 return (-1);
2806 break;
2807 #endif /* INET6 */
2809 default:
2810 return (-1);
2813 #ifdef __NetBSD__
2814 switch (pd->af) {
2815 #ifdef INET
2816 case AF_INET:
2817 so = inp->inp_socket;
2818 break;
2819 #endif
2820 #ifdef INET6
2821 case AF_INET6:
2822 /*###2840 [cc] error: 'struct inpcb' has no member named 'in6p_head'%%%*/
2823 so = in6p->in6p_socket;
2824 break;
2825 #endif /* INET6 */
2827 pd->lookup.uid = kauth_cred_geteuid(so->so_cred);
2828 pd->lookup.gid = kauth_cred_getegid(so->so_cred);
2829 #else
2830 so = inp->inp_socket;
2831 pd->lookup.uid = so->so_euid;
2832 pd->lookup.gid = so->so_egid;
2833 #endif /* !__NetBSD__ */
2834 pd->lookup.pid = so->so_cpid;
2835 return (1);
2838 u_int8_t
2839 pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
2841 int hlen;
2842 u_int8_t hdr[60];
2843 u_int8_t *opt, optlen;
2844 u_int8_t wscale = 0;
2846 hlen = th_off << 2; /* hlen <= sizeof(hdr) */
2847 if (hlen <= sizeof(struct tcphdr))
2848 return (0);
2849 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
2850 return (0);
2851 opt = hdr + sizeof(struct tcphdr);
2852 hlen -= sizeof(struct tcphdr);
2853 while (hlen >= 3) {
2854 switch (*opt) {
2855 case TCPOPT_EOL:
2856 case TCPOPT_NOP:
2857 ++opt;
2858 --hlen;
2859 break;
2860 case TCPOPT_WINDOW:
2861 wscale = opt[2];
2862 if (wscale > TCP_MAX_WINSHIFT)
2863 wscale = TCP_MAX_WINSHIFT;
2864 wscale |= PF_WSCALE_FLAG;
2865 /* FALLTHROUGH */
2866 default:
2867 optlen = opt[1];
2868 if (optlen < 2)
2869 optlen = 2;
2870 hlen -= optlen;
2871 opt += optlen;
2872 break;
2875 return (wscale);
2878 u_int16_t
2879 pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
2881 int hlen;
2882 u_int8_t hdr[60];
2883 u_int8_t *opt, optlen;
2884 u_int16_t mss = tcp_mssdflt;
2886 hlen = th_off << 2; /* hlen <= sizeof(hdr) */
2887 if (hlen <= sizeof(struct tcphdr))
2888 return (0);
2889 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
2890 return (0);
2891 opt = hdr + sizeof(struct tcphdr);
2892 hlen -= sizeof(struct tcphdr);
2893 while (hlen >= TCPOLEN_MAXSEG) {
2894 switch (*opt) {
2895 case TCPOPT_EOL:
2896 case TCPOPT_NOP:
2897 ++opt;
2898 --hlen;
2899 break;
2900 case TCPOPT_MAXSEG:
2901 bcopy((void *)(opt + 2), (void *)&mss, 2);
2902 NTOHS(mss);
2903 /* FALLTHROUGH */
2904 default:
2905 optlen = opt[1];
2906 if (optlen < 2)
2907 optlen = 2;
2908 hlen -= optlen;
2909 opt += optlen;
2910 break;
2913 return (mss);
2916 u_int16_t
2917 pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer)
2919 union {
2920 struct sockaddr dst;
2921 struct sockaddr_in dst4;
2922 struct sockaddr_in6 dst6;
2923 } u;
2924 struct route ro;
2925 struct route *rop = &ro;
2926 struct rtentry *rt;
2927 int hlen;
2928 u_int16_t mss = tcp_mssdflt;
2930 hlen = 0; /* XXXGCC -Wunitialized m68k */
2932 memset(&ro, 0, sizeof(ro));
2933 switch (af) {
2934 #ifdef INET
2935 case AF_INET:
2936 hlen = sizeof(struct ip);
2937 sockaddr_in_init(&u.dst4, &addr->v4, 0);
2938 rtcache_setdst(rop, &u.dst);
2939 break;
2940 #endif /* INET */
2941 #ifdef INET6
2942 case AF_INET6:
2943 hlen = sizeof(struct ip6_hdr);
2944 sockaddr_in6_init(&u.dst6, &addr->v6, 0, 0, 0);
2945 rtcache_setdst(rop, &u.dst);
2946 break;
2947 #endif /* INET6 */
2950 #ifndef __NetBSD__
2951 rtalloc_noclone(rop, NO_CLONING);
2952 if ((rt = ro->ro_rt) != NULL) {
2953 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr);
2954 mss = max(tcp_mssdflt, mss);
2956 #else
2957 if ((rt = rtcache_init_noclone(rop)) != NULL) {
2958 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr);
2959 mss = max(tcp_mssdflt, mss);
2961 rtcache_free(rop);
2962 #endif
2963 mss = min(mss, offer);
2964 mss = max(mss, 64); /* sanity - at least max opt space */
2965 return (mss);
2968 void
2969 pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
2971 struct pf_rule *r = s->rule.ptr;
2973 s->rt_kif = NULL;
2974 if (!r->rt || r->rt == PF_FASTROUTE)
2975 return;
2976 switch (s->state_key->af) {
2977 #ifdef INET
2978 case AF_INET:
2979 pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL,
2980 &s->nat_src_node);
2981 s->rt_kif = r->rpool.cur->kif;
2982 break;
2983 #endif /* INET */
2984 #ifdef INET6
2985 case AF_INET6:
2986 pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL,
2987 &s->nat_src_node);
2988 s->rt_kif = r->rpool.cur->kif;
2989 break;
2990 #endif /* INET6 */
2994 void
2995 pf_attach_state(struct pf_state_key *sk, struct pf_state *s, int tail)
2997 s->state_key = sk;
2998 sk->refcnt++;
3000 /* list is sorted, if-bound states before floating */
3001 if (tail)
3002 TAILQ_INSERT_TAIL(&sk->states, s, next);
3003 else
3004 TAILQ_INSERT_HEAD(&sk->states, s, next);
3007 void
3008 pf_detach_state(struct pf_state *s, int flags)
3010 struct pf_state_key *sk = s->state_key;
3012 if (sk == NULL)
3013 return;
3015 s->state_key = NULL;
3016 TAILQ_REMOVE(&sk->states, s, next);
3017 if (--sk->refcnt == 0) {
3018 if (!(flags & PF_DT_SKIP_EXTGWY))
3019 RB_REMOVE(pf_state_tree_ext_gwy,
3020 &pf_statetbl_ext_gwy, sk);
3021 if (!(flags & PF_DT_SKIP_LANEXT))
3022 RB_REMOVE(pf_state_tree_lan_ext,
3023 &pf_statetbl_lan_ext, sk);
3024 pool_put(&pf_state_key_pl, sk);
3028 struct pf_state_key *
3029 pf_alloc_state_key(struct pf_state *s)
3031 struct pf_state_key *sk;
3033 if ((sk = pool_get(&pf_state_key_pl, PR_NOWAIT)) == NULL)
3034 return (NULL);
3035 bzero(sk, sizeof(*sk));
3036 TAILQ_INIT(&sk->states);
3037 pf_attach_state(sk, s, 0);
3039 return (sk);
3043 pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
3044 struct pfi_kif *kif, struct mbuf *m, int off, void *h,
3045 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
3046 struct ifqueue *ifq)
3048 struct pf_rule *nr = NULL;
3049 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3050 u_int16_t bport, nport = 0;
3051 sa_family_t af = pd->af;
3052 struct pf_rule *r, *a = NULL;
3053 struct pf_ruleset *ruleset = NULL;
3054 struct pf_src_node *nsn = NULL;
3055 struct tcphdr *th = pd->hdr.tcp;
3056 u_short reason;
3057 int rewrite = 0, hdrlen = 0;
3058 int tag = -1, rtableid = -1;
3059 int asd = 0;
3060 int match = 0;
3061 int state_icmp = 0;
3062 u_int16_t mss = tcp_mssdflt;
3063 u_int16_t sport, dport;
3064 u_int8_t icmptype = 0, icmpcode = 0;
3066 if (direction == PF_IN && pf_check_congestion(ifq)) {
3067 REASON_SET(&reason, PFRES_CONGEST);
3068 return (PF_DROP);
3071 sport = dport = hdrlen = 0;
3073 switch (pd->proto) {
3074 case IPPROTO_TCP:
3075 sport = th->th_sport;
3076 dport = th->th_dport;
3077 hdrlen = sizeof(*th);
3078 break;
3079 case IPPROTO_UDP:
3080 sport = pd->hdr.udp->uh_sport;
3081 dport = pd->hdr.udp->uh_dport;
3082 hdrlen = sizeof(*pd->hdr.udp);
3083 break;
3084 #ifdef INET
3085 case IPPROTO_ICMP:
3086 if (pd->af != AF_INET)
3087 break;
3088 sport = dport = pd->hdr.icmp->icmp_id;
3089 icmptype = pd->hdr.icmp->icmp_type;
3090 icmpcode = pd->hdr.icmp->icmp_code;
3092 if (icmptype == ICMP_UNREACH ||
3093 icmptype == ICMP_SOURCEQUENCH ||
3094 icmptype == ICMP_REDIRECT ||
3095 icmptype == ICMP_TIMXCEED ||
3096 icmptype == ICMP_PARAMPROB)
3097 state_icmp++;
3098 break;
3099 #endif /* INET */
3101 #ifdef INET6
3102 case IPPROTO_ICMPV6:
3103 if (pd->af != AF_INET6)
3104 break;
3105 sport = dport = pd->hdr.icmp6->icmp6_id;
3106 hdrlen = sizeof(*pd->hdr.icmp6);
3107 icmptype = pd->hdr.icmp6->icmp6_type;
3108 icmpcode = pd->hdr.icmp6->icmp6_code;
3110 if (icmptype == ICMP6_DST_UNREACH ||
3111 icmptype == ICMP6_PACKET_TOO_BIG ||
3112 icmptype == ICMP6_TIME_EXCEEDED ||
3113 icmptype == ICMP6_PARAM_PROB)
3114 state_icmp++;
3115 break;
3116 #endif /* INET6 */
3119 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3121 if (direction == PF_OUT) {
3122 bport = nport = sport;
3123 /* check outgoing packet for BINAT/NAT */
3124 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
3125 saddr, sport, daddr, dport, &pd->naddr, &nport)) != NULL) {
3126 PF_ACPY(&pd->baddr, saddr, af);
3127 switch (pd->proto) {
3128 case IPPROTO_TCP:
3129 pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
3130 &th->th_sum, &pd->naddr, nport, 0, af);
3131 sport = th->th_sport;
3132 rewrite++;
3133 break;
3134 case IPPROTO_UDP:
3135 pf_change_ap(saddr, &pd->hdr.udp->uh_sport,
3136 pd->ip_sum, &pd->hdr.udp->uh_sum,
3137 &pd->naddr, nport, 1, af);
3138 sport = pd->hdr.udp->uh_sport;
3139 rewrite++;
3140 break;
3141 #ifdef INET
3142 case IPPROTO_ICMP:
3143 pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
3144 pd->naddr.v4.s_addr, 0);
3145 pd->hdr.icmp->icmp_cksum = pf_cksum_fixup(
3146 pd->hdr.icmp->icmp_cksum, sport, nport, 0);
3147 pd->hdr.icmp->icmp_id = nport;
3148 m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp);
3149 break;
3150 #endif /* INET */
3151 #ifdef INET6
3152 case IPPROTO_ICMPV6:
3153 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum,
3154 &pd->naddr, 0);
3155 rewrite++;
3156 break;
3157 #endif /* INET */
3158 default:
3159 switch (af) {
3160 #ifdef INET
3161 case AF_INET:
3162 pf_change_a(&saddr->v4.s_addr,
3163 pd->ip_sum, pd->naddr.v4.s_addr, 0);
3164 break;
3165 #endif /* INET */
3166 #ifdef INET6
3167 case AF_INET6:
3168 PF_ACPY(saddr, &pd->naddr, af);
3169 break;
3170 #endif /* INET */
3172 break;
3175 if (nr->natpass)
3176 r = NULL;
3177 pd->nat_rule = nr;
3179 } else {
3180 bport = nport = dport;
3181 /* check incoming packet for BINAT/RDR */
3182 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
3183 saddr, sport, daddr, dport, &pd->naddr, &nport)) != NULL) {
3184 PF_ACPY(&pd->baddr, daddr, af);
3185 switch (pd->proto) {
3186 case IPPROTO_TCP:
3187 pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
3188 &th->th_sum, &pd->naddr, nport, 0, af);
3189 dport = th->th_dport;
3190 rewrite++;
3191 break;
3192 case IPPROTO_UDP:
3193 pf_change_ap(daddr, &pd->hdr.udp->uh_dport,
3194 pd->ip_sum, &pd->hdr.udp->uh_sum,
3195 &pd->naddr, nport, 1, af);
3196 dport = pd->hdr.udp->uh_dport;
3197 rewrite++;
3198 break;
3199 #ifdef INET
3200 case IPPROTO_ICMP:
3201 pf_change_a(&daddr->v4.s_addr, pd->ip_sum,
3202 pd->naddr.v4.s_addr, 0);
3203 break;
3204 #endif /* INET */
3205 #ifdef INET6
3206 case IPPROTO_ICMPV6:
3207 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum,
3208 &pd->naddr, 0);
3209 rewrite++;
3210 break;
3211 #endif /* INET6 */
3212 default:
3213 switch (af) {
3214 #ifdef INET
3215 case AF_INET:
3216 pf_change_a(&daddr->v4.s_addr,
3217 pd->ip_sum, pd->naddr.v4.s_addr, 0);
3218 break;
3219 #endif /* INET */
3220 #ifdef INET6
3221 case AF_INET6:
3222 PF_ACPY(daddr, &pd->naddr, af);
3223 break;
3224 #endif /* INET */
3226 break;
3229 if (nr->natpass)
3230 r = NULL;
3231 pd->nat_rule = nr;
3235 while (r != NULL) {
3236 r->evaluations++;
3237 if (pfi_kif_match(r->kif, kif) == r->ifnot)
3238 r = r->skip[PF_SKIP_IFP].ptr;
3239 else if (r->direction && r->direction != direction)
3240 r = r->skip[PF_SKIP_DIR].ptr;
3241 else if (r->af && r->af != af)
3242 r = r->skip[PF_SKIP_AF].ptr;
3243 else if (r->proto && r->proto != pd->proto)
3244 r = r->skip[PF_SKIP_PROTO].ptr;
3245 else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
3246 r->src.neg, kif))
3247 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3248 /* tcp/udp only. port_op always 0 in other cases */
3249 else if (r->src.port_op && !pf_match_port(r->src.port_op,
3250 r->src.port[0], r->src.port[1], sport))
3251 r = r->skip[PF_SKIP_SRC_PORT].ptr;
3252 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
3253 r->dst.neg, NULL))
3254 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3255 /* tcp/udp only. port_op always 0 in other cases */
3256 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
3257 r->dst.port[0], r->dst.port[1], dport))
3258 r = r->skip[PF_SKIP_DST_PORT].ptr;
3259 /* icmp only. type always 0 in other cases */
3260 else if (r->type && r->type != icmptype + 1)
3261 r = TAILQ_NEXT(r, entries);
3262 /* icmp only. type always 0 in other cases */
3263 else if (r->code && r->code != icmpcode + 1)
3264 r = TAILQ_NEXT(r, entries);
3265 else if (r->tos && !(r->tos == pd->tos))
3266 r = TAILQ_NEXT(r, entries);
3267 else if (r->rule_flag & PFRULE_FRAGMENT)
3268 r = TAILQ_NEXT(r, entries);
3269 else if (pd->proto == IPPROTO_TCP &&
3270 (r->flagset & th->th_flags) != r->flags)
3271 r = TAILQ_NEXT(r, entries);
3272 /* tcp/udp only. uid.op always 0 in other cases */
3273 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done =
3274 pf_socket_lookup(direction, pd), 1)) &&
3275 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
3276 pd->lookup.uid))
3277 r = TAILQ_NEXT(r, entries);
3278 /* tcp/udp only. gid.op always 0 in other cases */
3279 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done =
3280 pf_socket_lookup(direction, pd), 1)) &&
3281 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
3282 pd->lookup.gid))
3283 r = TAILQ_NEXT(r, entries);
3284 else if (r->prob && r->prob <= arc4random())
3285 r = TAILQ_NEXT(r, entries);
3286 else if (r->match_tag && !pf_match_tag(m, r, &tag))
3287 r = TAILQ_NEXT(r, entries);
3288 else if (r->os_fingerprint != PF_OSFP_ANY &&
3289 (pd->proto != IPPROTO_TCP || !pf_osfp_match(
3290 pf_osfp_fingerprint(pd, m, off, th),
3291 r->os_fingerprint)))
3292 r = TAILQ_NEXT(r, entries);
3293 else {
3294 if (r->tag)
3295 tag = r->tag;
3296 if (r->rtableid >= 0)
3297 rtableid = r->rtableid;
3298 if (r->anchor == NULL) {
3299 match = 1;
3300 *rm = r;
3301 *am = a;
3302 *rsm = ruleset;
3303 if ((*rm)->quick)
3304 break;
3305 r = TAILQ_NEXT(r, entries);
3306 } else
3307 pf_step_into_anchor(&asd, &ruleset,
3308 PF_RULESET_FILTER, &r, &a, &match);
3310 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
3311 PF_RULESET_FILTER, &r, &a, &match))
3312 break;
3314 r = *rm;
3315 a = *am;
3316 ruleset = *rsm;
3318 REASON_SET(&reason, PFRES_MATCH);
3320 if (r->log || (nr != NULL && nr->log)) {
3321 if (rewrite)
3322 m_copyback(m, off, hdrlen, pd->hdr.any);
3323 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr,
3324 a, ruleset, pd);
3327 if ((r->action == PF_DROP) &&
3328 ((r->rule_flag & PFRULE_RETURNRST) ||
3329 (r->rule_flag & PFRULE_RETURNICMP) ||
3330 (r->rule_flag & PFRULE_RETURN))) {
3331 /* undo NAT changes, if they have taken place */
3332 if (nr != NULL) {
3333 if (direction == PF_OUT) {
3334 switch (pd->proto) {
3335 case IPPROTO_TCP:
3336 pf_change_ap(saddr, &th->th_sport,
3337 pd->ip_sum, &th->th_sum,
3338 &pd->baddr, bport, 0, af);
3339 sport = th->th_sport;
3340 rewrite++;
3341 break;
3342 case IPPROTO_UDP:
3343 pf_change_ap(saddr,
3344 &pd->hdr.udp->uh_sport, pd->ip_sum,
3345 &pd->hdr.udp->uh_sum, &pd->baddr,
3346 bport, 1, af);
3347 sport = pd->hdr.udp->uh_sport;
3348 rewrite++;
3349 break;
3350 case IPPROTO_ICMP:
3351 #ifdef INET6
3352 case IPPROTO_ICMPV6:
3353 #endif
3354 /* nothing! */
3355 break;
3356 default:
3357 switch (af) {
3358 case AF_INET:
3359 pf_change_a(&saddr->v4.s_addr,
3360 pd->ip_sum,
3361 pd->baddr.v4.s_addr, 0);
3362 break;
3363 case AF_INET6:
3364 PF_ACPY(saddr, &pd->baddr, af);
3365 break;
3368 } else {
3369 switch (pd->proto) {
3370 case IPPROTO_TCP:
3371 pf_change_ap(daddr, &th->th_dport,
3372 pd->ip_sum, &th->th_sum,
3373 &pd->baddr, bport, 0, af);
3374 dport = th->th_dport;
3375 rewrite++;
3376 break;
3377 case IPPROTO_UDP:
3378 pf_change_ap(daddr,
3379 &pd->hdr.udp->uh_dport, pd->ip_sum,
3380 &pd->hdr.udp->uh_sum, &pd->baddr,
3381 bport, 1, af);
3382 dport = pd->hdr.udp->uh_dport;
3383 rewrite++;
3384 break;
3385 case IPPROTO_ICMP:
3386 #ifdef INET6
3387 case IPPROTO_ICMPV6:
3388 #endif
3389 /* nothing! */
3390 break;
3391 default:
3392 switch (af) {
3393 case AF_INET:
3394 pf_change_a(&daddr->v4.s_addr,
3395 pd->ip_sum,
3396 pd->baddr.v4.s_addr, 0);
3397 break;
3398 case AF_INET6:
3399 PF_ACPY(daddr, &pd->baddr, af);
3400 break;
3405 if (pd->proto == IPPROTO_TCP &&
3406 ((r->rule_flag & PFRULE_RETURNRST) ||
3407 (r->rule_flag & PFRULE_RETURN)) &&
3408 !(th->th_flags & TH_RST)) {
3409 u_int32_t ack = ntohl(th->th_seq) + pd->p_len;
3410 struct ip *h = mtod(m, struct ip *);
3412 #ifdef __NetBSD__
3413 if (pf_check_proto_cksum(m, direction, off,
3414 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET))
3415 #else
3416 if (pf_check_proto_cksum(m, off,
3417 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET))
3418 #endif /* !__NetBSD__ */
3419 REASON_SET(&reason, PFRES_PROTCKSUM);
3420 else {
3421 if (th->th_flags & TH_SYN)
3422 ack++;
3423 if (th->th_flags & TH_FIN)
3424 ack++;
3425 pf_send_tcp(r, af, pd->dst,
3426 pd->src, th->th_dport, th->th_sport,
3427 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
3428 r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp);
3430 } else if ((af == AF_INET) && r->return_icmp)
3431 pf_send_icmp(m, r->return_icmp >> 8,
3432 r->return_icmp & 255, af, r);
3433 else if ((af == AF_INET6) && r->return_icmp6)
3434 pf_send_icmp(m, r->return_icmp6 >> 8,
3435 r->return_icmp6 & 255, af, r);
3438 if (r->action == PF_DROP)
3439 return (PF_DROP);
3441 if (pf_tag_packet(m, tag, rtableid)) {
3442 REASON_SET(&reason, PFRES_MEMORY);
3443 return (PF_DROP);
3446 if (!state_icmp && (r->keep_state || nr != NULL ||
3447 (pd->flags & PFDESC_TCP_NORM))) {
3448 /* create new state */
3449 u_int16_t len;
3450 struct pf_state *s = NULL;
3451 struct pf_state_key *sk = NULL;
3452 struct pf_src_node *sn = NULL;
3454 /* check maximums */
3455 if (r->max_states && (r->states >= r->max_states)) {
3456 pf_status.lcounters[LCNT_STATES]++;
3457 REASON_SET(&reason, PFRES_MAXSTATES);
3458 goto cleanup;
3460 /* src node for filter rule */
3461 if ((r->rule_flag & PFRULE_SRCTRACK ||
3462 r->rpool.opts & PF_POOL_STICKYADDR) &&
3463 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3464 REASON_SET(&reason, PFRES_SRCLIMIT);
3465 goto cleanup;
3467 /* src node for translation rule */
3468 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
3469 ((direction == PF_OUT &&
3470 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
3471 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
3472 REASON_SET(&reason, PFRES_SRCLIMIT);
3473 goto cleanup;
3475 s = pool_get(&pf_state_pl, PR_NOWAIT);
3476 if (s == NULL) {
3477 REASON_SET(&reason, PFRES_MEMORY);
3478 cleanup:
3479 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
3480 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
3481 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3482 pf_status.src_nodes--;
3483 pool_put(&pf_src_tree_pl, sn);
3485 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
3486 nsn->expire == 0) {
3487 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
3488 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3489 pf_status.src_nodes--;
3490 pool_put(&pf_src_tree_pl, nsn);
3492 if (sk != NULL) {
3493 pool_put(&pf_state_key_pl, sk);
3495 return (PF_DROP);
3497 bzero(s, sizeof(*s));
3498 s->rule.ptr = r;
3499 s->nat_rule.ptr = nr;
3500 s->anchor.ptr = a;
3501 STATE_INC_COUNTERS(s);
3502 s->allow_opts = r->allow_opts;
3503 s->log = r->log & PF_LOG_ALL;
3504 if (nr != NULL)
3505 s->log |= nr->log & PF_LOG_ALL;
3506 switch (pd->proto) {
3507 case IPPROTO_TCP:
3508 len = pd->tot_len - off - (th->th_off << 2);
3509 s->src.seqlo = ntohl(th->th_seq);
3510 s->src.seqhi = s->src.seqlo + len + 1;
3511 if ((th->th_flags & (TH_SYN|TH_ACK)) ==
3512 TH_SYN && r->keep_state == PF_STATE_MODULATE) {
3513 /* Generate sequence number modulator */
3514 while ((s->src.seqdiff =
3515 tcp_rndiss_next() - s->src.seqlo) == 0)
3517 pf_change_a(&th->th_seq, &th->th_sum,
3518 htonl(s->src.seqlo + s->src.seqdiff), 0);
3519 rewrite = 1;
3520 } else
3521 s->src.seqdiff = 0;
3522 if (th->th_flags & TH_SYN) {
3523 s->src.seqhi++;
3524 s->src.wscale = pf_get_wscale(m, off,
3525 th->th_off, af);
3527 s->src.max_win = MAX(ntohs(th->th_win), 1);
3528 if (s->src.wscale & PF_WSCALE_MASK) {
3529 /* Remove scale factor from initial window */
3530 int win = s->src.max_win;
3531 win += 1 << (s->src.wscale & PF_WSCALE_MASK);
3532 s->src.max_win = (win - 1) >>
3533 (s->src.wscale & PF_WSCALE_MASK);
3535 if (th->th_flags & TH_FIN)
3536 s->src.seqhi++;
3537 s->dst.seqhi = 1;
3538 s->dst.max_win = 1;
3539 s->src.state = TCPS_SYN_SENT;
3540 s->dst.state = TCPS_CLOSED;
3541 s->timeout = PFTM_TCP_FIRST_PACKET;
3542 break;
3543 case IPPROTO_UDP:
3544 s->src.state = PFUDPS_SINGLE;
3545 s->dst.state = PFUDPS_NO_TRAFFIC;
3546 s->timeout = PFTM_UDP_FIRST_PACKET;
3547 break;
3548 case IPPROTO_ICMP:
3549 #ifdef INET6
3550 case IPPROTO_ICMPV6:
3551 #endif
3552 s->timeout = PFTM_ICMP_FIRST_PACKET;
3553 break;
3554 default:
3555 s->src.state = PFOTHERS_SINGLE;
3556 s->dst.state = PFOTHERS_NO_TRAFFIC;
3557 s->timeout = PFTM_OTHER_FIRST_PACKET;
3560 s->creation = time_second;
3561 s->expire = time_second;
3563 if (sn != NULL) {
3564 s->src_node = sn;
3565 s->src_node->states++;
3567 if (nsn != NULL) {
3568 PF_ACPY(&nsn->raddr, &pd->naddr, af);
3569 s->nat_src_node = nsn;
3570 s->nat_src_node->states++;
3572 if (pd->proto == IPPROTO_TCP) {
3573 if ((pd->flags & PFDESC_TCP_NORM) &&
3574 pf_normalize_tcp_init(m, off, pd, th, &s->src,
3575 &s->dst)) {
3576 REASON_SET(&reason, PFRES_MEMORY);
3577 pf_src_tree_remove_state(s);
3578 STATE_DEC_COUNTERS(s);
3579 pool_put(&pf_state_pl, s);
3580 return (PF_DROP);
3582 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub &&
3583 pf_normalize_tcp_stateful(m, off, pd, &reason,
3584 th, s, &s->src, &s->dst, &rewrite)) {
3585 /* This really shouldn't happen!!! */
3586 DPFPRINTF(PF_DEBUG_URGENT,
3587 ("pf_normalize_tcp_stateful failed on "
3588 "first pkt"));
3589 pf_normalize_tcp_cleanup(s);
3590 pf_src_tree_remove_state(s);
3591 STATE_DEC_COUNTERS(s);
3592 pool_put(&pf_state_pl, s);
3593 return (PF_DROP);
3597 if ((sk = pf_alloc_state_key(s)) == NULL) {
3598 REASON_SET(&reason, PFRES_MEMORY);
3599 goto cleanup;
3602 sk->proto = pd->proto;
3603 sk->direction = direction;
3604 sk->af = af;
3605 if (direction == PF_OUT) {
3606 PF_ACPY(&sk->gwy.addr, saddr, af);
3607 PF_ACPY(&sk->ext.addr, daddr, af);
3608 switch (pd->proto) {
3609 case IPPROTO_ICMP:
3610 #ifdef INET6
3611 case IPPROTO_ICMPV6:
3612 #endif
3613 sk->gwy.port = nport;
3614 sk->ext.port = 0;
3615 break;
3616 default:
3617 sk->gwy.port = sport;
3618 sk->ext.port = dport;
3620 if (nr != NULL) {
3621 PF_ACPY(&sk->lan.addr, &pd->baddr, af);
3622 sk->lan.port = bport;
3623 } else {
3624 PF_ACPY(&sk->lan.addr, &sk->gwy.addr, af);
3625 sk->lan.port = sk->gwy.port;
3627 } else {
3628 PF_ACPY(&sk->lan.addr, daddr, af);
3629 PF_ACPY(&sk->ext.addr, saddr, af);
3630 switch (pd->proto) {
3631 case IPPROTO_ICMP:
3632 #ifdef INET6
3633 case IPPROTO_ICMPV6:
3634 #endif
3635 sk->lan.port = nport;
3636 sk->ext.port = 0;
3637 break;
3638 default:
3639 sk->lan.port = dport;
3640 sk->ext.port = sport;
3642 if (nr != NULL) {
3643 PF_ACPY(&sk->gwy.addr, &pd->baddr, af);
3644 sk->gwy.port = bport;
3645 } else {
3646 PF_ACPY(&sk->gwy.addr, &sk->lan.addr, af);
3647 sk->gwy.port = sk->lan.port;
3651 pf_set_rt_ifp(s, saddr); /* needs s->state_key set */
3653 if (pf_insert_state(bound_iface(r, nr, kif), s)) {
3654 if (pd->proto == IPPROTO_TCP)
3655 pf_normalize_tcp_cleanup(s);
3656 REASON_SET(&reason, PFRES_STATEINS);
3657 pf_src_tree_remove_state(s);
3658 STATE_DEC_COUNTERS(s);
3659 pool_put(&pf_state_pl, s);
3660 return (PF_DROP);
3661 } else
3662 *sm = s;
3663 if (tag > 0) {
3664 pf_tag_ref(tag);
3665 s->tag = tag;
3667 if (pd->proto == IPPROTO_TCP &&
3668 (th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
3669 r->keep_state == PF_STATE_SYNPROXY) {
3670 s->src.state = PF_TCPS_PROXY_SRC;
3671 if (nr != NULL) {
3672 if (direction == PF_OUT) {
3673 pf_change_ap(saddr, &th->th_sport,
3674 pd->ip_sum, &th->th_sum, &pd->baddr,
3675 bport, 0, af);
3676 sport = th->th_sport;
3677 } else {
3678 pf_change_ap(daddr, &th->th_dport,
3679 pd->ip_sum, &th->th_sum, &pd->baddr,
3680 bport, 0, af);
3681 sport = th->th_dport;
3684 s->src.seqhi = htonl(arc4random());
3685 /* Find mss option */
3686 mss = pf_get_mss(m, off, th->th_off, af);
3687 mss = pf_calc_mss(saddr, af, mss);
3688 mss = pf_calc_mss(daddr, af, mss);
3689 s->src.mss = mss;
3690 pf_send_tcp(r, af, daddr, saddr, th->th_dport,
3691 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
3692 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL);
3693 REASON_SET(&reason, PFRES_SYNPROXY);
3694 return (PF_SYNPROXY_DROP);
3698 /* copy back packet headers if we performed NAT operations */
3699 if (rewrite)
3700 m_copyback(m, off, hdrlen, pd->hdr.any);
3702 return (PF_PASS);
3706 pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
3707 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am,
3708 struct pf_ruleset **rsm)
3710 struct pf_rule *r, *a = NULL;
3711 struct pf_ruleset *ruleset = NULL;
3712 sa_family_t af = pd->af;
3713 u_short reason;
3714 int tag = -1;
3715 int asd = 0;
3716 int match = 0;
3718 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3719 while (r != NULL) {
3720 r->evaluations++;
3721 if (pfi_kif_match(r->kif, kif) == r->ifnot)
3722 r = r->skip[PF_SKIP_IFP].ptr;
3723 else if (r->direction && r->direction != direction)
3724 r = r->skip[PF_SKIP_DIR].ptr;
3725 else if (r->af && r->af != af)
3726 r = r->skip[PF_SKIP_AF].ptr;
3727 else if (r->proto && r->proto != pd->proto)
3728 r = r->skip[PF_SKIP_PROTO].ptr;
3729 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
3730 r->src.neg, kif))
3731 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3732 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
3733 r->dst.neg, NULL))
3734 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3735 else if (r->tos && !(r->tos == pd->tos))
3736 r = TAILQ_NEXT(r, entries);
3737 else if (r->src.port_op || r->dst.port_op ||
3738 r->flagset || r->type || r->code ||
3739 r->os_fingerprint != PF_OSFP_ANY)
3740 r = TAILQ_NEXT(r, entries);
3741 else if (r->prob && r->prob <= arc4random())
3742 r = TAILQ_NEXT(r, entries);
3743 else if (r->match_tag && !pf_match_tag(m, r, &tag))
3744 r = TAILQ_NEXT(r, entries);
3745 else {
3746 if (r->anchor == NULL) {
3747 match = 1;
3748 *rm = r;
3749 *am = a;
3750 *rsm = ruleset;
3751 if ((*rm)->quick)
3752 break;
3753 r = TAILQ_NEXT(r, entries);
3754 } else
3755 pf_step_into_anchor(&asd, &ruleset,
3756 PF_RULESET_FILTER, &r, &a, &match);
3758 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
3759 PF_RULESET_FILTER, &r, &a, &match))
3760 break;
3762 r = *rm;
3763 a = *am;
3764 ruleset = *rsm;
3766 REASON_SET(&reason, PFRES_MATCH);
3768 if (r->log)
3769 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset,
3770 pd);
3772 if (r->action != PF_PASS)
3773 return (PF_DROP);
3775 if (pf_tag_packet(m, tag, -1)) {
3776 REASON_SET(&reason, PFRES_MEMORY);
3777 return (PF_DROP);
3780 return (PF_PASS);
3784 pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
3785 struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
3786 u_short *reason)
3788 struct pf_state_key_cmp key;
3789 struct tcphdr *th = pd->hdr.tcp;
3790 u_int16_t win = ntohs(th->th_win);
3791 u_int32_t ack, end, seq, orig_seq;
3792 u_int8_t sws, dws;
3793 int ackskew;
3794 int copyback = 0;
3795 struct pf_state_peer *src, *dst;
3797 key.af = pd->af;
3798 key.proto = IPPROTO_TCP;
3799 if (direction == PF_IN) {
3800 PF_ACPY(&key.ext.addr, pd->src, key.af);
3801 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
3802 key.ext.port = th->th_sport;
3803 key.gwy.port = th->th_dport;
3804 } else {
3805 PF_ACPY(&key.lan.addr, pd->src, key.af);
3806 PF_ACPY(&key.ext.addr, pd->dst, key.af);
3807 key.lan.port = th->th_sport;
3808 key.ext.port = th->th_dport;
3811 STATE_LOOKUP();
3813 if (direction == (*state)->state_key->direction) {
3814 src = &(*state)->src;
3815 dst = &(*state)->dst;
3816 } else {
3817 src = &(*state)->dst;
3818 dst = &(*state)->src;
3821 if ((*state)->src.state == PF_TCPS_PROXY_SRC) {
3822 if (direction != (*state)->state_key->direction) {
3823 REASON_SET(reason, PFRES_SYNPROXY);
3824 return (PF_SYNPROXY_DROP);
3826 if (th->th_flags & TH_SYN) {
3827 if (ntohl(th->th_seq) != (*state)->src.seqlo) {
3828 REASON_SET(reason, PFRES_SYNPROXY);
3829 return (PF_DROP);
3831 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
3832 pd->src, th->th_dport, th->th_sport,
3833 (*state)->src.seqhi, ntohl(th->th_seq) + 1,
3834 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1,
3835 0, NULL, NULL);
3836 REASON_SET(reason, PFRES_SYNPROXY);
3837 return (PF_SYNPROXY_DROP);
3838 } else if (!(th->th_flags & TH_ACK) ||
3839 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
3840 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
3841 REASON_SET(reason, PFRES_SYNPROXY);
3842 return (PF_DROP);
3843 } else if ((*state)->src_node != NULL &&
3844 pf_src_connlimit(state)) {
3845 REASON_SET(reason, PFRES_SRCLIMIT);
3846 return (PF_DROP);
3847 } else
3848 (*state)->src.state = PF_TCPS_PROXY_DST;
3850 if ((*state)->src.state == PF_TCPS_PROXY_DST) {
3851 struct pf_state_host *src, *dst;
3853 if (direction == PF_OUT) {
3854 src = &(*state)->state_key->gwy;
3855 dst = &(*state)->state_key->ext;
3856 } else {
3857 src = &(*state)->state_key->ext;
3858 dst = &(*state)->state_key->lan;
3860 if (direction == (*state)->state_key->direction) {
3861 if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) ||
3862 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
3863 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
3864 REASON_SET(reason, PFRES_SYNPROXY);
3865 return (PF_DROP);
3867 (*state)->src.max_win = MAX(ntohs(th->th_win), 1);
3868 if ((*state)->dst.seqhi == 1)
3869 (*state)->dst.seqhi = htonl(arc4random());
3870 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
3871 &dst->addr, src->port, dst->port,
3872 (*state)->dst.seqhi, 0, TH_SYN, 0,
3873 (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL);
3874 REASON_SET(reason, PFRES_SYNPROXY);
3875 return (PF_SYNPROXY_DROP);
3876 } else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
3877 (TH_SYN|TH_ACK)) ||
3878 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) {
3879 REASON_SET(reason, PFRES_SYNPROXY);
3880 return (PF_DROP);
3881 } else {
3882 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1);
3883 (*state)->dst.seqlo = ntohl(th->th_seq);
3884 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
3885 pd->src, th->th_dport, th->th_sport,
3886 ntohl(th->th_ack), ntohl(th->th_seq) + 1,
3887 TH_ACK, (*state)->src.max_win, 0, 0, 0,
3888 (*state)->tag, NULL, NULL);
3889 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
3890 &dst->addr, src->port, dst->port,
3891 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
3892 TH_ACK, (*state)->dst.max_win, 0, 0, 1,
3893 0, NULL, NULL);
3894 (*state)->src.seqdiff = (*state)->dst.seqhi -
3895 (*state)->src.seqlo;
3896 (*state)->dst.seqdiff = (*state)->src.seqhi -
3897 (*state)->dst.seqlo;
3898 (*state)->src.seqhi = (*state)->src.seqlo +
3899 (*state)->dst.max_win;
3900 (*state)->dst.seqhi = (*state)->dst.seqlo +
3901 (*state)->src.max_win;
3902 (*state)->src.wscale = (*state)->dst.wscale = 0;
3903 (*state)->src.state = (*state)->dst.state =
3904 TCPS_ESTABLISHED;
3905 REASON_SET(reason, PFRES_SYNPROXY);
3906 return (PF_SYNPROXY_DROP);
3910 if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
3911 sws = src->wscale & PF_WSCALE_MASK;
3912 dws = dst->wscale & PF_WSCALE_MASK;
3913 } else
3914 sws = dws = 0;
3917 * Sequence tracking algorithm from Guido van Rooij's paper:
3918 * http://www.madison-gurkha.com/publications/tcp_filtering/
3919 * tcp_filtering.ps
3922 orig_seq = seq = ntohl(th->th_seq);
3923 if (src->seqlo == 0) {
3924 /* First packet from this end. Set its state */
3926 if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) &&
3927 src->scrub == NULL) {
3928 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) {
3929 REASON_SET(reason, PFRES_MEMORY);
3930 return (PF_DROP);
3934 /* Deferred generation of sequence number modulator */
3935 if (dst->seqdiff && !src->seqdiff) {
3936 while ((src->seqdiff = tcp_rndiss_next() - seq) == 0)
3938 ack = ntohl(th->th_ack) - dst->seqdiff;
3939 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
3940 src->seqdiff), 0);
3941 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
3942 copyback = 1;
3943 } else {
3944 ack = ntohl(th->th_ack);
3947 end = seq + pd->p_len;
3948 if (th->th_flags & TH_SYN) {
3949 end++;
3950 if (dst->wscale & PF_WSCALE_FLAG) {
3951 src->wscale = pf_get_wscale(m, off, th->th_off,
3952 pd->af);
3953 if (src->wscale & PF_WSCALE_FLAG) {
3954 /* Remove scale factor from initial
3955 * window */
3956 sws = src->wscale & PF_WSCALE_MASK;
3957 win = ((u_int32_t)win + (1 << sws) - 1)
3958 >> sws;
3959 dws = dst->wscale & PF_WSCALE_MASK;
3960 } else {
3961 /* fixup other window */
3962 dst->max_win <<= dst->wscale &
3963 PF_WSCALE_MASK;
3964 /* in case of a retrans SYN|ACK */
3965 dst->wscale = 0;
3969 if (th->th_flags & TH_FIN)
3970 end++;
3972 src->seqlo = seq;
3973 if (src->state < TCPS_SYN_SENT)
3974 src->state = TCPS_SYN_SENT;
3977 * May need to slide the window (seqhi may have been set by
3978 * the crappy stack check or if we picked up the connection
3979 * after establishment)
3981 if (src->seqhi == 1 ||
3982 SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi))
3983 src->seqhi = end + MAX(1, dst->max_win << dws);
3984 if (win > src->max_win)
3985 src->max_win = win;
3987 } else {
3988 ack = ntohl(th->th_ack) - dst->seqdiff;
3989 if (src->seqdiff) {
3990 /* Modulate sequence numbers */
3991 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
3992 src->seqdiff), 0);
3993 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
3994 copyback = 1;
3996 end = seq + pd->p_len;
3997 if (th->th_flags & TH_SYN)
3998 end++;
3999 if (th->th_flags & TH_FIN)
4000 end++;
4003 if ((th->th_flags & TH_ACK) == 0) {
4004 /* Let it pass through the ack skew check */
4005 ack = dst->seqlo;
4006 } else if ((ack == 0 &&
4007 (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) ||
4008 /* broken tcp stacks do not set ack */
4009 (dst->state < TCPS_SYN_SENT)) {
4011 * Many stacks (ours included) will set the ACK number in an
4012 * FIN|ACK if the SYN times out -- no sequence to ACK.
4014 ack = dst->seqlo;
4017 if (seq == end) {
4018 /* Ease sequencing restrictions on no data packets */
4019 seq = src->seqlo;
4020 end = seq;
4023 ackskew = dst->seqlo - ack;
4027 * Need to demodulate the sequence numbers in any TCP SACK options
4028 * (Selective ACK). We could optionally validate the SACK values
4029 * against the current ACK window, either forwards or backwards, but
4030 * I'm not confident that SACK has been implemented properly
4031 * everywhere. It wouldn't surprise me if several stacks accidently
4032 * SACK too far backwards of previously ACKed data. There really aren't
4033 * any security implications of bad SACKing unless the target stack
4034 * doesn't validate the option length correctly. Someone trying to
4035 * spoof into a TCP connection won't bother blindly sending SACK
4036 * options anyway.
4038 if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) {
4039 if (pf_modulate_sack(m, off, pd, th, dst))
4040 copyback = 1;
4044 #define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */
4045 if (SEQ_GEQ(src->seqhi, end) &&
4046 /* Last octet inside other's window space */
4047 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
4048 /* Retrans: not more than one window back */
4049 (ackskew >= -MAXACKWINDOW) &&
4050 /* Acking not more than one reassembled fragment backwards */
4051 (ackskew <= (MAXACKWINDOW << sws)) &&
4052 /* Acking not more than one window forward */
4053 ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
4054 (orig_seq == src->seqlo + 1) || (pd->flags & PFDESC_IP_REAS) == 0)) {
4055 /* Require an exact/+1 sequence match on resets when possible */
4057 if (dst->scrub || src->scrub) {
4058 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
4059 *state, src, dst, &copyback))
4060 return (PF_DROP);
4063 /* update max window */
4064 if (src->max_win < win)
4065 src->max_win = win;
4066 /* synchronize sequencing */
4067 if (SEQ_GT(end, src->seqlo))
4068 src->seqlo = end;
4069 /* slide the window of what the other end can send */
4070 if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
4071 dst->seqhi = ack + MAX((win << sws), 1);
4074 /* update states */
4075 if (th->th_flags & TH_SYN)
4076 if (src->state < TCPS_SYN_SENT)
4077 src->state = TCPS_SYN_SENT;
4078 if (th->th_flags & TH_FIN)
4079 if (src->state < TCPS_CLOSING)
4080 src->state = TCPS_CLOSING;
4081 if (th->th_flags & TH_ACK) {
4082 if (dst->state == TCPS_SYN_SENT) {
4083 dst->state = TCPS_ESTABLISHED;
4084 if (src->state == TCPS_ESTABLISHED &&
4085 (*state)->src_node != NULL &&
4086 pf_src_connlimit(state)) {
4087 REASON_SET(reason, PFRES_SRCLIMIT);
4088 return (PF_DROP);
4090 } else if (dst->state == TCPS_CLOSING)
4091 dst->state = TCPS_FIN_WAIT_2;
4093 if (th->th_flags & TH_RST)
4094 src->state = dst->state = TCPS_TIME_WAIT;
4096 /* update expire time */
4097 (*state)->expire = time_second;
4098 if (src->state >= TCPS_FIN_WAIT_2 &&
4099 dst->state >= TCPS_FIN_WAIT_2)
4100 (*state)->timeout = PFTM_TCP_CLOSED;
4101 else if (src->state >= TCPS_CLOSING &&
4102 dst->state >= TCPS_CLOSING)
4103 (*state)->timeout = PFTM_TCP_FIN_WAIT;
4104 else if (src->state < TCPS_ESTABLISHED ||
4105 dst->state < TCPS_ESTABLISHED)
4106 (*state)->timeout = PFTM_TCP_OPENING;
4107 else if (src->state >= TCPS_CLOSING ||
4108 dst->state >= TCPS_CLOSING)
4109 (*state)->timeout = PFTM_TCP_CLOSING;
4110 else
4111 (*state)->timeout = PFTM_TCP_ESTABLISHED;
4113 /* Fall through to PASS packet */
4115 } else if ((dst->state < TCPS_SYN_SENT ||
4116 dst->state >= TCPS_FIN_WAIT_2 ||
4117 src->state >= TCPS_FIN_WAIT_2) &&
4118 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) &&
4119 /* Within a window forward of the originating packet */
4120 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) {
4121 /* Within a window backward of the originating packet */
4124 * This currently handles three situations:
4125 * 1) Stupid stacks will shotgun SYNs before their peer
4126 * replies.
4127 * 2) When PF catches an already established stream (the
4128 * firewall rebooted, the state table was flushed, routes
4129 * changed...)
4130 * 3) Packets get funky immediately after the connection
4131 * closes (this should catch Solaris spurious ACK|FINs
4132 * that web servers like to spew after a close)
4134 * This must be a little more careful than the above code
4135 * since packet floods will also be caught here. We don't
4136 * update the TTL here to mitigate the damage of a packet
4137 * flood and so the same code can handle awkward establishment
4138 * and a loosened connection close.
4139 * In the establishment case, a correct peer response will
4140 * validate the connection, go through the normal state code
4141 * and keep updating the state TTL.
4144 if (pf_status.debug >= PF_DEBUG_MISC) {
4145 printf("pf: loose state match: ");
4146 pf_print_state(*state);
4147 pf_print_flags(th->th_flags);
4148 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
4149 "pkts=%llu:%llu\n", seq, orig_seq, ack, pd->p_len,
4150 ackskew,
4151 (unsigned long long int)(*state)->packets[0],
4152 (unsigned long long int)(*state)->packets[1]);
4155 if (dst->scrub || src->scrub) {
4156 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
4157 *state, src, dst, &copyback))
4158 return (PF_DROP);
4161 /* update max window */
4162 if (src->max_win < win)
4163 src->max_win = win;
4164 /* synchronize sequencing */
4165 if (SEQ_GT(end, src->seqlo))
4166 src->seqlo = end;
4167 /* slide the window of what the other end can send */
4168 if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
4169 dst->seqhi = ack + MAX((win << sws), 1);
4172 * Cannot set dst->seqhi here since this could be a shotgunned
4173 * SYN and not an already established connection.
4176 if (th->th_flags & TH_FIN)
4177 if (src->state < TCPS_CLOSING)
4178 src->state = TCPS_CLOSING;
4179 if (th->th_flags & TH_RST)
4180 src->state = dst->state = TCPS_TIME_WAIT;
4182 /* Fall through to PASS packet */
4184 } else {
4185 if ((*state)->dst.state == TCPS_SYN_SENT &&
4186 (*state)->src.state == TCPS_SYN_SENT) {
4187 /* Send RST for state mismatches during handshake */
4188 if (!(th->th_flags & TH_RST))
4189 pf_send_tcp((*state)->rule.ptr, pd->af,
4190 pd->dst, pd->src, th->th_dport,
4191 th->th_sport, ntohl(th->th_ack), 0,
4192 TH_RST, 0, 0,
4193 (*state)->rule.ptr->return_ttl, 1, 0,
4194 pd->eh, kif->pfik_ifp);
4195 src->seqlo = 0;
4196 src->seqhi = 1;
4197 src->max_win = 1;
4198 } else if (pf_status.debug >= PF_DEBUG_MISC) {
4199 printf("pf: BAD state: ");
4200 pf_print_state(*state);
4201 pf_print_flags(th->th_flags);
4202 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
4203 "pkts=%llu:%llu dir=%s,%s\n",
4204 seq, orig_seq, ack, pd->p_len, ackskew,
4205 (unsigned long long int)(*state)->packets[0],
4206 (unsigned long long int)(*state)->packets[1],
4207 direction == PF_IN ? "in" : "out",
4208 direction == (*state)->state_key->direction ?
4209 "fwd" : "rev");
4210 printf("pf: State failure on: %c %c %c %c | %c %c\n",
4211 SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
4212 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
4213 ' ': '2',
4214 (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
4215 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',
4216 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5',
4217 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6');
4219 REASON_SET(reason, PFRES_BADSTATE);
4220 return (PF_DROP);
4223 /* Any packets which have gotten here are to be passed */
4225 /* translate source/destination address, if necessary */
4226 if (STATE_TRANSLATE((*state)->state_key)) {
4227 if (direction == PF_OUT)
4228 pf_change_ap(pd->src, &th->th_sport, pd->ip_sum,
4229 &th->th_sum, &(*state)->state_key->gwy.addr,
4230 (*state)->state_key->gwy.port, 0, pd->af);
4231 else
4232 pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum,
4233 &th->th_sum, &(*state)->state_key->lan.addr,
4234 (*state)->state_key->lan.port, 0, pd->af);
4235 m_copyback(m, off, sizeof(*th), th);
4236 } else if (copyback) {
4237 /* Copyback sequence modulation or stateful scrub changes */
4238 m_copyback(m, off, sizeof(*th), th);
4241 return (PF_PASS);
4245 pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
4246 struct mbuf *m, int off, void *h, struct pf_pdesc *pd)
4248 struct pf_state_peer *src, *dst;
4249 struct pf_state_key_cmp key;
4250 struct udphdr *uh = pd->hdr.udp;
4252 key.af = pd->af;
4253 key.proto = IPPROTO_UDP;
4254 if (direction == PF_IN) {
4255 PF_ACPY(&key.ext.addr, pd->src, key.af);
4256 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4257 key.ext.port = uh->uh_sport;
4258 key.gwy.port = uh->uh_dport;
4259 } else {
4260 PF_ACPY(&key.lan.addr, pd->src, key.af);
4261 PF_ACPY(&key.ext.addr, pd->dst, key.af);
4262 key.lan.port = uh->uh_sport;
4263 key.ext.port = uh->uh_dport;
4266 STATE_LOOKUP();
4268 if (direction == (*state)->state_key->direction) {
4269 src = &(*state)->src;
4270 dst = &(*state)->dst;
4271 } else {
4272 src = &(*state)->dst;
4273 dst = &(*state)->src;
4276 /* update states */
4277 if (src->state < PFUDPS_SINGLE)
4278 src->state = PFUDPS_SINGLE;
4279 if (dst->state == PFUDPS_SINGLE)
4280 dst->state = PFUDPS_MULTIPLE;
4282 /* update expire time */
4283 (*state)->expire = time_second;
4284 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE)
4285 (*state)->timeout = PFTM_UDP_MULTIPLE;
4286 else
4287 (*state)->timeout = PFTM_UDP_SINGLE;
4289 /* translate source/destination address, if necessary */
4290 if (STATE_TRANSLATE((*state)->state_key)) {
4291 if (direction == PF_OUT)
4292 pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum,
4293 &uh->uh_sum, &(*state)->state_key->gwy.addr,
4294 (*state)->state_key->gwy.port, 1, pd->af);
4295 else
4296 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum,
4297 &uh->uh_sum, &(*state)->state_key->lan.addr,
4298 (*state)->state_key->lan.port, 1, pd->af);
4299 m_copyback(m, off, sizeof(*uh), uh);
4302 return (PF_PASS);
4306 pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
4307 struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
4308 u_short *reason)
4310 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
4311 u_int16_t icmpid = 0, *icmpsum;
4312 u_int8_t icmptype;
4313 int state_icmp = 0;
4314 struct pf_state_key_cmp key;
4316 icmpsum = NULL; /* XXXGCC -Wunitialized m68k */
4317 icmptype = 0; /* XXXGCC -Wunitialized m68k */
4319 switch (pd->proto) {
4320 #ifdef INET
4321 case IPPROTO_ICMP:
4322 icmptype = pd->hdr.icmp->icmp_type;
4323 icmpid = pd->hdr.icmp->icmp_id;
4324 icmpsum = &pd->hdr.icmp->icmp_cksum;
4326 if (icmptype == ICMP_UNREACH ||
4327 icmptype == ICMP_SOURCEQUENCH ||
4328 icmptype == ICMP_REDIRECT ||
4329 icmptype == ICMP_TIMXCEED ||
4330 icmptype == ICMP_PARAMPROB)
4331 state_icmp++;
4332 break;
4333 #endif /* INET */
4334 #ifdef INET6
4335 case IPPROTO_ICMPV6:
4336 icmptype = pd->hdr.icmp6->icmp6_type;
4337 icmpid = pd->hdr.icmp6->icmp6_id;
4338 icmpsum = &pd->hdr.icmp6->icmp6_cksum;
4340 if (icmptype == ICMP6_DST_UNREACH ||
4341 icmptype == ICMP6_PACKET_TOO_BIG ||
4342 icmptype == ICMP6_TIME_EXCEEDED ||
4343 icmptype == ICMP6_PARAM_PROB)
4344 state_icmp++;
4345 break;
4346 #endif /* INET6 */
4349 if (!state_icmp) {
4352 * ICMP query/reply message not related to a TCP/UDP packet.
4353 * Search for an ICMP state.
4355 key.af = pd->af;
4356 key.proto = pd->proto;
4357 if (direction == PF_IN) {
4358 PF_ACPY(&key.ext.addr, pd->src, key.af);
4359 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4360 key.ext.port = 0;
4361 key.gwy.port = icmpid;
4362 } else {
4363 PF_ACPY(&key.lan.addr, pd->src, key.af);
4364 PF_ACPY(&key.ext.addr, pd->dst, key.af);
4365 key.lan.port = icmpid;
4366 key.ext.port = 0;
4369 STATE_LOOKUP();
4371 (*state)->expire = time_second;
4372 (*state)->timeout = PFTM_ICMP_ERROR_REPLY;
4374 /* translate source/destination address, if necessary */
4375 if (STATE_TRANSLATE((*state)->state_key)) {
4376 if (direction == PF_OUT) {
4377 switch (pd->af) {
4378 #ifdef INET
4379 case AF_INET:
4380 pf_change_a(&saddr->v4.s_addr,
4381 pd->ip_sum,
4382 (*state)->state_key->gwy.addr.v4.s_addr, 0);
4383 pd->hdr.icmp->icmp_cksum =
4384 pf_cksum_fixup(
4385 pd->hdr.icmp->icmp_cksum, icmpid,
4386 (*state)->state_key->gwy.port, 0);
4387 pd->hdr.icmp->icmp_id =
4388 (*state)->state_key->gwy.port;
4389 m_copyback(m, off, ICMP_MINLEN,
4390 pd->hdr.icmp);
4391 break;
4392 #endif /* INET */
4393 #ifdef INET6
4394 case AF_INET6:
4395 pf_change_a6(saddr,
4396 &pd->hdr.icmp6->icmp6_cksum,
4397 &(*state)->state_key->gwy.addr, 0);
4398 m_copyback(m, off,
4399 sizeof(struct icmp6_hdr),
4400 pd->hdr.icmp6);
4401 break;
4402 #endif /* INET6 */
4404 } else {
4405 switch (pd->af) {
4406 #ifdef INET
4407 case AF_INET:
4408 pf_change_a(&daddr->v4.s_addr,
4409 pd->ip_sum,
4410 (*state)->state_key->lan.addr.v4.s_addr, 0);
4411 pd->hdr.icmp->icmp_cksum =
4412 pf_cksum_fixup(
4413 pd->hdr.icmp->icmp_cksum, icmpid,
4414 (*state)->state_key->lan.port, 0);
4415 pd->hdr.icmp->icmp_id =
4416 (*state)->state_key->lan.port;
4417 m_copyback(m, off, ICMP_MINLEN,
4418 pd->hdr.icmp);
4419 break;
4420 #endif /* INET */
4421 #ifdef INET6
4422 case AF_INET6:
4423 pf_change_a6(daddr,
4424 &pd->hdr.icmp6->icmp6_cksum,
4425 &(*state)->state_key->lan.addr, 0);
4426 m_copyback(m, off,
4427 sizeof(struct icmp6_hdr),
4428 pd->hdr.icmp6);
4429 break;
4430 #endif /* INET6 */
4435 return (PF_PASS);
4437 } else {
4439 * ICMP error message in response to a TCP/UDP packet.
4440 * Extract the inner TCP/UDP header and search for that state.
4443 struct pf_pdesc pd2;
4444 #ifdef INET
4445 struct ip h2;
4446 #endif /* INET */
4447 #ifdef INET6
4448 struct ip6_hdr h2_6;
4449 int terminal = 0;
4450 #endif /* INET6 */
4451 int ipoff2 = 0;
4452 int off2 = 0;
4454 memset(&pd2, 0, sizeof pd2); /* XXX gcc */
4456 pd2.af = pd->af;
4457 switch (pd->af) {
4458 #ifdef INET
4459 case AF_INET:
4460 /* offset of h2 in mbuf chain */
4461 ipoff2 = off + ICMP_MINLEN;
4463 if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2),
4464 NULL, reason, pd2.af)) {
4465 DPFPRINTF(PF_DEBUG_MISC,
4466 ("pf: ICMP error message too short "
4467 "(ip)\n"));
4468 return (PF_DROP);
4471 * ICMP error messages don't refer to non-first
4472 * fragments
4474 if (h2.ip_off & htons(IP_OFFMASK)) {
4475 REASON_SET(reason, PFRES_FRAG);
4476 return (PF_DROP);
4479 /* offset of protocol header that follows h2 */
4480 off2 = ipoff2 + (h2.ip_hl << 2);
4482 pd2.proto = h2.ip_p;
4483 pd2.src = (struct pf_addr *)&h2.ip_src;
4484 pd2.dst = (struct pf_addr *)&h2.ip_dst;
4485 pd2.ip_sum = &h2.ip_sum;
4486 break;
4487 #endif /* INET */
4488 #ifdef INET6
4489 case AF_INET6:
4490 ipoff2 = off + sizeof(struct icmp6_hdr);
4492 if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6),
4493 NULL, reason, pd2.af)) {
4494 DPFPRINTF(PF_DEBUG_MISC,
4495 ("pf: ICMP error message too short "
4496 "(ip6)\n"));
4497 return (PF_DROP);
4499 pd2.proto = h2_6.ip6_nxt;
4500 pd2.src = (struct pf_addr *)&h2_6.ip6_src;
4501 pd2.dst = (struct pf_addr *)&h2_6.ip6_dst;
4502 pd2.ip_sum = NULL;
4503 off2 = ipoff2 + sizeof(h2_6);
4504 do {
4505 switch (pd2.proto) {
4506 case IPPROTO_FRAGMENT:
4508 * ICMPv6 error messages for
4509 * non-first fragments
4511 REASON_SET(reason, PFRES_FRAG);
4512 return (PF_DROP);
4513 case IPPROTO_AH:
4514 case IPPROTO_HOPOPTS:
4515 case IPPROTO_ROUTING:
4516 case IPPROTO_DSTOPTS: {
4517 /* get next header and header length */
4518 struct ip6_ext opt6;
4520 if (!pf_pull_hdr(m, off2, &opt6,
4521 sizeof(opt6), NULL, reason,
4522 pd2.af)) {
4523 DPFPRINTF(PF_DEBUG_MISC,
4524 ("pf: ICMPv6 short opt\n"));
4525 return (PF_DROP);
4527 if (pd2.proto == IPPROTO_AH)
4528 off2 += (opt6.ip6e_len + 2) * 4;
4529 else
4530 off2 += (opt6.ip6e_len + 1) * 8;
4531 pd2.proto = opt6.ip6e_nxt;
4532 /* goto the next header */
4533 break;
4535 default:
4536 terminal++;
4537 break;
4539 } while (!terminal);
4540 break;
4541 #endif /* INET6 */
4544 switch (pd2.proto) {
4545 case IPPROTO_TCP: {
4546 struct tcphdr th;
4547 u_int32_t seq;
4548 struct pf_state_peer *src, *dst;
4549 u_int8_t dws;
4550 int copyback = 0;
4553 * Only the first 8 bytes of the TCP header can be
4554 * expected. Don't access any TCP header fields after
4555 * th_seq, an ackskew test is not possible.
4557 if (!pf_pull_hdr(m, off2, &th, 8, NULL, reason,
4558 pd2.af)) {
4559 DPFPRINTF(PF_DEBUG_MISC,
4560 ("pf: ICMP error message too short "
4561 "(tcp)\n"));
4562 return (PF_DROP);
4565 key.af = pd2.af;
4566 key.proto = IPPROTO_TCP;
4567 if (direction == PF_IN) {
4568 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
4569 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
4570 key.ext.port = th.th_dport;
4571 key.gwy.port = th.th_sport;
4572 } else {
4573 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
4574 PF_ACPY(&key.ext.addr, pd2.src, key.af);
4575 key.lan.port = th.th_dport;
4576 key.ext.port = th.th_sport;
4579 STATE_LOOKUP();
4581 if (direction == (*state)->state_key->direction) {
4582 src = &(*state)->dst;
4583 dst = &(*state)->src;
4584 } else {
4585 src = &(*state)->src;
4586 dst = &(*state)->dst;
4589 if (src->wscale && dst->wscale)
4590 dws = dst->wscale & PF_WSCALE_MASK;
4591 else
4592 dws = 0;
4594 /* Demodulate sequence number */
4595 seq = ntohl(th.th_seq) - src->seqdiff;
4596 if (src->seqdiff) {
4597 pf_change_a(&th.th_seq, icmpsum,
4598 htonl(seq), 0);
4599 copyback = 1;
4602 if (!SEQ_GEQ(src->seqhi, seq) ||
4603 !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws))) {
4604 if (pf_status.debug >= PF_DEBUG_MISC) {
4605 printf("pf: BAD ICMP %d:%d ",
4606 icmptype, pd->hdr.icmp->icmp_code);
4607 pf_print_host(pd->src, 0, pd->af);
4608 printf(" -> ");
4609 pf_print_host(pd->dst, 0, pd->af);
4610 printf(" state: ");
4611 pf_print_state(*state);
4612 printf(" seq=%u\n", seq);
4614 REASON_SET(reason, PFRES_BADSTATE);
4615 return (PF_DROP);
4618 if (STATE_TRANSLATE((*state)->state_key)) {
4619 if (direction == PF_IN) {
4620 pf_change_icmp(pd2.src, &th.th_sport,
4621 daddr, &(*state)->state_key->lan.addr,
4622 (*state)->state_key->lan.port, NULL,
4623 pd2.ip_sum, icmpsum,
4624 pd->ip_sum, 0, pd2.af);
4625 } else {
4626 pf_change_icmp(pd2.dst, &th.th_dport,
4627 saddr, &(*state)->state_key->gwy.addr,
4628 (*state)->state_key->gwy.port, NULL,
4629 pd2.ip_sum, icmpsum,
4630 pd->ip_sum, 0, pd2.af);
4632 copyback = 1;
4635 if (copyback) {
4636 switch (pd2.af) {
4637 #ifdef INET
4638 case AF_INET:
4639 m_copyback(m, off, ICMP_MINLEN,
4640 pd->hdr.icmp);
4641 m_copyback(m, ipoff2, sizeof(h2),
4642 &h2);
4643 break;
4644 #endif /* INET */
4645 #ifdef INET6
4646 case AF_INET6:
4647 m_copyback(m, off,
4648 sizeof(struct icmp6_hdr),
4649 pd->hdr.icmp6);
4650 m_copyback(m, ipoff2, sizeof(h2_6),
4651 &h2_6);
4652 break;
4653 #endif /* INET6 */
4655 m_copyback(m, off2, 8, &th);
4658 return (PF_PASS);
4659 break;
4661 case IPPROTO_UDP: {
4662 struct udphdr uh;
4664 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh),
4665 NULL, reason, pd2.af)) {
4666 DPFPRINTF(PF_DEBUG_MISC,
4667 ("pf: ICMP error message too short "
4668 "(udp)\n"));
4669 return (PF_DROP);
4672 key.af = pd2.af;
4673 key.proto = IPPROTO_UDP;
4674 if (direction == PF_IN) {
4675 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
4676 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
4677 key.ext.port = uh.uh_dport;
4678 key.gwy.port = uh.uh_sport;
4679 } else {
4680 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
4681 PF_ACPY(&key.ext.addr, pd2.src, key.af);
4682 key.lan.port = uh.uh_dport;
4683 key.ext.port = uh.uh_sport;
4686 STATE_LOOKUP();
4688 if (STATE_TRANSLATE((*state)->state_key)) {
4689 if (direction == PF_IN) {
4690 pf_change_icmp(pd2.src, &uh.uh_sport,
4691 daddr,
4692 &(*state)->state_key->lan.addr,
4693 (*state)->state_key->lan.port,
4694 &uh.uh_sum,
4695 pd2.ip_sum, icmpsum,
4696 pd->ip_sum, 1, pd2.af);
4697 } else {
4698 pf_change_icmp(pd2.dst, &uh.uh_dport,
4699 saddr,
4700 &(*state)->state_key->gwy.addr,
4701 (*state)->state_key->gwy.port, &uh.uh_sum,
4702 pd2.ip_sum, icmpsum,
4703 pd->ip_sum, 1, pd2.af);
4705 switch (pd2.af) {
4706 #ifdef INET
4707 case AF_INET:
4708 m_copyback(m, off, ICMP_MINLEN,
4709 pd->hdr.icmp);
4710 m_copyback(m, ipoff2, sizeof(h2), &h2);
4711 break;
4712 #endif /* INET */
4713 #ifdef INET6
4714 case AF_INET6:
4715 m_copyback(m, off,
4716 sizeof(struct icmp6_hdr),
4717 pd->hdr.icmp6);
4718 m_copyback(m, ipoff2, sizeof(h2_6),
4719 &h2_6);
4720 break;
4721 #endif /* INET6 */
4723 m_copyback(m, off2, sizeof(uh), &uh);
4726 return (PF_PASS);
4727 break;
4729 #ifdef INET
4730 case IPPROTO_ICMP: {
4731 struct icmp iih;
4733 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN,
4734 NULL, reason, pd2.af)) {
4735 DPFPRINTF(PF_DEBUG_MISC,
4736 ("pf: ICMP error message too short i"
4737 "(icmp)\n"));
4738 return (PF_DROP);
4741 key.af = pd2.af;
4742 key.proto = IPPROTO_ICMP;
4743 if (direction == PF_IN) {
4744 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
4745 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
4746 key.ext.port = 0;
4747 key.gwy.port = iih.icmp_id;
4748 } else {
4749 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
4750 PF_ACPY(&key.ext.addr, pd2.src, key.af);
4751 key.lan.port = iih.icmp_id;
4752 key.ext.port = 0;
4755 STATE_LOOKUP();
4757 if (STATE_TRANSLATE((*state)->state_key)) {
4758 if (direction == PF_IN) {
4759 pf_change_icmp(pd2.src, &iih.icmp_id,
4760 daddr,
4761 &(*state)->state_key->lan.addr,
4762 (*state)->state_key->lan.port, NULL,
4763 pd2.ip_sum, icmpsum,
4764 pd->ip_sum, 0, AF_INET);
4765 } else {
4766 pf_change_icmp(pd2.dst, &iih.icmp_id,
4767 saddr,
4768 &(*state)->state_key->gwy.addr,
4769 (*state)->state_key->gwy.port, NULL,
4770 pd2.ip_sum, icmpsum,
4771 pd->ip_sum, 0, AF_INET);
4773 m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp);
4774 m_copyback(m, ipoff2, sizeof(h2), &h2);
4775 m_copyback(m, off2, ICMP_MINLEN, &iih);
4778 return (PF_PASS);
4779 break;
4781 #endif /* INET */
4782 #ifdef INET6
4783 case IPPROTO_ICMPV6: {
4784 struct icmp6_hdr iih;
4786 if (!pf_pull_hdr(m, off2, &iih,
4787 sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
4788 DPFPRINTF(PF_DEBUG_MISC,
4789 ("pf: ICMP error message too short "
4790 "(icmp6)\n"));
4791 return (PF_DROP);
4794 key.af = pd2.af;
4795 key.proto = IPPROTO_ICMPV6;
4796 if (direction == PF_IN) {
4797 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
4798 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
4799 key.ext.port = 0;
4800 key.gwy.port = iih.icmp6_id;
4801 } else {
4802 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
4803 PF_ACPY(&key.ext.addr, pd2.src, key.af);
4804 key.lan.port = iih.icmp6_id;
4805 key.ext.port = 0;
4808 STATE_LOOKUP();
4810 if (STATE_TRANSLATE((*state)->state_key)) {
4811 if (direction == PF_IN) {
4812 pf_change_icmp(pd2.src, &iih.icmp6_id,
4813 daddr,
4814 &(*state)->state_key->lan.addr,
4815 (*state)->state_key->lan.port, NULL,
4816 pd2.ip_sum, icmpsum,
4817 pd->ip_sum, 0, AF_INET6);
4818 } else {
4819 pf_change_icmp(pd2.dst, &iih.icmp6_id,
4820 saddr, &(*state)->state_key->gwy.addr,
4821 (*state)->state_key->gwy.port, NULL,
4822 pd2.ip_sum, icmpsum,
4823 pd->ip_sum, 0, AF_INET6);
4825 m_copyback(m, off, sizeof(struct icmp6_hdr),
4826 pd->hdr.icmp6);
4827 m_copyback(m, ipoff2, sizeof(h2_6), &h2_6);
4828 m_copyback(m, off2, sizeof(struct icmp6_hdr),
4829 &iih);
4832 return (PF_PASS);
4833 break;
4835 #endif /* INET6 */
4836 default: {
4837 key.af = pd2.af;
4838 key.proto = pd2.proto;
4839 if (direction == PF_IN) {
4840 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
4841 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
4842 key.ext.port = 0;
4843 key.gwy.port = 0;
4844 } else {
4845 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
4846 PF_ACPY(&key.ext.addr, pd2.src, key.af);
4847 key.lan.port = 0;
4848 key.ext.port = 0;
4851 STATE_LOOKUP();
4853 if (STATE_TRANSLATE((*state)->state_key)) {
4854 if (direction == PF_IN) {
4855 pf_change_icmp(pd2.src, NULL,
4856 daddr,
4857 &(*state)->state_key->lan.addr,
4858 0, NULL,
4859 pd2.ip_sum, icmpsum,
4860 pd->ip_sum, 0, pd2.af);
4861 } else {
4862 pf_change_icmp(pd2.dst, NULL,
4863 saddr,
4864 &(*state)->state_key->gwy.addr,
4865 0, NULL,
4866 pd2.ip_sum, icmpsum,
4867 pd->ip_sum, 0, pd2.af);
4869 switch (pd2.af) {
4870 #ifdef INET
4871 case AF_INET:
4872 m_copyback(m, off, ICMP_MINLEN,
4873 pd->hdr.icmp);
4874 m_copyback(m, ipoff2, sizeof(h2), &h2);
4875 break;
4876 #endif /* INET */
4877 #ifdef INET6
4878 case AF_INET6:
4879 m_copyback(m, off,
4880 sizeof(struct icmp6_hdr),
4881 pd->hdr.icmp6);
4882 m_copyback(m, ipoff2, sizeof(h2_6),
4883 &h2_6);
4884 break;
4885 #endif /* INET6 */
4889 return (PF_PASS);
4890 break;
4897 pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
4898 struct pf_pdesc *pd)
4900 struct pf_state_peer *src, *dst;
4901 struct pf_state_key_cmp key;
4903 key.af = pd->af;
4904 key.proto = pd->proto;
4905 if (direction == PF_IN) {
4906 PF_ACPY(&key.ext.addr, pd->src, key.af);
4907 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4908 key.ext.port = 0;
4909 key.gwy.port = 0;
4910 } else {
4911 PF_ACPY(&key.lan.addr, pd->src, key.af);
4912 PF_ACPY(&key.ext.addr, pd->dst, key.af);
4913 key.lan.port = 0;
4914 key.ext.port = 0;
4917 STATE_LOOKUP();
4919 if (direction == (*state)->state_key->direction) {
4920 src = &(*state)->src;
4921 dst = &(*state)->dst;
4922 } else {
4923 src = &(*state)->dst;
4924 dst = &(*state)->src;
4927 /* update states */
4928 if (src->state < PFOTHERS_SINGLE)
4929 src->state = PFOTHERS_SINGLE;
4930 if (dst->state == PFOTHERS_SINGLE)
4931 dst->state = PFOTHERS_MULTIPLE;
4933 /* update expire time */
4934 (*state)->expire = time_second;
4935 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE)
4936 (*state)->timeout = PFTM_OTHER_MULTIPLE;
4937 else
4938 (*state)->timeout = PFTM_OTHER_SINGLE;
4940 /* translate source/destination address, if necessary */
4941 if (STATE_TRANSLATE((*state)->state_key)) {
4942 if (direction == PF_OUT)
4943 switch (pd->af) {
4944 #ifdef INET
4945 case AF_INET:
4946 pf_change_a(&pd->src->v4.s_addr,
4947 pd->ip_sum,
4948 (*state)->state_key->gwy.addr.v4.s_addr,
4950 break;
4951 #endif /* INET */
4952 #ifdef INET6
4953 case AF_INET6:
4954 PF_ACPY(pd->src,
4955 &(*state)->state_key->gwy.addr, pd->af);
4956 break;
4957 #endif /* INET6 */
4959 else
4960 switch (pd->af) {
4961 #ifdef INET
4962 case AF_INET:
4963 pf_change_a(&pd->dst->v4.s_addr,
4964 pd->ip_sum,
4965 (*state)->state_key->lan.addr.v4.s_addr,
4967 break;
4968 #endif /* INET */
4969 #ifdef INET6
4970 case AF_INET6:
4971 PF_ACPY(pd->dst,
4972 &(*state)->state_key->lan.addr, pd->af);
4973 break;
4974 #endif /* INET6 */
4978 return (PF_PASS);
4982 * ipoff and off are measured from the start of the mbuf chain.
4983 * h must be at "ipoff" on the mbuf chain.
4985 void *
4986 pf_pull_hdr(struct mbuf *m, int off, void *p, int len,
4987 u_short *actionp, u_short *reasonp, sa_family_t af)
4989 switch (af) {
4990 #ifdef INET
4991 case AF_INET: {
4992 struct ip *h = mtod(m, struct ip *);
4993 u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
4995 if (fragoff) {
4996 if (fragoff >= len)
4997 ACTION_SET(actionp, PF_PASS);
4998 else {
4999 ACTION_SET(actionp, PF_DROP);
5000 REASON_SET(reasonp, PFRES_FRAG);
5002 return (NULL);
5004 if (m->m_pkthdr.len < off + len ||
5005 ntohs(h->ip_len) < off + len) {
5006 ACTION_SET(actionp, PF_DROP);
5007 REASON_SET(reasonp, PFRES_SHORT);
5008 return (NULL);
5010 break;
5012 #endif /* INET */
5013 #ifdef INET6
5014 case AF_INET6: {
5015 struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
5017 if (m->m_pkthdr.len < off + len ||
5018 (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) <
5019 (unsigned)(off + len)) {
5020 ACTION_SET(actionp, PF_DROP);
5021 REASON_SET(reasonp, PFRES_SHORT);
5022 return (NULL);
5024 break;
5026 #endif /* INET6 */
5028 m_copydata(m, off, len, p);
5029 return (p);
5033 pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif)
5035 #ifdef __NetBSD__
5036 union {
5037 struct sockaddr dst;
5038 struct sockaddr_in dst4;
5039 struct sockaddr_in6 dst6;
5040 } u;
5041 struct route ro;
5042 int ret = 1;
5044 bzero(&ro, sizeof(ro));
5045 switch (af) {
5046 case AF_INET:
5047 sockaddr_in_init(&u.dst4, &addr->v4, 0);
5048 break;
5049 #ifdef INET6
5050 case AF_INET6:
5051 sockaddr_in6_init(&u.dst6, &addr->v6, 0, 0, 0);
5052 break;
5053 #endif /* INET6 */
5054 default:
5055 return (0);
5057 rtcache_setdst(&ro, &u.dst);
5059 ret = rtcache_init(&ro) != NULL ? 1 : 0;
5060 rtcache_free(&ro);
5062 return (ret);
5063 #else /* !__NetBSD__ */
5064 struct sockaddr_in *dst;
5065 int ret = 1;
5066 int check_mpath;
5067 extern int ipmultipath;
5068 #ifdef INET6
5069 extern int ip6_multipath;
5070 struct sockaddr_in6 *dst6;
5071 struct route_in6 ro;
5072 #else
5073 struct route ro;
5074 #endif
5075 struct radix_node *rn;
5076 struct rtentry *rt;
5077 struct ifnet *ifp;
5079 check_mpath = 0;
5080 bzero(&ro, sizeof(ro));
5081 switch (af) {
5082 case AF_INET:
5083 dst = satosin(&ro.ro_dst);
5084 dst->sin_family = AF_INET;
5085 dst->sin_len = sizeof(*dst);
5086 dst->sin_addr = addr->v4;
5087 if (ipmultipath)
5088 check_mpath = 1;
5089 break;
5090 #ifdef INET6
5091 case AF_INET6:
5092 dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
5093 dst6->sin6_family = AF_INET6;
5094 dst6->sin6_len = sizeof(*dst6);
5095 dst6->sin6_addr = addr->v6;
5096 if (ip6_multipath)
5097 check_mpath = 1;
5098 break;
5099 #endif /* INET6 */
5100 default:
5101 return (0);
5104 /* Skip checks for ipsec interfaces */
5105 if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC)
5106 goto out;
5108 rtalloc_noclone((struct route *)&ro, NO_CLONING);
5110 if (ro.ro_rt != NULL) {
5111 /* No interface given, this is a no-route check */
5112 if (kif == NULL)
5113 goto out;
5115 if (kif->pfik_ifp == NULL) {
5116 ret = 0;
5117 goto out;
5120 /* Perform uRPF check if passed input interface */
5121 ret = 0;
5122 rn = (struct radix_node *)ro.ro_rt;
5123 do {
5124 rt = (struct rtentry *)rn;
5125 if (rt->rt_ifp->if_type == IFT_CARP)
5126 ifp = rt->rt_ifp->if_carpdev;
5127 else
5128 ifp = rt->rt_ifp;
5130 if (kif->pfik_ifp == ifp)
5131 ret = 1;
5132 rn = rn_mpath_next(rn);
5133 } while (check_mpath == 1 && rn != NULL && ret == 0);
5134 } else
5135 ret = 0;
5136 out:
5137 if (ro.ro_rt != NULL)
5138 RTFREE(ro.ro_rt);
5139 return (ret);
5140 #endif /* !__NetBSD__ */
5144 pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw)
5146 #ifdef __NetBSD__
5147 /* NetBSD doesn't have route labels. */
5149 return (0);
5150 #else
5151 struct sockaddr_in *dst;
5152 #ifdef INET6
5153 struct sockaddr_in6 *dst6;
5154 struct route_in6 ro;
5155 #else
5156 struct route ro;
5157 #endif
5158 int ret = 0;
5160 bzero(&ro, sizeof(ro));
5161 switch (af) {
5162 case AF_INET:
5163 dst = satosin(&ro.ro_dst);
5164 dst->sin_family = AF_INET;
5165 dst->sin_len = sizeof(*dst);
5166 dst->sin_addr = addr->v4;
5167 break;
5168 #ifdef INET6
5169 case AF_INET6:
5170 dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
5171 dst6->sin6_family = AF_INET6;
5172 dst6->sin6_len = sizeof(*dst6);
5173 dst6->sin6_addr = addr->v6;
5174 break;
5175 #endif /* INET6 */
5176 default:
5177 return (0);
5180 rtalloc_noclone((struct route *)&ro, NO_CLONING);
5182 if (ro.ro_rt != NULL) {
5183 if (ro.ro_rt->rt_labelid == aw->v.rtlabel)
5184 ret = 1;
5185 RTFREE(ro.ro_rt);
5188 return (ret);
5189 #endif /* !__NetBSD__ */
5192 #ifdef INET
5193 void
5194 pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
5195 struct pf_state *s, struct pf_pdesc *pd)
5197 struct mbuf *m0, *m1;
5198 struct route iproute;
5199 struct route *ro = NULL;
5200 const struct sockaddr *dst;
5201 union {
5202 struct sockaddr dst;
5203 struct sockaddr_in dst4;
5204 } u;
5205 struct ip *ip;
5206 struct ifnet *ifp = NULL;
5207 struct pf_addr naddr;
5208 struct pf_src_node *sn = NULL;
5209 int error = 0;
5210 #ifdef IPSEC
5211 struct m_tag *mtag;
5212 #endif /* IPSEC */
5213 #ifdef __NetBSD__
5214 struct pf_mtag *pf_mtag;
5215 #endif /* __NetBSD__ */
5217 if (m == NULL || *m == NULL || r == NULL ||
5218 (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
5219 panic("pf_route: invalid parameters");
5221 #ifdef __NetBSD__
5222 if ((pf_mtag = pf_get_mtag(*m)) == NULL) {
5223 m0 = *m;
5224 *m = NULL;
5225 goto bad;
5227 if (pf_mtag->routed++ > 3) {
5228 m0 = *m;
5229 *m = NULL;
5230 goto bad;
5232 #else
5233 if ((*m)->m_pkthdr.pf.routed++ > 3) {
5234 m0 = *m;
5235 *m = NULL;
5236 goto bad;
5238 #endif /* !__NetBSD__ */
5240 if (r->rt == PF_DUPTO) {
5241 if ((m0 = m_dup(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
5242 return;
5243 } else {
5244 if ((r->rt == PF_REPLYTO) == (r->direction == dir))
5245 return;
5246 m0 = *m;
5249 if (m0->m_len < sizeof(struct ip)) {
5250 DPFPRINTF(PF_DEBUG_URGENT,
5251 ("pf_route: m0->m_len < sizeof(struct ip)\n"));
5252 goto bad;
5255 ip = mtod(m0, struct ip *);
5257 ro = &iproute;
5258 memset(ro, 0, sizeof(*ro));
5259 sockaddr_in_init(&u.dst4, &ip->ip_dst, 0);
5260 dst = &u.dst;
5261 rtcache_setdst(ro, dst);
5263 if (r->rt == PF_FASTROUTE) {
5264 struct rtentry *rt;
5266 rt = rtcache_init(ro);
5268 if (rt == NULL) {
5269 ip_statinc(IP_STAT_NOROUTE);
5270 goto bad;
5273 ifp = rt->rt_ifp;
5274 rt->rt_use++;
5276 if (rt->rt_flags & RTF_GATEWAY)
5277 dst = rt->rt_gateway;
5278 } else {
5279 if (TAILQ_EMPTY(&r->rpool.list)) {
5280 DPFPRINTF(PF_DEBUG_URGENT,
5281 ("pf_route: TAILQ_EMPTY(&r->rpool.list)\n"));
5282 goto bad;
5284 if (s == NULL) {
5285 pf_map_addr(AF_INET, r,
5286 (const struct pf_addr *)&ip->ip_src,
5287 &naddr, NULL, &sn);
5288 if (!PF_AZERO(&naddr, AF_INET))
5289 u.dst4.sin_addr.s_addr = naddr.v4.s_addr;
5290 ifp = r->rpool.cur->kif ?
5291 r->rpool.cur->kif->pfik_ifp : NULL;
5292 } else {
5293 if (!PF_AZERO(&s->rt_addr, AF_INET))
5294 u.dst4.sin_addr.s_addr = s->rt_addr.v4.s_addr;
5295 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
5298 if (ifp == NULL)
5299 goto bad;
5301 if (oifp != ifp) {
5302 if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS)
5303 goto bad;
5304 else if (m0 == NULL)
5305 goto done;
5306 if (m0->m_len < sizeof(struct ip)) {
5307 DPFPRINTF(PF_DEBUG_URGENT,
5308 ("pf_route: m0->m_len < sizeof(struct ip)\n"));
5309 goto bad;
5311 ip = mtod(m0, struct ip *);
5314 /* Copied from ip_output. */
5315 #ifdef IPSEC
5317 * If deferred crypto processing is needed, check that the
5318 * interface supports it.
5320 if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL))
5321 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) {
5322 /* Notify IPsec to do its own crypto. */
5323 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
5324 goto bad;
5326 #endif /* IPSEC */
5328 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */
5329 #ifdef __NetBSD__
5330 if (m0->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
5331 in_delayed_cksum(m0);
5332 m0->m_pkthdr.csum_flags &= ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
5334 #else
5335 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) {
5336 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) ||
5337 ifp->if_bridge != NULL) {
5338 in_delayed_cksum(m0);
5339 m0->m_pkthdr.csum_flags &= ~M_TCPV4_CSUM_OUT; /* Clear */
5341 } else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) {
5342 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) ||
5343 ifp->if_bridge != NULL) {
5344 in_delayed_cksum(m0);
5345 m0->m_pkthdr.csum_flags &= ~M_UDPV4_CSUM_OUT; /* Clear */
5348 #endif /* !__NetBSD__ */
5350 if (ntohs(ip->ip_len) <= ifp->if_mtu) {
5351 #ifdef __NetBSD__
5352 ip->ip_sum = 0;
5353 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
5355 m0->m_pkthdr.csum_flags &= ~M_CSUM_IPv4;
5356 #else
5357 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
5358 ifp->if_bridge == NULL) {
5359 m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
5360 ipstat.ips_outhwcsum++;
5361 } else {
5362 ip->ip_sum = 0;
5363 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
5365 /* Update relevant hardware checksum stats for TCP/UDP */
5366 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT)
5367 tcpstat.tcps_outhwcsum++;
5368 else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT)
5369 udpstat.udps_outhwcsum++;
5370 #endif /* !__NetBSD__ */
5371 error = (*ifp->if_output)(ifp, m0, dst, NULL);
5372 goto done;
5376 * Too large for interface; fragment if possible.
5377 * Must be able to put at least 8 bytes per fragment.
5379 if (ip->ip_off & htons(IP_DF)) {
5380 ip_statinc(IP_STAT_CANTFRAG);
5381 if (r->rt != PF_DUPTO) {
5382 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
5383 ifp->if_mtu);
5384 goto done;
5385 } else
5386 goto bad;
5389 #ifdef __NetBSD__
5390 /* Make ip_fragment re-compute checksums. */
5391 if (IN_NEED_CHECKSUM(ifp, M_CSUM_IPv4)) {
5392 m0->m_pkthdr.csum_flags |= M_CSUM_IPv4;
5394 #endif /* __NetBSD__ */
5395 m1 = m0;
5396 error = ip_fragment(m0, ifp, ifp->if_mtu);
5397 if (error) {
5398 m0 = NULL;
5399 goto bad;
5402 for (m0 = m1; m0; m0 = m1) {
5403 m1 = m0->m_nextpkt;
5404 m0->m_nextpkt = 0;
5405 if (error == 0)
5406 error = (*ifp->if_output)(ifp, m0, dst, NULL);
5407 else
5408 m_freem(m0);
5411 if (error == 0)
5412 ip_statinc(IP_STAT_FRAGMENTED);
5414 done:
5415 if (r->rt != PF_DUPTO)
5416 *m = NULL;
5417 if (ro == &iproute)
5418 rtcache_free(ro);
5419 return;
5421 bad:
5422 m_freem(m0);
5423 goto done;
5425 #endif /* INET */
5427 #ifdef INET6
5428 void
5429 pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
5430 struct pf_state *s, struct pf_pdesc *pd)
5432 struct mbuf *m0;
5433 struct sockaddr_in6 dst;
5434 struct ip6_hdr *ip6;
5435 struct ifnet *ifp = NULL;
5436 struct pf_addr naddr;
5437 struct pf_src_node *sn = NULL;
5438 int error = 0;
5439 #ifdef __NetBSD__
5440 struct pf_mtag *pf_mtag;
5441 #endif /* __NetBSD__ */
5443 if (m == NULL || *m == NULL || r == NULL ||
5444 (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
5445 panic("pf_route6: invalid parameters");
5447 #ifdef __NetBSD__
5448 if ((pf_mtag = pf_get_mtag(*m)) == NULL) {
5449 m0 = *m;
5450 *m = NULL;
5451 goto bad;
5453 if (pf_mtag->routed++ > 3) {
5454 m0 = *m;
5455 *m = NULL;
5456 goto bad;
5458 #else
5459 if ((*m)->m_pkthdr.pf.routed++ > 3) {
5460 m0 = *m;
5461 *m = NULL;
5462 goto bad;
5464 #endif /* !__NetBSD__ */
5466 if (r->rt == PF_DUPTO) {
5467 if ((m0 = m_dup(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
5468 return;
5469 } else {
5470 if ((r->rt == PF_REPLYTO) == (r->direction == dir))
5471 return;
5472 m0 = *m;
5475 if (m0->m_len < sizeof(struct ip6_hdr)) {
5476 DPFPRINTF(PF_DEBUG_URGENT,
5477 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n"));
5478 goto bad;
5480 ip6 = mtod(m0, struct ip6_hdr *);
5482 dst.sin6_family = AF_INET6;
5483 dst.sin6_len = sizeof(dst);
5484 dst.sin6_addr = ip6->ip6_dst;
5486 /* Cheat. XXX why only in the v6 case??? */
5487 if (r->rt == PF_FASTROUTE) {
5488 #ifdef __NetBSD__
5489 pf_mtag->flags |= PF_TAG_GENERATED;
5490 #else
5491 m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
5492 #endif /* !__NetBSD__ */
5493 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
5494 return;
5497 if (TAILQ_EMPTY(&r->rpool.list)) {
5498 DPFPRINTF(PF_DEBUG_URGENT,
5499 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n"));
5500 goto bad;
5502 if (s == NULL) {
5503 pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
5504 &naddr, NULL, &sn);
5505 if (!PF_AZERO(&naddr, AF_INET6))
5506 PF_ACPY((struct pf_addr *)&dst.sin6_addr,
5507 &naddr, AF_INET6);
5508 ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
5509 } else {
5510 if (!PF_AZERO(&s->rt_addr, AF_INET6))
5511 PF_ACPY((struct pf_addr *)&dst.sin6_addr,
5512 &s->rt_addr, AF_INET6);
5513 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
5515 if (ifp == NULL)
5516 goto bad;
5518 if (oifp != ifp) {
5519 if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS)
5520 goto bad;
5521 else if (m0 == NULL)
5522 goto done;
5523 if (m0->m_len < sizeof(struct ip6_hdr)) {
5524 DPFPRINTF(PF_DEBUG_URGENT,
5525 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n"));
5526 goto bad;
5528 ip6 = mtod(m0, struct ip6_hdr *);
5532 * If the packet is too large for the outgoing interface,
5533 * send back an icmp6 error.
5535 if (IN6_IS_SCOPE_EMBEDDABLE(&dst.sin6_addr))
5536 dst.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
5537 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
5538 error = nd6_output(ifp, ifp, m0, &dst, NULL);
5539 } else {
5540 in6_ifstat_inc(ifp, ifs6_in_toobig);
5541 if (r->rt != PF_DUPTO)
5542 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
5543 else
5544 goto bad;
5547 done:
5548 if (r->rt != PF_DUPTO)
5549 *m = NULL;
5550 return;
5552 bad:
5553 m_freem(m0);
5554 goto done;
5556 #endif /* INET6 */
5560 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag
5561 * off is the offset where the protocol header starts
5562 * len is the total length of protocol header plus payload
5563 * returns 0 when the checksum is valid, otherwise returns 1.
5565 #ifdef __NetBSD__
5567 pf_check_proto_cksum(struct mbuf *m, int direction, int off, int len,
5568 u_int8_t p, sa_family_t af)
5569 #else
5571 pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,
5572 sa_family_t af)
5573 #endif /* !__NetBSD__ */
5575 #ifndef __NetBSD__
5576 u_int16_t flag_ok, flag_bad;
5577 #endif /* !__NetBSD__ */
5578 u_int16_t sum;
5580 #ifndef __NetBSD__
5581 switch (p) {
5582 case IPPROTO_TCP:
5583 flag_ok = M_TCP_CSUM_IN_OK;
5584 flag_bad = M_TCP_CSUM_IN_BAD;
5585 break;
5586 case IPPROTO_UDP:
5587 flag_ok = M_UDP_CSUM_IN_OK;
5588 flag_bad = M_UDP_CSUM_IN_BAD;
5589 break;
5590 case IPPROTO_ICMP:
5591 #ifdef INET6
5592 case IPPROTO_ICMPV6:
5593 #endif /* INET6 */
5594 flag_ok = flag_bad = 0;
5595 break;
5596 default:
5597 return (1);
5599 if (m->m_pkthdr.csum_flags & flag_ok)
5600 return (0);
5601 if (m->m_pkthdr.csum_flags & flag_bad)
5602 return (1);
5603 #endif /* !__NetBSD__ */
5604 if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
5605 return (1);
5606 if (m->m_pkthdr.len < off + len)
5607 return (1);
5608 #ifdef __NetBSD__
5609 if (direction == PF_IN) {
5610 switch (p) {
5611 case IPPROTO_TCP: {
5612 struct tcphdr th; /* XXX */
5613 int thlen;
5615 m_copydata(m, off, sizeof(th), &th); /* XXX */
5616 thlen = th.th_off << 2;
5617 return tcp_input_checksum(af, m, &th, off,
5618 thlen, len - thlen) != 0;
5621 case IPPROTO_UDP: {
5622 struct udphdr uh; /* XXX */
5624 m_copydata(m, off, sizeof(uh), &uh); /* XXX */
5625 return udp_input_checksum(af, m, &uh, off, len) != 0;
5629 #endif /* __NetBSD__ */
5630 switch (af) {
5631 #ifdef INET
5632 case AF_INET:
5633 if (p == IPPROTO_ICMP) {
5634 if (m->m_len < off)
5635 return (1);
5636 m->m_data += off;
5637 m->m_len -= off;
5638 sum = in_cksum(m, len);
5639 m->m_data -= off;
5640 m->m_len += off;
5641 } else {
5642 if (m->m_len < sizeof(struct ip))
5643 return (1);
5644 sum = in4_cksum(m, p, off, len);
5646 break;
5647 #endif /* INET */
5648 #ifdef INET6
5649 case AF_INET6:
5650 if (m->m_len < sizeof(struct ip6_hdr))
5651 return (1);
5652 sum = in6_cksum(m, p, off, len);
5653 break;
5654 #endif /* INET6 */
5655 default:
5656 return (1);
5658 if (sum) {
5659 #ifndef __NetBSD__
5660 m->m_pkthdr.csum_flags |= flag_bad;
5661 #endif /* !__NetBSD__ */
5662 switch (p) {
5663 case IPPROTO_TCP:
5664 tcp_statinc(TCP_STAT_RCVBADSUM);
5665 break;
5666 case IPPROTO_UDP:
5667 udp_statinc(UDP_STAT_BADSUM);
5668 break;
5669 case IPPROTO_ICMP:
5670 icmp_statinc(ICMP_STAT_CHECKSUM);
5671 break;
5672 #ifdef INET6
5673 case IPPROTO_ICMPV6:
5674 icmp6_statinc(ICMP6_STAT_CHECKSUM);
5675 break;
5676 #endif /* INET6 */
5678 return (1);
5680 #ifndef __NetBSD__
5681 m->m_pkthdr.csum_flags |= flag_ok;
5682 #endif /* !__NetBSD__ */
5683 return (0);
5686 #ifdef INET
5688 pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
5689 struct ether_header *eh)
5691 struct pfi_kif *kif;
5692 u_short action, reason = 0, log = 0;
5693 struct mbuf *m = *m0;
5694 struct ip *h = NULL;
5695 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
5696 struct pf_state *s = NULL;
5697 struct pf_state_key *sk = NULL;
5698 struct pf_ruleset *ruleset = NULL;
5699 struct pf_pdesc pd;
5700 int off, dirndx, pqid = 0;
5701 #ifdef __NetBSD__
5702 struct pf_mtag *pf_mtag = NULL; /* XXX gcc */
5703 #endif /* __NetBSD__ */
5705 if (!pf_status.running)
5706 return (PF_PASS);
5708 memset(&pd, 0, sizeof(pd));
5709 if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
5710 kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
5711 else
5712 kif = (struct pfi_kif *)ifp->if_pf_kif;
5714 if (kif == NULL) {
5715 DPFPRINTF(PF_DEBUG_URGENT,
5716 ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname));
5717 return (PF_DROP);
5719 if (kif->pfik_flags & PFI_IFLAG_SKIP)
5720 return (PF_PASS);
5722 #ifdef DIAGNOSTIC
5723 if ((m->m_flags & M_PKTHDR) == 0)
5724 panic("non-M_PKTHDR is passed to pf_test");
5725 #endif /* DIAGNOSTIC */
5727 if (m->m_pkthdr.len < (int)sizeof(*h)) {
5728 action = PF_DROP;
5729 REASON_SET(&reason, PFRES_SHORT);
5730 log = 1;
5731 goto done;
5734 #ifdef __NetBSD__
5735 if ((pf_mtag = pf_get_mtag(m)) == NULL) {
5736 DPFPRINTF(PF_DEBUG_URGENT,
5737 ("pf_test: pf_get_mtag returned NULL\n"));
5738 return (PF_DROP);
5740 if (pf_mtag->flags & PF_TAG_GENERATED)
5741 return (PF_PASS);
5742 #else
5743 if (m->m_pkthdr.pf.flags & PF_TAG_GENERATED)
5744 return (PF_PASS);
5745 #endif /* !__NetBSD__ */
5747 /* We do IP header normalization and packet reassembly here */
5748 if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) {
5749 action = PF_DROP;
5750 goto done;
5752 m = *m0; /* pf_normalize messes with m0 */
5753 h = mtod(m, struct ip *);
5755 off = h->ip_hl << 2;
5756 if (off < (int)sizeof(*h)) {
5757 action = PF_DROP;
5758 REASON_SET(&reason, PFRES_SHORT);
5759 log = 1;
5760 goto done;
5763 pd.src = (struct pf_addr *)&h->ip_src;
5764 pd.dst = (struct pf_addr *)&h->ip_dst;
5765 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET);
5766 pd.ip_sum = &h->ip_sum;
5767 pd.proto = h->ip_p;
5768 pd.af = AF_INET;
5769 pd.tos = h->ip_tos;
5770 pd.tot_len = ntohs(h->ip_len);
5771 pd.eh = eh;
5773 /* handle fragments that didn't get reassembled by normalization */
5774 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) {
5775 action = pf_test_fragment(&r, dir, kif, m, h,
5776 &pd, &a, &ruleset);
5777 goto done;
5780 switch (h->ip_p) {
5782 case IPPROTO_TCP: {
5783 struct tcphdr th;
5785 pd.hdr.tcp = &th;
5786 if (!pf_pull_hdr(m, off, &th, sizeof(th),
5787 &action, &reason, AF_INET)) {
5788 log = action != PF_PASS;
5789 goto done;
5791 pd.p_len = pd.tot_len - off - (th.th_off << 2);
5792 if ((th.th_flags & TH_ACK) && pd.p_len == 0)
5793 pqid = 1;
5794 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
5795 if (action == PF_DROP)
5796 goto done;
5797 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
5798 &reason);
5799 if (action == PF_PASS) {
5800 #if NPFSYNC
5801 pfsync_update_state(s);
5802 #endif /* NPFSYNC */
5803 r = s->rule.ptr;
5804 a = s->anchor.ptr;
5805 log = s->log;
5806 } else if (s == NULL)
5807 action = pf_test_rule(&r, &s, dir, kif,
5808 m, off, h, &pd, &a, &ruleset, &ipintrq);
5809 break;
5812 case IPPROTO_UDP: {
5813 struct udphdr uh;
5815 pd.hdr.udp = &uh;
5816 if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
5817 &action, &reason, AF_INET)) {
5818 log = action != PF_PASS;
5819 goto done;
5821 if (uh.uh_dport == 0 ||
5822 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
5823 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
5824 action = PF_DROP;
5825 REASON_SET(&reason, PFRES_SHORT);
5826 goto done;
5828 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
5829 if (action == PF_PASS) {
5830 #if NPFSYNC
5831 pfsync_update_state(s);
5832 #endif /* NPFSYNC */
5833 r = s->rule.ptr;
5834 a = s->anchor.ptr;
5835 log = s->log;
5836 } else if (s == NULL)
5837 action = pf_test_rule(&r, &s, dir, kif,
5838 m, off, h, &pd, &a, &ruleset, &ipintrq);
5839 break;
5842 case IPPROTO_ICMP: {
5843 struct icmp ih;
5845 pd.hdr.icmp = &ih;
5846 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN,
5847 &action, &reason, AF_INET)) {
5848 log = action != PF_PASS;
5849 goto done;
5851 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd,
5852 &reason);
5853 if (action == PF_PASS) {
5854 #if NPFSYNC
5855 pfsync_update_state(s);
5856 #endif /* NPFSYNC */
5857 r = s->rule.ptr;
5858 a = s->anchor.ptr;
5859 log = s->log;
5860 } else if (s == NULL)
5861 action = pf_test_rule(&r, &s, dir, kif,
5862 m, off, h, &pd, &a, &ruleset, &ipintrq);
5863 break;
5866 #ifdef INET6
5867 case IPPROTO_ICMPV6: {
5868 action = PF_DROP;
5869 DPFPRINTF(PF_DEBUG_MISC,
5870 ("pf: dropping IPv4 packet with ICMPv6 payload\n"));
5871 goto done;
5873 #endif
5875 default:
5876 action = pf_test_state_other(&s, dir, kif, &pd);
5877 if (action == PF_PASS) {
5878 #if NPFSYNC
5879 pfsync_update_state(s);
5880 #endif /* NPFSYNC */
5881 r = s->rule.ptr;
5882 a = s->anchor.ptr;
5883 log = s->log;
5884 } else if (s == NULL)
5885 action = pf_test_rule(&r, &s, dir, kif, m, off, h,
5886 &pd, &a, &ruleset, &ipintrq);
5887 break;
5890 done:
5891 if (action == PF_PASS && h->ip_hl > 5 &&
5892 !((s && s->allow_opts) || r->allow_opts)) {
5893 action = PF_DROP;
5894 REASON_SET(&reason, PFRES_IPOPTIONS);
5895 log = 1;
5896 DPFPRINTF(PF_DEBUG_MISC,
5897 ("pf: dropping packet with ip options\n"));
5900 if ((s && s->tag) || r->rtableid)
5901 pf_tag_packet(m, s ? s->tag : 0, r->rtableid);
5903 #ifdef ALTQ
5904 if (action == PF_PASS && r->qid) {
5905 #ifdef __NetBSD__
5906 struct m_tag *mtag;
5907 struct altq_tag *atag;
5909 mtag = m_tag_get(PACKET_TAG_ALTQ_QID, sizeof(*atag), M_NOWAIT);
5910 if (mtag != NULL) {
5911 atag = (struct altq_tag *)(mtag + 1);
5912 if (pqid || (pd.tos & IPTOS_LOWDELAY))
5913 atag->qid = r->pqid;
5914 else
5915 atag->qid = r->qid;
5916 /* add hints for ecn */
5917 atag->af = AF_INET;
5918 atag->hdr = h;
5919 m_tag_prepend(m, mtag);
5921 #else
5922 if (pqid || (pd.tos & IPTOS_LOWDELAY))
5923 m->m_pkthdr.pf.qid = r->pqid;
5924 else
5925 m->m_pkthdr.pf.qid = r->qid;
5926 /* add hints for ecn */
5927 m->m_pkthdr.pf.hdr = h;
5928 #endif /* !__NetBSD__ */
5930 #endif /* ALTQ */
5933 * connections redirected to loopback should not match sockets
5934 * bound specifically to loopback due to security implications,
5935 * see tcp_input() and in_pcblookup_listen().
5937 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
5938 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
5939 (s->nat_rule.ptr->action == PF_RDR ||
5940 s->nat_rule.ptr->action == PF_BINAT) &&
5941 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
5942 #ifdef __NetBSD__
5943 pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST;
5944 #else
5945 m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST;
5946 #endif /* !__NetBSD__ */
5948 if (log) {
5949 struct pf_rule *lr;
5951 if (s != NULL && s->nat_rule.ptr != NULL &&
5952 s->nat_rule.ptr->log & PF_LOG_ALL)
5953 lr = s->nat_rule.ptr;
5954 else
5955 lr = r;
5956 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, lr, a, ruleset,
5957 &pd);
5960 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
5961 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++;
5963 if (action == PF_PASS || r->action == PF_DROP) {
5964 dirndx = (dir == PF_OUT);
5965 r->packets[dirndx]++;
5966 r->bytes[dirndx] += pd.tot_len;
5967 if (a != NULL) {
5968 a->packets[dirndx]++;
5969 a->bytes[dirndx] += pd.tot_len;
5971 if (s != NULL) {
5972 sk = s->state_key;
5973 if (s->nat_rule.ptr != NULL) {
5974 s->nat_rule.ptr->packets[dirndx]++;
5975 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
5977 if (s->src_node != NULL) {
5978 s->src_node->packets[dirndx]++;
5979 s->src_node->bytes[dirndx] += pd.tot_len;
5981 if (s->nat_src_node != NULL) {
5982 s->nat_src_node->packets[dirndx]++;
5983 s->nat_src_node->bytes[dirndx] += pd.tot_len;
5985 dirndx = (dir == sk->direction) ? 0 : 1;
5986 s->packets[dirndx]++;
5987 s->bytes[dirndx] += pd.tot_len;
5989 tr = r;
5990 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
5991 if (nr != NULL) {
5992 struct pf_addr *x;
5994 * XXX: we need to make sure that the addresses
5995 * passed to pfr_update_stats() are the same than
5996 * the addresses used during matching (pfr_match)
5998 if (r == &pf_default_rule) {
5999 tr = nr;
6000 x = (sk == NULL || sk->direction == dir) ?
6001 &pd.baddr : &pd.naddr;
6002 } else
6003 x = (sk == NULL || sk->direction == dir) ?
6004 &pd.naddr : &pd.baddr;
6005 if (x == &pd.baddr || s == NULL) {
6006 /* we need to change the address */
6007 if (dir == PF_OUT)
6008 pd.src = x;
6009 else
6010 pd.dst = x;
6013 if (tr->src.addr.type == PF_ADDR_TABLE)
6014 pfr_update_stats(tr->src.addr.p.tbl, (sk == NULL ||
6015 sk->direction == dir) ?
6016 pd.src : pd.dst, pd.af,
6017 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
6018 tr->src.neg);
6019 if (tr->dst.addr.type == PF_ADDR_TABLE)
6020 pfr_update_stats(tr->dst.addr.p.tbl, (sk == NULL ||
6021 sk->direction == dir) ? pd.dst : pd.src, pd.af,
6022 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
6023 tr->dst.neg);
6027 if (action == PF_SYNPROXY_DROP) {
6028 m_freem(*m0);
6029 *m0 = NULL;
6030 action = PF_PASS;
6031 } else if (r->rt)
6032 /* pf_route can free the mbuf causing *m0 to become NULL */
6033 pf_route(m0, r, dir, kif->pfik_ifp, s, &pd);
6035 return (action);
6037 #endif /* INET */
6039 #ifdef INET6
6041 pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
6042 struct ether_header *eh)
6044 struct pfi_kif *kif;
6045 u_short action, reason = 0, log = 0;
6046 struct mbuf *m = *m0, *n = NULL;
6047 struct ip6_hdr *h = NULL; /* XXX gcc */
6048 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
6049 struct pf_state *s = NULL;
6050 struct pf_state_key *sk = NULL;
6051 struct pf_ruleset *ruleset = NULL;
6052 struct pf_pdesc pd;
6053 int off, terminal = 0, dirndx, rh_cnt = 0;
6054 #ifdef __NetBSD__
6055 struct pf_mtag *pf_mtag = NULL; /* XXX gcc */
6056 #endif /* __NetBSD__ */
6058 if (!pf_status.running)
6059 return (PF_PASS);
6061 memset(&pd, 0, sizeof(pd));
6062 if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
6063 kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
6064 else
6065 kif = (struct pfi_kif *)ifp->if_pf_kif;
6067 if (kif == NULL) {
6068 DPFPRINTF(PF_DEBUG_URGENT,
6069 ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname));
6070 return (PF_DROP);
6072 if (kif->pfik_flags & PFI_IFLAG_SKIP)
6073 return (PF_PASS);
6075 #ifdef DIAGNOSTIC
6076 if ((m->m_flags & M_PKTHDR) == 0)
6077 panic("non-M_PKTHDR is passed to pf_test6");
6078 #endif /* DIAGNOSTIC */
6080 if (m->m_pkthdr.len < (int)sizeof(*h)) {
6081 action = PF_DROP;
6082 REASON_SET(&reason, PFRES_SHORT);
6083 log = 1;
6084 goto done;
6087 #ifdef __NetBSD__
6088 if ((pf_mtag = pf_get_mtag(m)) == NULL) {
6089 DPFPRINTF(PF_DEBUG_URGENT,
6090 ("pf_test6: pf_get_mtag returned NULL\n"));
6091 return (PF_DROP);
6093 if (pf_mtag->flags & PF_TAG_GENERATED)
6094 return (PF_PASS);
6095 #else
6096 if (m->m_pkthdr.pf.flags & PF_TAG_GENERATED)
6097 return (PF_PASS);
6098 #endif /* !__NetBSD__ */
6100 /* We do IP header normalization and packet reassembly here */
6101 if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) {
6102 action = PF_DROP;
6103 goto done;
6105 m = *m0; /* pf_normalize messes with m0 */
6106 h = mtod(m, struct ip6_hdr *);
6108 #if 1
6110 * we do not support jumbogram yet. if we keep going, zero ip6_plen
6111 * will do something bad, so drop the packet for now.
6113 if (htons(h->ip6_plen) == 0) {
6114 action = PF_DROP;
6115 REASON_SET(&reason, PFRES_NORM); /*XXX*/
6116 goto done;
6118 #endif
6120 pd.src = (struct pf_addr *)&h->ip6_src;
6121 pd.dst = (struct pf_addr *)&h->ip6_dst;
6122 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET6);
6123 pd.ip_sum = NULL;
6124 pd.af = AF_INET6;
6125 pd.tos = 0;
6126 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
6127 pd.eh = eh;
6129 off = ((char *)h - m->m_data) + sizeof(struct ip6_hdr);
6130 pd.proto = h->ip6_nxt;
6131 do {
6132 switch (pd.proto) {
6133 case IPPROTO_FRAGMENT:
6134 action = pf_test_fragment(&r, dir, kif, m, h,
6135 &pd, &a, &ruleset);
6136 if (action == PF_DROP)
6137 REASON_SET(&reason, PFRES_FRAG);
6138 goto done;
6139 case IPPROTO_ROUTING: {
6140 struct ip6_rthdr rthdr;
6142 if (rh_cnt++) {
6143 DPFPRINTF(PF_DEBUG_MISC,
6144 ("pf: IPv6 more than one rthdr\n"));
6145 action = PF_DROP;
6146 REASON_SET(&reason, PFRES_IPOPTIONS);
6147 log = 1;
6148 goto done;
6150 if (!pf_pull_hdr(m, off, &rthdr, sizeof(rthdr), NULL,
6151 &reason, pd.af)) {
6152 DPFPRINTF(PF_DEBUG_MISC,
6153 ("pf: IPv6 short rthdr\n"));
6154 action = PF_DROP;
6155 REASON_SET(&reason, PFRES_SHORT);
6156 log = 1;
6157 goto done;
6159 if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) {
6160 DPFPRINTF(PF_DEBUG_MISC,
6161 ("pf: IPv6 rthdr0\n"));
6162 action = PF_DROP;
6163 REASON_SET(&reason, PFRES_IPOPTIONS);
6164 log = 1;
6165 goto done;
6167 /* FALLTHROUGH */
6169 case IPPROTO_AH:
6170 case IPPROTO_HOPOPTS:
6171 case IPPROTO_DSTOPTS: {
6172 /* get next header and header length */
6173 struct ip6_ext opt6;
6175 if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6),
6176 NULL, &reason, pd.af)) {
6177 DPFPRINTF(PF_DEBUG_MISC,
6178 ("pf: IPv6 short opt\n"));
6179 action = PF_DROP;
6180 log = 1;
6181 goto done;
6183 if (pd.proto == IPPROTO_AH)
6184 off += (opt6.ip6e_len + 2) * 4;
6185 else
6186 off += (opt6.ip6e_len + 1) * 8;
6187 pd.proto = opt6.ip6e_nxt;
6188 /* goto the next header */
6189 break;
6191 default:
6192 terminal++;
6193 break;
6195 } while (!terminal);
6197 /* if there's no routing header, use unmodified mbuf for checksumming */
6198 if (!n)
6199 n = m;
6201 switch (pd.proto) {
6203 case IPPROTO_TCP: {
6204 struct tcphdr th;
6206 pd.hdr.tcp = &th;
6207 if (!pf_pull_hdr(m, off, &th, sizeof(th),
6208 &action, &reason, AF_INET6)) {
6209 log = action != PF_PASS;
6210 goto done;
6212 pd.p_len = pd.tot_len - off - (th.th_off << 2);
6213 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
6214 if (action == PF_DROP)
6215 goto done;
6216 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
6217 &reason);
6218 if (action == PF_PASS) {
6219 #if NPFSYNC
6220 pfsync_update_state(s);
6221 #endif /* NPFSYNC */
6222 r = s->rule.ptr;
6223 a = s->anchor.ptr;
6224 log = s->log;
6225 } else if (s == NULL)
6226 action = pf_test_rule(&r, &s, dir, kif,
6227 m, off, h, &pd, &a, &ruleset, &ip6intrq);
6228 break;
6231 case IPPROTO_UDP: {
6232 struct udphdr uh;
6234 pd.hdr.udp = &uh;
6235 if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
6236 &action, &reason, AF_INET6)) {
6237 log = action != PF_PASS;
6238 goto done;
6240 if (uh.uh_dport == 0 ||
6241 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
6242 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
6243 action = PF_DROP;
6244 REASON_SET(&reason, PFRES_SHORT);
6245 goto done;
6247 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
6248 if (action == PF_PASS) {
6249 #if NPFSYNC
6250 pfsync_update_state(s);
6251 #endif /* NPFSYNC */
6252 r = s->rule.ptr;
6253 a = s->anchor.ptr;
6254 log = s->log;
6255 } else if (s == NULL)
6256 action = pf_test_rule(&r, &s, dir, kif,
6257 m, off, h, &pd, &a, &ruleset, &ip6intrq);
6258 break;
6261 #ifdef INET
6262 case IPPROTO_ICMP: {
6263 action = PF_DROP;
6264 DPFPRINTF(PF_DEBUG_MISC,
6265 ("pf: dropping IPv6 packet with ICMPv4 payload\n"));
6266 goto done;
6268 #endif
6270 case IPPROTO_ICMPV6: {
6271 struct icmp6_hdr ih;
6273 pd.hdr.icmp6 = &ih;
6274 if (!pf_pull_hdr(m, off, &ih, sizeof(ih),
6275 &action, &reason, AF_INET6)) {
6276 log = action != PF_PASS;
6277 goto done;
6279 action = pf_test_state_icmp(&s, dir, kif,
6280 m, off, h, &pd, &reason);
6281 if (action == PF_PASS) {
6282 #if NPFSYNC
6283 pfsync_update_state(s);
6284 #endif /* NPFSYNC */
6285 r = s->rule.ptr;
6286 a = s->anchor.ptr;
6287 log = s->log;
6288 } else if (s == NULL)
6289 action = pf_test_rule(&r, &s, dir, kif,
6290 m, off, h, &pd, &a, &ruleset, &ip6intrq);
6291 break;
6294 default:
6295 action = pf_test_state_other(&s, dir, kif, &pd);
6296 if (action == PF_PASS) {
6297 #if NPFSYNC
6298 pfsync_update_state(s);
6299 #endif /* NPFSYNC */
6300 r = s->rule.ptr;
6301 a = s->anchor.ptr;
6302 log = s->log;
6303 } else if (s == NULL)
6304 action = pf_test_rule(&r, &s, dir, kif, m, off, h,
6305 &pd, &a, &ruleset, &ip6intrq);
6306 break;
6309 done:
6310 if (n != m) {
6311 m_freem(n);
6312 n = NULL;
6315 /* handle dangerous IPv6 extension headers. */
6316 if (action == PF_PASS && rh_cnt &&
6317 !((s && s->allow_opts) || r->allow_opts)) {
6318 action = PF_DROP;
6319 REASON_SET(&reason, PFRES_IPOPTIONS);
6320 log = 1;
6321 DPFPRINTF(PF_DEBUG_MISC,
6322 ("pf: dropping packet with dangerous v6 headers\n"));
6325 if ((s && s->tag) || r->rtableid)
6326 pf_tag_packet(m, s ? s->tag : 0, r->rtableid);
6328 #ifdef ALTQ
6329 if (action == PF_PASS && r->qid) {
6330 #ifdef __NetBSD__
6331 struct m_tag *mtag;
6332 struct altq_tag *atag;
6334 mtag = m_tag_get(PACKET_TAG_ALTQ_QID, sizeof(*atag), M_NOWAIT);
6335 if (mtag != NULL) {
6336 atag = (struct altq_tag *)(mtag + 1);
6337 if (pd.tos & IPTOS_LOWDELAY)
6338 atag->qid = r->pqid;
6339 else
6340 atag->qid = r->qid;
6341 /* add hints for ecn */
6342 atag->af = AF_INET6;
6343 atag->hdr = h;
6344 m_tag_prepend(m, mtag);
6346 #else
6347 if (pd.tos & IPTOS_LOWDELAY)
6348 m->m_pkthdr.pf.qid = r->pqid;
6349 else
6350 m->m_pkthdr.pf.qid = r->qid;
6351 /* add hints for ecn */
6352 m->m_pkthdr.pf.hdr = h;
6353 #endif /* !__NetBSD__ */
6355 #endif /* ALTQ */
6357 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
6358 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
6359 (s->nat_rule.ptr->action == PF_RDR ||
6360 s->nat_rule.ptr->action == PF_BINAT) &&
6361 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6))
6362 #ifdef __NetBSD__
6363 pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST;
6364 #else
6365 m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST;
6366 #endif /* !__NetBSD__ */
6368 if (log) {
6369 struct pf_rule *lr;
6371 if (s != NULL && s->nat_rule.ptr != NULL &&
6372 s->nat_rule.ptr->log & PF_LOG_ALL)
6373 lr = s->nat_rule.ptr;
6374 else
6375 lr = r;
6376 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, lr, a, ruleset,
6377 &pd);
6380 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
6381 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++;
6383 if (action == PF_PASS || r->action == PF_DROP) {
6384 dirndx = (dir == PF_OUT);
6385 r->packets[dirndx]++;
6386 r->bytes[dirndx] += pd.tot_len;
6387 if (a != NULL) {
6388 a->packets[dirndx]++;
6389 a->bytes[dirndx] += pd.tot_len;
6391 if (s != NULL) {
6392 sk = s->state_key;
6393 if (s->nat_rule.ptr != NULL) {
6394 s->nat_rule.ptr->packets[dirndx]++;
6395 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
6397 if (s->src_node != NULL) {
6398 s->src_node->packets[dirndx]++;
6399 s->src_node->bytes[dirndx] += pd.tot_len;
6401 if (s->nat_src_node != NULL) {
6402 s->nat_src_node->packets[dirndx]++;
6403 s->nat_src_node->bytes[dirndx] += pd.tot_len;
6405 dirndx = (dir == sk->direction) ? 0 : 1;
6406 s->packets[dirndx]++;
6407 s->bytes[dirndx] += pd.tot_len;
6409 tr = r;
6410 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
6411 if (nr != NULL) {
6412 struct pf_addr *x;
6414 * XXX: we need to make sure that the addresses
6415 * passed to pfr_update_stats() are the same than
6416 * the addresses used during matching (pfr_match)
6418 if (r == &pf_default_rule) {
6419 tr = nr;
6420 x = (s == NULL || sk->direction == dir) ?
6421 &pd.baddr : &pd.naddr;
6422 } else {
6423 x = (s == NULL || sk->direction == dir) ?
6424 &pd.naddr : &pd.baddr;
6426 if (x == &pd.baddr || s == NULL) {
6427 if (dir == PF_OUT)
6428 pd.src = x;
6429 else
6430 pd.dst = x;
6433 if (tr->src.addr.type == PF_ADDR_TABLE)
6434 pfr_update_stats(tr->src.addr.p.tbl, (sk == NULL ||
6435 sk->direction == dir) ? pd.src : pd.dst, pd.af,
6436 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
6437 tr->src.neg);
6438 if (tr->dst.addr.type == PF_ADDR_TABLE)
6439 pfr_update_stats(tr->dst.addr.p.tbl, (sk == NULL ||
6440 sk->direction == dir) ? pd.dst : pd.src, pd.af,
6441 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
6442 tr->dst.neg);
6446 if (action == PF_SYNPROXY_DROP) {
6447 m_freem(*m0);
6448 *m0 = NULL;
6449 action = PF_PASS;
6450 } else if (r->rt)
6451 /* pf_route6 can free the mbuf causing *m0 to become NULL */
6452 pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd);
6454 return (action);
6456 #endif /* INET6 */
6459 pf_check_congestion(struct ifqueue *ifq)
6461 #ifdef __NetBSD__
6462 return (0);
6463 #else
6464 if (ifq->ifq_congestion)
6465 return (1);
6466 else
6467 return (0);
6468 #endif /* !__NetBSD__ */