pf.c (169843) | pf.c (171168) |
---|---|
1/* $FreeBSD: head/sys/contrib/pf/net/pf.c 169843 2007-05-21 20:08:59Z dhartmei $ */ 2/* $OpenBSD: pf.c,v 1.483 2005/03/15 17:38:43 dhartmei Exp $ */ | 1/* $OpenBSD: pf.c,v 1.527 2007/02/22 15:23:23 pyr Exp $ */ |
3 4/* 5 * Copyright (c) 2001 Daniel Hartmeier 6 * Copyright (c) 2002,2003 Henning Brauer 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions --- 23 unchanged lines hidden (view full) --- 34 * Agency (DARPA) and Air Force Research Laboratory, Air Force 35 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 36 * 37 */ 38 39#ifdef __FreeBSD__ 40#include "opt_inet.h" 41#include "opt_inet6.h" | 2 3/* 4 * Copyright (c) 2001 Daniel Hartmeier 5 * Copyright (c) 2002,2003 Henning Brauer 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 23 unchanged lines hidden (view full) --- 33 * Agency (DARPA) and Air Force Research Laboratory, Air Force 34 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 35 * 36 */ 37 38#ifdef __FreeBSD__ 39#include "opt_inet.h" 40#include "opt_inet6.h" |
41 42#include <sys/cdefs.h> 43__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf.c 171168 2007-07-03 12:16:07Z mlaier $"); |
|
42#endif 43 44#ifdef __FreeBSD__ 45#include "opt_mac.h" 46#include "opt_bpf.h" 47#include "opt_pf.h" 48 49#ifdef DEV_BPF --- 29 unchanged lines hidden (view full) --- 79#include <sys/kernel.h> 80#include <sys/time.h> 81#ifdef __FreeBSD__ 82#include <sys/sysctl.h> 83#include <sys/endian.h> 84#else 85#include <sys/pool.h> 86#endif | 44#endif 45 46#ifdef __FreeBSD__ 47#include "opt_mac.h" 48#include "opt_bpf.h" 49#include "opt_pf.h" 50 51#ifdef DEV_BPF --- 29 unchanged lines hidden (view full) --- 81#include <sys/kernel.h> 82#include <sys/time.h> 83#ifdef __FreeBSD__ 84#include <sys/sysctl.h> 85#include <sys/endian.h> 86#else 87#include <sys/pool.h> 88#endif |
89#include <sys/proc.h> 90#ifdef __FreeBSD__ 91#include <sys/kthread.h> 92#include <sys/lock.h> 93#include <sys/sx.h> 94#else 95#include <sys/rwlock.h> 96#endif |
|
87 88#include <net/if.h> 89#include <net/if_types.h> 90#include <net/bpf.h> 91#include <net/route.h> | 97 98#include <net/if.h> 99#include <net/if_types.h> 100#include <net/bpf.h> 101#include <net/route.h> |
102#ifndef __FreeBSD__ 103#include <net/radix_mpath.h> 104#endif |
|
92 93#include <netinet/in.h> 94#include <netinet/in_var.h> 95#include <netinet/in_systm.h> 96#include <netinet/ip.h> 97#include <netinet/ip_var.h> 98#include <netinet/tcp.h> 99#include <netinet/tcp_seq.h> --- 29 unchanged lines hidden (view full) --- 129 130#ifdef __FreeBSD__ 131#include <machine/in_cksum.h> 132#include <sys/limits.h> 133#include <sys/ucred.h> 134#include <security/mac/mac_framework.h> 135 136extern int ip_optcopy(struct ip *, struct ip *); | 105 106#include <netinet/in.h> 107#include <netinet/in_var.h> 108#include <netinet/in_systm.h> 109#include <netinet/ip.h> 110#include <netinet/ip_var.h> 111#include <netinet/tcp.h> 112#include <netinet/tcp_seq.h> --- 29 unchanged lines hidden (view full) --- 142 143#ifdef __FreeBSD__ 144#include <machine/in_cksum.h> 145#include <sys/limits.h> 146#include <sys/ucred.h> 147#include <security/mac/mac_framework.h> 148 149extern int ip_optcopy(struct ip *, struct ip *); |
150extern int debug_pfugidhack; |
|
137#endif 138 139#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x 140 141/* 142 * Global variables 143 */ 144 | 151#endif 152 153#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x 154 155/* 156 * Global variables 157 */ 158 |
145struct pf_anchor_global pf_anchors; 146struct pf_ruleset pf_main_ruleset; | |
147struct pf_altqqueue pf_altqs[2]; 148struct pf_palist pf_pabuf; 149struct pf_altqqueue *pf_altqs_active; 150struct pf_altqqueue *pf_altqs_inactive; 151struct pf_status pf_status; 152 153u_int32_t ticket_altqs_active; 154u_int32_t ticket_altqs_inactive; 155int altqs_inactive_open; 156u_int32_t ticket_pabuf; 157 | 159struct pf_altqqueue pf_altqs[2]; 160struct pf_palist pf_pabuf; 161struct pf_altqqueue *pf_altqs_active; 162struct pf_altqqueue *pf_altqs_inactive; 163struct pf_status pf_status; 164 165u_int32_t ticket_altqs_active; 166u_int32_t ticket_altqs_inactive; 167int altqs_inactive_open; 168u_int32_t ticket_pabuf; 169 |
158#ifdef __FreeBSD__ 159struct callout pf_expire_to; /* expire timeout */ 160#else 161struct timeout pf_expire_to; /* expire timeout */ 162#endif 163 | |
164struct pf_anchor_stackframe { 165 struct pf_ruleset *rs; 166 struct pf_rule *r; 167 struct pf_anchor_node *parent; 168 struct pf_anchor *child; 169} pf_anchor_stack[64]; 170 171#ifdef __FreeBSD__ --- 9 unchanged lines hidden (view full) --- 181void pf_init_threshold(struct pf_threshold *, u_int32_t, 182 u_int32_t); 183void pf_add_threshold(struct pf_threshold *); 184int pf_check_threshold(struct pf_threshold *); 185 186void pf_change_ap(struct pf_addr *, u_int16_t *, 187 u_int16_t *, u_int16_t *, struct pf_addr *, 188 u_int16_t, u_int8_t, sa_family_t); | 170struct pf_anchor_stackframe { 171 struct pf_ruleset *rs; 172 struct pf_rule *r; 173 struct pf_anchor_node *parent; 174 struct pf_anchor *child; 175} pf_anchor_stack[64]; 176 177#ifdef __FreeBSD__ --- 9 unchanged lines hidden (view full) --- 187void pf_init_threshold(struct pf_threshold *, u_int32_t, 188 u_int32_t); 189void pf_add_threshold(struct pf_threshold *); 190int pf_check_threshold(struct pf_threshold *); 191 192void pf_change_ap(struct pf_addr *, u_int16_t *, 193 u_int16_t *, u_int16_t *, struct pf_addr *, 194 u_int16_t, u_int8_t, sa_family_t); |
195int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *, 196 struct tcphdr *, struct pf_state_peer *); |
|
189#ifdef INET6 190void pf_change_a6(struct pf_addr *, u_int16_t *, 191 struct pf_addr *, u_int8_t); 192#endif /* INET6 */ 193void pf_change_icmp(struct pf_addr *, u_int16_t *, 194 struct pf_addr *, struct pf_addr *, u_int16_t, 195 u_int16_t *, u_int16_t *, u_int16_t *, 196 u_int16_t *, u_int8_t, sa_family_t); 197#ifdef __FreeBSD__ 198void pf_send_tcp(struct mbuf *, 199 const struct pf_rule *, sa_family_t, 200#else 201void pf_send_tcp(const struct pf_rule *, sa_family_t, 202#endif 203 const struct pf_addr *, const struct pf_addr *, 204 u_int16_t, u_int16_t, u_int32_t, u_int32_t, 205 u_int8_t, u_int16_t, u_int16_t, u_int8_t, int, | 197#ifdef INET6 198void pf_change_a6(struct pf_addr *, u_int16_t *, 199 struct pf_addr *, u_int8_t); 200#endif /* INET6 */ 201void pf_change_icmp(struct pf_addr *, u_int16_t *, 202 struct pf_addr *, struct pf_addr *, u_int16_t, 203 u_int16_t *, u_int16_t *, u_int16_t *, 204 u_int16_t *, u_int8_t, sa_family_t); 205#ifdef __FreeBSD__ 206void pf_send_tcp(struct mbuf *, 207 const struct pf_rule *, sa_family_t, 208#else 209void pf_send_tcp(const struct pf_rule *, sa_family_t, 210#endif 211 const struct pf_addr *, const struct pf_addr *, 212 u_int16_t, u_int16_t, u_int32_t, u_int32_t, 213 u_int8_t, u_int16_t, u_int16_t, u_int8_t, int, |
206 struct ether_header *, struct ifnet *); | 214 u_int16_t, struct ether_header *, struct ifnet *); |
207void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t, 208 sa_family_t, struct pf_rule *); 209struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *, 210 int, int, struct pfi_kif *, 211 struct pf_addr *, u_int16_t, struct pf_addr *, 212 u_int16_t, int); 213struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *, 214 int, int, struct pfi_kif *, struct pf_src_node **, --- 36 unchanged lines hidden (view full) --- 251int pf_test_state_udp(struct pf_state **, int, 252 struct pfi_kif *, struct mbuf *, int, 253 void *, struct pf_pdesc *); 254int pf_test_state_icmp(struct pf_state **, int, 255 struct pfi_kif *, struct mbuf *, int, 256 void *, struct pf_pdesc *, u_short *); 257int pf_test_state_other(struct pf_state **, int, 258 struct pfi_kif *, struct pf_pdesc *); | 215void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t, 216 sa_family_t, struct pf_rule *); 217struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *, 218 int, int, struct pfi_kif *, 219 struct pf_addr *, u_int16_t, struct pf_addr *, 220 u_int16_t, int); 221struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *, 222 int, int, struct pfi_kif *, struct pf_src_node **, --- 36 unchanged lines hidden (view full) --- 259int pf_test_state_udp(struct pf_state **, int, 260 struct pfi_kif *, struct mbuf *, int, 261 void *, struct pf_pdesc *); 262int pf_test_state_icmp(struct pf_state **, int, 263 struct pfi_kif *, struct mbuf *, int, 264 void *, struct pf_pdesc *, u_short *); 265int pf_test_state_other(struct pf_state **, int, 266 struct pfi_kif *, struct pf_pdesc *); |
259struct pf_tag *pf_get_tag(struct mbuf *); | |
260int pf_match_tag(struct mbuf *, struct pf_rule *, | 267int pf_match_tag(struct mbuf *, struct pf_rule *, |
261 struct pf_tag **, int *); | 268 struct pf_mtag *, int *); 269int pf_step_out_of_anchor(int *, struct pf_ruleset **, 270 int, struct pf_rule **, struct pf_rule **, 271 int *); |
262void pf_hash(struct pf_addr *, struct pf_addr *, 263 struct pf_poolhashkey *, sa_family_t); 264int pf_map_addr(u_int8_t, struct pf_rule *, 265 struct pf_addr *, struct pf_addr *, 266 struct pf_addr *, struct pf_src_node **); 267int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *, 268 struct pf_addr *, struct pf_addr *, u_int16_t, 269 struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t, 270 struct pf_src_node **); 271void pf_route(struct mbuf **, struct pf_rule *, int, | 272void pf_hash(struct pf_addr *, struct pf_addr *, 273 struct pf_poolhashkey *, sa_family_t); 274int pf_map_addr(u_int8_t, struct pf_rule *, 275 struct pf_addr *, struct pf_addr *, 276 struct pf_addr *, struct pf_src_node **); 277int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *, 278 struct pf_addr *, struct pf_addr *, u_int16_t, 279 struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t, 280 struct pf_src_node **); 281void pf_route(struct mbuf **, struct pf_rule *, int, |
272 struct ifnet *, struct pf_state *); | 282 struct ifnet *, struct pf_state *, 283 struct pf_pdesc *); |
273void pf_route6(struct mbuf **, struct pf_rule *, int, | 284void pf_route6(struct mbuf **, struct pf_rule *, int, |
274 struct ifnet *, struct pf_state *); | 285 struct ifnet *, struct pf_state *, 286 struct pf_pdesc *); |
275#ifdef __FreeBSD__ | 287#ifdef __FreeBSD__ |
276int pf_socket_lookup(uid_t *, gid_t *, 277 int, struct pf_pdesc *, struct inpcb *); | 288/* XXX: import */ |
278#else | 289#else |
279int pf_socket_lookup(uid_t *, gid_t *, 280 int, struct pf_pdesc *); | 290int pf_socket_lookup(int, struct pf_pdesc *); |
281#endif 282u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t, 283 sa_family_t); 284u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t, 285 sa_family_t); 286u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, 287 u_int16_t); 288void pf_set_rt_ifp(struct pf_state *, 289 struct pf_addr *); 290int pf_check_proto_cksum(struct mbuf *, int, int, 291 u_int8_t, sa_family_t); 292int pf_addr_wrap_neq(struct pf_addr_wrap *, 293 struct pf_addr_wrap *); | 291#endif 292u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t, 293 sa_family_t); 294u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t, 295 sa_family_t); 296u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, 297 u_int16_t); 298void pf_set_rt_ifp(struct pf_state *, 299 struct pf_addr *); 300int pf_check_proto_cksum(struct mbuf *, int, int, 301 u_int8_t, sa_family_t); 302int pf_addr_wrap_neq(struct pf_addr_wrap *, 303 struct pf_addr_wrap *); |
294static int pf_add_mbuf_tag(struct mbuf *, u_int); | |
295struct pf_state *pf_find_state_recurse(struct pfi_kif *, | 304struct pf_state *pf_find_state_recurse(struct pfi_kif *, |
296 struct pf_state *, u_int8_t); | 305 struct pf_state_cmp *, u_int8_t); |
297int pf_src_connlimit(struct pf_state **); 298int pf_check_congestion(struct ifqueue *); 299 300#ifdef __FreeBSD__ 301int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len); 302 | 306int pf_src_connlimit(struct pf_state **); 307int pf_check_congestion(struct ifqueue *); 308 309#ifdef __FreeBSD__ 310int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len); 311 |
303struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX]; | 312extern int pf_end_threads; |
304 | 313 |
314struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX]; |
|
305#else | 315#else |
316extern struct pool pfr_ktable_pl; 317extern struct pool pfr_kentry_pl; 318 |
|
306struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = { 307 { &pf_state_pl, PFSTATE_HIWAT }, 308 { &pf_src_tree_pl, PFSNODE_HIWAT }, | 319struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = { 320 { &pf_state_pl, PFSTATE_HIWAT }, 321 { &pf_src_tree_pl, PFSNODE_HIWAT }, |
309 { &pf_frent_pl, PFFRAG_FRENT_HIWAT } | 322 { &pf_frent_pl, PFFRAG_FRENT_HIWAT }, 323 { &pfr_ktable_pl, PFR_KTABLE_HIWAT }, 324 { &pfr_kentry_pl, PFR_KENTRY_HIWAT } |
310}; 311#endif 312 313#define STATE_LOOKUP() \ 314 do { \ 315 if (direction == PF_IN) \ 316 *state = pf_find_state_recurse( \ 317 kif, &key, PF_EXT_GWY); \ --- 15 unchanged lines hidden (view full) --- 333#define STATE_TRANSLATE(s) \ 334 (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \ 335 ((s)->af == AF_INET6 && \ 336 ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \ 337 (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \ 338 (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \ 339 (s)->lan.port != (s)->gwy.port 340 | 325}; 326#endif 327 328#define STATE_LOOKUP() \ 329 do { \ 330 if (direction == PF_IN) \ 331 *state = pf_find_state_recurse( \ 332 kif, &key, PF_EXT_GWY); \ --- 15 unchanged lines hidden (view full) --- 348#define STATE_TRANSLATE(s) \ 349 (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \ 350 ((s)->af == AF_INET6 && \ 351 ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \ 352 (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \ 353 (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \ 354 (s)->lan.port != (s)->gwy.port 355 |
341#define BOUND_IFACE(r, k) (((r)->rule_flag & PFRULE_IFBOUND) ? (k) : \ 342 ((r)->rule_flag & PFRULE_GRBOUND) ? (k)->pfik_parent : \ 343 (k)->pfik_parent->pfik_parent) | 356#define BOUND_IFACE(r, k) \ 357 ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all |
344 345#define STATE_INC_COUNTERS(s) \ 346 do { \ 347 s->rule.ptr->states++; \ 348 if (s->anchor.ptr != NULL) \ 349 s->anchor.ptr->states++; \ 350 if (s->nat_rule.ptr != NULL) \ 351 s->nat_rule.ptr->states++; \ 352 } while (0) 353 354#define STATE_DEC_COUNTERS(s) \ 355 do { \ 356 if (s->nat_rule.ptr != NULL) \ 357 s->nat_rule.ptr->states--; \ 358 if (s->anchor.ptr != NULL) \ 359 s->anchor.ptr->states--; \ 360 s->rule.ptr->states--; \ 361 } while (0) 362 | 358 359#define STATE_INC_COUNTERS(s) \ 360 do { \ 361 s->rule.ptr->states++; \ 362 if (s->anchor.ptr != NULL) \ 363 s->anchor.ptr->states++; \ 364 if (s->nat_rule.ptr != NULL) \ 365 s->nat_rule.ptr->states++; \ 366 } while (0) 367 368#define STATE_DEC_COUNTERS(s) \ 369 do { \ 370 if (s->nat_rule.ptr != NULL) \ 371 s->nat_rule.ptr->states--; \ 372 if (s->anchor.ptr != NULL) \ 373 s->anchor.ptr->states--; \ 374 s->rule.ptr->states--; \ 375 } while (0) 376 |
363#ifndef __FreeBSD__ 364static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *); 365static __inline int pf_state_compare_lan_ext(struct pf_state *, 366 struct pf_state *); 367static __inline int pf_state_compare_ext_gwy(struct pf_state *, 368 struct pf_state *); 369static __inline int pf_state_compare_id(struct pf_state *, 370 struct pf_state *); 371static __inline int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *); 372#else 373static int pf_src_compare(struct pf_src_node *, struct pf_src_node *); 374static int pf_state_compare_lan_ext(struct pf_state *, 375 struct pf_state *); 376static int pf_state_compare_ext_gwy(struct pf_state *, 377 struct pf_state *); 378static int pf_state_compare_id(struct pf_state *, 379 struct pf_state *); 380static int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *); 381#endif 382 | |
383struct pf_src_tree tree_src_tracking; 384 385struct pf_state_tree_id tree_id; | 377struct pf_src_tree tree_src_tracking; 378 379struct pf_state_tree_id tree_id; |
386struct pf_state_queue state_updates; | 380struct pf_state_queue state_list; |
387 | 381 |
382#ifdef __FreeBSD__ 383static int pf_src_compare(struct pf_src_node *, struct pf_src_node *); 384static int pf_state_compare_lan_ext(struct pf_state *, struct pf_state *); 385static int pf_state_compare_ext_gwy(struct pf_state *, struct pf_state *); 386static int pf_state_compare_id(struct pf_state *, struct pf_state *); 387#endif 388 |
|
388RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare); 389RB_GENERATE(pf_state_tree_lan_ext, pf_state, 390 u.s.entry_lan_ext, pf_state_compare_lan_ext); 391RB_GENERATE(pf_state_tree_ext_gwy, pf_state, 392 u.s.entry_ext_gwy, pf_state_compare_ext_gwy); 393RB_GENERATE(pf_state_tree_id, pf_state, 394 u.s.entry_id, pf_state_compare_id); | 389RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare); 390RB_GENERATE(pf_state_tree_lan_ext, pf_state, 391 u.s.entry_lan_ext, pf_state_compare_lan_ext); 392RB_GENERATE(pf_state_tree_ext_gwy, pf_state, 393 u.s.entry_ext_gwy, pf_state_compare_ext_gwy); 394RB_GENERATE(pf_state_tree_id, pf_state, 395 u.s.entry_id, pf_state_compare_id); |
395RB_GENERATE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare); 396RB_GENERATE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare); | |
397 398#ifdef __FreeBSD__ 399static int 400#else 401static __inline int 402#endif 403pf_src_compare(struct pf_src_node *a, struct pf_src_node *b) 404{ --- 196 unchanged lines hidden (view full) --- 601 if (a->creatorid > b->creatorid) 602 return (1); 603 if (a->creatorid < b->creatorid) 604 return (-1); 605 606 return (0); 607} 608 | 396 397#ifdef __FreeBSD__ 398static int 399#else 400static __inline int 401#endif 402pf_src_compare(struct pf_src_node *a, struct pf_src_node *b) 403{ --- 196 unchanged lines hidden (view full) --- 600 if (a->creatorid > b->creatorid) 601 return (1); 602 if (a->creatorid < b->creatorid) 603 return (-1); 604 605 return (0); 606} 607 |
609#ifdef __FreeBSD__ 610static int 611#else 612static __inline int 613#endif 614pf_anchor_compare(struct pf_anchor *a, struct pf_anchor *b) 615{ 616 int c = strcmp(a->path, b->path); 617 618 return (c ? (c < 0 ? -1 : 1) : 0); 619} 620 | |
621#ifdef INET6 622void 623pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af) 624{ 625 switch (af) { 626#ifdef INET 627 case AF_INET: 628 dst->addr32[0] = src->addr32[0]; --- 5 unchanged lines hidden (view full) --- 634 dst->addr32[2] = src->addr32[2]; 635 dst->addr32[3] = src->addr32[3]; 636 break; 637 } 638} 639#endif /* INET6 */ 640 641struct pf_state * | 608#ifdef INET6 609void 610pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af) 611{ 612 switch (af) { 613#ifdef INET 614 case AF_INET: 615 dst->addr32[0] = src->addr32[0]; --- 5 unchanged lines hidden (view full) --- 621 dst->addr32[2] = src->addr32[2]; 622 dst->addr32[3] = src->addr32[3]; 623 break; 624 } 625} 626#endif /* INET6 */ 627 628struct pf_state * |
642pf_find_state_byid(struct pf_state *key) | 629pf_find_state_byid(struct pf_state_cmp *key) |
643{ 644 pf_status.fcounters[FCNT_STATE_SEARCH]++; | 630{ 631 pf_status.fcounters[FCNT_STATE_SEARCH]++; |
645 return (RB_FIND(pf_state_tree_id, &tree_id, key)); | 632 return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key)); |
646} 647 648struct pf_state * | 633} 634 635struct pf_state * |
649pf_find_state_recurse(struct pfi_kif *kif, struct pf_state *key, u_int8_t tree) | 636pf_find_state_recurse(struct pfi_kif *kif, struct pf_state_cmp *key, u_int8_t tree) |
650{ 651 struct pf_state *s; 652 653 pf_status.fcounters[FCNT_STATE_SEARCH]++; 654 655 switch (tree) { 656 case PF_LAN_EXT: | 637{ 638 struct pf_state *s; 639 640 pf_status.fcounters[FCNT_STATE_SEARCH]++; 641 642 switch (tree) { 643 case PF_LAN_EXT: |
657 for (; kif != NULL; kif = kif->pfik_parent) { 658 s = RB_FIND(pf_state_tree_lan_ext, 659 &kif->pfik_lan_ext, key); 660 if (s != NULL) 661 return (s); 662 } | 644 if ((s = RB_FIND(pf_state_tree_lan_ext, &kif->pfik_lan_ext, 645 (struct pf_state *)key)) != NULL) 646 return (s); 647 if ((s = RB_FIND(pf_state_tree_lan_ext, &pfi_all->pfik_lan_ext, 648 (struct pf_state *)key)) != NULL) 649 return (s); |
663 return (NULL); 664 case PF_EXT_GWY: | 650 return (NULL); 651 case PF_EXT_GWY: |
665 for (; kif != NULL; kif = kif->pfik_parent) { 666 s = RB_FIND(pf_state_tree_ext_gwy, 667 &kif->pfik_ext_gwy, key); 668 if (s != NULL) 669 return (s); 670 } | 652 if ((s = RB_FIND(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, 653 (struct pf_state *)key)) != NULL) 654 return (s); 655 if ((s = RB_FIND(pf_state_tree_ext_gwy, &pfi_all->pfik_ext_gwy, 656 (struct pf_state *)key)) != NULL) 657 return (s); |
671 return (NULL); 672 default: 673 panic("pf_find_state_recurse"); 674 } 675} 676 677struct pf_state * | 658 return (NULL); 659 default: 660 panic("pf_find_state_recurse"); 661 } 662} 663 664struct pf_state * |
678pf_find_state_all(struct pf_state *key, u_int8_t tree, int *more) | 665pf_find_state_all(struct pf_state_cmp *key, u_int8_t tree, int *more) |
679{ 680 struct pf_state *s, *ss = NULL; 681 struct pfi_kif *kif; 682 683 pf_status.fcounters[FCNT_STATE_SEARCH]++; 684 685 switch (tree) { 686 case PF_LAN_EXT: 687 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) { 688 s = RB_FIND(pf_state_tree_lan_ext, | 666{ 667 struct pf_state *s, *ss = NULL; 668 struct pfi_kif *kif; 669 670 pf_status.fcounters[FCNT_STATE_SEARCH]++; 671 672 switch (tree) { 673 case PF_LAN_EXT: 674 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) { 675 s = RB_FIND(pf_state_tree_lan_ext, |
689 &kif->pfik_lan_ext, key); | 676 &kif->pfik_lan_ext, (struct pf_state *)key); |
690 if (s == NULL) 691 continue; 692 if (more == NULL) 693 return (s); 694 ss = s; 695 (*more)++; 696 } 697 return (ss); 698 case PF_EXT_GWY: 699 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) { 700 s = RB_FIND(pf_state_tree_ext_gwy, | 677 if (s == NULL) 678 continue; 679 if (more == NULL) 680 return (s); 681 ss = s; 682 (*more)++; 683 } 684 return (ss); 685 case PF_EXT_GWY: 686 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) { 687 s = RB_FIND(pf_state_tree_ext_gwy, |
701 &kif->pfik_ext_gwy, key); | 688 &kif->pfik_ext_gwy, (struct pf_state *)key); |
702 if (s == NULL) 703 continue; 704 if (more == NULL) 705 return (s); 706 ss = s; 707 (*more)++; 708 } 709 return (ss); --- 34 unchanged lines hidden (view full) --- 744 745int 746pf_src_connlimit(struct pf_state **state) 747{ 748 struct pf_state *s; 749 int bad = 0; 750 751 (*state)->src_node->conn++; | 689 if (s == NULL) 690 continue; 691 if (more == NULL) 692 return (s); 693 ss = s; 694 (*more)++; 695 } 696 return (ss); --- 34 unchanged lines hidden (view full) --- 731 732int 733pf_src_connlimit(struct pf_state **state) 734{ 735 struct pf_state *s; 736 int bad = 0; 737 738 (*state)->src_node->conn++; |
752#ifdef __FreeBSD__ 753 (*state)->local_flags |= PFSTATE_SRC_CONN; 754#endif | 739 (*state)->src.tcp_est = 1; |
755 pf_add_threshold(&(*state)->src_node->conn_rate); 756 757 if ((*state)->rule.ptr->max_src_conn && 758 (*state)->rule.ptr->max_src_conn < 759 (*state)->src_node->conn) { 760 pf_status.lcounters[LCNT_SRCCONN]++; 761 bad++; 762 } --- 204 unchanged lines hidden (view full) --- 967 if (state->sync_flags & PFSTATE_FROMSYNC) 968 printf(" (from sync)"); 969 printf("\n"); 970 } 971 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state); 972 RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state); 973 return (-1); 974 } | 740 pf_add_threshold(&(*state)->src_node->conn_rate); 741 742 if ((*state)->rule.ptr->max_src_conn && 743 (*state)->rule.ptr->max_src_conn < 744 (*state)->src_node->conn) { 745 pf_status.lcounters[LCNT_SRCCONN]++; 746 bad++; 747 } --- 204 unchanged lines hidden (view full) --- 952 if (state->sync_flags & PFSTATE_FROMSYNC) 953 printf(" (from sync)"); 954 printf("\n"); 955 } 956 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state); 957 RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state); 958 return (-1); 959 } |
975 TAILQ_INSERT_HEAD(&state_updates, state, u.s.entry_updates); 976 | 960 TAILQ_INSERT_TAIL(&state_list, state, u.s.entry_list); |
977 pf_status.fcounters[FCNT_STATE_INSERT]++; 978 pf_status.states++; | 961 pf_status.fcounters[FCNT_STATE_INSERT]++; 962 pf_status.states++; |
979 pfi_attach_state(kif); | 963 pfi_kif_ref(kif, PFI_KIF_REF_STATE); |
980#if NPFSYNC 981 pfsync_insert_state(state); 982#endif 983 return (0); 984} 985 986void | 964#if NPFSYNC 965 pfsync_insert_state(state); 966#endif 967 return (0); 968} 969 970void |
987pf_purge_timeout(void *arg) | 971pf_purge_thread(void *v) |
988{ | 972{ |
989#ifdef __FreeBSD__ 990 struct callout *to = arg; 991#else 992 struct timeout *to = arg; 993#endif 994 int s; | 973 int nloops = 0, s; |
995 | 974 |
975 for (;;) { 976 tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz); 977 |
|
996#ifdef __FreeBSD__ | 978#ifdef __FreeBSD__ |
997 PF_LOCK(); | 979 sx_slock(&pf_consistency_lock); 980 PF_LOCK(); 981 982 if (pf_end_threads) { 983 pf_purge_expired_states(pf_status.states); 984 pf_purge_expired_fragments(); 985 pf_purge_expired_src_nodes(0); 986 pf_end_threads++; 987 988 sx_sunlock(&pf_consistency_lock); 989 PF_UNLOCK(); 990 wakeup(pf_purge_thread); 991 kthread_exit(0); 992 } |
998#endif | 993#endif |
999 s = splsoftnet(); 1000 pf_purge_expired_states(); 1001 pf_purge_expired_fragments(); 1002 pf_purge_expired_src_nodes(); 1003 splx(s); 1004#ifdef __FreeBSD__ 1005 PF_UNLOCK(); 1006#endif | 994 s = splsoftnet(); |
1007 | 995 |
996 /* process a fraction of the state table every second */ 997 pf_purge_expired_states(1 + (pf_status.states 998 / pf_default_rule.timeout[PFTM_INTERVAL])); 999 1000 /* purge other expired types every PFTM_INTERVAL seconds */ 1001 if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) { 1002 pf_purge_expired_fragments(); 1003 pf_purge_expired_src_nodes(0); 1004 nloops = 0; 1005 } 1006 1007 splx(s); |
|
1008#ifdef __FreeBSD__ | 1008#ifdef __FreeBSD__ |
1009 callout_reset(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz, 1010 pf_purge_timeout, to); 1011#else 1012 timeout_add(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz); | 1009 PF_UNLOCK(); 1010 sx_sunlock(&pf_consistency_lock); |
1013#endif | 1011#endif |
1012 } |
|
1014} 1015 1016u_int32_t 1017pf_state_expires(const struct pf_state *state) 1018{ 1019 u_int32_t timeout; 1020 u_int32_t start; 1021 u_int32_t end; 1022 u_int32_t states; 1023 1024 /* handle all PFTM_* > PFTM_MAX here */ 1025 if (state->timeout == PFTM_PURGE) 1026 return (time_second); 1027 if (state->timeout == PFTM_UNTIL_PACKET) 1028 return (0); 1029#ifdef __FreeBSD__ | 1013} 1014 1015u_int32_t 1016pf_state_expires(const struct pf_state *state) 1017{ 1018 u_int32_t timeout; 1019 u_int32_t start; 1020 u_int32_t end; 1021 u_int32_t states; 1022 1023 /* handle all PFTM_* > PFTM_MAX here */ 1024 if (state->timeout == PFTM_PURGE) 1025 return (time_second); 1026 if (state->timeout == PFTM_UNTIL_PACKET) 1027 return (0); 1028#ifdef __FreeBSD__ |
1029 KASSERT(state->timeout != PFTM_UNLINKED, 1030 ("pf_state_expires: timeout == PFTM_UNLINKED")); |
|
1030 KASSERT((state->timeout < PFTM_MAX), 1031 ("pf_state_expires: timeout > PFTM_MAX")); 1032#else | 1031 KASSERT((state->timeout < PFTM_MAX), 1032 ("pf_state_expires: timeout > PFTM_MAX")); 1033#else |
1034 KASSERT(state->timeout != PFTM_UNLINKED); |
|
1033 KASSERT(state->timeout < PFTM_MAX); 1034#endif 1035 timeout = state->rule.ptr->timeout[state->timeout]; 1036 if (!timeout) 1037 timeout = pf_default_rule.timeout[state->timeout]; 1038 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START]; 1039 if (start) { 1040 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END]; --- 9 unchanged lines hidden (view full) --- 1050 (end - start)); 1051 else 1052 return (time_second); 1053 } 1054 return (state->expire + timeout); 1055} 1056 1057void | 1035 KASSERT(state->timeout < PFTM_MAX); 1036#endif 1037 timeout = state->rule.ptr->timeout[state->timeout]; 1038 if (!timeout) 1039 timeout = pf_default_rule.timeout[state->timeout]; 1040 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START]; 1041 if (start) { 1042 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END]; --- 9 unchanged lines hidden (view full) --- 1052 (end - start)); 1053 else 1054 return (time_second); 1055 } 1056 return (state->expire + timeout); 1057} 1058 1059void |
1058pf_purge_expired_src_nodes(void) | 1060pf_purge_expired_src_nodes(int waslocked) |
1059{ 1060 struct pf_src_node *cur, *next; | 1061{ 1062 struct pf_src_node *cur, *next; |
1063 int locked = waslocked; |
|
1061 1062 for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) { 1063 next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur); 1064 1065 if (cur->states <= 0 && cur->expire <= time_second) { | 1064 1065 for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) { 1066 next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur); 1067 1068 if (cur->states <= 0 && cur->expire <= time_second) { |
1069 if (! locked) { 1070#ifdef __FreeBSD__ 1071 if (!sx_try_upgrade(&pf_consistency_lock)) { 1072 PF_UNLOCK(); 1073 sx_sunlock(&pf_consistency_lock); 1074 sx_xlock(&pf_consistency_lock); 1075 PF_LOCK(); 1076 } 1077#else 1078 rw_enter_write(&pf_consistency_lock); 1079#endif 1080 next = RB_NEXT(pf_src_tree, 1081 &tree_src_tracking, cur); 1082 locked = 1; 1083 } |
|
1066 if (cur->rule.ptr != NULL) { 1067 cur->rule.ptr->src_nodes--; 1068 if (cur->rule.ptr->states <= 0 && 1069 cur->rule.ptr->max_src_nodes <= 0) 1070 pf_rm_rule(NULL, cur->rule.ptr); 1071 } 1072 RB_REMOVE(pf_src_tree, &tree_src_tracking, cur); 1073 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 1074 pf_status.src_nodes--; 1075 pool_put(&pf_src_tree_pl, cur); 1076 } 1077 } | 1084 if (cur->rule.ptr != NULL) { 1085 cur->rule.ptr->src_nodes--; 1086 if (cur->rule.ptr->states <= 0 && 1087 cur->rule.ptr->max_src_nodes <= 0) 1088 pf_rm_rule(NULL, cur->rule.ptr); 1089 } 1090 RB_REMOVE(pf_src_tree, &tree_src_tracking, cur); 1091 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 1092 pf_status.src_nodes--; 1093 pool_put(&pf_src_tree_pl, cur); 1094 } 1095 } |
1096 1097 if (locked && !waslocked) 1098#ifdef __FreeBSD__ 1099 sx_downgrade(&pf_consistency_lock); 1100#else 1101 rw_exit_write(&pf_consistency_lock); 1102#endif |
|
1078} 1079 1080void 1081pf_src_tree_remove_state(struct pf_state *s) 1082{ 1083 u_int32_t timeout; 1084 1085 if (s->src_node != NULL) { 1086 if (s->proto == IPPROTO_TCP) { | 1103} 1104 1105void 1106pf_src_tree_remove_state(struct pf_state *s) 1107{ 1108 u_int32_t timeout; 1109 1110 if (s->src_node != NULL) { 1111 if (s->proto == IPPROTO_TCP) { |
1087#ifdef __FreeBSD__ 1088 if (s->local_flags & PFSTATE_SRC_CONN) 1089#else 1090 if (s->src.state == PF_TCPS_PROXY_DST || 1091 s->timeout >= PFTM_TCP_ESTABLISHED) 1092#endif | 1112 if (s->src.tcp_est) |
1093 --s->src_node->conn; 1094 } 1095 if (--s->src_node->states <= 0) { 1096 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE]; 1097 if (!timeout) 1098 timeout = 1099 pf_default_rule.timeout[PFTM_SRC_NODE]; 1100 s->src_node->expire = time_second + timeout; --- 6 unchanged lines hidden (view full) --- 1107 timeout = 1108 pf_default_rule.timeout[PFTM_SRC_NODE]; 1109 s->nat_src_node->expire = time_second + timeout; 1110 } 1111 } 1112 s->src_node = s->nat_src_node = NULL; 1113} 1114 | 1113 --s->src_node->conn; 1114 } 1115 if (--s->src_node->states <= 0) { 1116 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE]; 1117 if (!timeout) 1118 timeout = 1119 pf_default_rule.timeout[PFTM_SRC_NODE]; 1120 s->src_node->expire = time_second + timeout; --- 6 unchanged lines hidden (view full) --- 1127 timeout = 1128 pf_default_rule.timeout[PFTM_SRC_NODE]; 1129 s->nat_src_node->expire = time_second + timeout; 1130 } 1131 } 1132 s->src_node = s->nat_src_node = NULL; 1133} 1134 |
1135/* callers should be at splsoftnet */ |
|
1115void | 1136void |
1116pf_purge_expired_state(struct pf_state *cur) | 1137pf_unlink_state(struct pf_state *cur) |
1117{ 1118#ifdef __FreeBSD__ 1119 if (cur->local_flags & PFSTATE_EXPIRING) 1120 return; 1121 cur->local_flags |= PFSTATE_EXPIRING; 1122#endif | 1138{ 1139#ifdef __FreeBSD__ 1140 if (cur->local_flags & PFSTATE_EXPIRING) 1141 return; 1142 cur->local_flags |= PFSTATE_EXPIRING; 1143#endif |
1123 if (cur->src.state == PF_TCPS_PROXY_DST) | 1144 if (cur->src.state == PF_TCPS_PROXY_DST) { |
1124#ifdef __FreeBSD__ 1125 pf_send_tcp(NULL, cur->rule.ptr, cur->af, 1126#else 1127 pf_send_tcp(cur->rule.ptr, cur->af, 1128#endif 1129 &cur->ext.addr, &cur->lan.addr, 1130 cur->ext.port, cur->lan.port, 1131 cur->src.seqhi, cur->src.seqlo + 1, | 1145#ifdef __FreeBSD__ 1146 pf_send_tcp(NULL, cur->rule.ptr, cur->af, 1147#else 1148 pf_send_tcp(cur->rule.ptr, cur->af, 1149#endif 1150 &cur->ext.addr, &cur->lan.addr, 1151 cur->ext.port, cur->lan.port, 1152 cur->src.seqhi, cur->src.seqlo + 1, |
1132 TH_RST|TH_ACK, 0, 0, 0, 1, NULL, NULL); | 1153 TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL); 1154 } |
1133 RB_REMOVE(pf_state_tree_ext_gwy, 1134 &cur->u.s.kif->pfik_ext_gwy, cur); 1135 RB_REMOVE(pf_state_tree_lan_ext, 1136 &cur->u.s.kif->pfik_lan_ext, cur); 1137 RB_REMOVE(pf_state_tree_id, &tree_id, cur); 1138#if NPFSYNC | 1155 RB_REMOVE(pf_state_tree_ext_gwy, 1156 &cur->u.s.kif->pfik_ext_gwy, cur); 1157 RB_REMOVE(pf_state_tree_lan_ext, 1158 &cur->u.s.kif->pfik_lan_ext, cur); 1159 RB_REMOVE(pf_state_tree_id, &tree_id, cur); 1160#if NPFSYNC |
1139 pfsync_delete_state(cur); | 1161 if (cur->creatorid == pf_status.hostid) 1162 pfsync_delete_state(cur); |
1140#endif | 1163#endif |
1164 cur->timeout = PFTM_UNLINKED; |
|
1141 pf_src_tree_remove_state(cur); | 1165 pf_src_tree_remove_state(cur); |
1166} 1167 1168/* callers should be at splsoftnet and hold the 1169 * write_lock on pf_consistency_lock */ 1170void 1171pf_free_state(struct pf_state *cur) 1172{ 1173#if NPFSYNC 1174 if (pfsyncif != NULL && 1175 (pfsyncif->sc_bulk_send_next == cur || 1176 pfsyncif->sc_bulk_terminator == cur)) 1177 return; 1178#endif 1179#ifdef __FreeBSD__ 1180 KASSERT(cur->timeout == PFTM_UNLINKED, 1181 ("pf_free_state: cur->timeout != PFTM_UNLINKED")); 1182#else 1183 KASSERT(cur->timeout == PFTM_UNLINKED); 1184#endif |
|
1142 if (--cur->rule.ptr->states <= 0 && 1143 cur->rule.ptr->src_nodes <= 0) 1144 pf_rm_rule(NULL, cur->rule.ptr); 1145 if (cur->nat_rule.ptr != NULL) 1146 if (--cur->nat_rule.ptr->states <= 0 && 1147 cur->nat_rule.ptr->src_nodes <= 0) 1148 pf_rm_rule(NULL, cur->nat_rule.ptr); 1149 if (cur->anchor.ptr != NULL) 1150 if (--cur->anchor.ptr->states <= 0) 1151 pf_rm_rule(NULL, cur->anchor.ptr); 1152 pf_normalize_tcp_cleanup(cur); | 1185 if (--cur->rule.ptr->states <= 0 && 1186 cur->rule.ptr->src_nodes <= 0) 1187 pf_rm_rule(NULL, cur->rule.ptr); 1188 if (cur->nat_rule.ptr != NULL) 1189 if (--cur->nat_rule.ptr->states <= 0 && 1190 cur->nat_rule.ptr->src_nodes <= 0) 1191 pf_rm_rule(NULL, cur->nat_rule.ptr); 1192 if (cur->anchor.ptr != NULL) 1193 if (--cur->anchor.ptr->states <= 0) 1194 pf_rm_rule(NULL, cur->anchor.ptr); 1195 pf_normalize_tcp_cleanup(cur); |
1153 pfi_detach_state(cur->u.s.kif); 1154 TAILQ_REMOVE(&state_updates, cur, u.s.entry_updates); | 1196 pfi_kif_unref(cur->u.s.kif, PFI_KIF_REF_STATE); 1197 TAILQ_REMOVE(&state_list, cur, u.s.entry_list); |
1155 if (cur->tag) 1156 pf_tag_unref(cur->tag); 1157 pool_put(&pf_state_pl, cur); 1158 pf_status.fcounters[FCNT_STATE_REMOVALS]++; 1159 pf_status.states--; 1160} 1161 1162void | 1198 if (cur->tag) 1199 pf_tag_unref(cur->tag); 1200 pool_put(&pf_state_pl, cur); 1201 pf_status.fcounters[FCNT_STATE_REMOVALS]++; 1202 pf_status.states--; 1203} 1204 1205void |
1163pf_purge_expired_states(void) | 1206pf_purge_expired_states(u_int32_t maxcheck) |
1164{ | 1207{ |
1165 struct pf_state *cur, *next; | 1208 static struct pf_state *cur = NULL; 1209 struct pf_state *next; 1210 int locked = 0; |
1166 | 1211 |
1167 for (cur = RB_MIN(pf_state_tree_id, &tree_id); 1168 cur; cur = next) { 1169 next = RB_NEXT(pf_state_tree_id, &tree_id, cur); 1170 if (pf_state_expires(cur) <= time_second) 1171 pf_purge_expired_state(cur); | 1212 while (maxcheck--) { 1213 /* wrap to start of list when we hit the end */ 1214 if (cur == NULL) { 1215 cur = TAILQ_FIRST(&state_list); 1216 if (cur == NULL) 1217 break; /* list empty */ 1218 } 1219 1220 /* get next state, as cur may get deleted */ 1221 next = TAILQ_NEXT(cur, u.s.entry_list); 1222 1223 if (cur->timeout == PFTM_UNLINKED) { 1224 /* free unlinked state */ 1225 if (! locked) { 1226#ifdef __FreeBSD__ 1227 if (!sx_try_upgrade(&pf_consistency_lock)) { 1228 PF_UNLOCK(); 1229 sx_sunlock(&pf_consistency_lock); 1230 sx_xlock(&pf_consistency_lock); 1231 PF_LOCK(); 1232 } 1233#else 1234 rw_enter_write(&pf_consistency_lock); 1235#endif 1236 locked = 1; 1237 } 1238 pf_free_state(cur); 1239 } else if (pf_state_expires(cur) <= time_second) { 1240 /* unlink and free expired state */ 1241 pf_unlink_state(cur); 1242 if (! locked) { 1243#ifdef __FreeBSD__ 1244 if (!sx_try_upgrade(&pf_consistency_lock)) { 1245 PF_UNLOCK(); 1246 sx_sunlock(&pf_consistency_lock); 1247 sx_xlock(&pf_consistency_lock); 1248 PF_LOCK(); 1249 } 1250#else 1251 rw_enter_write(&pf_consistency_lock); 1252#endif 1253 locked = 1; 1254 } 1255 pf_free_state(cur); 1256 } 1257 cur = next; |
1172 } | 1258 } |
1259 1260 if (locked) 1261#ifdef __FreeBSD__ 1262 sx_downgrade(&pf_consistency_lock); 1263#else 1264 rw_exit_write(&pf_consistency_lock); 1265#endif |
|
1173} 1174 1175int 1176pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw) 1177{ 1178 if (aw->type != PF_ADDR_TABLE) 1179 return (0); 1180 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL) --- 209 unchanged lines hidden (view full) --- 1390 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0)) 1391 return (1); 1392 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0)) 1393 return (1); 1394 return (0); 1395 case PF_ADDR_DYNIFTL: 1396 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt); 1397 case PF_ADDR_NOROUTE: | 1266} 1267 1268int 1269pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw) 1270{ 1271 if (aw->type != PF_ADDR_TABLE) 1272 return (0); 1273 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL) --- 209 unchanged lines hidden (view full) --- 1483 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0)) 1484 return (1); 1485 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0)) 1486 return (1); 1487 return (0); 1488 case PF_ADDR_DYNIFTL: 1489 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt); 1490 case PF_ADDR_NOROUTE: |
1491 case PF_ADDR_URPFFAILED: |
|
1398 return (0); 1399 case PF_ADDR_TABLE: 1400 return (aw1->p.tbl != aw2->p.tbl); | 1492 return (0); 1493 case PF_ADDR_TABLE: 1494 return (aw1->p.tbl != aw2->p.tbl); |
1495 case PF_ADDR_RTLABEL: 1496 return (aw1->v.rtlabel != aw2->v.rtlabel); |
|
1401 default: 1402 printf("invalid address type: %d\n", aw1->type); 1403 return (1); 1404 } 1405} 1406 1407u_int16_t 1408pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp) --- 170 unchanged lines hidden (view full) --- 1579 ooa.addr16[5], oa->addr16[5], u), 1580 ooa.addr16[6], oa->addr16[6], u), 1581 ooa.addr16[7], oa->addr16[7], u); 1582 break; 1583#endif /* INET6 */ 1584 } 1585} 1586 | 1497 default: 1498 printf("invalid address type: %d\n", aw1->type); 1499 return (1); 1500 } 1501} 1502 1503u_int16_t 1504pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp) --- 170 unchanged lines hidden (view full) --- 1675 ooa.addr16[5], oa->addr16[5], u), 1676 ooa.addr16[6], oa->addr16[6], u), 1677 ooa.addr16[7], oa->addr16[7], u); 1678 break; 1679#endif /* INET6 */ 1680 } 1681} 1682 |
1683 1684/* 1685 * Need to modulate the sequence numbers in the TCP SACK option 1686 * (credits to Krzysztof Pfaff for report and patch) 1687 */ 1688int 1689pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd, 1690 struct tcphdr *th, struct pf_state_peer *dst) 1691{ 1692 int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen; 1693#ifdef __FreeBSD__ 1694 u_int8_t opts[TCP_MAXOLEN], *opt = opts; 1695#else 1696 u_int8_t opts[MAX_TCPOPTLEN], *opt = opts; 1697#endif 1698 int copyback = 0, i, olen; 1699 struct sackblk sack; 1700 1701#define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2) 1702 if (hlen < TCPOLEN_SACKLEN || 1703 !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af)) 1704 return 0; 1705 1706 while (hlen >= TCPOLEN_SACKLEN) { 1707 olen = opt[1]; 1708 switch (*opt) { 1709 case TCPOPT_EOL: /* FALLTHROUGH */ 1710 case TCPOPT_NOP: 1711 opt++; 1712 hlen--; 1713 break; 1714 case TCPOPT_SACK: 1715 if (olen > hlen) 1716 olen = hlen; 1717 if (olen >= TCPOLEN_SACKLEN) { 1718 for (i = 2; i + TCPOLEN_SACK <= olen; 1719 i += TCPOLEN_SACK) { 1720 memcpy(&sack, &opt[i], sizeof(sack)); 1721 pf_change_a(&sack.start, &th->th_sum, 1722 htonl(ntohl(sack.start) - 1723 dst->seqdiff), 0); 1724 pf_change_a(&sack.end, &th->th_sum, 1725 htonl(ntohl(sack.end) - 1726 dst->seqdiff), 0); 1727 memcpy(&opt[i], &sack, sizeof(sack)); 1728 } 1729 copyback = 1; 1730 } 1731 /* FALLTHROUGH */ 1732 default: 1733 if (olen < 2) 1734 olen = 2; 1735 hlen -= olen; 1736 opt += olen; 1737 } 1738 } 1739 1740 if (copyback) 1741#ifdef __FreeBSD__ 1742 m_copyback(m, off + sizeof(*th), thoptlen, (caddr_t)opts); 1743#else 1744 m_copyback(m, off + sizeof(*th), thoptlen, opts); 1745#endif 1746 return (copyback); 1747} 1748 |
|
1587void 1588#ifdef __FreeBSD__ 1589pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af, 1590#else 1591pf_send_tcp(const struct pf_rule *r, sa_family_t af, 1592#endif 1593 const struct pf_addr *saddr, const struct pf_addr *daddr, 1594 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack, 1595 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag, | 1749void 1750#ifdef __FreeBSD__ 1751pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af, 1752#else 1753pf_send_tcp(const struct pf_rule *r, sa_family_t af, 1754#endif 1755 const struct pf_addr *saddr, const struct pf_addr *daddr, 1756 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack, 1757 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag, |
1596 struct ether_header *eh, struct ifnet *ifp) | 1758 u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp) |
1597{ 1598 struct mbuf *m; | 1759{ 1760 struct mbuf *m; |
1599 int len = 0, tlen; /* make the compiler happy */ | 1761 int len, tlen; |
1600#ifdef INET | 1762#ifdef INET |
1601 struct ip *h = NULL; /* make the compiler happy */ | 1763 struct ip *h; |
1602#endif /* INET */ 1603#ifdef INET6 | 1764#endif /* INET */ 1765#ifdef INET6 |
1604 struct ip6_hdr *h6 = NULL; /* make the compiler happy */ | 1766 struct ip6_hdr *h6; |
1605#endif /* INET6 */ | 1767#endif /* INET6 */ |
1606 struct tcphdr *th = NULL; /* make the compiler happy */ 1607 char *opt; | 1768 struct tcphdr *th; 1769 char *opt; 1770 struct pf_mtag *pf_mtag; |
1608 | 1771 |
1772#ifdef __FreeBSD__ 1773 KASSERT( 1774#ifdef INET 1775 af == AF_INET 1776#else 1777 0 1778#endif 1779 || 1780#ifdef INET6 1781 af == AF_INET6 1782#else 1783 0 1784#endif 1785 , ("Unsupported AF %d", af)); 1786 len = 0; 1787 th = NULL; 1788#ifdef INET 1789 h = NULL; 1790#endif 1791#ifdef INET6 1792 h6 = NULL; 1793#endif 1794#endif 1795 |
|
1609 /* maximum segment size tcp option */ 1610 tlen = sizeof(struct tcphdr); 1611 if (mss) 1612 tlen += 4; 1613 1614 switch (af) { 1615#ifdef INET 1616 case AF_INET: --- 16 unchanged lines hidden (view full) --- 1633 if (replyto) 1634 mac_create_mbuf_netlayer(replyto, m); 1635 else 1636 mac_create_mbuf_from_firewall(m); 1637#else 1638 (void)replyto; 1639#endif 1640#endif | 1796 /* maximum segment size tcp option */ 1797 tlen = sizeof(struct tcphdr); 1798 if (mss) 1799 tlen += 4; 1800 1801 switch (af) { 1802#ifdef INET 1803 case AF_INET: --- 16 unchanged lines hidden (view full) --- 1820 if (replyto) 1821 mac_create_mbuf_netlayer(replyto, m); 1822 else 1823 mac_create_mbuf_from_firewall(m); 1824#else 1825 (void)replyto; 1826#endif 1827#endif |
1641 if (tag) { | 1828 if ((pf_mtag = pf_get_mtag(m)) == NULL) { 1829 m_freem(m); 1830 return; 1831 } 1832 if (tag) |
1642#ifdef __FreeBSD__ 1643 m->m_flags |= M_SKIP_FIREWALL; 1644#else | 1833#ifdef __FreeBSD__ 1834 m->m_flags |= M_SKIP_FIREWALL; 1835#else |
1645 struct m_tag *mtag; 1646 1647 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 1648 if (mtag == NULL) { 1649 m_freem(m); 1650 return; 1651 } 1652 m_tag_prepend(m, mtag); | 1836 pf_mtag->flags |= PF_TAG_GENERATED; |
1653#endif | 1837#endif |
1654 } | 1838 1839 pf_mtag->tag = rtag; 1840 1841 if (r != NULL && r->rtableid >= 0) 1842 pf_mtag->rtableid = r->rtableid; |
1655#ifdef ALTQ 1656 if (r != NULL && r->qid) { | 1843#ifdef ALTQ 1844 if (r != NULL && r->qid) { |
1657 struct m_tag *mtag; 1658 struct altq_tag *atag; 1659 1660 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); 1661 if (mtag != NULL) { 1662 atag = (struct altq_tag *)(mtag + 1); 1663 atag->qid = r->qid; 1664 /* add hints for ecn */ 1665 atag->af = af; 1666 atag->hdr = mtod(m, struct ip *); 1667 m_tag_prepend(m, mtag); 1668 } | 1845 pf_mtag->qid = r->qid; 1846 /* add hints for ecn */ 1847 pf_mtag->af = af; 1848 pf_mtag->hdr = mtod(m, struct ip *); |
1669 } 1670#endif /* ALTQ */ 1671 m->m_data += max_linkhdr; 1672 m->m_pkthdr.len = m->m_len = len; 1673 m->m_pkthdr.rcvif = NULL; 1674 bzero(m->m_data, len); 1675 switch (af) { 1676#ifdef INET --- 119 unchanged lines hidden (view full) --- 1796#endif /* INET6 */ 1797 } 1798} 1799 1800void 1801pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, 1802 struct pf_rule *r) 1803{ | 1849 } 1850#endif /* ALTQ */ 1851 m->m_data += max_linkhdr; 1852 m->m_pkthdr.len = m->m_len = len; 1853 m->m_pkthdr.rcvif = NULL; 1854 bzero(m->m_data, len); 1855 switch (af) { 1856#ifdef INET --- 119 unchanged lines hidden (view full) --- 1976#endif /* INET6 */ 1977 } 1978} 1979 1980void 1981pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, 1982 struct pf_rule *r) 1983{ |
1804#ifdef ALTQ 1805 struct m_tag *mtag; 1806#endif | 1984 struct pf_mtag *pf_mtag; |
1807 struct mbuf *m0; 1808#ifdef __FreeBSD__ 1809 struct ip *ip; 1810#endif 1811 1812#ifdef __FreeBSD__ 1813 m0 = m_copypacket(m, M_DONTWAIT); 1814 if (m0 == NULL) 1815 return; | 1985 struct mbuf *m0; 1986#ifdef __FreeBSD__ 1987 struct ip *ip; 1988#endif 1989 1990#ifdef __FreeBSD__ 1991 m0 = m_copypacket(m, M_DONTWAIT); 1992 if (m0 == NULL) 1993 return; |
1816 m0->m_flags |= M_SKIP_FIREWALL; | |
1817#else | 1994#else |
1818 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 1819 if (mtag == NULL) 1820 return; | |
1821 m0 = m_copy(m, 0, M_COPYALL); | 1995 m0 = m_copy(m, 0, M_COPYALL); |
1822 if (m0 == NULL) { 1823 m_tag_free(mtag); | 1996#endif 1997 if ((pf_mtag = pf_get_mtag(m0)) == NULL) |
1824 return; | 1998 return; |
1825 } 1826 m_tag_prepend(m0, mtag); | 1999#ifdef __FreeBSD__ 2000 /* XXX: revisit */ 2001 m0->m_flags |= M_SKIP_FIREWALL; 2002#else 2003 pf_mtag->flags |= PF_TAG_GENERATED; |
1827#endif 1828 | 2004#endif 2005 |
2006 if (r->rtableid >= 0) 2007 pf_mtag->rtableid = r->rtableid; 2008 |
|
1829#ifdef ALTQ 1830 if (r->qid) { | 2009#ifdef ALTQ 2010 if (r->qid) { |
1831 struct altq_tag *atag; 1832 1833 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); 1834 if (mtag != NULL) { 1835 atag = (struct altq_tag *)(mtag + 1); 1836 atag->qid = r->qid; 1837 /* add hints for ecn */ 1838 atag->af = af; 1839 atag->hdr = mtod(m0, struct ip *); 1840 m_tag_prepend(m0, mtag); 1841 } | 2011 pf_mtag->qid = r->qid; 2012 /* add hints for ecn */ 2013 pf_mtag->af = af; 2014 pf_mtag->hdr = mtod(m0, struct ip *); |
1842 } 1843#endif /* ALTQ */ 1844 1845 switch (af) { 1846#ifdef INET 1847 case AF_INET: 1848#ifdef __FreeBSD__ 1849 /* icmp_error() expects host byte ordering */ 1850 ip = mtod(m0, struct ip *); 1851 NTOHS(ip->ip_len); 1852 NTOHS(ip->ip_off); 1853 PF_UNLOCK(); 1854 icmp_error(m0, type, code, 0, 0); 1855 PF_LOCK(); 1856#else | 2015 } 2016#endif /* ALTQ */ 2017 2018 switch (af) { 2019#ifdef INET 2020 case AF_INET: 2021#ifdef __FreeBSD__ 2022 /* icmp_error() expects host byte ordering */ 2023 ip = mtod(m0, struct ip *); 2024 NTOHS(ip->ip_len); 2025 NTOHS(ip->ip_off); 2026 PF_UNLOCK(); 2027 icmp_error(m0, type, code, 0, 0); 2028 PF_LOCK(); 2029#else |
1857 icmp_error(m0, type, code, 0, (void *)NULL); | 2030 icmp_error(m0, type, code, 0, 0); |
1858#endif 1859 break; 1860#endif /* INET */ 1861#ifdef INET6 1862 case AF_INET6: 1863#ifdef __FreeBSD__ 1864 PF_UNLOCK(); 1865#endif --- 98 unchanged lines hidden (view full) --- 1964int 1965pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g) 1966{ 1967 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 1968 return (0); 1969 return (pf_match(op, a1, a2, g)); 1970} 1971 | 2031#endif 2032 break; 2033#endif /* INET */ 2034#ifdef INET6 2035 case AF_INET6: 2036#ifdef __FreeBSD__ 2037 PF_UNLOCK(); 2038#endif --- 98 unchanged lines hidden (view full) --- 2137int 2138pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g) 2139{ 2140 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 2141 return (0); 2142 return (pf_match(op, a1, a2, g)); 2143} 2144 |
1972struct pf_tag * 1973pf_get_tag(struct mbuf *m) | 2145#ifndef __FreeBSD__ 2146struct pf_mtag * 2147pf_find_mtag(struct mbuf *m) |
1974{ 1975 struct m_tag *mtag; 1976 | 2148{ 2149 struct m_tag *mtag; 2150 |
1977 if ((mtag = m_tag_find(m, PACKET_TAG_PF_TAG, NULL)) != NULL) 1978 return ((struct pf_tag *)(mtag + 1)); 1979 else | 2151 if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) |
1980 return (NULL); | 2152 return (NULL); |
2153 2154 return ((struct pf_mtag *)(mtag + 1)); |
|
1981} 1982 | 2155} 2156 |
1983int 1984pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_tag **pftag, int *tag) | 2157struct pf_mtag * 2158pf_get_mtag(struct mbuf *m) |
1985{ | 2159{ |
1986 if (*tag == -1) { /* find mbuf tag */ 1987 *pftag = pf_get_tag(m); 1988 if (*pftag != NULL) 1989 *tag = (*pftag)->tag; 1990 else 1991 *tag = 0; | 2160 struct m_tag *mtag; 2161 2162 if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) { 2163 mtag = m_tag_get(PACKET_TAG_PF, sizeof(struct pf_mtag), 2164 M_NOWAIT); 2165 if (mtag == NULL) 2166 return (NULL); 2167 bzero(mtag + 1, sizeof(struct pf_mtag)); 2168 m_tag_prepend(m, mtag); |
1992 } 1993 | 2169 } 2170 |
2171 return ((struct pf_mtag *)(mtag + 1)); 2172} 2173#endif 2174 2175int 2176pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_mtag *pf_mtag, 2177 int *tag) 2178{ 2179 if (*tag == -1) 2180 *tag = pf_mtag->tag; 2181 |
|
1994 return ((!r->match_tag_not && r->match_tag == *tag) || 1995 (r->match_tag_not && r->match_tag != *tag)); 1996} 1997 1998int | 2182 return ((!r->match_tag_not && r->match_tag == *tag) || 2183 (r->match_tag_not && r->match_tag != *tag)); 2184} 2185 2186int |
1999pf_tag_packet(struct mbuf *m, struct pf_tag *pftag, int tag) | 2187pf_tag_packet(struct mbuf *m, struct pf_mtag *pf_mtag, int tag, int rtableid) |
2000{ | 2188{ |
2001 struct m_tag *mtag; 2002 2003 if (tag <= 0) | 2189 if (tag <= 0 && rtableid < 0) |
2004 return (0); 2005 | 2190 return (0); 2191 |
2006 if (pftag == NULL) { 2007 mtag = m_tag_get(PACKET_TAG_PF_TAG, sizeof(*pftag), M_NOWAIT); 2008 if (mtag == NULL) | 2192 if (pf_mtag == NULL) 2193 if ((pf_mtag = pf_get_mtag(m)) == NULL) |
2009 return (1); | 2194 return (1); |
2010 ((struct pf_tag *)(mtag + 1))->tag = tag; 2011 m_tag_prepend(m, mtag); 2012 } else 2013 pftag->tag = tag; | 2195 if (tag > 0) 2196 pf_mtag->tag = tag; 2197 if (rtableid >= 0) 2198 pf_mtag->rtableid = rtableid; |
2014 2015 return (0); 2016} 2017 2018static void 2019pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n, | 2199 2200 return (0); 2201} 2202 2203static void 2204pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n, |
2020 struct pf_rule **r, struct pf_rule **a) | 2205 struct pf_rule **r, struct pf_rule **a, int *match) |
2021{ 2022 struct pf_anchor_stackframe *f; 2023 | 2206{ 2207 struct pf_anchor_stackframe *f; 2208 |
2209 (*r)->anchor->match = 0; 2210 if (match) 2211 *match = 0; |
|
2024 if (*depth >= sizeof(pf_anchor_stack) / 2025 sizeof(pf_anchor_stack[0])) { 2026 printf("pf_step_into_anchor: stack overflow\n"); 2027 *r = TAILQ_NEXT(*r, entries); 2028 return; 2029 } else if (*depth == 0 && a != NULL) 2030 *a = *r; 2031 f = pf_anchor_stack + (*depth)++; --- 10 unchanged lines hidden (view full) --- 2042 } else { 2043 f->parent = NULL; 2044 f->child = NULL; 2045 *rs = &(*r)->anchor->ruleset; 2046 } 2047 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2048} 2049 | 2212 if (*depth >= sizeof(pf_anchor_stack) / 2213 sizeof(pf_anchor_stack[0])) { 2214 printf("pf_step_into_anchor: stack overflow\n"); 2215 *r = TAILQ_NEXT(*r, entries); 2216 return; 2217 } else if (*depth == 0 && a != NULL) 2218 *a = *r; 2219 f = pf_anchor_stack + (*depth)++; --- 10 unchanged lines hidden (view full) --- 2230 } else { 2231 f->parent = NULL; 2232 f->child = NULL; 2233 *rs = &(*r)->anchor->ruleset; 2234 } 2235 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2236} 2237 |
2050static void | 2238int |
2051pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n, | 2239pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n, |
2052 struct pf_rule **r, struct pf_rule **a) | 2240 struct pf_rule **r, struct pf_rule **a, int *match) |
2053{ 2054 struct pf_anchor_stackframe *f; | 2241{ 2242 struct pf_anchor_stackframe *f; |
2243 int quick = 0; |
|
2055 2056 do { 2057 if (*depth <= 0) 2058 break; 2059 f = pf_anchor_stack + *depth - 1; 2060 if (f->parent != NULL && f->child != NULL) { | 2244 2245 do { 2246 if (*depth <= 0) 2247 break; 2248 f = pf_anchor_stack + *depth - 1; 2249 if (f->parent != NULL && f->child != NULL) { |
2250 if (f->child->match || 2251 (match != NULL && *match)) { 2252 f->r->anchor->match = 1; 2253 *match = 0; 2254 } |
|
2061 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child); 2062 if (f->child != NULL) { 2063 *rs = &f->child->ruleset; 2064 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2065 if (*r == NULL) 2066 continue; 2067 else 2068 break; 2069 } 2070 } 2071 (*depth)--; 2072 if (*depth == 0 && a != NULL) 2073 *a = NULL; 2074 *rs = f->rs; | 2255 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child); 2256 if (f->child != NULL) { 2257 *rs = &f->child->ruleset; 2258 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2259 if (*r == NULL) 2260 continue; 2261 else 2262 break; 2263 } 2264 } 2265 (*depth)--; 2266 if (*depth == 0 && a != NULL) 2267 *a = NULL; 2268 *rs = f->rs; |
2269 if (f->r->anchor->match || (match != NULL && *match)) 2270 quick = f->r->quick; |
|
2075 *r = TAILQ_NEXT(f->r, entries); 2076 } while (*r == NULL); | 2271 *r = TAILQ_NEXT(f->r, entries); 2272 } while (*r == NULL); |
2273 2274 return (quick); |
|
2077} 2078 2079#ifdef INET6 2080void 2081pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr, 2082 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af) 2083{ 2084 switch (af) { --- 287 unchanged lines hidden (view full) --- 2372} 2373 2374int 2375pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, 2376 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport, 2377 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high, 2378 struct pf_src_node **sn) 2379{ | 2275} 2276 2277#ifdef INET6 2278void 2279pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr, 2280 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af) 2281{ 2282 switch (af) { --- 287 unchanged lines hidden (view full) --- 2570} 2571 2572int 2573pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, 2574 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport, 2575 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high, 2576 struct pf_src_node **sn) 2577{ |
2380 struct pf_state key; | 2578 struct pf_state_cmp key; |
2381 struct pf_addr init_addr; 2382 u_int16_t cut; 2383 2384 bzero(&init_addr, sizeof(init_addr)); 2385 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) 2386 return (1); 2387 2388 if (proto == IPPROTO_ICMP) { --- 75 unchanged lines hidden (view full) --- 2464 2465struct pf_rule * 2466pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, 2467 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport, 2468 struct pf_addr *daddr, u_int16_t dport, int rs_num) 2469{ 2470 struct pf_rule *r, *rm = NULL; 2471 struct pf_ruleset *ruleset = NULL; | 2579 struct pf_addr init_addr; 2580 u_int16_t cut; 2581 2582 bzero(&init_addr, sizeof(init_addr)); 2583 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) 2584 return (1); 2585 2586 if (proto == IPPROTO_ICMP) { --- 75 unchanged lines hidden (view full) --- 2662 2663struct pf_rule * 2664pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, 2665 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport, 2666 struct pf_addr *daddr, u_int16_t dport, int rs_num) 2667{ 2668 struct pf_rule *r, *rm = NULL; 2669 struct pf_ruleset *ruleset = NULL; |
2472 struct pf_tag *pftag = NULL; | |
2473 int tag = -1; | 2670 int tag = -1; |
2671 int rtableid = -1; |
|
2474 int asd = 0; 2475 2476 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr); 2477 while (r && rm == NULL) { 2478 struct pf_rule_addr *src = NULL, *dst = NULL; 2479 struct pf_addr_wrap *xdst = NULL; 2480 2481 if (r->action == PF_BINAT && direction == PF_IN) { 2482 src = &r->dst; 2483 if (r->rpool.cur != NULL) 2484 xdst = &r->rpool.cur->addr; 2485 } else { 2486 src = &r->src; 2487 dst = &r->dst; 2488 } 2489 2490 r->evaluations++; | 2672 int asd = 0; 2673 2674 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr); 2675 while (r && rm == NULL) { 2676 struct pf_rule_addr *src = NULL, *dst = NULL; 2677 struct pf_addr_wrap *xdst = NULL; 2678 2679 if (r->action == PF_BINAT && direction == PF_IN) { 2680 src = &r->dst; 2681 if (r->rpool.cur != NULL) 2682 xdst = &r->rpool.cur->addr; 2683 } else { 2684 src = &r->src; 2685 dst = &r->dst; 2686 } 2687 2688 r->evaluations++; |
2491 if (r->kif != NULL && 2492 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) | 2689 if (pfi_kif_match(r->kif, kif) == r->ifnot) |
2493 r = r->skip[PF_SKIP_IFP].ptr; 2494 else if (r->direction && r->direction != direction) 2495 r = r->skip[PF_SKIP_DIR].ptr; 2496 else if (r->af && r->af != pd->af) 2497 r = r->skip[PF_SKIP_AF].ptr; 2498 else if (r->proto && r->proto != pd->proto) 2499 r = r->skip[PF_SKIP_PROTO].ptr; | 2690 r = r->skip[PF_SKIP_IFP].ptr; 2691 else if (r->direction && r->direction != direction) 2692 r = r->skip[PF_SKIP_DIR].ptr; 2693 else if (r->af && r->af != pd->af) 2694 r = r->skip[PF_SKIP_AF].ptr; 2695 else if (r->proto && r->proto != pd->proto) 2696 r = r->skip[PF_SKIP_PROTO].ptr; |
2500 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, src->neg)) | 2697 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, 2698 src->neg, kif)) |
2501 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR : 2502 PF_SKIP_DST_ADDR].ptr; 2503 else if (src->port_op && !pf_match_port(src->port_op, 2504 src->port[0], src->port[1], sport)) 2505 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT : 2506 PF_SKIP_DST_PORT].ptr; 2507 else if (dst != NULL && | 2699 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR : 2700 PF_SKIP_DST_ADDR].ptr; 2701 else if (src->port_op && !pf_match_port(src->port_op, 2702 src->port[0], src->port[1], sport)) 2703 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT : 2704 PF_SKIP_DST_PORT].ptr; 2705 else if (dst != NULL && |
2508 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg)) | 2706 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL)) |
2509 r = r->skip[PF_SKIP_DST_ADDR].ptr; | 2707 r = r->skip[PF_SKIP_DST_ADDR].ptr; |
2510 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, 0)) | 2708 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, 2709 0, NULL)) |
2511 r = TAILQ_NEXT(r, entries); 2512 else if (dst != NULL && dst->port_op && 2513 !pf_match_port(dst->port_op, dst->port[0], 2514 dst->port[1], dport)) 2515 r = r->skip[PF_SKIP_DST_PORT].ptr; | 2710 r = TAILQ_NEXT(r, entries); 2711 else if (dst != NULL && dst->port_op && 2712 !pf_match_port(dst->port_op, dst->port[0], 2713 dst->port[1], dport)) 2714 r = r->skip[PF_SKIP_DST_PORT].ptr; |
2516 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag)) | 2715 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) |
2517 r = TAILQ_NEXT(r, entries); 2518 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto != 2519 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m, 2520 off, pd->hdr.tcp), r->os_fingerprint))) 2521 r = TAILQ_NEXT(r, entries); 2522 else { 2523 if (r->tag) 2524 tag = r->tag; | 2716 r = TAILQ_NEXT(r, entries); 2717 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto != 2718 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m, 2719 off, pd->hdr.tcp), r->os_fingerprint))) 2720 r = TAILQ_NEXT(r, entries); 2721 else { 2722 if (r->tag) 2723 tag = r->tag; |
2724 if (r->rtableid >= 0) 2725 rtableid = r->rtableid; |
|
2525 if (r->anchor == NULL) { 2526 rm = r; 2527 } else | 2726 if (r->anchor == NULL) { 2727 rm = r; 2728 } else |
2528 pf_step_into_anchor(&asd, &ruleset, rs_num, &r, NULL); | 2729 pf_step_into_anchor(&asd, &ruleset, rs_num, 2730 &r, NULL, NULL); |
2529 } 2530 if (r == NULL) | 2731 } 2732 if (r == NULL) |
2531 pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r, NULL); | 2733 pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r, 2734 NULL, NULL); |
2532 } | 2735 } |
2533 if (pf_tag_packet(m, pftag, tag)) | 2736 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) |
2534 return (NULL); 2535 if (rm != NULL && (rm->action == PF_NONAT || 2536 rm->action == PF_NORDR || rm->action == PF_NOBINAT)) 2537 return (NULL); 2538 return (rm); 2539} 2540 2541struct pf_rule * --- 144 unchanged lines hidden (view full) --- 2686 } 2687 } 2688 2689 return (r); 2690} 2691 2692int 2693#ifdef __FreeBSD__ | 2737 return (NULL); 2738 if (rm != NULL && (rm->action == PF_NONAT || 2739 rm->action == PF_NORDR || rm->action == PF_NOBINAT)) 2740 return (NULL); 2741 return (rm); 2742} 2743 2744struct pf_rule * --- 144 unchanged lines hidden (view full) --- 2889 } 2890 } 2891 2892 return (r); 2893} 2894 2895int 2896#ifdef __FreeBSD__ |
2694pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd, 2695 struct inpcb *inp_arg) | 2897pf_socket_lookup(int direction, struct pf_pdesc *pd, struct inpcb *inp_arg) |
2696#else | 2898#else |
2697pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd) | 2899pf_socket_lookup(int direction, struct pf_pdesc *pd) |
2698#endif 2699{ 2700 struct pf_addr *saddr, *daddr; 2701 u_int16_t sport, dport; 2702#ifdef __FreeBSD__ 2703 struct inpcbinfo *pi; 2704#else 2705 struct inpcbtable *tb; 2706#endif 2707 struct inpcb *inp; 2708 | 2900#endif 2901{ 2902 struct pf_addr *saddr, *daddr; 2903 u_int16_t sport, dport; 2904#ifdef __FreeBSD__ 2905 struct inpcbinfo *pi; 2906#else 2907 struct inpcbtable *tb; 2908#endif 2909 struct inpcb *inp; 2910 |
2709 *uid = UID_MAX; 2710 *gid = GID_MAX; | 2911 if (pd == NULL) 2912 return (-1); 2913 pd->lookup.uid = UID_MAX; 2914 pd->lookup.gid = GID_MAX; 2915 pd->lookup.pid = NO_PID; /* XXX: revisit */ |
2711#ifdef __FreeBSD__ 2712 if (inp_arg != NULL) { 2713 INP_LOCK_ASSERT(inp_arg); 2714 if (inp_arg->inp_socket) { | 2916#ifdef __FreeBSD__ 2917 if (inp_arg != NULL) { 2918 INP_LOCK_ASSERT(inp_arg); 2919 if (inp_arg->inp_socket) { |
2715 *uid = inp_arg->inp_socket->so_cred->cr_uid; 2716 *gid = inp_arg->inp_socket->so_cred->cr_groups[0]; | 2920 pd->lookup.uid = inp_arg->inp_socket->so_cred->cr_uid; 2921 pd->lookup.gid = 2922 inp_arg->inp_socket->so_cred->cr_groups[0]; |
2717 return (1); 2718 } else | 2923 return (1); 2924 } else |
2719 return (0); | 2925 return (-1); |
2720 } 2721#endif 2722 switch (pd->proto) { 2723 case IPPROTO_TCP: | 2926 } 2927#endif 2928 switch (pd->proto) { 2929 case IPPROTO_TCP: |
2930 if (pd->hdr.tcp == NULL) 2931 return (-1); |
|
2724 sport = pd->hdr.tcp->th_sport; 2725 dport = pd->hdr.tcp->th_dport; 2726#ifdef __FreeBSD__ 2727 pi = &tcbinfo; 2728#else 2729 tb = &tcbtable; 2730#endif 2731 break; 2732 case IPPROTO_UDP: | 2932 sport = pd->hdr.tcp->th_sport; 2933 dport = pd->hdr.tcp->th_dport; 2934#ifdef __FreeBSD__ 2935 pi = &tcbinfo; 2936#else 2937 tb = &tcbtable; 2938#endif 2939 break; 2940 case IPPROTO_UDP: |
2941 if (pd->hdr.udp == NULL) 2942 return (-1); |
|
2733 sport = pd->hdr.udp->uh_sport; 2734 dport = pd->hdr.udp->uh_dport; 2735#ifdef __FreeBSD__ 2736 pi = &udbinfo; 2737#else 2738 tb = &udbtable; 2739#endif 2740 break; 2741 default: | 2943 sport = pd->hdr.udp->uh_sport; 2944 dport = pd->hdr.udp->uh_dport; 2945#ifdef __FreeBSD__ 2946 pi = &udbinfo; 2947#else 2948 tb = &udbtable; 2949#endif 2950 break; 2951 default: |
2742 return (0); | 2952 return (-1); |
2743 } 2744 if (direction == PF_IN) { 2745 saddr = pd->src; 2746 daddr = pd->dst; 2747 } else { 2748 u_int16_t p; 2749 2750 p = sport; --- 9 unchanged lines hidden (view full) --- 2760 INP_INFO_RLOCK(pi); /* XXX LOR */ 2761 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4, 2762 dport, 0, NULL); 2763 if (inp == NULL) { 2764 inp = in_pcblookup_hash(pi, saddr->v4, sport, 2765 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL); 2766 if(inp == NULL) { 2767 INP_INFO_RUNLOCK(pi); | 2953 } 2954 if (direction == PF_IN) { 2955 saddr = pd->src; 2956 daddr = pd->dst; 2957 } else { 2958 u_int16_t p; 2959 2960 p = sport; --- 9 unchanged lines hidden (view full) --- 2970 INP_INFO_RLOCK(pi); /* XXX LOR */ 2971 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4, 2972 dport, 0, NULL); 2973 if (inp == NULL) { 2974 inp = in_pcblookup_hash(pi, saddr->v4, sport, 2975 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL); 2976 if(inp == NULL) { 2977 INP_INFO_RUNLOCK(pi); |
2768 return (0); | 2978 return (-1); |
2769 } 2770 } 2771#else 2772 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); 2773 if (inp == NULL) { 2774 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0); 2775 if (inp == NULL) | 2979 } 2980 } 2981#else 2982 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); 2983 if (inp == NULL) { 2984 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0); 2985 if (inp == NULL) |
2776 return (0); | 2986 return (-1); |
2777 } 2778#endif 2779 break; 2780#endif /* INET */ 2781#ifdef INET6 2782 case AF_INET6: 2783#ifdef __FreeBSD__ 2784 INP_INFO_RLOCK(pi); 2785 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 2786 &daddr->v6, dport, 0, NULL); 2787 if (inp == NULL) { 2788 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 2789 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL); 2790 if (inp == NULL) { 2791 INP_INFO_RUNLOCK(pi); | 2987 } 2988#endif 2989 break; 2990#endif /* INET */ 2991#ifdef INET6 2992 case AF_INET6: 2993#ifdef __FreeBSD__ 2994 INP_INFO_RLOCK(pi); 2995 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 2996 &daddr->v6, dport, 0, NULL); 2997 if (inp == NULL) { 2998 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 2999 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL); 3000 if (inp == NULL) { 3001 INP_INFO_RUNLOCK(pi); |
2792 return (0); | 3002 return (-1); |
2793 } 2794 } 2795#else 2796 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, 2797 dport); 2798 if (inp == NULL) { 2799 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0); 2800 if (inp == NULL) | 3003 } 3004 } 3005#else 3006 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, 3007 dport); 3008 if (inp == NULL) { 3009 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0); 3010 if (inp == NULL) |
2801 return (0); | 3011 return (-1); |
2802 } 2803#endif 2804 break; 2805#endif /* INET6 */ 2806 2807 default: | 3012 } 3013#endif 3014 break; 3015#endif /* INET6 */ 3016 3017 default: |
2808 return (0); | 3018 return (-1); |
2809 } 2810#ifdef __FreeBSD__ 2811 INP_LOCK(inp); 2812 if ((inp->inp_socket == NULL) || (inp->inp_socket->so_cred == NULL)) { 2813 INP_UNLOCK(inp); 2814 INP_INFO_RUNLOCK(pi); | 3019 } 3020#ifdef __FreeBSD__ 3021 INP_LOCK(inp); 3022 if ((inp->inp_socket == NULL) || (inp->inp_socket->so_cred == NULL)) { 3023 INP_UNLOCK(inp); 3024 INP_INFO_RUNLOCK(pi); |
2815 return (0); | 3025 return (-1); |
2816 } | 3026 } |
2817 *uid = inp->inp_socket->so_cred->cr_uid; 2818 *gid = inp->inp_socket->so_cred->cr_groups[0]; | 3027 pd->lookup.uid = inp->inp_socket->so_cred->cr_uid; 3028 pd->lookup.gid = inp->inp_socket->so_cred->cr_groups[0]; |
2819 INP_UNLOCK(inp); 2820 INP_INFO_RUNLOCK(pi); 2821#else | 3029 INP_UNLOCK(inp); 3030 INP_INFO_RUNLOCK(pi); 3031#else |
2822 *uid = inp->inp_socket->so_euid; 2823 *gid = inp->inp_socket->so_egid; | 3032 pd->lookup.uid = inp->inp_socket->so_euid; 3033 pd->lookup.gid = inp->inp_socket->so_egid; 3034 pd->lookup.pid = inp->inp_socket->so_cpid; |
2824#endif 2825 return (1); 2826} 2827 2828u_int8_t 2829pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 2830{ 2831 int hlen; --- 177 unchanged lines hidden (view full) --- 3009 struct ifqueue *ifq) 3010#endif 3011{ 3012 struct pf_rule *nr = NULL; 3013 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3014 struct tcphdr *th = pd->hdr.tcp; 3015 u_int16_t bport, nport = 0; 3016 sa_family_t af = pd->af; | 3035#endif 3036 return (1); 3037} 3038 3039u_int8_t 3040pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 3041{ 3042 int hlen; --- 177 unchanged lines hidden (view full) --- 3220 struct ifqueue *ifq) 3221#endif 3222{ 3223 struct pf_rule *nr = NULL; 3224 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3225 struct tcphdr *th = pd->hdr.tcp; 3226 u_int16_t bport, nport = 0; 3227 sa_family_t af = pd->af; |
3017 int lookup = -1; 3018 uid_t uid; 3019 gid_t gid; | |
3020 struct pf_rule *r, *a = NULL; 3021 struct pf_ruleset *ruleset = NULL; 3022 struct pf_src_node *nsn = NULL; 3023 u_short reason; 3024 int rewrite = 0; | 3228 struct pf_rule *r, *a = NULL; 3229 struct pf_ruleset *ruleset = NULL; 3230 struct pf_src_node *nsn = NULL; 3231 u_short reason; 3232 int rewrite = 0; |
3025 struct pf_tag *pftag = NULL; 3026 int tag = -1; | 3233 int tag = -1, rtableid = -1; |
3027 u_int16_t mss = tcp_mssdflt; 3028 int asd = 0; | 3234 u_int16_t mss = tcp_mssdflt; 3235 int asd = 0; |
3236 int match = 0; |
|
3029 3030 if (pf_check_congestion(ifq)) { 3031 REASON_SET(&reason, PFRES_CONGEST); 3032 return (PF_DROP); 3033 } 3034 | 3237 3238 if (pf_check_congestion(ifq)) { 3239 REASON_SET(&reason, PFRES_CONGEST); 3240 return (PF_DROP); 3241 } 3242 |
3035#if defined(__FreeBSD__) && defined(PF_MPSAFE_UGID) 3036 PF_UNLOCK(); 3037 lookup = pf_socket_lookup(&uid, &gid, direction, pd, inp); 3038 PF_LOCK(); | 3243#ifdef __FreeBSD__ 3244 if (inp != NULL) 3245 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3246 else if (debug_pfugidhack) { 3247 PF_UNLOCK(); 3248 DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n")); 3249 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3250 PF_LOCK(); 3251 } |
3039#endif 3040 3041 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3042 3043 if (direction == PF_OUT) { 3044 bport = nport = th->th_sport; 3045 /* check outgoing packet for BINAT/NAT */ 3046 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, --- 20 unchanged lines hidden (view full) --- 3067 if (nr->natpass) 3068 r = NULL; 3069 pd->nat_rule = nr; 3070 } 3071 } 3072 3073 while (r != NULL) { 3074 r->evaluations++; | 3252#endif 3253 3254 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3255 3256 if (direction == PF_OUT) { 3257 bport = nport = th->th_sport; 3258 /* check outgoing packet for BINAT/NAT */ 3259 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, --- 20 unchanged lines hidden (view full) --- 3280 if (nr->natpass) 3281 r = NULL; 3282 pd->nat_rule = nr; 3283 } 3284 } 3285 3286 while (r != NULL) { 3287 r->evaluations++; |
3075 if (r->kif != NULL && 3076 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) | 3288 if (pfi_kif_match(r->kif, kif) == r->ifnot) |
3077 r = r->skip[PF_SKIP_IFP].ptr; 3078 else if (r->direction && r->direction != direction) 3079 r = r->skip[PF_SKIP_DIR].ptr; 3080 else if (r->af && r->af != af) 3081 r = r->skip[PF_SKIP_AF].ptr; 3082 else if (r->proto && r->proto != IPPROTO_TCP) 3083 r = r->skip[PF_SKIP_PROTO].ptr; | 3289 r = r->skip[PF_SKIP_IFP].ptr; 3290 else if (r->direction && r->direction != direction) 3291 r = r->skip[PF_SKIP_DIR].ptr; 3292 else if (r->af && r->af != af) 3293 r = r->skip[PF_SKIP_AF].ptr; 3294 else if (r->proto && r->proto != IPPROTO_TCP) 3295 r = r->skip[PF_SKIP_PROTO].ptr; |
3084 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg)) | 3296 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, 3297 r->src.neg, kif)) |
3085 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3086 else if (r->src.port_op && !pf_match_port(r->src.port_op, 3087 r->src.port[0], r->src.port[1], th->th_sport)) 3088 r = r->skip[PF_SKIP_SRC_PORT].ptr; | 3298 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3299 else if (r->src.port_op && !pf_match_port(r->src.port_op, 3300 r->src.port[0], r->src.port[1], th->th_sport)) 3301 r = r->skip[PF_SKIP_SRC_PORT].ptr; |
3089 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg)) | 3302 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, 3303 r->dst.neg, NULL)) |
3090 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3091 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 3092 r->dst.port[0], r->dst.port[1], th->th_dport)) 3093 r = r->skip[PF_SKIP_DST_PORT].ptr; | 3304 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3305 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 3306 r->dst.port[0], r->dst.port[1], th->th_dport)) 3307 r = r->skip[PF_SKIP_DST_PORT].ptr; |
3094 else if (r->tos && !(r->tos & pd->tos)) | 3308 else if (r->tos && !(r->tos == pd->tos)) |
3095 r = TAILQ_NEXT(r, entries); 3096 else if (r->rule_flag & PFRULE_FRAGMENT) 3097 r = TAILQ_NEXT(r, entries); 3098 else if ((r->flagset & th->th_flags) != r->flags) 3099 r = TAILQ_NEXT(r, entries); | 3309 r = TAILQ_NEXT(r, entries); 3310 else if (r->rule_flag & PFRULE_FRAGMENT) 3311 r = TAILQ_NEXT(r, entries); 3312 else if ((r->flagset & th->th_flags) != r->flags) 3313 r = TAILQ_NEXT(r, entries); |
3100 else if (r->uid.op && (lookup != -1 || (lookup = | 3314 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done = |
3101#ifdef __FreeBSD__ | 3315#ifdef __FreeBSD__ |
3102 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) && | 3316 pf_socket_lookup(direction, pd, inp), 1)) && |
3103#else | 3317#else |
3104 pf_socket_lookup(&uid, &gid, direction, pd), 1)) && | 3318 pf_socket_lookup(direction, pd), 1)) && |
3105#endif 3106 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], | 3319#endif 3320 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], |
3107 uid)) | 3321 pd->lookup.uid)) |
3108 r = TAILQ_NEXT(r, entries); | 3322 r = TAILQ_NEXT(r, entries); |
3109 else if (r->gid.op && (lookup != -1 || (lookup = | 3323 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done = |
3110#ifdef __FreeBSD__ | 3324#ifdef __FreeBSD__ |
3111 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) && | 3325 pf_socket_lookup(direction, pd, inp), 1)) && |
3112#else | 3326#else |
3113 pf_socket_lookup(&uid, &gid, direction, pd), 1)) && | 3327 pf_socket_lookup(direction, pd), 1)) && |
3114#endif 3115 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], | 3328#endif 3329 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], |
3116 gid)) | 3330 pd->lookup.gid)) |
3117 r = TAILQ_NEXT(r, entries); 3118 else if (r->prob && r->prob <= arc4random()) 3119 r = TAILQ_NEXT(r, entries); | 3331 r = TAILQ_NEXT(r, entries); 3332 else if (r->prob && r->prob <= arc4random()) 3333 r = TAILQ_NEXT(r, entries); |
3120 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag)) | 3334 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) |
3121 r = TAILQ_NEXT(r, entries); 3122 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match( 3123 pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint)) 3124 r = TAILQ_NEXT(r, entries); 3125 else { 3126 if (r->tag) 3127 tag = r->tag; | 3335 r = TAILQ_NEXT(r, entries); 3336 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match( 3337 pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint)) 3338 r = TAILQ_NEXT(r, entries); 3339 else { 3340 if (r->tag) 3341 tag = r->tag; |
3342 if (r->rtableid >= 0) 3343 rtableid = r->rtableid; |
|
3128 if (r->anchor == NULL) { | 3344 if (r->anchor == NULL) { |
3345 match = 1; |
|
3129 *rm = r; 3130 *am = a; 3131 *rsm = ruleset; 3132 if ((*rm)->quick) 3133 break; 3134 r = TAILQ_NEXT(r, entries); 3135 } else 3136 pf_step_into_anchor(&asd, &ruleset, | 3346 *rm = r; 3347 *am = a; 3348 *rsm = ruleset; 3349 if ((*rm)->quick) 3350 break; 3351 r = TAILQ_NEXT(r, entries); 3352 } else 3353 pf_step_into_anchor(&asd, &ruleset, |
3137 PF_RULESET_FILTER, &r, &a); | 3354 PF_RULESET_FILTER, &r, &a, &match); |
3138 } | 3355 } |
3139 if (r == NULL) 3140 pf_step_out_of_anchor(&asd, &ruleset, 3141 PF_RULESET_FILTER, &r, &a); | 3356 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 3357 PF_RULESET_FILTER, &r, &a, &match)) 3358 break; |
3142 } 3143 r = *rm; 3144 a = *am; 3145 ruleset = *rsm; 3146 3147 REASON_SET(&reason, PFRES_MATCH); 3148 | 3359 } 3360 r = *rm; 3361 a = *am; 3362 ruleset = *rsm; 3363 3364 REASON_SET(&reason, PFRES_MATCH); 3365 |
3149 if (r->log) { | 3366 if (r->log || (nr != NULL && nr->natpass && nr->log)) { |
3150 if (rewrite) | 3367 if (rewrite) |
3368#ifdef __FreeBSD__ |
|
3151 m_copyback(m, off, sizeof(*th), (caddr_t)th); | 3369 m_copyback(m, off, sizeof(*th), (caddr_t)th); |
3152 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); | 3370#else 3371 m_copyback(m, off, sizeof(*th), th); 3372#endif 3373 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 3374 a, ruleset, pd); |
3153 } 3154 3155 if ((r->action == PF_DROP) && 3156 ((r->rule_flag & PFRULE_RETURNRST) || 3157 (r->rule_flag & PFRULE_RETURNICMP) || 3158 (r->rule_flag & PFRULE_RETURN))) { 3159 /* undo NAT changes, if they have taken place */ 3160 if (nr != NULL) { --- 18 unchanged lines hidden (view full) --- 3179 ack++; 3180#ifdef __FreeBSD__ 3181 pf_send_tcp(m, r, af, pd->dst, 3182#else 3183 pf_send_tcp(r, af, pd->dst, 3184#endif 3185 pd->src, th->th_dport, th->th_sport, 3186 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0, | 3375 } 3376 3377 if ((r->action == PF_DROP) && 3378 ((r->rule_flag & PFRULE_RETURNRST) || 3379 (r->rule_flag & PFRULE_RETURNICMP) || 3380 (r->rule_flag & PFRULE_RETURN))) { 3381 /* undo NAT changes, if they have taken place */ 3382 if (nr != NULL) { --- 18 unchanged lines hidden (view full) --- 3401 ack++; 3402#ifdef __FreeBSD__ 3403 pf_send_tcp(m, r, af, pd->dst, 3404#else 3405 pf_send_tcp(r, af, pd->dst, 3406#endif 3407 pd->src, th->th_dport, th->th_sport, 3408 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0, |
3187 r->return_ttl, 1, pd->eh, kif->pfik_ifp); | 3409 r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp); |
3188 } else if ((af == AF_INET) && r->return_icmp) 3189 pf_send_icmp(m, r->return_icmp >> 8, 3190 r->return_icmp & 255, af, r); 3191 else if ((af == AF_INET6) && r->return_icmp6) 3192 pf_send_icmp(m, r->return_icmp6 >> 8, 3193 r->return_icmp6 & 255, af, r); 3194 } 3195 3196 if (r->action == PF_DROP) 3197 return (PF_DROP); 3198 | 3410 } else if ((af == AF_INET) && r->return_icmp) 3411 pf_send_icmp(m, r->return_icmp >> 8, 3412 r->return_icmp & 255, af, r); 3413 else if ((af == AF_INET6) && r->return_icmp6) 3414 pf_send_icmp(m, r->return_icmp6 >> 8, 3415 r->return_icmp6 & 255, af, r); 3416 } 3417 3418 if (r->action == PF_DROP) 3419 return (PF_DROP); 3420 |
3199 if (pf_tag_packet(m, pftag, tag)) { | 3421 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) { |
3200 REASON_SET(&reason, PFRES_MEMORY); 3201 return (PF_DROP); 3202 } 3203 3204 if (r->keep_state || nr != NULL || 3205 (pd->flags & PFDESC_TCP_NORM)) { 3206 /* create new state */ 3207 u_int16_t len; 3208 struct pf_state *s = NULL; 3209 struct pf_src_node *sn = NULL; 3210 3211 len = pd->tot_len - off - (th->th_off << 2); 3212 3213 /* check maximums */ 3214 if (r->max_states && (r->states >= r->max_states)) { 3215 pf_status.lcounters[LCNT_STATES]++; 3216 REASON_SET(&reason, PFRES_MAXSTATES); 3217 goto cleanup; 3218 } | 3422 REASON_SET(&reason, PFRES_MEMORY); 3423 return (PF_DROP); 3424 } 3425 3426 if (r->keep_state || nr != NULL || 3427 (pd->flags & PFDESC_TCP_NORM)) { 3428 /* create new state */ 3429 u_int16_t len; 3430 struct pf_state *s = NULL; 3431 struct pf_src_node *sn = NULL; 3432 3433 len = pd->tot_len - off - (th->th_off << 2); 3434 3435 /* check maximums */ 3436 if (r->max_states && (r->states >= r->max_states)) { 3437 pf_status.lcounters[LCNT_STATES]++; 3438 REASON_SET(&reason, PFRES_MAXSTATES); 3439 goto cleanup; 3440 } |
3219 /* src node for flter rule */ | 3441 /* src node for filter rule */ |
3220 if ((r->rule_flag & PFRULE_SRCTRACK || 3221 r->rpool.opts & PF_POOL_STICKYADDR) && 3222 pf_insert_src_node(&sn, r, saddr, af) != 0) { 3223 REASON_SET(&reason, PFRES_SRCLIMIT); 3224 goto cleanup; 3225 } 3226 /* src node for translation rule */ 3227 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && --- 23 unchanged lines hidden (view full) --- 3251 return (PF_DROP); 3252 } 3253 bzero(s, sizeof(*s)); 3254 s->rule.ptr = r; 3255 s->nat_rule.ptr = nr; 3256 s->anchor.ptr = a; 3257 STATE_INC_COUNTERS(s); 3258 s->allow_opts = r->allow_opts; | 3442 if ((r->rule_flag & PFRULE_SRCTRACK || 3443 r->rpool.opts & PF_POOL_STICKYADDR) && 3444 pf_insert_src_node(&sn, r, saddr, af) != 0) { 3445 REASON_SET(&reason, PFRES_SRCLIMIT); 3446 goto cleanup; 3447 } 3448 /* src node for translation rule */ 3449 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && --- 23 unchanged lines hidden (view full) --- 3473 return (PF_DROP); 3474 } 3475 bzero(s, sizeof(*s)); 3476 s->rule.ptr = r; 3477 s->nat_rule.ptr = nr; 3478 s->anchor.ptr = a; 3479 STATE_INC_COUNTERS(s); 3480 s->allow_opts = r->allow_opts; |
3259 s->log = r->log & 2; | 3481 s->log = r->log & PF_LOG_ALL; 3482 if (nr != NULL) 3483 s->log |= nr->log & PF_LOG_ALL; |
3260 s->proto = IPPROTO_TCP; 3261 s->direction = direction; 3262 s->af = af; 3263 if (direction == PF_OUT) { 3264 PF_ACPY(&s->gwy.addr, saddr, af); 3265 s->gwy.port = th->th_sport; /* sport */ 3266 PF_ACPY(&s->ext.addr, daddr, af); 3267 s->ext.port = th->th_dport; --- 18 unchanged lines hidden (view full) --- 3286 } 3287 } 3288 3289 s->src.seqlo = ntohl(th->th_seq); 3290 s->src.seqhi = s->src.seqlo + len + 1; 3291 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 3292 r->keep_state == PF_STATE_MODULATE) { 3293 /* Generate sequence number modulator */ | 3484 s->proto = IPPROTO_TCP; 3485 s->direction = direction; 3486 s->af = af; 3487 if (direction == PF_OUT) { 3488 PF_ACPY(&s->gwy.addr, saddr, af); 3489 s->gwy.port = th->th_sport; /* sport */ 3490 PF_ACPY(&s->ext.addr, daddr, af); 3491 s->ext.port = th->th_dport; --- 18 unchanged lines hidden (view full) --- 3510 } 3511 } 3512 3513 s->src.seqlo = ntohl(th->th_seq); 3514 s->src.seqhi = s->src.seqlo + len + 1; 3515 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 3516 r->keep_state == PF_STATE_MODULATE) { 3517 /* Generate sequence number modulator */ |
3294 while ((s->src.seqdiff = htonl(arc4random())) == 0) | 3518#ifdef __FreeBSD__ 3519 while ((s->src.seqdiff = 3520 pf_new_isn(s) - s->src.seqlo) == 0) 3521 ; 3522#else 3523 while ((s->src.seqdiff = 3524 tcp_rndiss_next() - s->src.seqlo) == 0) |
3295 ; | 3525 ; |
3526#endif |
|
3296 pf_change_a(&th->th_seq, &th->th_sum, 3297 htonl(s->src.seqlo + s->src.seqdiff), 0); 3298 rewrite = 1; 3299 } else 3300 s->src.seqdiff = 0; 3301 if (th->th_flags & TH_SYN) { 3302 s->src.seqhi++; 3303 s->src.wscale = pf_get_wscale(m, off, th->th_off, af); --- 79 unchanged lines hidden (view full) --- 3383 mss = pf_calc_mss(daddr, af, mss); 3384 s->src.mss = mss; 3385#ifdef __FreeBSD__ 3386 pf_send_tcp(NULL, r, af, daddr, saddr, th->th_dport, 3387#else 3388 pf_send_tcp(r, af, daddr, saddr, th->th_dport, 3389#endif 3390 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1, | 3527 pf_change_a(&th->th_seq, &th->th_sum, 3528 htonl(s->src.seqlo + s->src.seqdiff), 0); 3529 rewrite = 1; 3530 } else 3531 s->src.seqdiff = 0; 3532 if (th->th_flags & TH_SYN) { 3533 s->src.seqhi++; 3534 s->src.wscale = pf_get_wscale(m, off, th->th_off, af); --- 79 unchanged lines hidden (view full) --- 3614 mss = pf_calc_mss(daddr, af, mss); 3615 s->src.mss = mss; 3616#ifdef __FreeBSD__ 3617 pf_send_tcp(NULL, r, af, daddr, saddr, th->th_dport, 3618#else 3619 pf_send_tcp(r, af, daddr, saddr, th->th_dport, 3620#endif 3621 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1, |
3391 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, NULL, NULL); | 3622 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL); |
3392 REASON_SET(&reason, PFRES_SYNPROXY); 3393 return (PF_SYNPROXY_DROP); 3394 } 3395 } 3396 3397 /* copy back packet headers if we performed NAT operations */ 3398 if (rewrite) 3399 m_copyback(m, off, sizeof(*th), (caddr_t)th); --- 12 unchanged lines hidden (view full) --- 3412 struct ifqueue *ifq) 3413#endif 3414{ 3415 struct pf_rule *nr = NULL; 3416 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3417 struct udphdr *uh = pd->hdr.udp; 3418 u_int16_t bport, nport = 0; 3419 sa_family_t af = pd->af; | 3623 REASON_SET(&reason, PFRES_SYNPROXY); 3624 return (PF_SYNPROXY_DROP); 3625 } 3626 } 3627 3628 /* copy back packet headers if we performed NAT operations */ 3629 if (rewrite) 3630 m_copyback(m, off, sizeof(*th), (caddr_t)th); --- 12 unchanged lines hidden (view full) --- 3643 struct ifqueue *ifq) 3644#endif 3645{ 3646 struct pf_rule *nr = NULL; 3647 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3648 struct udphdr *uh = pd->hdr.udp; 3649 u_int16_t bport, nport = 0; 3650 sa_family_t af = pd->af; |
3420 int lookup = -1; 3421 uid_t uid; 3422 gid_t gid; | |
3423 struct pf_rule *r, *a = NULL; 3424 struct pf_ruleset *ruleset = NULL; 3425 struct pf_src_node *nsn = NULL; 3426 u_short reason; 3427 int rewrite = 0; | 3651 struct pf_rule *r, *a = NULL; 3652 struct pf_ruleset *ruleset = NULL; 3653 struct pf_src_node *nsn = NULL; 3654 u_short reason; 3655 int rewrite = 0; |
3428 struct pf_tag *pftag = NULL; 3429 int tag = -1; | 3656 int tag = -1, rtableid = -1; |
3430 int asd = 0; | 3657 int asd = 0; |
3658 int match = 0; |
|
3431 3432 if (pf_check_congestion(ifq)) { 3433 REASON_SET(&reason, PFRES_CONGEST); 3434 return (PF_DROP); 3435 } 3436 | 3659 3660 if (pf_check_congestion(ifq)) { 3661 REASON_SET(&reason, PFRES_CONGEST); 3662 return (PF_DROP); 3663 } 3664 |
3437#if defined(__FreeBSD__) && defined(PF_MPSAFE_UGID) 3438 PF_UNLOCK(); 3439 lookup = pf_socket_lookup(&uid, &gid, direction, pd, inp); 3440 PF_LOCK(); | 3665#ifdef __FreeBSD__ 3666 if (inp != NULL) 3667 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3668 else if (debug_pfugidhack) { 3669 PF_UNLOCK(); 3670 DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n")); 3671 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3672 PF_LOCK(); 3673 } |
3441#endif 3442 3443 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3444 3445 if (direction == PF_OUT) { 3446 bport = nport = uh->uh_sport; 3447 /* check outgoing packet for BINAT/NAT */ 3448 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, --- 20 unchanged lines hidden (view full) --- 3469 if (nr->natpass) 3470 r = NULL; 3471 pd->nat_rule = nr; 3472 } 3473 } 3474 3475 while (r != NULL) { 3476 r->evaluations++; | 3674#endif 3675 3676 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3677 3678 if (direction == PF_OUT) { 3679 bport = nport = uh->uh_sport; 3680 /* check outgoing packet for BINAT/NAT */ 3681 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, --- 20 unchanged lines hidden (view full) --- 3702 if (nr->natpass) 3703 r = NULL; 3704 pd->nat_rule = nr; 3705 } 3706 } 3707 3708 while (r != NULL) { 3709 r->evaluations++; |
3477 if (r->kif != NULL && 3478 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) | 3710 if (pfi_kif_match(r->kif, kif) == r->ifnot) |
3479 r = r->skip[PF_SKIP_IFP].ptr; 3480 else if (r->direction && r->direction != direction) 3481 r = r->skip[PF_SKIP_DIR].ptr; 3482 else if (r->af && r->af != af) 3483 r = r->skip[PF_SKIP_AF].ptr; 3484 else if (r->proto && r->proto != IPPROTO_UDP) 3485 r = r->skip[PF_SKIP_PROTO].ptr; | 3711 r = r->skip[PF_SKIP_IFP].ptr; 3712 else if (r->direction && r->direction != direction) 3713 r = r->skip[PF_SKIP_DIR].ptr; 3714 else if (r->af && r->af != af) 3715 r = r->skip[PF_SKIP_AF].ptr; 3716 else if (r->proto && r->proto != IPPROTO_UDP) 3717 r = r->skip[PF_SKIP_PROTO].ptr; |
3486 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg)) | 3718 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, 3719 r->src.neg, kif)) |
3487 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3488 else if (r->src.port_op && !pf_match_port(r->src.port_op, 3489 r->src.port[0], r->src.port[1], uh->uh_sport)) 3490 r = r->skip[PF_SKIP_SRC_PORT].ptr; | 3720 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3721 else if (r->src.port_op && !pf_match_port(r->src.port_op, 3722 r->src.port[0], r->src.port[1], uh->uh_sport)) 3723 r = r->skip[PF_SKIP_SRC_PORT].ptr; |
3491 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg)) | 3724 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, 3725 r->dst.neg, NULL)) |
3492 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3493 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 3494 r->dst.port[0], r->dst.port[1], uh->uh_dport)) 3495 r = r->skip[PF_SKIP_DST_PORT].ptr; | 3726 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3727 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 3728 r->dst.port[0], r->dst.port[1], uh->uh_dport)) 3729 r = r->skip[PF_SKIP_DST_PORT].ptr; |
3496 else if (r->tos && !(r->tos & pd->tos)) | 3730 else if (r->tos && !(r->tos == pd->tos)) |
3497 r = TAILQ_NEXT(r, entries); 3498 else if (r->rule_flag & PFRULE_FRAGMENT) 3499 r = TAILQ_NEXT(r, entries); | 3731 r = TAILQ_NEXT(r, entries); 3732 else if (r->rule_flag & PFRULE_FRAGMENT) 3733 r = TAILQ_NEXT(r, entries); |
3500 else if (r->uid.op && (lookup != -1 || (lookup = | 3734 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done = |
3501#ifdef __FreeBSD__ | 3735#ifdef __FreeBSD__ |
3502 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) && | 3736 pf_socket_lookup(direction, pd, inp), 1)) && |
3503#else | 3737#else |
3504 pf_socket_lookup(&uid, &gid, direction, pd), 1)) && | 3738 pf_socket_lookup(direction, pd), 1)) && |
3505#endif 3506 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], | 3739#endif 3740 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], |
3507 uid)) | 3741 pd->lookup.uid)) |
3508 r = TAILQ_NEXT(r, entries); | 3742 r = TAILQ_NEXT(r, entries); |
3509 else if (r->gid.op && (lookup != -1 || (lookup = | 3743 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done = |
3510#ifdef __FreeBSD__ | 3744#ifdef __FreeBSD__ |
3511 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) && | 3745 pf_socket_lookup(direction, pd, inp), 1)) && |
3512#else | 3746#else |
3513 pf_socket_lookup(&uid, &gid, direction, pd), 1)) && | 3747 pf_socket_lookup(direction, pd), 1)) && |
3514#endif 3515 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], | 3748#endif 3749 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], |
3516 gid)) | 3750 pd->lookup.gid)) |
3517 r = TAILQ_NEXT(r, entries); 3518 else if (r->prob && r->prob <= arc4random()) 3519 r = TAILQ_NEXT(r, entries); | 3751 r = TAILQ_NEXT(r, entries); 3752 else if (r->prob && r->prob <= arc4random()) 3753 r = TAILQ_NEXT(r, entries); |
3520 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag)) | 3754 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) |
3521 r = TAILQ_NEXT(r, entries); 3522 else if (r->os_fingerprint != PF_OSFP_ANY) 3523 r = TAILQ_NEXT(r, entries); 3524 else { 3525 if (r->tag) 3526 tag = r->tag; | 3755 r = TAILQ_NEXT(r, entries); 3756 else if (r->os_fingerprint != PF_OSFP_ANY) 3757 r = TAILQ_NEXT(r, entries); 3758 else { 3759 if (r->tag) 3760 tag = r->tag; |
3761 if (r->rtableid >= 0) 3762 rtableid = r->rtableid; |
|
3527 if (r->anchor == NULL) { | 3763 if (r->anchor == NULL) { |
3764 match = 1; |
|
3528 *rm = r; 3529 *am = a; 3530 *rsm = ruleset; 3531 if ((*rm)->quick) 3532 break; 3533 r = TAILQ_NEXT(r, entries); 3534 } else 3535 pf_step_into_anchor(&asd, &ruleset, | 3765 *rm = r; 3766 *am = a; 3767 *rsm = ruleset; 3768 if ((*rm)->quick) 3769 break; 3770 r = TAILQ_NEXT(r, entries); 3771 } else 3772 pf_step_into_anchor(&asd, &ruleset, |
3536 PF_RULESET_FILTER, &r, &a); | 3773 PF_RULESET_FILTER, &r, &a, &match); |
3537 } | 3774 } |
3538 if (r == NULL) 3539 pf_step_out_of_anchor(&asd, &ruleset, 3540 PF_RULESET_FILTER, &r, &a); | 3775 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 3776 PF_RULESET_FILTER, &r, &a, &match)) 3777 break; |
3541 } 3542 r = *rm; 3543 a = *am; 3544 ruleset = *rsm; 3545 3546 REASON_SET(&reason, PFRES_MATCH); 3547 | 3778 } 3779 r = *rm; 3780 a = *am; 3781 ruleset = *rsm; 3782 3783 REASON_SET(&reason, PFRES_MATCH); 3784 |
3548 if (r->log) { | 3785 if (r->log || (nr != NULL && nr->natpass && nr->log)) { |
3549 if (rewrite) | 3786 if (rewrite) |
3787#ifdef __FreeBSD__ |
|
3550 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); | 3788 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); |
3551 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); | 3789#else 3790 m_copyback(m, off, sizeof(*uh), uh); 3791#endif 3792 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 3793 a, ruleset, pd); |
3552 } 3553 3554 if ((r->action == PF_DROP) && 3555 ((r->rule_flag & PFRULE_RETURNICMP) || 3556 (r->rule_flag & PFRULE_RETURN))) { 3557 /* undo NAT changes, if they have taken place */ 3558 if (nr != NULL) { 3559 if (direction == PF_OUT) { --- 12 unchanged lines hidden (view full) --- 3572 else if ((af == AF_INET6) && r->return_icmp6) 3573 pf_send_icmp(m, r->return_icmp6 >> 8, 3574 r->return_icmp6 & 255, af, r); 3575 } 3576 3577 if (r->action == PF_DROP) 3578 return (PF_DROP); 3579 | 3794 } 3795 3796 if ((r->action == PF_DROP) && 3797 ((r->rule_flag & PFRULE_RETURNICMP) || 3798 (r->rule_flag & PFRULE_RETURN))) { 3799 /* undo NAT changes, if they have taken place */ 3800 if (nr != NULL) { 3801 if (direction == PF_OUT) { --- 12 unchanged lines hidden (view full) --- 3814 else if ((af == AF_INET6) && r->return_icmp6) 3815 pf_send_icmp(m, r->return_icmp6 >> 8, 3816 r->return_icmp6 & 255, af, r); 3817 } 3818 3819 if (r->action == PF_DROP) 3820 return (PF_DROP); 3821 |
3580 if (pf_tag_packet(m, pftag, tag)) { | 3822 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) { |
3581 REASON_SET(&reason, PFRES_MEMORY); 3582 return (PF_DROP); 3583 } 3584 3585 if (r->keep_state || nr != NULL) { 3586 /* create new state */ 3587 struct pf_state *s = NULL; 3588 struct pf_src_node *sn = NULL; 3589 3590 /* check maximums */ 3591 if (r->max_states && (r->states >= r->max_states)) { 3592 pf_status.lcounters[LCNT_STATES]++; 3593 REASON_SET(&reason, PFRES_MAXSTATES); 3594 goto cleanup; 3595 } | 3823 REASON_SET(&reason, PFRES_MEMORY); 3824 return (PF_DROP); 3825 } 3826 3827 if (r->keep_state || nr != NULL) { 3828 /* create new state */ 3829 struct pf_state *s = NULL; 3830 struct pf_src_node *sn = NULL; 3831 3832 /* check maximums */ 3833 if (r->max_states && (r->states >= r->max_states)) { 3834 pf_status.lcounters[LCNT_STATES]++; 3835 REASON_SET(&reason, PFRES_MAXSTATES); 3836 goto cleanup; 3837 } |
3596 /* src node for flter rule */ | 3838 /* src node for filter rule */ |
3597 if ((r->rule_flag & PFRULE_SRCTRACK || 3598 r->rpool.opts & PF_POOL_STICKYADDR) && 3599 pf_insert_src_node(&sn, r, saddr, af) != 0) { 3600 REASON_SET(&reason, PFRES_SRCLIMIT); 3601 goto cleanup; 3602 } 3603 /* src node for translation rule */ 3604 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && --- 23 unchanged lines hidden (view full) --- 3628 return (PF_DROP); 3629 } 3630 bzero(s, sizeof(*s)); 3631 s->rule.ptr = r; 3632 s->nat_rule.ptr = nr; 3633 s->anchor.ptr = a; 3634 STATE_INC_COUNTERS(s); 3635 s->allow_opts = r->allow_opts; | 3839 if ((r->rule_flag & PFRULE_SRCTRACK || 3840 r->rpool.opts & PF_POOL_STICKYADDR) && 3841 pf_insert_src_node(&sn, r, saddr, af) != 0) { 3842 REASON_SET(&reason, PFRES_SRCLIMIT); 3843 goto cleanup; 3844 } 3845 /* src node for translation rule */ 3846 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && --- 23 unchanged lines hidden (view full) --- 3870 return (PF_DROP); 3871 } 3872 bzero(s, sizeof(*s)); 3873 s->rule.ptr = r; 3874 s->nat_rule.ptr = nr; 3875 s->anchor.ptr = a; 3876 STATE_INC_COUNTERS(s); 3877 s->allow_opts = r->allow_opts; |
3636 s->log = r->log & 2; | 3878 s->log = r->log & PF_LOG_ALL; 3879 if (nr != NULL) 3880 s->log |= nr->log & PF_LOG_ALL; |
3637 s->proto = IPPROTO_UDP; 3638 s->direction = direction; 3639 s->af = af; 3640 if (direction == PF_OUT) { 3641 PF_ACPY(&s->gwy.addr, saddr, af); 3642 s->gwy.port = uh->uh_sport; 3643 PF_ACPY(&s->ext.addr, daddr, af); 3644 s->ext.port = uh->uh_dport; --- 65 unchanged lines hidden (view full) --- 3710 struct pf_ruleset *ruleset = NULL; 3711 struct pf_src_node *nsn = NULL; 3712 u_short reason; 3713 u_int16_t icmpid = 0, bport, nport = 0; 3714 sa_family_t af = pd->af; 3715 u_int8_t icmptype = 0; /* make the compiler happy */ 3716 u_int8_t icmpcode = 0; /* make the compiler happy */ 3717 int state_icmp = 0; | 3881 s->proto = IPPROTO_UDP; 3882 s->direction = direction; 3883 s->af = af; 3884 if (direction == PF_OUT) { 3885 PF_ACPY(&s->gwy.addr, saddr, af); 3886 s->gwy.port = uh->uh_sport; 3887 PF_ACPY(&s->ext.addr, daddr, af); 3888 s->ext.port = uh->uh_dport; --- 65 unchanged lines hidden (view full) --- 3954 struct pf_ruleset *ruleset = NULL; 3955 struct pf_src_node *nsn = NULL; 3956 u_short reason; 3957 u_int16_t icmpid = 0, bport, nport = 0; 3958 sa_family_t af = pd->af; 3959 u_int8_t icmptype = 0; /* make the compiler happy */ 3960 u_int8_t icmpcode = 0; /* make the compiler happy */ 3961 int state_icmp = 0; |
3718 struct pf_tag *pftag = NULL; 3719 int tag = -1; | 3962 int tag = -1, rtableid = -1; |
3720#ifdef INET6 3721 int rewrite = 0; 3722#endif /* INET6 */ 3723 int asd = 0; | 3963#ifdef INET6 3964 int rewrite = 0; 3965#endif /* INET6 */ 3966 int asd = 0; |
3967 int match = 0; |
|
3724 3725 if (pf_check_congestion(ifq)) { 3726 REASON_SET(&reason, PFRES_CONGEST); 3727 return (PF_DROP); 3728 } 3729 3730 switch (pd->proto) { 3731#ifdef INET --- 83 unchanged lines hidden (view full) --- 3815 if (nr->natpass) 3816 r = NULL; 3817 pd->nat_rule = nr; 3818 } 3819 } 3820 3821 while (r != NULL) { 3822 r->evaluations++; | 3968 3969 if (pf_check_congestion(ifq)) { 3970 REASON_SET(&reason, PFRES_CONGEST); 3971 return (PF_DROP); 3972 } 3973 3974 switch (pd->proto) { 3975#ifdef INET --- 83 unchanged lines hidden (view full) --- 4059 if (nr->natpass) 4060 r = NULL; 4061 pd->nat_rule = nr; 4062 } 4063 } 4064 4065 while (r != NULL) { 4066 r->evaluations++; |
3823 if (r->kif != NULL && 3824 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) | 4067 if (pfi_kif_match(r->kif, kif) == r->ifnot) |
3825 r = r->skip[PF_SKIP_IFP].ptr; 3826 else if (r->direction && r->direction != direction) 3827 r = r->skip[PF_SKIP_DIR].ptr; 3828 else if (r->af && r->af != af) 3829 r = r->skip[PF_SKIP_AF].ptr; 3830 else if (r->proto && r->proto != pd->proto) 3831 r = r->skip[PF_SKIP_PROTO].ptr; | 4068 r = r->skip[PF_SKIP_IFP].ptr; 4069 else if (r->direction && r->direction != direction) 4070 r = r->skip[PF_SKIP_DIR].ptr; 4071 else if (r->af && r->af != af) 4072 r = r->skip[PF_SKIP_AF].ptr; 4073 else if (r->proto && r->proto != pd->proto) 4074 r = r->skip[PF_SKIP_PROTO].ptr; |
3832 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg)) | 4075 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, 4076 r->src.neg, kif)) |
3833 r = r->skip[PF_SKIP_SRC_ADDR].ptr; | 4077 r = r->skip[PF_SKIP_SRC_ADDR].ptr; |
3834 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg)) | 4078 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, 4079 r->dst.neg, NULL)) |
3835 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3836 else if (r->type && r->type != icmptype + 1) 3837 r = TAILQ_NEXT(r, entries); 3838 else if (r->code && r->code != icmpcode + 1) 3839 r = TAILQ_NEXT(r, entries); | 4080 r = r->skip[PF_SKIP_DST_ADDR].ptr; 4081 else if (r->type && r->type != icmptype + 1) 4082 r = TAILQ_NEXT(r, entries); 4083 else if (r->code && r->code != icmpcode + 1) 4084 r = TAILQ_NEXT(r, entries); |
3840 else if (r->tos && !(r->tos & pd->tos)) | 4085 else if (r->tos && !(r->tos == pd->tos)) |
3841 r = TAILQ_NEXT(r, entries); 3842 else if (r->rule_flag & PFRULE_FRAGMENT) 3843 r = TAILQ_NEXT(r, entries); 3844 else if (r->prob && r->prob <= arc4random()) 3845 r = TAILQ_NEXT(r, entries); | 4086 r = TAILQ_NEXT(r, entries); 4087 else if (r->rule_flag & PFRULE_FRAGMENT) 4088 r = TAILQ_NEXT(r, entries); 4089 else if (r->prob && r->prob <= arc4random()) 4090 r = TAILQ_NEXT(r, entries); |
3846 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag)) | 4091 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) |
3847 r = TAILQ_NEXT(r, entries); 3848 else if (r->os_fingerprint != PF_OSFP_ANY) 3849 r = TAILQ_NEXT(r, entries); 3850 else { 3851 if (r->tag) 3852 tag = r->tag; | 4092 r = TAILQ_NEXT(r, entries); 4093 else if (r->os_fingerprint != PF_OSFP_ANY) 4094 r = TAILQ_NEXT(r, entries); 4095 else { 4096 if (r->tag) 4097 tag = r->tag; |
4098 if (r->rtableid >= 0) 4099 rtableid = r->rtableid; |
|
3853 if (r->anchor == NULL) { | 4100 if (r->anchor == NULL) { |
4101 match = 1; |
|
3854 *rm = r; 3855 *am = a; 3856 *rsm = ruleset; 3857 if ((*rm)->quick) 3858 break; 3859 r = TAILQ_NEXT(r, entries); 3860 } else 3861 pf_step_into_anchor(&asd, &ruleset, | 4102 *rm = r; 4103 *am = a; 4104 *rsm = ruleset; 4105 if ((*rm)->quick) 4106 break; 4107 r = TAILQ_NEXT(r, entries); 4108 } else 4109 pf_step_into_anchor(&asd, &ruleset, |
3862 PF_RULESET_FILTER, &r, &a); | 4110 PF_RULESET_FILTER, &r, &a, &match); |
3863 } | 4111 } |
3864 if (r == NULL) 3865 pf_step_out_of_anchor(&asd, &ruleset, 3866 PF_RULESET_FILTER, &r, &a); | 4112 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 4113 PF_RULESET_FILTER, &r, &a, &match)) 4114 break; |
3867 } 3868 r = *rm; 3869 a = *am; 3870 ruleset = *rsm; 3871 3872 REASON_SET(&reason, PFRES_MATCH); 3873 | 4115 } 4116 r = *rm; 4117 a = *am; 4118 ruleset = *rsm; 4119 4120 REASON_SET(&reason, PFRES_MATCH); 4121 |
3874 if (r->log) { | 4122 if (r->log || (nr != NULL && nr->natpass && nr->log)) { |
3875#ifdef INET6 3876 if (rewrite) 3877 m_copyback(m, off, sizeof(struct icmp6_hdr), 3878 (caddr_t)pd->hdr.icmp6); 3879#endif /* INET6 */ | 4123#ifdef INET6 4124 if (rewrite) 4125 m_copyback(m, off, sizeof(struct icmp6_hdr), 4126 (caddr_t)pd->hdr.icmp6); 4127#endif /* INET6 */ |
3880 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); | 4128 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 4129 a, ruleset, pd); |
3881 } 3882 3883 if (r->action != PF_PASS) 3884 return (PF_DROP); 3885 | 4130 } 4131 4132 if (r->action != PF_PASS) 4133 return (PF_DROP); 4134 |
3886 if (pf_tag_packet(m, pftag, tag)) { | 4135 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) { |
3887 REASON_SET(&reason, PFRES_MEMORY); 3888 return (PF_DROP); 3889 } 3890 3891 if (!state_icmp && (r->keep_state || nr != NULL)) { 3892 /* create new state */ 3893 struct pf_state *s = NULL; 3894 struct pf_src_node *sn = NULL; 3895 3896 /* check maximums */ 3897 if (r->max_states && (r->states >= r->max_states)) { 3898 pf_status.lcounters[LCNT_STATES]++; 3899 REASON_SET(&reason, PFRES_MAXSTATES); 3900 goto cleanup; 3901 } | 4136 REASON_SET(&reason, PFRES_MEMORY); 4137 return (PF_DROP); 4138 } 4139 4140 if (!state_icmp && (r->keep_state || nr != NULL)) { 4141 /* create new state */ 4142 struct pf_state *s = NULL; 4143 struct pf_src_node *sn = NULL; 4144 4145 /* check maximums */ 4146 if (r->max_states && (r->states >= r->max_states)) { 4147 pf_status.lcounters[LCNT_STATES]++; 4148 REASON_SET(&reason, PFRES_MAXSTATES); 4149 goto cleanup; 4150 } |
3902 /* src node for flter rule */ | 4151 /* src node for filter rule */ |
3903 if ((r->rule_flag & PFRULE_SRCTRACK || 3904 r->rpool.opts & PF_POOL_STICKYADDR) && 3905 pf_insert_src_node(&sn, r, saddr, af) != 0) { 3906 REASON_SET(&reason, PFRES_SRCLIMIT); 3907 goto cleanup; 3908 } 3909 /* src node for translation rule */ 3910 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && --- 23 unchanged lines hidden (view full) --- 3934 return (PF_DROP); 3935 } 3936 bzero(s, sizeof(*s)); 3937 s->rule.ptr = r; 3938 s->nat_rule.ptr = nr; 3939 s->anchor.ptr = a; 3940 STATE_INC_COUNTERS(s); 3941 s->allow_opts = r->allow_opts; | 4152 if ((r->rule_flag & PFRULE_SRCTRACK || 4153 r->rpool.opts & PF_POOL_STICKYADDR) && 4154 pf_insert_src_node(&sn, r, saddr, af) != 0) { 4155 REASON_SET(&reason, PFRES_SRCLIMIT); 4156 goto cleanup; 4157 } 4158 /* src node for translation rule */ 4159 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && --- 23 unchanged lines hidden (view full) --- 4183 return (PF_DROP); 4184 } 4185 bzero(s, sizeof(*s)); 4186 s->rule.ptr = r; 4187 s->nat_rule.ptr = nr; 4188 s->anchor.ptr = a; 4189 STATE_INC_COUNTERS(s); 4190 s->allow_opts = r->allow_opts; |
3942 s->log = r->log & 2; | 4191 s->log = r->log & PF_LOG_ALL; 4192 if (nr != NULL) 4193 s->log |= nr->log & PF_LOG_ALL; |
3943 s->proto = pd->proto; 3944 s->direction = direction; 3945 s->af = af; 3946 if (direction == PF_OUT) { 3947 PF_ACPY(&s->gwy.addr, saddr, af); 3948 s->gwy.port = nport; 3949 PF_ACPY(&s->ext.addr, daddr, af); 3950 s->ext.port = 0; --- 61 unchanged lines hidden (view full) --- 4012{ 4013 struct pf_rule *nr = NULL; 4014 struct pf_rule *r, *a = NULL; 4015 struct pf_ruleset *ruleset = NULL; 4016 struct pf_src_node *nsn = NULL; 4017 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 4018 sa_family_t af = pd->af; 4019 u_short reason; | 4194 s->proto = pd->proto; 4195 s->direction = direction; 4196 s->af = af; 4197 if (direction == PF_OUT) { 4198 PF_ACPY(&s->gwy.addr, saddr, af); 4199 s->gwy.port = nport; 4200 PF_ACPY(&s->ext.addr, daddr, af); 4201 s->ext.port = 0; --- 61 unchanged lines hidden (view full) --- 4263{ 4264 struct pf_rule *nr = NULL; 4265 struct pf_rule *r, *a = NULL; 4266 struct pf_ruleset *ruleset = NULL; 4267 struct pf_src_node *nsn = NULL; 4268 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 4269 sa_family_t af = pd->af; 4270 u_short reason; |
4020 struct pf_tag *pftag = NULL; 4021 int tag = -1; | 4271 int tag = -1, rtableid = -1; |
4022 int asd = 0; | 4272 int asd = 0; |
4273 int match = 0; |
|
4023 4024 if (pf_check_congestion(ifq)) { 4025 REASON_SET(&reason, PFRES_CONGEST); 4026 return (PF_DROP); 4027 } 4028 4029 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 4030 --- 40 unchanged lines hidden (view full) --- 4071 if (nr->natpass) 4072 r = NULL; 4073 pd->nat_rule = nr; 4074 } 4075 } 4076 4077 while (r != NULL) { 4078 r->evaluations++; | 4274 4275 if (pf_check_congestion(ifq)) { 4276 REASON_SET(&reason, PFRES_CONGEST); 4277 return (PF_DROP); 4278 } 4279 4280 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 4281 --- 40 unchanged lines hidden (view full) --- 4322 if (nr->natpass) 4323 r = NULL; 4324 pd->nat_rule = nr; 4325 } 4326 } 4327 4328 while (r != NULL) { 4329 r->evaluations++; |
4079 if (r->kif != NULL && 4080 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) | 4330 if (pfi_kif_match(r->kif, kif) == r->ifnot) |
4081 r = r->skip[PF_SKIP_IFP].ptr; 4082 else if (r->direction && r->direction != direction) 4083 r = r->skip[PF_SKIP_DIR].ptr; 4084 else if (r->af && r->af != af) 4085 r = r->skip[PF_SKIP_AF].ptr; 4086 else if (r->proto && r->proto != pd->proto) 4087 r = r->skip[PF_SKIP_PROTO].ptr; | 4331 r = r->skip[PF_SKIP_IFP].ptr; 4332 else if (r->direction && r->direction != direction) 4333 r = r->skip[PF_SKIP_DIR].ptr; 4334 else if (r->af && r->af != af) 4335 r = r->skip[PF_SKIP_AF].ptr; 4336 else if (r->proto && r->proto != pd->proto) 4337 r = r->skip[PF_SKIP_PROTO].ptr; |
4088 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.neg)) | 4338 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, 4339 r->src.neg, kif)) |
4089 r = r->skip[PF_SKIP_SRC_ADDR].ptr; | 4340 r = r->skip[PF_SKIP_SRC_ADDR].ptr; |
4090 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.neg)) | 4341 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, 4342 r->dst.neg, NULL)) |
4091 r = r->skip[PF_SKIP_DST_ADDR].ptr; | 4343 r = r->skip[PF_SKIP_DST_ADDR].ptr; |
4092 else if (r->tos && !(r->tos & pd->tos)) | 4344 else if (r->tos && !(r->tos == pd->tos)) |
4093 r = TAILQ_NEXT(r, entries); 4094 else if (r->rule_flag & PFRULE_FRAGMENT) 4095 r = TAILQ_NEXT(r, entries); 4096 else if (r->prob && r->prob <= arc4random()) 4097 r = TAILQ_NEXT(r, entries); | 4345 r = TAILQ_NEXT(r, entries); 4346 else if (r->rule_flag & PFRULE_FRAGMENT) 4347 r = TAILQ_NEXT(r, entries); 4348 else if (r->prob && r->prob <= arc4random()) 4349 r = TAILQ_NEXT(r, entries); |
4098 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag)) | 4350 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) |
4099 r = TAILQ_NEXT(r, entries); 4100 else if (r->os_fingerprint != PF_OSFP_ANY) 4101 r = TAILQ_NEXT(r, entries); 4102 else { 4103 if (r->tag) 4104 tag = r->tag; | 4351 r = TAILQ_NEXT(r, entries); 4352 else if (r->os_fingerprint != PF_OSFP_ANY) 4353 r = TAILQ_NEXT(r, entries); 4354 else { 4355 if (r->tag) 4356 tag = r->tag; |
4357 if (r->rtableid >= 0) 4358 rtableid = r->rtableid; |
|
4105 if (r->anchor == NULL) { | 4359 if (r->anchor == NULL) { |
4360 match = 1; |
|
4106 *rm = r; 4107 *am = a; 4108 *rsm = ruleset; 4109 if ((*rm)->quick) 4110 break; 4111 r = TAILQ_NEXT(r, entries); 4112 } else 4113 pf_step_into_anchor(&asd, &ruleset, | 4361 *rm = r; 4362 *am = a; 4363 *rsm = ruleset; 4364 if ((*rm)->quick) 4365 break; 4366 r = TAILQ_NEXT(r, entries); 4367 } else 4368 pf_step_into_anchor(&asd, &ruleset, |
4114 PF_RULESET_FILTER, &r, &a); | 4369 PF_RULESET_FILTER, &r, &a, &match); |
4115 } | 4370 } |
4116 if (r == NULL) 4117 pf_step_out_of_anchor(&asd, &ruleset, 4118 PF_RULESET_FILTER, &r, &a); | 4371 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 4372 PF_RULESET_FILTER, &r, &a, &match)) 4373 break; |
4119 } 4120 r = *rm; 4121 a = *am; 4122 ruleset = *rsm; 4123 4124 REASON_SET(&reason, PFRES_MATCH); 4125 | 4374 } 4375 r = *rm; 4376 a = *am; 4377 ruleset = *rsm; 4378 4379 REASON_SET(&reason, PFRES_MATCH); 4380 |
4126 if (r->log) 4127 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); | 4381 if (r->log || (nr != NULL && nr->natpass && nr->log)) 4382 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 4383 a, ruleset, pd); |
4128 4129 if ((r->action == PF_DROP) && 4130 ((r->rule_flag & PFRULE_RETURNICMP) || 4131 (r->rule_flag & PFRULE_RETURN))) { 4132 struct pf_addr *a = NULL; 4133 4134 if (nr != NULL) { 4135 if (direction == PF_OUT) --- 22 unchanged lines hidden (view full) --- 4158 else if ((af == AF_INET6) && r->return_icmp6) 4159 pf_send_icmp(m, r->return_icmp6 >> 8, 4160 r->return_icmp6 & 255, af, r); 4161 } 4162 4163 if (r->action != PF_PASS) 4164 return (PF_DROP); 4165 | 4384 4385 if ((r->action == PF_DROP) && 4386 ((r->rule_flag & PFRULE_RETURNICMP) || 4387 (r->rule_flag & PFRULE_RETURN))) { 4388 struct pf_addr *a = NULL; 4389 4390 if (nr != NULL) { 4391 if (direction == PF_OUT) --- 22 unchanged lines hidden (view full) --- 4414 else if ((af == AF_INET6) && r->return_icmp6) 4415 pf_send_icmp(m, r->return_icmp6 >> 8, 4416 r->return_icmp6 & 255, af, r); 4417 } 4418 4419 if (r->action != PF_PASS) 4420 return (PF_DROP); 4421 |
4166 if (pf_tag_packet(m, pftag, tag)) { | 4422 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) { |
4167 REASON_SET(&reason, PFRES_MEMORY); 4168 return (PF_DROP); 4169 } 4170 4171 if (r->keep_state || nr != NULL) { 4172 /* create new state */ 4173 struct pf_state *s = NULL; 4174 struct pf_src_node *sn = NULL; 4175 4176 /* check maximums */ 4177 if (r->max_states && (r->states >= r->max_states)) { 4178 pf_status.lcounters[LCNT_STATES]++; 4179 REASON_SET(&reason, PFRES_MAXSTATES); 4180 goto cleanup; 4181 } | 4423 REASON_SET(&reason, PFRES_MEMORY); 4424 return (PF_DROP); 4425 } 4426 4427 if (r->keep_state || nr != NULL) { 4428 /* create new state */ 4429 struct pf_state *s = NULL; 4430 struct pf_src_node *sn = NULL; 4431 4432 /* check maximums */ 4433 if (r->max_states && (r->states >= r->max_states)) { 4434 pf_status.lcounters[LCNT_STATES]++; 4435 REASON_SET(&reason, PFRES_MAXSTATES); 4436 goto cleanup; 4437 } |
4182 /* src node for flter rule */ | 4438 /* src node for filter rule */ |
4183 if ((r->rule_flag & PFRULE_SRCTRACK || 4184 r->rpool.opts & PF_POOL_STICKYADDR) && 4185 pf_insert_src_node(&sn, r, saddr, af) != 0) { 4186 REASON_SET(&reason, PFRES_SRCLIMIT); 4187 goto cleanup; 4188 } 4189 /* src node for translation rule */ 4190 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && --- 23 unchanged lines hidden (view full) --- 4214 return (PF_DROP); 4215 } 4216 bzero(s, sizeof(*s)); 4217 s->rule.ptr = r; 4218 s->nat_rule.ptr = nr; 4219 s->anchor.ptr = a; 4220 STATE_INC_COUNTERS(s); 4221 s->allow_opts = r->allow_opts; | 4439 if ((r->rule_flag & PFRULE_SRCTRACK || 4440 r->rpool.opts & PF_POOL_STICKYADDR) && 4441 pf_insert_src_node(&sn, r, saddr, af) != 0) { 4442 REASON_SET(&reason, PFRES_SRCLIMIT); 4443 goto cleanup; 4444 } 4445 /* src node for translation rule */ 4446 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && --- 23 unchanged lines hidden (view full) --- 4470 return (PF_DROP); 4471 } 4472 bzero(s, sizeof(*s)); 4473 s->rule.ptr = r; 4474 s->nat_rule.ptr = nr; 4475 s->anchor.ptr = a; 4476 STATE_INC_COUNTERS(s); 4477 s->allow_opts = r->allow_opts; |
4222 s->log = r->log & 2; | 4478 s->log = r->log & PF_LOG_ALL; 4479 if (nr != NULL) 4480 s->log |= nr->log & PF_LOG_ALL; |
4223 s->proto = pd->proto; 4224 s->direction = direction; 4225 s->af = af; 4226 if (direction == PF_OUT) { 4227 PF_ACPY(&s->gwy.addr, saddr, af); 4228 PF_ACPY(&s->ext.addr, daddr, af); 4229 if (nr != NULL) 4230 PF_ACPY(&s->lan.addr, &pd->baddr, af); --- 43 unchanged lines hidden (view full) --- 4274pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, 4275 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, 4276 struct pf_ruleset **rsm) 4277{ 4278 struct pf_rule *r, *a = NULL; 4279 struct pf_ruleset *ruleset = NULL; 4280 sa_family_t af = pd->af; 4281 u_short reason; | 4481 s->proto = pd->proto; 4482 s->direction = direction; 4483 s->af = af; 4484 if (direction == PF_OUT) { 4485 PF_ACPY(&s->gwy.addr, saddr, af); 4486 PF_ACPY(&s->ext.addr, daddr, af); 4487 if (nr != NULL) 4488 PF_ACPY(&s->lan.addr, &pd->baddr, af); --- 43 unchanged lines hidden (view full) --- 4532pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, 4533 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, 4534 struct pf_ruleset **rsm) 4535{ 4536 struct pf_rule *r, *a = NULL; 4537 struct pf_ruleset *ruleset = NULL; 4538 sa_family_t af = pd->af; 4539 u_short reason; |
4282 struct pf_tag *pftag = NULL; | |
4283 int tag = -1; 4284 int asd = 0; | 4540 int tag = -1; 4541 int asd = 0; |
4542 int match = 0; |
|
4285 4286 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 4287 while (r != NULL) { 4288 r->evaluations++; | 4543 4544 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 4545 while (r != NULL) { 4546 r->evaluations++; |
4289 if (r->kif != NULL && 4290 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) | 4547 if (pfi_kif_match(r->kif, kif) == r->ifnot) |
4291 r = r->skip[PF_SKIP_IFP].ptr; 4292 else if (r->direction && r->direction != direction) 4293 r = r->skip[PF_SKIP_DIR].ptr; 4294 else if (r->af && r->af != af) 4295 r = r->skip[PF_SKIP_AF].ptr; 4296 else if (r->proto && r->proto != pd->proto) 4297 r = r->skip[PF_SKIP_PROTO].ptr; | 4548 r = r->skip[PF_SKIP_IFP].ptr; 4549 else if (r->direction && r->direction != direction) 4550 r = r->skip[PF_SKIP_DIR].ptr; 4551 else if (r->af && r->af != af) 4552 r = r->skip[PF_SKIP_AF].ptr; 4553 else if (r->proto && r->proto != pd->proto) 4554 r = r->skip[PF_SKIP_PROTO].ptr; |
4298 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.neg)) | 4555 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, 4556 r->src.neg, kif)) |
4299 r = r->skip[PF_SKIP_SRC_ADDR].ptr; | 4557 r = r->skip[PF_SKIP_SRC_ADDR].ptr; |
4300 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.neg)) | 4558 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, 4559 r->dst.neg, NULL)) |
4301 r = r->skip[PF_SKIP_DST_ADDR].ptr; | 4560 r = r->skip[PF_SKIP_DST_ADDR].ptr; |
4302 else if (r->tos && !(r->tos & pd->tos)) | 4561 else if (r->tos && !(r->tos == pd->tos)) |
4303 r = TAILQ_NEXT(r, entries); 4304 else if (r->src.port_op || r->dst.port_op || 4305 r->flagset || r->type || r->code || 4306 r->os_fingerprint != PF_OSFP_ANY) 4307 r = TAILQ_NEXT(r, entries); 4308 else if (r->prob && r->prob <= arc4random()) 4309 r = TAILQ_NEXT(r, entries); | 4562 r = TAILQ_NEXT(r, entries); 4563 else if (r->src.port_op || r->dst.port_op || 4564 r->flagset || r->type || r->code || 4565 r->os_fingerprint != PF_OSFP_ANY) 4566 r = TAILQ_NEXT(r, entries); 4567 else if (r->prob && r->prob <= arc4random()) 4568 r = TAILQ_NEXT(r, entries); |
4310 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag)) | 4569 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) |
4311 r = TAILQ_NEXT(r, entries); 4312 else { 4313 if (r->anchor == NULL) { | 4570 r = TAILQ_NEXT(r, entries); 4571 else { 4572 if (r->anchor == NULL) { |
4573 match = 1; |
|
4314 *rm = r; 4315 *am = a; 4316 *rsm = ruleset; 4317 if ((*rm)->quick) 4318 break; 4319 r = TAILQ_NEXT(r, entries); 4320 } else 4321 pf_step_into_anchor(&asd, &ruleset, | 4574 *rm = r; 4575 *am = a; 4576 *rsm = ruleset; 4577 if ((*rm)->quick) 4578 break; 4579 r = TAILQ_NEXT(r, entries); 4580 } else 4581 pf_step_into_anchor(&asd, &ruleset, |
4322 PF_RULESET_FILTER, &r, &a); | 4582 PF_RULESET_FILTER, &r, &a, &match); |
4323 } | 4583 } |
4324 if (r == NULL) 4325 pf_step_out_of_anchor(&asd, &ruleset, 4326 PF_RULESET_FILTER, &r, &a); | 4584 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 4585 PF_RULESET_FILTER, &r, &a, &match)) 4586 break; |
4327 } 4328 r = *rm; 4329 a = *am; 4330 ruleset = *rsm; 4331 4332 REASON_SET(&reason, PFRES_MATCH); 4333 4334 if (r->log) | 4587 } 4588 r = *rm; 4589 a = *am; 4590 ruleset = *rsm; 4591 4592 REASON_SET(&reason, PFRES_MATCH); 4593 4594 if (r->log) |
4335 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); | 4595 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset, 4596 pd); |
4336 4337 if (r->action != PF_PASS) 4338 return (PF_DROP); 4339 | 4597 4598 if (r->action != PF_PASS) 4599 return (PF_DROP); 4600 |
4340 if (pf_tag_packet(m, pftag, tag)) { | 4601 if (pf_tag_packet(m, pd->pf_mtag, tag, -1)) { |
4341 REASON_SET(&reason, PFRES_MEMORY); 4342 return (PF_DROP); 4343 } 4344 4345 return (PF_PASS); 4346} 4347 4348int 4349pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, 4350 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, 4351 u_short *reason) 4352{ | 4602 REASON_SET(&reason, PFRES_MEMORY); 4603 return (PF_DROP); 4604 } 4605 4606 return (PF_PASS); 4607} 4608 4609int 4610pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, 4611 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, 4612 u_short *reason) 4613{ |
4353 struct pf_state key; | 4614 struct pf_state_cmp key; |
4354 struct tcphdr *th = pd->hdr.tcp; 4355 u_int16_t win = ntohs(th->th_win); 4356 u_int32_t ack, end, seq, orig_seq; 4357 u_int8_t sws, dws; 4358 int ackskew; 4359 int copyback = 0; 4360 struct pf_state_peer *src, *dst; 4361 --- 34 unchanged lines hidden (view full) --- 4396#ifdef __FreeBSD__ 4397 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst, 4398#else 4399 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4400#endif 4401 pd->src, th->th_dport, th->th_sport, 4402 (*state)->src.seqhi, ntohl(th->th_seq) + 1, 4403 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1, | 4615 struct tcphdr *th = pd->hdr.tcp; 4616 u_int16_t win = ntohs(th->th_win); 4617 u_int32_t ack, end, seq, orig_seq; 4618 u_int8_t sws, dws; 4619 int ackskew; 4620 int copyback = 0; 4621 struct pf_state_peer *src, *dst; 4622 --- 34 unchanged lines hidden (view full) --- 4657#ifdef __FreeBSD__ 4658 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst, 4659#else 4660 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4661#endif 4662 pd->src, th->th_dport, th->th_sport, 4663 (*state)->src.seqhi, ntohl(th->th_seq) + 1, 4664 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1, |
4404 NULL, NULL); | 4665 0, NULL, NULL); |
4405 REASON_SET(reason, PFRES_SYNPROXY); 4406 return (PF_SYNPROXY_DROP); 4407 } else if (!(th->th_flags & TH_ACK) || 4408 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 4409 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) { 4410 REASON_SET(reason, PFRES_SYNPROXY); 4411 return (PF_DROP); 4412 } else if ((*state)->src_node != NULL && --- 26 unchanged lines hidden (view full) --- 4439#ifdef __FreeBSD__ 4440 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4441 &src->addr, 4442#else 4443 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 4444#endif 4445 &dst->addr, src->port, dst->port, 4446 (*state)->dst.seqhi, 0, TH_SYN, 0, | 4666 REASON_SET(reason, PFRES_SYNPROXY); 4667 return (PF_SYNPROXY_DROP); 4668 } else if (!(th->th_flags & TH_ACK) || 4669 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 4670 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) { 4671 REASON_SET(reason, PFRES_SYNPROXY); 4672 return (PF_DROP); 4673 } else if ((*state)->src_node != NULL && --- 26 unchanged lines hidden (view full) --- 4700#ifdef __FreeBSD__ 4701 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4702 &src->addr, 4703#else 4704 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 4705#endif 4706 &dst->addr, src->port, dst->port, 4707 (*state)->dst.seqhi, 0, TH_SYN, 0, |
4447 (*state)->src.mss, 0, 0, NULL, NULL); | 4708 (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL); |
4448 REASON_SET(reason, PFRES_SYNPROXY); 4449 return (PF_SYNPROXY_DROP); 4450 } else if (((th->th_flags & (TH_SYN|TH_ACK)) != 4451 (TH_SYN|TH_ACK)) || 4452 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) { 4453 REASON_SET(reason, PFRES_SYNPROXY); 4454 return (PF_DROP); 4455 } else { 4456 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1); 4457 (*state)->dst.seqlo = ntohl(th->th_seq); 4458#ifdef __FreeBSD__ 4459 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst, 4460#else 4461 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4462#endif 4463 pd->src, th->th_dport, th->th_sport, 4464 ntohl(th->th_ack), ntohl(th->th_seq) + 1, 4465 TH_ACK, (*state)->src.max_win, 0, 0, 0, | 4709 REASON_SET(reason, PFRES_SYNPROXY); 4710 return (PF_SYNPROXY_DROP); 4711 } else if (((th->th_flags & (TH_SYN|TH_ACK)) != 4712 (TH_SYN|TH_ACK)) || 4713 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) { 4714 REASON_SET(reason, PFRES_SYNPROXY); 4715 return (PF_DROP); 4716 } else { 4717 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1); 4718 (*state)->dst.seqlo = ntohl(th->th_seq); 4719#ifdef __FreeBSD__ 4720 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst, 4721#else 4722 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4723#endif 4724 pd->src, th->th_dport, th->th_sport, 4725 ntohl(th->th_ack), ntohl(th->th_seq) + 1, 4726 TH_ACK, (*state)->src.max_win, 0, 0, 0, |
4466 NULL, NULL); | 4727 (*state)->tag, NULL, NULL); |
4467#ifdef __FreeBSD__ 4468 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4469 &src->addr, 4470#else 4471 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 4472#endif 4473 &dst->addr, src->port, dst->port, 4474 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1, 4475 TH_ACK, (*state)->dst.max_win, 0, 0, 1, | 4728#ifdef __FreeBSD__ 4729 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4730 &src->addr, 4731#else 4732 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 4733#endif 4734 &dst->addr, src->port, dst->port, 4735 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1, 4736 TH_ACK, (*state)->dst.max_win, 0, 0, 1, |
4476 NULL, NULL); | 4737 0, NULL, NULL); |
4477 (*state)->src.seqdiff = (*state)->dst.seqhi - 4478 (*state)->src.seqlo; 4479 (*state)->dst.seqdiff = (*state)->src.seqhi - 4480 (*state)->dst.seqlo; 4481 (*state)->src.seqhi = (*state)->src.seqlo + 4482 (*state)->dst.max_win; 4483 (*state)->dst.seqhi = (*state)->dst.seqlo + 4484 (*state)->src.max_win; --- 26 unchanged lines hidden (view full) --- 4511 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) { 4512 REASON_SET(reason, PFRES_MEMORY); 4513 return (PF_DROP); 4514 } 4515 } 4516 4517 /* Deferred generation of sequence number modulator */ 4518 if (dst->seqdiff && !src->seqdiff) { | 4738 (*state)->src.seqdiff = (*state)->dst.seqhi - 4739 (*state)->src.seqlo; 4740 (*state)->dst.seqdiff = (*state)->src.seqhi - 4741 (*state)->dst.seqlo; 4742 (*state)->src.seqhi = (*state)->src.seqlo + 4743 (*state)->dst.max_win; 4744 (*state)->dst.seqhi = (*state)->dst.seqlo + 4745 (*state)->src.max_win; --- 26 unchanged lines hidden (view full) --- 4772 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) { 4773 REASON_SET(reason, PFRES_MEMORY); 4774 return (PF_DROP); 4775 } 4776 } 4777 4778 /* Deferred generation of sequence number modulator */ 4779 if (dst->seqdiff && !src->seqdiff) { |
4519 while ((src->seqdiff = htonl(arc4random())) == 0) | 4780#ifdef __FreeBSD__ 4781 while ((src->seqdiff = pf_new_isn(*state) - seq) == 0) |
4520 ; | 4782 ; |
4783#else 4784 while ((src->seqdiff = tcp_rndiss_next() - seq) == 0) 4785 ; 4786#endif |
|
4521 ack = ntohl(th->th_ack) - dst->seqdiff; 4522 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4523 src->seqdiff), 0); 4524 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4525 copyback = 1; 4526 } else { 4527 ack = ntohl(th->th_ack); 4528 } --- 71 unchanged lines hidden (view full) --- 4600 if (seq == end) { 4601 /* Ease sequencing restrictions on no data packets */ 4602 seq = src->seqlo; 4603 end = seq; 4604 } 4605 4606 ackskew = dst->seqlo - ack; 4607 | 4787 ack = ntohl(th->th_ack) - dst->seqdiff; 4788 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4789 src->seqdiff), 0); 4790 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4791 copyback = 1; 4792 } else { 4793 ack = ntohl(th->th_ack); 4794 } --- 71 unchanged lines hidden (view full) --- 4866 if (seq == end) { 4867 /* Ease sequencing restrictions on no data packets */ 4868 seq = src->seqlo; 4869 end = seq; 4870 } 4871 4872 ackskew = dst->seqlo - ack; 4873 |
4874 4875 /* 4876 * Need to demodulate the sequence numbers in any TCP SACK options 4877 * (Selective ACK). We could optionally validate the SACK values 4878 * against the current ACK window, either forwards or backwards, but 4879 * I'm not confident that SACK has been implemented properly 4880 * everywhere. It wouldn't surprise me if several stacks accidently 4881 * SACK too far backwards of previously ACKed data. There really aren't 4882 * any security implications of bad SACKing unless the target stack 4883 * doesn't validate the option length correctly. Someone trying to 4884 * spoof into a TCP connection won't bother blindly sending SACK 4885 * options anyway. 4886 */ 4887 if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) { 4888 if (pf_modulate_sack(m, off, pd, th, dst)) 4889 copyback = 1; 4890 } 4891 4892 |
|
4608#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */ 4609 if (SEQ_GEQ(src->seqhi, end) && 4610 /* Last octet inside other's window space */ 4611 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) && 4612 /* Retrans: not more than one window back */ 4613 (ackskew >= -MAXACKWINDOW) && 4614 /* Acking not more than one reassembled fragment backwards */ 4615 (ackskew <= (MAXACKWINDOW << sws)) && 4616 /* Acking not more than one window forward */ 4617 ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo || | 4893#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */ 4894 if (SEQ_GEQ(src->seqhi, end) && 4895 /* Last octet inside other's window space */ 4896 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) && 4897 /* Retrans: not more than one window back */ 4898 (ackskew >= -MAXACKWINDOW) && 4899 /* Acking not more than one reassembled fragment backwards */ 4900 (ackskew <= (MAXACKWINDOW << sws)) && 4901 /* Acking not more than one window forward */ 4902 ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo || |
4618 (pd->flags & PFDESC_IP_REAS) == 0)) { 4619 /* Require an exact sequence match on resets when possible */ | 4903 (orig_seq == src->seqlo + 1) || (pd->flags & PFDESC_IP_REAS) == 0)) { 4904 /* Require an exact/+1 sequence match on resets when possible */ |
4620 4621 if (dst->scrub || src->scrub) { 4622 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 4623 *state, src, dst, ©back)) 4624 return (PF_DROP); 4625 } 4626 4627 /* update max window */ --- 29 unchanged lines hidden (view full) --- 4657 if (th->th_flags & TH_RST) 4658 src->state = dst->state = TCPS_TIME_WAIT; 4659 4660 /* update expire time */ 4661 (*state)->expire = time_second; 4662 if (src->state >= TCPS_FIN_WAIT_2 && 4663 dst->state >= TCPS_FIN_WAIT_2) 4664 (*state)->timeout = PFTM_TCP_CLOSED; | 4905 4906 if (dst->scrub || src->scrub) { 4907 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 4908 *state, src, dst, ©back)) 4909 return (PF_DROP); 4910 } 4911 4912 /* update max window */ --- 29 unchanged lines hidden (view full) --- 4942 if (th->th_flags & TH_RST) 4943 src->state = dst->state = TCPS_TIME_WAIT; 4944 4945 /* update expire time */ 4946 (*state)->expire = time_second; 4947 if (src->state >= TCPS_FIN_WAIT_2 && 4948 dst->state >= TCPS_FIN_WAIT_2) 4949 (*state)->timeout = PFTM_TCP_CLOSED; |
4665 else if (src->state >= TCPS_FIN_WAIT_2 || 4666 dst->state >= TCPS_FIN_WAIT_2) | 4950 else if (src->state >= TCPS_CLOSING && 4951 dst->state >= TCPS_CLOSING) |
4667 (*state)->timeout = PFTM_TCP_FIN_WAIT; 4668 else if (src->state < TCPS_ESTABLISHED || 4669 dst->state < TCPS_ESTABLISHED) 4670 (*state)->timeout = PFTM_TCP_OPENING; 4671 else if (src->state >= TCPS_CLOSING || 4672 dst->state >= TCPS_CLOSING) 4673 (*state)->timeout = PFTM_TCP_CLOSING; 4674 else --- 29 unchanged lines hidden (view full) --- 4704 * validate the connection, go through the normal state code 4705 * and keep updating the state TTL. 4706 */ 4707 4708 if (pf_status.debug >= PF_DEBUG_MISC) { 4709 printf("pf: loose state match: "); 4710 pf_print_state(*state); 4711 pf_print_flags(th->th_flags); | 4952 (*state)->timeout = PFTM_TCP_FIN_WAIT; 4953 else if (src->state < TCPS_ESTABLISHED || 4954 dst->state < TCPS_ESTABLISHED) 4955 (*state)->timeout = PFTM_TCP_OPENING; 4956 else if (src->state >= TCPS_CLOSING || 4957 dst->state >= TCPS_CLOSING) 4958 (*state)->timeout = PFTM_TCP_CLOSING; 4959 else --- 29 unchanged lines hidden (view full) --- 4989 * validate the connection, go through the normal state code 4990 * and keep updating the state TTL. 4991 */ 4992 4993 if (pf_status.debug >= PF_DEBUG_MISC) { 4994 printf("pf: loose state match: "); 4995 pf_print_state(*state); 4996 pf_print_flags(th->th_flags); |
4712 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d\n", 4713 seq, ack, pd->p_len, ackskew, 4714 (*state)->packets[0], (*state)->packets[1]); | 4997 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d " 4998 "pkts=%llu:%llu\n", seq, orig_seq, ack, pd->p_len, 4999#ifdef __FreeBSD__ 5000 ackskew, (unsigned long long)(*state)->packets[0], 5001 (unsigned long long)(*state)->packets[1]); 5002#else 5003 ackskew, (*state)->packets[0], 5004 (*state)->packets[1]); 5005#endif |
4715 } 4716 4717 if (dst->scrub || src->scrub) { 4718 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 4719 *state, src, dst, ©back)) 4720 return (PF_DROP); 4721 } 4722 --- 28 unchanged lines hidden (view full) --- 4751#ifdef __FreeBSD__ 4752 pf_send_tcp(m, (*state)->rule.ptr, pd->af, 4753#else 4754 pf_send_tcp((*state)->rule.ptr, pd->af, 4755#endif 4756 pd->dst, pd->src, th->th_dport, 4757 th->th_sport, ntohl(th->th_ack), 0, 4758 TH_RST, 0, 0, | 5006 } 5007 5008 if (dst->scrub || src->scrub) { 5009 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 5010 *state, src, dst, ©back)) 5011 return (PF_DROP); 5012 } 5013 --- 28 unchanged lines hidden (view full) --- 5042#ifdef __FreeBSD__ 5043 pf_send_tcp(m, (*state)->rule.ptr, pd->af, 5044#else 5045 pf_send_tcp((*state)->rule.ptr, pd->af, 5046#endif 5047 pd->dst, pd->src, th->th_dport, 5048 th->th_sport, ntohl(th->th_ack), 0, 5049 TH_RST, 0, 0, |
4759 (*state)->rule.ptr->return_ttl, 1, | 5050 (*state)->rule.ptr->return_ttl, 1, 0, |
4760 pd->eh, kif->pfik_ifp); 4761 src->seqlo = 0; 4762 src->seqhi = 1; 4763 src->max_win = 1; 4764 } else if (pf_status.debug >= PF_DEBUG_MISC) { 4765 printf("pf: BAD state: "); 4766 pf_print_state(*state); 4767 pf_print_flags(th->th_flags); | 5051 pd->eh, kif->pfik_ifp); 5052 src->seqlo = 0; 5053 src->seqhi = 1; 5054 src->max_win = 1; 5055 } else if (pf_status.debug >= PF_DEBUG_MISC) { 5056 printf("pf: BAD state: "); 5057 pf_print_state(*state); 5058 pf_print_flags(th->th_flags); |
4768 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d " 4769 "dir=%s,%s\n", seq, ack, pd->p_len, ackskew, | 5059 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d " 5060 "pkts=%llu:%llu dir=%s,%s\n", 5061 seq, orig_seq, ack, pd->p_len, ackskew, 5062#ifdef __FreeBSD__ 5063 (unsigned long long)(*state)->packets[0], 5064 (unsigned long long)(*state)->packets[1], 5065#else |
4770 (*state)->packets[0], (*state)->packets[1], | 5066 (*state)->packets[0], (*state)->packets[1], |
5067#endif |
|
4771 direction == PF_IN ? "in" : "out", 4772 direction == (*state)->direction ? "fwd" : "rev"); 4773 printf("pf: State failure on: %c %c %c %c | %c %c\n", 4774 SEQ_GEQ(src->seqhi, end) ? ' ' : '1', 4775 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ? 4776 ' ': '2', 4777 (ackskew >= -MAXACKWINDOW) ? ' ' : '3', 4778 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4', --- 25 unchanged lines hidden (view full) --- 4804 return (PF_PASS); 4805} 4806 4807int 4808pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, 4809 struct mbuf *m, int off, void *h, struct pf_pdesc *pd) 4810{ 4811 struct pf_state_peer *src, *dst; | 5068 direction == PF_IN ? "in" : "out", 5069 direction == (*state)->direction ? "fwd" : "rev"); 5070 printf("pf: State failure on: %c %c %c %c | %c %c\n", 5071 SEQ_GEQ(src->seqhi, end) ? ' ' : '1', 5072 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ? 5073 ' ': '2', 5074 (ackskew >= -MAXACKWINDOW) ? ' ' : '3', 5075 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4', --- 25 unchanged lines hidden (view full) --- 5101 return (PF_PASS); 5102} 5103 5104int 5105pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, 5106 struct mbuf *m, int off, void *h, struct pf_pdesc *pd) 5107{ 5108 struct pf_state_peer *src, *dst; |
4812 struct pf_state key; | 5109 struct pf_state_cmp key; |
4813 struct udphdr *uh = pd->hdr.udp; 4814 4815 key.af = pd->af; 4816 key.proto = IPPROTO_UDP; 4817 if (direction == PF_IN) { 4818 PF_ACPY(&key.ext.addr, pd->src, key.af); 4819 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 4820 key.ext.port = uh->uh_sport; --- 48 unchanged lines hidden (view full) --- 4869pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, 4870 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason) 4871{ 4872 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 4873 u_int16_t icmpid = 0; /* make the compiler happy */ 4874 u_int16_t *icmpsum = NULL; /* make the compiler happy */ 4875 u_int8_t icmptype = 0; /* make the compiler happy */ 4876 int state_icmp = 0; | 5110 struct udphdr *uh = pd->hdr.udp; 5111 5112 key.af = pd->af; 5113 key.proto = IPPROTO_UDP; 5114 if (direction == PF_IN) { 5115 PF_ACPY(&key.ext.addr, pd->src, key.af); 5116 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 5117 key.ext.port = uh->uh_sport; --- 48 unchanged lines hidden (view full) --- 5166pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, 5167 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason) 5168{ 5169 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 5170 u_int16_t icmpid = 0; /* make the compiler happy */ 5171 u_int16_t *icmpsum = NULL; /* make the compiler happy */ 5172 u_int8_t icmptype = 0; /* make the compiler happy */ 5173 int state_icmp = 0; |
5174 struct pf_state_cmp key; |
|
4877 4878 switch (pd->proto) { 4879#ifdef INET 4880 case IPPROTO_ICMP: 4881 icmptype = pd->hdr.icmp->icmp_type; 4882 icmpid = pd->hdr.icmp->icmp_id; 4883 icmpsum = &pd->hdr.icmp->icmp_cksum; 4884 --- 21 unchanged lines hidden (view full) --- 4906 } 4907 4908 if (!state_icmp) { 4909 4910 /* 4911 * ICMP query/reply message not related to a TCP/UDP packet. 4912 * Search for an ICMP state. 4913 */ | 5175 5176 switch (pd->proto) { 5177#ifdef INET 5178 case IPPROTO_ICMP: 5179 icmptype = pd->hdr.icmp->icmp_type; 5180 icmpid = pd->hdr.icmp->icmp_id; 5181 icmpsum = &pd->hdr.icmp->icmp_cksum; 5182 --- 21 unchanged lines hidden (view full) --- 5204 } 5205 5206 if (!state_icmp) { 5207 5208 /* 5209 * ICMP query/reply message not related to a TCP/UDP packet. 5210 * Search for an ICMP state. 5211 */ |
4914 struct pf_state key; 4915 | |
4916 key.af = pd->af; 4917 key.proto = pd->proto; 4918 if (direction == PF_IN) { 4919 PF_ACPY(&key.ext.addr, pd->src, key.af); 4920 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 4921 key.ext.port = 0; 4922 key.gwy.port = icmpid; 4923 } else { --- 169 unchanged lines hidden (view full) --- 5093 } 5094 default: 5095 terminal++; 5096 break; 5097 } 5098 } while (!terminal); 5099 break; 5100#endif /* INET6 */ | 5212 key.af = pd->af; 5213 key.proto = pd->proto; 5214 if (direction == PF_IN) { 5215 PF_ACPY(&key.ext.addr, pd->src, key.af); 5216 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 5217 key.ext.port = 0; 5218 key.gwy.port = icmpid; 5219 } else { --- 169 unchanged lines hidden (view full) --- 5389 } 5390 default: 5391 terminal++; 5392 break; 5393 } 5394 } while (!terminal); 5395 break; 5396#endif /* INET6 */ |
5397#ifdef __FreeBSD__ 5398 default: 5399 panic("AF not supported: %d", pd->af); 5400#endif |
|
5101 } 5102 5103 switch (pd2.proto) { 5104 case IPPROTO_TCP: { 5105 struct tcphdr th; 5106 u_int32_t seq; | 5401 } 5402 5403 switch (pd2.proto) { 5404 case IPPROTO_TCP: { 5405 struct tcphdr th; 5406 u_int32_t seq; |
5107 struct pf_state key; | |
5108 struct pf_state_peer *src, *dst; 5109 u_int8_t dws; 5110 int copyback = 0; 5111 5112 /* 5113 * Only the first 8 bytes of the TCP header can be 5114 * expected. Don't access any TCP header fields after 5115 * th_seq, an ackskew test is not possible. --- 100 unchanged lines hidden (view full) --- 5216 m_copyback(m, off2, 8, (caddr_t)&th); 5217 } 5218 5219 return (PF_PASS); 5220 break; 5221 } 5222 case IPPROTO_UDP: { 5223 struct udphdr uh; | 5407 struct pf_state_peer *src, *dst; 5408 u_int8_t dws; 5409 int copyback = 0; 5410 5411 /* 5412 * Only the first 8 bytes of the TCP header can be 5413 * expected. Don't access any TCP header fields after 5414 * th_seq, an ackskew test is not possible. --- 100 unchanged lines hidden (view full) --- 5515 m_copyback(m, off2, 8, (caddr_t)&th); 5516 } 5517 5518 return (PF_PASS); 5519 break; 5520 } 5521 case IPPROTO_UDP: { 5522 struct udphdr uh; |
5224 struct pf_state key; | |
5225 5226 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh), 5227 NULL, reason, pd2.af)) { 5228 DPFPRINTF(PF_DEBUG_MISC, 5229 ("pf: ICMP error message too short " 5230 "(udp)\n")); 5231 return (PF_DROP); 5232 } --- 52 unchanged lines hidden (view full) --- 5285 } 5286 5287 return (PF_PASS); 5288 break; 5289 } 5290#ifdef INET 5291 case IPPROTO_ICMP: { 5292 struct icmp iih; | 5523 5524 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh), 5525 NULL, reason, pd2.af)) { 5526 DPFPRINTF(PF_DEBUG_MISC, 5527 ("pf: ICMP error message too short " 5528 "(udp)\n")); 5529 return (PF_DROP); 5530 } --- 52 unchanged lines hidden (view full) --- 5583 } 5584 5585 return (PF_PASS); 5586 break; 5587 } 5588#ifdef INET 5589 case IPPROTO_ICMP: { 5590 struct icmp iih; |
5293 struct pf_state key; | |
5294 5295 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN, 5296 NULL, reason, pd2.af)) { 5297 DPFPRINTF(PF_DEBUG_MISC, 5298 ("pf: ICMP error message too short i" 5299 "(icmp)\n")); 5300 return (PF_DROP); 5301 } --- 38 unchanged lines hidden (view full) --- 5340 5341 return (PF_PASS); 5342 break; 5343 } 5344#endif /* INET */ 5345#ifdef INET6 5346 case IPPROTO_ICMPV6: { 5347 struct icmp6_hdr iih; | 5591 5592 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN, 5593 NULL, reason, pd2.af)) { 5594 DPFPRINTF(PF_DEBUG_MISC, 5595 ("pf: ICMP error message too short i" 5596 "(icmp)\n")); 5597 return (PF_DROP); 5598 } --- 38 unchanged lines hidden (view full) --- 5637 5638 return (PF_PASS); 5639 break; 5640 } 5641#endif /* INET */ 5642#ifdef INET6 5643 case IPPROTO_ICMPV6: { 5644 struct icmp6_hdr iih; |
5348 struct pf_state key; | |
5349 5350 if (!pf_pull_hdr(m, off2, &iih, 5351 sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) { 5352 DPFPRINTF(PF_DEBUG_MISC, 5353 ("pf: ICMP error message too short " 5354 "(icmp6)\n")); 5355 return (PF_DROP); 5356 } --- 36 unchanged lines hidden (view full) --- 5393 (caddr_t)&iih); 5394 } 5395 5396 return (PF_PASS); 5397 break; 5398 } 5399#endif /* INET6 */ 5400 default: { | 5645 5646 if (!pf_pull_hdr(m, off2, &iih, 5647 sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) { 5648 DPFPRINTF(PF_DEBUG_MISC, 5649 ("pf: ICMP error message too short " 5650 "(icmp6)\n")); 5651 return (PF_DROP); 5652 } --- 36 unchanged lines hidden (view full) --- 5689 (caddr_t)&iih); 5690 } 5691 5692 return (PF_PASS); 5693 break; 5694 } 5695#endif /* INET6 */ 5696 default: { |
5401 struct pf_state key; 5402 | |
5403 key.af = pd2.af; 5404 key.proto = pd2.proto; 5405 if (direction == PF_IN) { 5406 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 5407 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 5408 key.ext.port = 0; 5409 key.gwy.port = 0; 5410 } else { --- 47 unchanged lines hidden (view full) --- 5458 } 5459} 5460 5461int 5462pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, 5463 struct pf_pdesc *pd) 5464{ 5465 struct pf_state_peer *src, *dst; | 5697 key.af = pd2.af; 5698 key.proto = pd2.proto; 5699 if (direction == PF_IN) { 5700 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 5701 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 5702 key.ext.port = 0; 5703 key.gwy.port = 0; 5704 } else { --- 47 unchanged lines hidden (view full) --- 5752 } 5753} 5754 5755int 5756pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, 5757 struct pf_pdesc *pd) 5758{ 5759 struct pf_state_peer *src, *dst; |
5466 struct pf_state key; | 5760 struct pf_state_cmp key; |
5467 5468 key.af = pd->af; 5469 key.proto = pd->proto; 5470 if (direction == PF_IN) { 5471 PF_ACPY(&key.ext.addr, pd->src, key.af); 5472 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 5473 key.ext.port = 0; 5474 key.gwy.port = 0; --- 111 unchanged lines hidden (view full) --- 5586 } 5587#endif /* INET6 */ 5588 } 5589 m_copydata(m, off, len, p); 5590 return (p); 5591} 5592 5593int | 5761 5762 key.af = pd->af; 5763 key.proto = pd->proto; 5764 if (direction == PF_IN) { 5765 PF_ACPY(&key.ext.addr, pd->src, key.af); 5766 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 5767 key.ext.port = 0; 5768 key.gwy.port = 0; --- 111 unchanged lines hidden (view full) --- 5880 } 5881#endif /* INET6 */ 5882 } 5883 m_copydata(m, off, len, p); 5884 return (p); 5885} 5886 5887int |
5594pf_routable(struct pf_addr *addr, sa_family_t af) | 5888pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif) |
5595{ 5596 struct sockaddr_in *dst; | 5889{ 5890 struct sockaddr_in *dst; |
5891 int ret = 1; 5892 int check_mpath; 5893#ifndef __FreeBSD__ 5894 extern int ipmultipath; 5895#endif |
|
5597#ifdef INET6 | 5896#ifdef INET6 |
5897#ifndef __FreeBSD__ 5898 extern int ip6_multipath; 5899#endif |
|
5598 struct sockaddr_in6 *dst6; 5599 struct route_in6 ro; 5600#else 5601 struct route ro; 5602#endif | 5900 struct sockaddr_in6 *dst6; 5901 struct route_in6 ro; 5902#else 5903 struct route ro; 5904#endif |
5905 struct radix_node *rn; 5906 struct rtentry *rt; 5907 struct ifnet *ifp; |
|
5603 | 5908 |
5909 check_mpath = 0; |
|
5604 bzero(&ro, sizeof(ro)); 5605 switch (af) { 5606 case AF_INET: 5607 dst = satosin(&ro.ro_dst); 5608 dst->sin_family = AF_INET; 5609 dst->sin_len = sizeof(*dst); 5610 dst->sin_addr = addr->v4; | 5910 bzero(&ro, sizeof(ro)); 5911 switch (af) { 5912 case AF_INET: 5913 dst = satosin(&ro.ro_dst); 5914 dst->sin_family = AF_INET; 5915 dst->sin_len = sizeof(*dst); 5916 dst->sin_addr = addr->v4; |
5917#ifndef __FreeBSD__ /* MULTIPATH_ROUTING */ 5918 if (ipmultipath) 5919 check_mpath = 1; 5920#endif |
|
5611 break; 5612#ifdef INET6 5613 case AF_INET6: 5614 dst6 = (struct sockaddr_in6 *)&ro.ro_dst; 5615 dst6->sin6_family = AF_INET6; 5616 dst6->sin6_len = sizeof(*dst6); 5617 dst6->sin6_addr = addr->v6; | 5921 break; 5922#ifdef INET6 5923 case AF_INET6: 5924 dst6 = (struct sockaddr_in6 *)&ro.ro_dst; 5925 dst6->sin6_family = AF_INET6; 5926 dst6->sin6_len = sizeof(*dst6); 5927 dst6->sin6_addr = addr->v6; |
5928#ifndef __FreeBSD__ /* MULTIPATH_ROUTING */ 5929 if (ip6_multipath) 5930 check_mpath = 1; 5931#endif |
|
5618 break; 5619#endif /* INET6 */ 5620 default: 5621 return (0); 5622 } 5623 | 5932 break; 5933#endif /* INET6 */ 5934 default: 5935 return (0); 5936 } 5937 |
5938 /* Skip checks for ipsec interfaces */ 5939 if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC) 5940 goto out; 5941 |
|
5624#ifdef __FreeBSD__ | 5942#ifdef __FreeBSD__ |
5625#ifdef RTF_PRCLONING 5626 rtalloc_ign((struct route *)&ro, (RTF_CLONING | RTF_PRCLONING)); 5627#else /* !RTF_PRCLONING */ | |
5628 rtalloc_ign((struct route *)&ro, RTF_CLONING); | 5943 rtalloc_ign((struct route *)&ro, RTF_CLONING); |
5629#endif | |
5630#else /* ! __FreeBSD__ */ 5631 rtalloc_noclone((struct route *)&ro, NO_CLONING); 5632#endif 5633 5634 if (ro.ro_rt != NULL) { | 5944#else /* ! __FreeBSD__ */ 5945 rtalloc_noclone((struct route *)&ro, NO_CLONING); 5946#endif 5947 5948 if (ro.ro_rt != NULL) { |
5635 RTFREE(ro.ro_rt); 5636 return (1); 5637 } | 5949 /* No interface given, this is a no-route check */ 5950 if (kif == NULL) 5951 goto out; |
5638 | 5952 |
5639 return (0); | 5953 if (kif->pfik_ifp == NULL) { 5954 ret = 0; 5955 goto out; 5956 } 5957 5958 /* Perform uRPF check if passed input interface */ 5959 ret = 0; 5960 rn = (struct radix_node *)ro.ro_rt; 5961 do { 5962 rt = (struct rtentry *)rn; 5963#ifndef __FreeBSD__ /* CARPDEV */ 5964 if (rt->rt_ifp->if_type == IFT_CARP) 5965 ifp = rt->rt_ifp->if_carpdev; 5966 else 5967#endif 5968 ifp = rt->rt_ifp; 5969 5970 if (kif->pfik_ifp == ifp) 5971 ret = 1; 5972#ifdef __FreeBSD__ /* MULTIPATH_ROUTING */ 5973 rn = NULL; 5974#else 5975 rn = rn_mpath_next(rn); 5976#endif 5977 } while (check_mpath == 1 && rn != NULL && ret == 0); 5978 } else 5979 ret = 0; 5980out: 5981 if (ro.ro_rt != NULL) 5982 RTFREE(ro.ro_rt); 5983 return (ret); |
5640} 5641 5642int 5643pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw) 5644{ 5645 struct sockaddr_in *dst; 5646#ifdef INET6 5647 struct sockaddr_in6 *dst6; --- 45 unchanged lines hidden (view full) --- 5693 5694 return (ret); 5695} 5696 5697#ifdef INET 5698 5699void 5700pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, | 5984} 5985 5986int 5987pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw) 5988{ 5989 struct sockaddr_in *dst; 5990#ifdef INET6 5991 struct sockaddr_in6 *dst6; --- 45 unchanged lines hidden (view full) --- 6037 6038 return (ret); 6039} 6040 6041#ifdef INET 6042 6043void 6044pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, |
5701 struct pf_state *s) | 6045 struct pf_state *s, struct pf_pdesc *pd) |
5702{ 5703 struct mbuf *m0, *m1; | 6046{ 6047 struct mbuf *m0, *m1; |
5704 struct m_tag *mtag; | |
5705 struct route iproute; | 6048 struct route iproute; |
5706 struct route *ro = NULL; /* XXX: was uninitialized */ | 6049 struct route *ro = NULL; |
5707 struct sockaddr_in *dst; 5708 struct ip *ip; 5709 struct ifnet *ifp = NULL; 5710 struct pf_addr naddr; 5711 struct pf_src_node *sn = NULL; 5712 int error = 0; 5713#ifdef __FreeBSD__ 5714 int sw_csum; 5715#endif | 6050 struct sockaddr_in *dst; 6051 struct ip *ip; 6052 struct ifnet *ifp = NULL; 6053 struct pf_addr naddr; 6054 struct pf_src_node *sn = NULL; 6055 int error = 0; 6056#ifdef __FreeBSD__ 6057 int sw_csum; 6058#endif |
6059#ifdef IPSEC 6060 struct m_tag *mtag; 6061#endif /* IPSEC */ |
|
5716 5717 if (m == NULL || *m == NULL || r == NULL || 5718 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 5719 panic("pf_route: invalid parameters"); 5720 | 6062 6063 if (m == NULL || *m == NULL || r == NULL || 6064 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 6065 panic("pf_route: invalid parameters"); 6066 |
5721 if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) { 5722 if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) == 5723 NULL) { 5724 m0 = *m; 5725 *m = NULL; 5726 goto bad; 5727 } 5728 *(char *)(mtag + 1) = 1; 5729 m_tag_prepend(*m, mtag); 5730 } else { 5731 if (*(char *)(mtag + 1) > 3) { 5732 m0 = *m; 5733 *m = NULL; 5734 goto bad; 5735 } 5736 (*(char *)(mtag + 1))++; | 6067 if (pd->pf_mtag->routed++ > 3) { 6068 m0 = *m; 6069 *m = NULL; 6070 goto bad; |
5737 } 5738 5739 if (r->rt == PF_DUPTO) { 5740#ifdef __FreeBSD__ 5741 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 5742#else 5743 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 5744#endif --- 130 unchanged lines hidden (view full) --- 5875 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) { 5876 /* Notify IPsec to do its own crypto. */ 5877 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); 5878 goto bad; 5879 } 5880#endif /* IPSEC */ 5881 5882 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */ | 6071 } 6072 6073 if (r->rt == PF_DUPTO) { 6074#ifdef __FreeBSD__ 6075 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 6076#else 6077 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 6078#endif --- 130 unchanged lines hidden (view full) --- 6209 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) { 6210 /* Notify IPsec to do its own crypto. */ 6211 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); 6212 goto bad; 6213 } 6214#endif /* IPSEC */ 6215 6216 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */ |
5883 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) { | 6217 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) { |
5884 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) || 5885 ifp->if_bridge != NULL) { 5886 in_delayed_cksum(m0); | 6218 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) || 6219 ifp->if_bridge != NULL) { 6220 in_delayed_cksum(m0); |
5887 m0->m_pkthdr.csum &= ~M_TCPV4_CSUM_OUT; /* Clear */ | 6221 m0->m_pkthdr.csum_flags &= ~M_TCPV4_CSUM_OUT; /* Clear */ |
5888 } | 6222 } |
5889 } else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) { | 6223 } else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) { |
5890 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) || 5891 ifp->if_bridge != NULL) { 5892 in_delayed_cksum(m0); | 6224 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) || 6225 ifp->if_bridge != NULL) { 6226 in_delayed_cksum(m0); |
5893 m0->m_pkthdr.csum &= ~M_UDPV4_CSUM_OUT; /* Clear */ | 6227 m0->m_pkthdr.csum_flags &= ~M_UDPV4_CSUM_OUT; /* Clear */ |
5894 } 5895 } 5896 5897 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 5898 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 5899 ifp->if_bridge == NULL) { | 6228 } 6229 } 6230 6231 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 6232 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 6233 ifp->if_bridge == NULL) { |
5900 m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT; | 6234 m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; |
5901 ipstat.ips_outhwcsum++; 5902 } else { 5903 ip->ip_sum = 0; 5904 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 5905 } 5906 /* Update relevant hardware checksum stats for TCP/UDP */ | 6235 ipstat.ips_outhwcsum++; 6236 } else { 6237 ip->ip_sum = 0; 6238 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 6239 } 6240 /* Update relevant hardware checksum stats for TCP/UDP */ |
5907 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) | 6241 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) |
5908 tcpstat.tcps_outhwcsum++; | 6242 tcpstat.tcps_outhwcsum++; |
5909 else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) | 6243 else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) |
5910 udpstat.udps_outhwcsum++; 5911 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); 5912 goto done; 5913 } 5914#endif 5915 /* 5916 * Too large for interface; fragment if possible. 5917 * Must be able to put at least 8 bytes per fragment. --- 6 unchanged lines hidden (view full) --- 5924 NTOHS(ip->ip_len); 5925 NTOHS(ip->ip_off); 5926 PF_UNLOCK(); 5927 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 5928 ifp->if_mtu); 5929 PF_LOCK(); 5930#else 5931 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, | 6244 udpstat.udps_outhwcsum++; 6245 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); 6246 goto done; 6247 } 6248#endif 6249 /* 6250 * Too large for interface; fragment if possible. 6251 * Must be able to put at least 8 bytes per fragment. --- 6 unchanged lines hidden (view full) --- 6258 NTOHS(ip->ip_len); 6259 NTOHS(ip->ip_off); 6260 PF_UNLOCK(); 6261 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 6262 ifp->if_mtu); 6263 PF_LOCK(); 6264#else 6265 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, |
5932 ifp); | 6266 ifp->if_mtu); |
5933#endif 5934 goto done; 5935 } else 5936 goto bad; 5937 } 5938 5939 m1 = m0; 5940#ifdef __FreeBSD__ --- 46 unchanged lines hidden (view full) --- 5987 m_freem(m0); 5988 goto done; 5989} 5990#endif /* INET */ 5991 5992#ifdef INET6 5993void 5994pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, | 6267#endif 6268 goto done; 6269 } else 6270 goto bad; 6271 } 6272 6273 m1 = m0; 6274#ifdef __FreeBSD__ --- 46 unchanged lines hidden (view full) --- 6321 m_freem(m0); 6322 goto done; 6323} 6324#endif /* INET */ 6325 6326#ifdef INET6 6327void 6328pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, |
5995 struct pf_state *s) | 6329 struct pf_state *s, struct pf_pdesc *pd) |
5996{ 5997 struct mbuf *m0; | 6330{ 6331 struct mbuf *m0; |
5998 struct m_tag *mtag; | |
5999 struct route_in6 ip6route; 6000 struct route_in6 *ro; 6001 struct sockaddr_in6 *dst; 6002 struct ip6_hdr *ip6; 6003 struct ifnet *ifp = NULL; 6004 struct pf_addr naddr; 6005 struct pf_src_node *sn = NULL; 6006 int error = 0; 6007 6008 if (m == NULL || *m == NULL || r == NULL || 6009 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 6010 panic("pf_route6: invalid parameters"); 6011 | 6332 struct route_in6 ip6route; 6333 struct route_in6 *ro; 6334 struct sockaddr_in6 *dst; 6335 struct ip6_hdr *ip6; 6336 struct ifnet *ifp = NULL; 6337 struct pf_addr naddr; 6338 struct pf_src_node *sn = NULL; 6339 int error = 0; 6340 6341 if (m == NULL || *m == NULL || r == NULL || 6342 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 6343 panic("pf_route6: invalid parameters"); 6344 |
6012 if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) { 6013 if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) == 6014 NULL) { 6015 m0 = *m; 6016 *m = NULL; 6017 goto bad; 6018 } 6019 *(char *)(mtag + 1) = 1; 6020 m_tag_prepend(*m, mtag); 6021 } else { 6022 if (*(char *)(mtag + 1) > 3) { 6023 m0 = *m; 6024 *m = NULL; 6025 goto bad; 6026 } 6027 (*(char *)(mtag + 1))++; | 6345 if (pd->pf_mtag->routed++ > 3) { 6346 m0 = *m; 6347 *m = NULL; 6348 goto bad; |
6028 } 6029 6030 if (r->rt == PF_DUPTO) { 6031#ifdef __FreeBSD__ 6032 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 6033#else 6034 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 6035#endif --- 13 unchanged lines hidden (view full) --- 6049 6050 ro = &ip6route; 6051 bzero((caddr_t)ro, sizeof(*ro)); 6052 dst = (struct sockaddr_in6 *)&ro->ro_dst; 6053 dst->sin6_family = AF_INET6; 6054 dst->sin6_len = sizeof(*dst); 6055 dst->sin6_addr = ip6->ip6_dst; 6056 | 6349 } 6350 6351 if (r->rt == PF_DUPTO) { 6352#ifdef __FreeBSD__ 6353 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 6354#else 6355 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 6356#endif --- 13 unchanged lines hidden (view full) --- 6370 6371 ro = &ip6route; 6372 bzero((caddr_t)ro, sizeof(*ro)); 6373 dst = (struct sockaddr_in6 *)&ro->ro_dst; 6374 dst->sin6_family = AF_INET6; 6375 dst->sin6_len = sizeof(*dst); 6376 dst->sin6_addr = ip6->ip6_dst; 6377 |
6057 /* Cheat. */ | 6378 /* Cheat. XXX why only in the v6 case??? */ |
6058 if (r->rt == PF_FASTROUTE) { 6059#ifdef __FreeBSD__ 6060 m0->m_flags |= M_SKIP_FIREWALL; 6061 PF_UNLOCK(); 6062 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 6063 PF_LOCK(); 6064#else 6065 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 6066 if (mtag == NULL) 6067 goto bad; 6068 m_tag_prepend(m0, mtag); | 6379 if (r->rt == PF_FASTROUTE) { 6380#ifdef __FreeBSD__ 6381 m0->m_flags |= M_SKIP_FIREWALL; 6382 PF_UNLOCK(); 6383 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 6384 PF_LOCK(); 6385#else 6386 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 6387 if (mtag == NULL) 6388 goto bad; 6389 m_tag_prepend(m0, mtag); |
6390 pd->pf_mtag->flags |= PF_TAG_GENERATED; |
|
6069 ip6_output(m0, NULL, NULL, 0, NULL, NULL); 6070#endif 6071 return; 6072 } 6073 6074 if (TAILQ_EMPTY(&r->rpool.list)) { 6075 DPFPRINTF(PF_DEBUG_URGENT, 6076 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n")); --- 39 unchanged lines hidden (view full) --- 6116 } 6117 ip6 = mtod(m0, struct ip6_hdr *); 6118 } 6119 6120 /* 6121 * If the packet is too large for the outgoing interface, 6122 * send back an icmp6 error. 6123 */ | 6391 ip6_output(m0, NULL, NULL, 0, NULL, NULL); 6392#endif 6393 return; 6394 } 6395 6396 if (TAILQ_EMPTY(&r->rpool.list)) { 6397 DPFPRINTF(PF_DEBUG_URGENT, 6398 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n")); --- 39 unchanged lines hidden (view full) --- 6438 } 6439 ip6 = mtod(m0, struct ip6_hdr *); 6440 } 6441 6442 /* 6443 * If the packet is too large for the outgoing interface, 6444 * send back an icmp6 error. 6445 */ |
6124 if (IN6_IS_ADDR_LINKLOCAL(&dst->sin6_addr)) | 6446 if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr)) |
6125 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); 6126 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { 6127#ifdef __FreeBSD__ 6128 PF_UNLOCK(); 6129#endif 6130 error = nd6_output(ifp, ifp, m0, dst, NULL); 6131#ifdef __FreeBSD__ 6132 PF_LOCK(); --- 145 unchanged lines hidden (view full) --- 6278 if (p == IPPROTO_TCP || p == IPPROTO_UDP) { 6279 m->m_pkthdr.csum_flags |= 6280 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); 6281 m->m_pkthdr.csum_data = 0xffff; 6282 } 6283 } 6284 return (0); 6285} | 6447 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); 6448 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { 6449#ifdef __FreeBSD__ 6450 PF_UNLOCK(); 6451#endif 6452 error = nd6_output(ifp, ifp, m0, dst, NULL); 6453#ifdef __FreeBSD__ 6454 PF_LOCK(); --- 145 unchanged lines hidden (view full) --- 6600 if (p == IPPROTO_TCP || p == IPPROTO_UDP) { 6601 m->m_pkthdr.csum_flags |= 6602 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); 6603 m->m_pkthdr.csum_data = 0xffff; 6604 } 6605 } 6606 return (0); 6607} |
6286#else | 6608#else /* !__FreeBSD__ */ |
6287/* 6288 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 6289 * off is the offset where the protocol header starts 6290 * len is the total length of protocol header plus payload 6291 * returns 0 when the checksum is valid, otherwise returns 1. 6292 */ 6293int 6294pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, --- 15 unchanged lines hidden (view full) --- 6310#ifdef INET6 6311 case IPPROTO_ICMPV6: 6312#endif /* INET6 */ 6313 flag_ok = flag_bad = 0; 6314 break; 6315 default: 6316 return (1); 6317 } | 6609/* 6610 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 6611 * off is the offset where the protocol header starts 6612 * len is the total length of protocol header plus payload 6613 * returns 0 when the checksum is valid, otherwise returns 1. 6614 */ 6615int 6616pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, --- 15 unchanged lines hidden (view full) --- 6632#ifdef INET6 6633 case IPPROTO_ICMPV6: 6634#endif /* INET6 */ 6635 flag_ok = flag_bad = 0; 6636 break; 6637 default: 6638 return (1); 6639 } |
6318 if (m->m_pkthdr.csum & flag_ok) | 6640 if (m->m_pkthdr.csum_flags & flag_ok) |
6319 return (0); | 6641 return (0); |
6320 if (m->m_pkthdr.csum & flag_bad) | 6642 if (m->m_pkthdr.csum_flags & flag_bad) |
6321 return (1); 6322 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 6323 return (1); 6324 if (m->m_pkthdr.len < off + len) 6325 return (1); 6326 switch (af) { 6327#ifdef INET 6328 case AF_INET: --- 18 unchanged lines hidden (view full) --- 6347 return (1); 6348 sum = in6_cksum(m, p, off, len); 6349 break; 6350#endif /* INET6 */ 6351 default: 6352 return (1); 6353 } 6354 if (sum) { | 6643 return (1); 6644 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 6645 return (1); 6646 if (m->m_pkthdr.len < off + len) 6647 return (1); 6648 switch (af) { 6649#ifdef INET 6650 case AF_INET: --- 18 unchanged lines hidden (view full) --- 6669 return (1); 6670 sum = in6_cksum(m, p, off, len); 6671 break; 6672#endif /* INET6 */ 6673 default: 6674 return (1); 6675 } 6676 if (sum) { |
6355 m->m_pkthdr.csum |= flag_bad; | 6677 m->m_pkthdr.csum_flags |= flag_bad; |
6356 switch (p) { 6357 case IPPROTO_TCP: 6358 tcpstat.tcps_rcvbadsum++; 6359 break; 6360 case IPPROTO_UDP: 6361 udpstat.udps_badsum++; 6362 break; 6363 case IPPROTO_ICMP: 6364 icmpstat.icps_checksum++; 6365 break; 6366#ifdef INET6 6367 case IPPROTO_ICMPV6: 6368 icmp6stat.icp6s_checksum++; 6369 break; 6370#endif /* INET6 */ 6371 } 6372 return (1); 6373 } | 6678 switch (p) { 6679 case IPPROTO_TCP: 6680 tcpstat.tcps_rcvbadsum++; 6681 break; 6682 case IPPROTO_UDP: 6683 udpstat.udps_badsum++; 6684 break; 6685 case IPPROTO_ICMP: 6686 icmpstat.icps_checksum++; 6687 break; 6688#ifdef INET6 6689 case IPPROTO_ICMPV6: 6690 icmp6stat.icp6s_checksum++; 6691 break; 6692#endif /* INET6 */ 6693 } 6694 return (1); 6695 } |
6374 m->m_pkthdr.csum |= flag_ok; | 6696 m->m_pkthdr.csum_flags |= flag_ok; |
6375 return (0); 6376} | 6697 return (0); 6698} |
6377#endif | 6699#endif /* __FreeBSD__ */ |
6378 | 6700 |
6379static int 6380pf_add_mbuf_tag(struct mbuf *m, u_int tag) 6381{ 6382 struct m_tag *mtag; 6383 6384 if (m_tag_find(m, tag, NULL) != NULL) 6385 return (0); 6386 mtag = m_tag_get(tag, 0, M_NOWAIT); 6387 if (mtag == NULL) 6388 return (1); 6389 m_tag_prepend(m, mtag); 6390 return (0); 6391} 6392 | |
6393#ifdef INET 6394int 6395#ifdef __FreeBSD__ 6396pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6397 struct ether_header *eh, struct inpcb *inp) 6398#else 6399pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6400 struct ether_header *eh) --- 7 unchanged lines hidden (view full) --- 6408 struct pf_state *s = NULL; 6409 struct pf_ruleset *ruleset = NULL; 6410 struct pf_pdesc pd; 6411 int off, dirndx, pqid = 0; 6412 6413#ifdef __FreeBSD__ 6414 PF_LOCK(); 6415#endif | 6701#ifdef INET 6702int 6703#ifdef __FreeBSD__ 6704pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6705 struct ether_header *eh, struct inpcb *inp) 6706#else 6707pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6708 struct ether_header *eh) --- 7 unchanged lines hidden (view full) --- 6716 struct pf_state *s = NULL; 6717 struct pf_ruleset *ruleset = NULL; 6718 struct pf_pdesc pd; 6719 int off, dirndx, pqid = 0; 6720 6721#ifdef __FreeBSD__ 6722 PF_LOCK(); 6723#endif |
6416 if (!pf_status.running || | 6724 if (!pf_status.running) |
6417#ifdef __FreeBSD__ | 6725#ifdef __FreeBSD__ |
6418 (m->m_flags & M_SKIP_FIREWALL)) { | 6726 { |
6419 PF_UNLOCK(); | 6727 PF_UNLOCK(); |
6420#else 6421 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) { | |
6422#endif | 6728#endif |
6423 return (PF_PASS); | 6729 return (PF_PASS); 6730#ifdef __FreeBSD__ |
6424 } | 6731 } |
6732#endif |
|
6425 | 6733 |
6734 memset(&pd, 0, sizeof(pd)); 6735 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) { |
|
6426#ifdef __FreeBSD__ | 6736#ifdef __FreeBSD__ |
6737 PF_UNLOCK(); 6738#endif 6739 DPFPRINTF(PF_DEBUG_URGENT, 6740 ("pf_test: pf_get_mtag returned NULL\n")); 6741 return (PF_DROP); 6742 } 6743#ifdef __FreeBSD__ 6744 if (m->m_flags & M_SKIP_FIREWALL) { 6745 PF_UNLOCK(); 6746 return (PF_PASS); 6747 } 6748#else 6749 if (pd.pf_mtag->flags & PF_TAG_GENERATED) 6750 return (PF_PASS); 6751#endif 6752 6753#ifdef __FreeBSD__ |
|
6427 /* XXX_IMPORT: later */ 6428#else 6429 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 6430 ifp = ifp->if_carpdev; 6431#endif 6432 | 6754 /* XXX_IMPORT: later */ 6755#else 6756 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 6757 ifp = ifp->if_carpdev; 6758#endif 6759 |
6433 kif = pfi_index2kif[ifp->if_index]; | 6760 kif = (struct pfi_kif *)ifp->if_pf_kif; |
6434 if (kif == NULL) { 6435#ifdef __FreeBSD__ 6436 PF_UNLOCK(); 6437#endif 6438 DPFPRINTF(PF_DEBUG_URGENT, 6439 ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname)); 6440 return (PF_DROP); 6441 } --- 8 unchanged lines hidden (view full) --- 6450 M_ASSERTPKTHDR(m); 6451#else 6452#ifdef DIAGNOSTIC 6453 if ((m->m_flags & M_PKTHDR) == 0) 6454 panic("non-M_PKTHDR is passed to pf_test"); 6455#endif /* DIAGNOSTIC */ 6456#endif /* __FreeBSD__ */ 6457 | 6761 if (kif == NULL) { 6762#ifdef __FreeBSD__ 6763 PF_UNLOCK(); 6764#endif 6765 DPFPRINTF(PF_DEBUG_URGENT, 6766 ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname)); 6767 return (PF_DROP); 6768 } --- 8 unchanged lines hidden (view full) --- 6777 M_ASSERTPKTHDR(m); 6778#else 6779#ifdef DIAGNOSTIC 6780 if ((m->m_flags & M_PKTHDR) == 0) 6781 panic("non-M_PKTHDR is passed to pf_test"); 6782#endif /* DIAGNOSTIC */ 6783#endif /* __FreeBSD__ */ 6784 |
6458 memset(&pd, 0, sizeof(pd)); | |
6459 if (m->m_pkthdr.len < (int)sizeof(*h)) { 6460 action = PF_DROP; 6461 REASON_SET(&reason, PFRES_SHORT); 6462 log = 1; 6463 goto done; 6464 } 6465 6466 /* We do IP header normalization and packet reassembly here */ --- 37 unchanged lines hidden (view full) --- 6504 pd.hdr.tcp = &th; 6505 if (!pf_pull_hdr(m, off, &th, sizeof(th), 6506 &action, &reason, AF_INET)) { 6507 log = action != PF_PASS; 6508 goto done; 6509 } 6510 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6511 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) { | 6785 if (m->m_pkthdr.len < (int)sizeof(*h)) { 6786 action = PF_DROP; 6787 REASON_SET(&reason, PFRES_SHORT); 6788 log = 1; 6789 goto done; 6790 } 6791 6792 /* We do IP header normalization and packet reassembly here */ --- 37 unchanged lines hidden (view full) --- 6830 pd.hdr.tcp = &th; 6831 if (!pf_pull_hdr(m, off, &th, sizeof(th), 6832 &action, &reason, AF_INET)) { 6833 log = action != PF_PASS; 6834 goto done; 6835 } 6836 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6837 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) { |
6838 REASON_SET(&reason, PFRES_PROTCKSUM); |
|
6512 action = PF_DROP; 6513 goto done; 6514 } 6515 pd.p_len = pd.tot_len - off - (th.th_off << 2); 6516 if ((th.th_flags & TH_ACK) && pd.p_len == 0) 6517 pqid = 1; 6518 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 6519 if (action == PF_DROP) --- 25 unchanged lines hidden (view full) --- 6545 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 6546 &action, &reason, AF_INET)) { 6547 log = action != PF_PASS; 6548 goto done; 6549 } 6550 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 6551 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) { 6552 action = PF_DROP; | 6839 action = PF_DROP; 6840 goto done; 6841 } 6842 pd.p_len = pd.tot_len - off - (th.th_off << 2); 6843 if ((th.th_flags & TH_ACK) && pd.p_len == 0) 6844 pqid = 1; 6845 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 6846 if (action == PF_DROP) --- 25 unchanged lines hidden (view full) --- 6872 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 6873 &action, &reason, AF_INET)) { 6874 log = action != PF_PASS; 6875 goto done; 6876 } 6877 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 6878 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) { 6879 action = PF_DROP; |
6880 REASON_SET(&reason, PFRES_PROTCKSUM); |
|
6553 goto done; 6554 } 6555 if (uh.uh_dport == 0 || 6556 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 6557 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 6558 action = PF_DROP; | 6881 goto done; 6882 } 6883 if (uh.uh_dport == 0 || 6884 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 6885 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 6886 action = PF_DROP; |
6887 REASON_SET(&reason, PFRES_SHORT); |
|
6559 goto done; 6560 } 6561 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 6562 if (action == PF_PASS) { 6563#if NPFSYNC 6564 pfsync_update_state(s); 6565#endif /* NPFSYNC */ 6566 r = s->rule.ptr; --- 17 unchanged lines hidden (view full) --- 6584 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN, 6585 &action, &reason, AF_INET)) { 6586 log = action != PF_PASS; 6587 goto done; 6588 } 6589 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6590 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) { 6591 action = PF_DROP; | 6888 goto done; 6889 } 6890 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 6891 if (action == PF_PASS) { 6892#if NPFSYNC 6893 pfsync_update_state(s); 6894#endif /* NPFSYNC */ 6895 r = s->rule.ptr; --- 17 unchanged lines hidden (view full) --- 6913 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN, 6914 &action, &reason, AF_INET)) { 6915 log = action != PF_PASS; 6916 goto done; 6917 } 6918 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6919 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) { 6920 action = PF_DROP; |
6921 REASON_SET(&reason, PFRES_PROTCKSUM); |
|
6592 goto done; 6593 } 6594 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd, 6595 &reason); 6596 if (action == PF_PASS) { 6597#if NPFSYNC 6598 pfsync_update_state(s); 6599#endif /* NPFSYNC */ --- 36 unchanged lines hidden (view full) --- 6636 !((s && s->allow_opts) || r->allow_opts)) { 6637 action = PF_DROP; 6638 REASON_SET(&reason, PFRES_IPOPTIONS); 6639 log = 1; 6640 DPFPRINTF(PF_DEBUG_MISC, 6641 ("pf: dropping packet with ip options\n")); 6642 } 6643 | 6922 goto done; 6923 } 6924 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd, 6925 &reason); 6926 if (action == PF_PASS) { 6927#if NPFSYNC 6928 pfsync_update_state(s); 6929#endif /* NPFSYNC */ --- 36 unchanged lines hidden (view full) --- 6966 !((s && s->allow_opts) || r->allow_opts)) { 6967 action = PF_DROP; 6968 REASON_SET(&reason, PFRES_IPOPTIONS); 6969 log = 1; 6970 DPFPRINTF(PF_DEBUG_MISC, 6971 ("pf: dropping packet with ip options\n")); 6972 } 6973 |
6644 if (s && s->tag) 6645 pf_tag_packet(m, pf_get_tag(m), s->tag); | 6974 if ((s && s->tag) || r->rtableid) 6975 pf_tag_packet(m, pd.pf_mtag, s ? s->tag : 0, r->rtableid); |
6646 6647#ifdef ALTQ 6648 if (action == PF_PASS && r->qid) { | 6976 6977#ifdef ALTQ 6978 if (action == PF_PASS && r->qid) { |
6649 struct m_tag *mtag; 6650 struct altq_tag *atag; 6651 6652 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); 6653 if (mtag != NULL) { 6654 atag = (struct altq_tag *)(mtag + 1); 6655 if (pqid || pd.tos == IPTOS_LOWDELAY) 6656 atag->qid = r->pqid; 6657 else 6658 atag->qid = r->qid; 6659 /* add hints for ecn */ 6660 atag->af = AF_INET; 6661 atag->hdr = h; 6662 m_tag_prepend(m, mtag); 6663 } | 6979 if (pqid || (pd.tos & IPTOS_LOWDELAY)) 6980 pd.pf_mtag->qid = r->pqid; 6981 else 6982 pd.pf_mtag->qid = r->qid; 6983 /* add hints for ecn */ 6984 pd.pf_mtag->af = AF_INET; 6985 pd.pf_mtag->hdr = h; |
6664 } 6665#endif /* ALTQ */ 6666 6667 /* 6668 * connections redirected to loopback should not match sockets 6669 * bound specifically to loopback due to security implications, 6670 * see tcp_input() and in_pcblookup_listen(). 6671 */ 6672 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 6673 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 6674 (s->nat_rule.ptr->action == PF_RDR || 6675 s->nat_rule.ptr->action == PF_BINAT) && | 6986 } 6987#endif /* ALTQ */ 6988 6989 /* 6990 * connections redirected to loopback should not match sockets 6991 * bound specifically to loopback due to security implications, 6992 * see tcp_input() and in_pcblookup_listen(). 6993 */ 6994 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 6995 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 6996 (s->nat_rule.ptr->action == PF_RDR || 6997 s->nat_rule.ptr->action == PF_BINAT) && |
6676 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET && 6677 pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) { 6678 action = PF_DROP; 6679 REASON_SET(&reason, PFRES_MEMORY); 6680 } | 6998 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 6999 pd.pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST; |
6681 | 7000 |
6682 if (log) 6683 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, a, ruleset); | 7001 if (log) { 7002 struct pf_rule *lr; |
6684 | 7003 |
7004 if (s != NULL && s->nat_rule.ptr != NULL && 7005 s->nat_rule.ptr->log & PF_LOG_ALL) 7006 lr = s->nat_rule.ptr; 7007 else 7008 lr = r; 7009 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, lr, a, ruleset, 7010 &pd); 7011 } 7012 |
|
6685 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 6686 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++; 6687 6688 if (action == PF_PASS || r->action == PF_DROP) { | 7013 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7014 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++; 7015 7016 if (action == PF_PASS || r->action == PF_DROP) { |
6689 r->packets++; 6690 r->bytes += pd.tot_len; | 7017 dirndx = (dir == PF_OUT); 7018 r->packets[dirndx]++; 7019 r->bytes[dirndx] += pd.tot_len; |
6691 if (a != NULL) { | 7020 if (a != NULL) { |
6692 a->packets++; 6693 a->bytes += pd.tot_len; | 7021 a->packets[dirndx]++; 7022 a->bytes[dirndx] += pd.tot_len; |
6694 } 6695 if (s != NULL) { | 7023 } 7024 if (s != NULL) { |
6696 dirndx = (dir == s->direction) ? 0 : 1; 6697 s->packets[dirndx]++; 6698 s->bytes[dirndx] += pd.tot_len; | |
6699 if (s->nat_rule.ptr != NULL) { | 7025 if (s->nat_rule.ptr != NULL) { |
6700 s->nat_rule.ptr->packets++; 6701 s->nat_rule.ptr->bytes += pd.tot_len; | 7026 s->nat_rule.ptr->packets[dirndx]++; 7027 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; |
6702 } 6703 if (s->src_node != NULL) { | 7028 } 7029 if (s->src_node != NULL) { |
6704 s->src_node->packets++; 6705 s->src_node->bytes += pd.tot_len; | 7030 s->src_node->packets[dirndx]++; 7031 s->src_node->bytes[dirndx] += pd.tot_len; |
6706 } 6707 if (s->nat_src_node != NULL) { | 7032 } 7033 if (s->nat_src_node != NULL) { |
6708 s->nat_src_node->packets++; 6709 s->nat_src_node->bytes += pd.tot_len; | 7034 s->nat_src_node->packets[dirndx]++; 7035 s->nat_src_node->bytes[dirndx] += pd.tot_len; |
6710 } | 7036 } |
7037 dirndx = (dir == s->direction) ? 0 : 1; 7038 s->packets[dirndx]++; 7039 s->bytes[dirndx] += pd.tot_len; |
|
6711 } 6712 tr = r; 6713 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 6714 if (nr != NULL) { 6715 struct pf_addr *x; 6716 /* 6717 * XXX: we need to make sure that the addresses 6718 * passed to pfr_update_stats() are the same than --- 28 unchanged lines hidden (view full) --- 6747 6748 6749 if (action == PF_SYNPROXY_DROP) { 6750 m_freem(*m0); 6751 *m0 = NULL; 6752 action = PF_PASS; 6753 } else if (r->rt) 6754 /* pf_route can free the mbuf causing *m0 to become NULL */ | 7040 } 7041 tr = r; 7042 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7043 if (nr != NULL) { 7044 struct pf_addr *x; 7045 /* 7046 * XXX: we need to make sure that the addresses 7047 * passed to pfr_update_stats() are the same than --- 28 unchanged lines hidden (view full) --- 7076 7077 7078 if (action == PF_SYNPROXY_DROP) { 7079 m_freem(*m0); 7080 *m0 = NULL; 7081 action = PF_PASS; 7082 } else if (r->rt) 7083 /* pf_route can free the mbuf causing *m0 to become NULL */ |
6755 pf_route(m0, r, dir, ifp, s); | 7084 pf_route(m0, r, dir, ifp, s, &pd); |
6756 6757#ifdef __FreeBSD__ 6758 PF_UNLOCK(); 6759#endif 6760 6761 return (action); 6762} 6763#endif /* INET */ --- 5 unchanged lines hidden (view full) --- 6769 struct ether_header *eh, struct inpcb *inp) 6770#else 6771pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, 6772 struct ether_header *eh) 6773#endif 6774{ 6775 struct pfi_kif *kif; 6776 u_short action, reason = 0, log = 0; | 7085 7086#ifdef __FreeBSD__ 7087 PF_UNLOCK(); 7088#endif 7089 7090 return (action); 7091} 7092#endif /* INET */ --- 5 unchanged lines hidden (view full) --- 7098 struct ether_header *eh, struct inpcb *inp) 7099#else 7100pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, 7101 struct ether_header *eh) 7102#endif 7103{ 7104 struct pfi_kif *kif; 7105 u_short action, reason = 0, log = 0; |
6777 struct mbuf *m = *m0; 6778 struct ip6_hdr *h = NULL; /* make the compiler happy */ | 7106 struct mbuf *m = *m0, *n = NULL; 7107 struct ip6_hdr *h; |
6779 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 6780 struct pf_state *s = NULL; 6781 struct pf_ruleset *ruleset = NULL; 6782 struct pf_pdesc pd; 6783 int off, terminal = 0, dirndx, rh_cnt = 0; 6784 6785#ifdef __FreeBSD__ 6786 PF_LOCK(); 6787#endif 6788 | 7108 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 7109 struct pf_state *s = NULL; 7110 struct pf_ruleset *ruleset = NULL; 7111 struct pf_pdesc pd; 7112 int off, terminal = 0, dirndx, rh_cnt = 0; 7113 7114#ifdef __FreeBSD__ 7115 PF_LOCK(); 7116#endif 7117 |
6789 if (!pf_status.running || | 7118 if (!pf_status.running) |
6790#ifdef __FreeBSD__ | 7119#ifdef __FreeBSD__ |
6791 (m->m_flags & M_SKIP_FIREWALL)) { | 7120 { |
6792 PF_UNLOCK(); | 7121 PF_UNLOCK(); |
6793#else 6794 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) { | |
6795#endif 6796 return (PF_PASS); | 7122#endif 7123 return (PF_PASS); |
7124#ifdef __FreeBSD__ |
|
6797 } | 7125 } |
7126#endif |
|
6798 | 7127 |
7128 memset(&pd, 0, sizeof(pd)); 7129 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) { |
|
6799#ifdef __FreeBSD__ | 7130#ifdef __FreeBSD__ |
7131 PF_UNLOCK(); 7132#endif 7133 DPFPRINTF(PF_DEBUG_URGENT, 7134 ("pf_test6: pf_get_mtag returned NULL\n")); 7135 return (PF_DROP); 7136 } 7137 if (pd.pf_mtag->flags & PF_TAG_GENERATED) 7138 return (PF_PASS); 7139 7140#ifdef __FreeBSD__ |
|
6800 /* XXX_IMPORT: later */ 6801#else 6802 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 6803 ifp = ifp->if_carpdev; 6804#endif 6805 | 7141 /* XXX_IMPORT: later */ 7142#else 7143 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 7144 ifp = ifp->if_carpdev; 7145#endif 7146 |
6806 kif = pfi_index2kif[ifp->if_index]; | 7147 kif = (struct pfi_kif *)ifp->if_pf_kif; |
6807 if (kif == NULL) { 6808#ifdef __FreeBSD__ 6809 PF_UNLOCK(); 6810#endif 6811 DPFPRINTF(PF_DEBUG_URGENT, 6812 ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname)); 6813 return (PF_DROP); 6814 } --- 8 unchanged lines hidden (view full) --- 6823 M_ASSERTPKTHDR(m); 6824#else 6825#ifdef DIAGNOSTIC 6826 if ((m->m_flags & M_PKTHDR) == 0) 6827 panic("non-M_PKTHDR is passed to pf_test6"); 6828#endif /* DIAGNOSTIC */ 6829#endif 6830 | 7148 if (kif == NULL) { 7149#ifdef __FreeBSD__ 7150 PF_UNLOCK(); 7151#endif 7152 DPFPRINTF(PF_DEBUG_URGENT, 7153 ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname)); 7154 return (PF_DROP); 7155 } --- 8 unchanged lines hidden (view full) --- 7164 M_ASSERTPKTHDR(m); 7165#else 7166#ifdef DIAGNOSTIC 7167 if ((m->m_flags & M_PKTHDR) == 0) 7168 panic("non-M_PKTHDR is passed to pf_test6"); 7169#endif /* DIAGNOSTIC */ 7170#endif 7171 |
6831 memset(&pd, 0, sizeof(pd)); | 7172#ifdef __FreeBSD__ 7173 h = NULL; /* make the compiler happy */ 7174#endif 7175 |
6832 if (m->m_pkthdr.len < (int)sizeof(*h)) { 6833 action = PF_DROP; 6834 REASON_SET(&reason, PFRES_SHORT); 6835 log = 1; 6836 goto done; 6837 } 6838 6839 /* We do IP header normalization and packet reassembly here */ --- 88 unchanged lines hidden (view full) --- 6928 break; 6929 } 6930 default: 6931 terminal++; 6932 break; 6933 } 6934 } while (!terminal); 6935 | 7176 if (m->m_pkthdr.len < (int)sizeof(*h)) { 7177 action = PF_DROP; 7178 REASON_SET(&reason, PFRES_SHORT); 7179 log = 1; 7180 goto done; 7181 } 7182 7183 /* We do IP header normalization and packet reassembly here */ --- 88 unchanged lines hidden (view full) --- 7272 break; 7273 } 7274 default: 7275 terminal++; 7276 break; 7277 } 7278 } while (!terminal); 7279 |
7280 /* if there's no routing header, use unmodified mbuf for checksumming */ 7281 if (!n) 7282 n = m; 7283 |
|
6936 switch (pd.proto) { 6937 6938 case IPPROTO_TCP: { 6939 struct tcphdr th; 6940 6941 pd.hdr.tcp = &th; 6942 if (!pf_pull_hdr(m, off, &th, sizeof(th), 6943 &action, &reason, AF_INET6)) { 6944 log = action != PF_PASS; 6945 goto done; 6946 } | 7284 switch (pd.proto) { 7285 7286 case IPPROTO_TCP: { 7287 struct tcphdr th; 7288 7289 pd.hdr.tcp = &th; 7290 if (!pf_pull_hdr(m, off, &th, sizeof(th), 7291 &action, &reason, AF_INET6)) { 7292 log = action != PF_PASS; 7293 goto done; 7294 } |
6947 if (dir == PF_IN && pf_check_proto_cksum(m, off, | 7295 if (dir == PF_IN && pf_check_proto_cksum(n, off, |
6948 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 6949 IPPROTO_TCP, AF_INET6)) { 6950 action = PF_DROP; 6951 REASON_SET(&reason, PFRES_PROTCKSUM); 6952 goto done; 6953 } 6954 pd.p_len = pd.tot_len - off - (th.th_off << 2); 6955 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); --- 23 unchanged lines hidden (view full) --- 6979 struct udphdr uh; 6980 6981 pd.hdr.udp = &uh; 6982 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 6983 &action, &reason, AF_INET6)) { 6984 log = action != PF_PASS; 6985 goto done; 6986 } | 7296 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7297 IPPROTO_TCP, AF_INET6)) { 7298 action = PF_DROP; 7299 REASON_SET(&reason, PFRES_PROTCKSUM); 7300 goto done; 7301 } 7302 pd.p_len = pd.tot_len - off - (th.th_off << 2); 7303 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); --- 23 unchanged lines hidden (view full) --- 7327 struct udphdr uh; 7328 7329 pd.hdr.udp = &uh; 7330 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 7331 &action, &reason, AF_INET6)) { 7332 log = action != PF_PASS; 7333 goto done; 7334 } |
6987 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, | 7335 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(n, |
6988 off, ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 6989 IPPROTO_UDP, AF_INET6)) { 6990 action = PF_DROP; 6991 REASON_SET(&reason, PFRES_PROTCKSUM); 6992 goto done; 6993 } 6994 if (uh.uh_dport == 0 || 6995 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 6996 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 6997 action = PF_DROP; | 7336 off, ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7337 IPPROTO_UDP, AF_INET6)) { 7338 action = PF_DROP; 7339 REASON_SET(&reason, PFRES_PROTCKSUM); 7340 goto done; 7341 } 7342 if (uh.uh_dport == 0 || 7343 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 7344 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 7345 action = PF_DROP; |
7346 REASON_SET(&reason, PFRES_SHORT); |
|
6998 goto done; 6999 } 7000 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 7001 if (action == PF_PASS) { 7002#if NPFSYNC 7003 pfsync_update_state(s); 7004#endif /* NPFSYNC */ 7005 r = s->rule.ptr; --- 14 unchanged lines hidden (view full) --- 7020 struct icmp6_hdr ih; 7021 7022 pd.hdr.icmp6 = &ih; 7023 if (!pf_pull_hdr(m, off, &ih, sizeof(ih), 7024 &action, &reason, AF_INET6)) { 7025 log = action != PF_PASS; 7026 goto done; 7027 } | 7347 goto done; 7348 } 7349 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 7350 if (action == PF_PASS) { 7351#if NPFSYNC 7352 pfsync_update_state(s); 7353#endif /* NPFSYNC */ 7354 r = s->rule.ptr; --- 14 unchanged lines hidden (view full) --- 7369 struct icmp6_hdr ih; 7370 7371 pd.hdr.icmp6 = &ih; 7372 if (!pf_pull_hdr(m, off, &ih, sizeof(ih), 7373 &action, &reason, AF_INET6)) { 7374 log = action != PF_PASS; 7375 goto done; 7376 } |
7028 if (dir == PF_IN && pf_check_proto_cksum(m, off, | 7377 if (dir == PF_IN && pf_check_proto_cksum(n, off, |
7029 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7030 IPPROTO_ICMPV6, AF_INET6)) { 7031 action = PF_DROP; 7032 REASON_SET(&reason, PFRES_PROTCKSUM); 7033 goto done; 7034 } 7035 action = pf_test_state_icmp(&s, dir, kif, 7036 m, off, h, &pd, &reason); --- 41 unchanged lines hidden (view full) --- 7078 !((s && s->allow_opts) || r->allow_opts)) { 7079 action = PF_DROP; 7080 REASON_SET(&reason, PFRES_IPOPTIONS); 7081 log = 1; 7082 DPFPRINTF(PF_DEBUG_MISC, 7083 ("pf: dropping packet with dangerous v6 headers\n")); 7084 } 7085 | 7378 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7379 IPPROTO_ICMPV6, AF_INET6)) { 7380 action = PF_DROP; 7381 REASON_SET(&reason, PFRES_PROTCKSUM); 7382 goto done; 7383 } 7384 action = pf_test_state_icmp(&s, dir, kif, 7385 m, off, h, &pd, &reason); --- 41 unchanged lines hidden (view full) --- 7427 !((s && s->allow_opts) || r->allow_opts)) { 7428 action = PF_DROP; 7429 REASON_SET(&reason, PFRES_IPOPTIONS); 7430 log = 1; 7431 DPFPRINTF(PF_DEBUG_MISC, 7432 ("pf: dropping packet with dangerous v6 headers\n")); 7433 } 7434 |
7086 if (s && s->tag) 7087 pf_tag_packet(m, pf_get_tag(m), s->tag); | 7435 if ((s && s->tag) || r->rtableid) 7436 pf_tag_packet(m, pd.pf_mtag, s ? s->tag : 0, r->rtableid); |
7088 7089#ifdef ALTQ 7090 if (action == PF_PASS && r->qid) { | 7437 7438#ifdef ALTQ 7439 if (action == PF_PASS && r->qid) { |
7091 struct m_tag *mtag; 7092 struct altq_tag *atag; 7093 7094 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); 7095 if (mtag != NULL) { 7096 atag = (struct altq_tag *)(mtag + 1); 7097 if (pd.tos == IPTOS_LOWDELAY) 7098 atag->qid = r->pqid; 7099 else 7100 atag->qid = r->qid; 7101 /* add hints for ecn */ 7102 atag->af = AF_INET6; 7103 atag->hdr = h; 7104 m_tag_prepend(m, mtag); 7105 } | 7440 if (pd.tos & IPTOS_LOWDELAY) 7441 pd.pf_mtag->qid = r->pqid; 7442 else 7443 pd.pf_mtag->qid = r->qid; 7444 /* add hints for ecn */ 7445 pd.pf_mtag->af = AF_INET6; 7446 pd.pf_mtag->hdr = h; |
7106 } 7107#endif /* ALTQ */ 7108 7109 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 7110 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 7111 (s->nat_rule.ptr->action == PF_RDR || 7112 s->nat_rule.ptr->action == PF_BINAT) && | 7447 } 7448#endif /* ALTQ */ 7449 7450 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 7451 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 7452 (s->nat_rule.ptr->action == PF_RDR || 7453 s->nat_rule.ptr->action == PF_BINAT) && |
7113 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6) && 7114 pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) { 7115 action = PF_DROP; 7116 REASON_SET(&reason, PFRES_MEMORY); 7117 } | 7454 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6)) 7455 pd.pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST; |
7118 | 7456 |
7119 if (log) 7120 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, r, a, ruleset); | 7457 if (log) { 7458 struct pf_rule *lr; |
7121 | 7459 |
7460 if (s != NULL && s->nat_rule.ptr != NULL && 7461 s->nat_rule.ptr->log & PF_LOG_ALL) 7462 lr = s->nat_rule.ptr; 7463 else 7464 lr = r; 7465 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, lr, a, ruleset, 7466 &pd); 7467 } 7468 |
|
7122 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7123 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++; 7124 7125 if (action == PF_PASS || r->action == PF_DROP) { | 7469 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7470 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++; 7471 7472 if (action == PF_PASS || r->action == PF_DROP) { |
7126 r->packets++; 7127 r->bytes += pd.tot_len; | 7473 dirndx = (dir == PF_OUT); 7474 r->packets[dirndx]++; 7475 r->bytes[dirndx] += pd.tot_len; |
7128 if (a != NULL) { | 7476 if (a != NULL) { |
7129 a->packets++; 7130 a->bytes += pd.tot_len; | 7477 a->packets[dirndx]++; 7478 a->bytes[dirndx] += pd.tot_len; |
7131 } 7132 if (s != NULL) { | 7479 } 7480 if (s != NULL) { |
7133 dirndx = (dir == s->direction) ? 0 : 1; 7134 s->packets[dirndx]++; 7135 s->bytes[dirndx] += pd.tot_len; | |
7136 if (s->nat_rule.ptr != NULL) { | 7481 if (s->nat_rule.ptr != NULL) { |
7137 s->nat_rule.ptr->packets++; 7138 s->nat_rule.ptr->bytes += pd.tot_len; | 7482 s->nat_rule.ptr->packets[dirndx]++; 7483 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; |
7139 } 7140 if (s->src_node != NULL) { | 7484 } 7485 if (s->src_node != NULL) { |
7141 s->src_node->packets++; 7142 s->src_node->bytes += pd.tot_len; | 7486 s->src_node->packets[dirndx]++; 7487 s->src_node->bytes[dirndx] += pd.tot_len; |
7143 } 7144 if (s->nat_src_node != NULL) { | 7488 } 7489 if (s->nat_src_node != NULL) { |
7145 s->nat_src_node->packets++; 7146 s->nat_src_node->bytes += pd.tot_len; | 7490 s->nat_src_node->packets[dirndx]++; 7491 s->nat_src_node->bytes[dirndx] += pd.tot_len; |
7147 } | 7492 } |
7493 dirndx = (dir == s->direction) ? 0 : 1; 7494 s->packets[dirndx]++; 7495 s->bytes[dirndx] += pd.tot_len; |
|
7148 } 7149 tr = r; 7150 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7151 if (nr != NULL) { 7152 struct pf_addr *x; 7153 /* 7154 * XXX: we need to make sure that the addresses 7155 * passed to pfr_update_stats() are the same than --- 28 unchanged lines hidden (view full) --- 7184 7185 7186 if (action == PF_SYNPROXY_DROP) { 7187 m_freem(*m0); 7188 *m0 = NULL; 7189 action = PF_PASS; 7190 } else if (r->rt) 7191 /* pf_route6 can free the mbuf causing *m0 to become NULL */ | 7496 } 7497 tr = r; 7498 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7499 if (nr != NULL) { 7500 struct pf_addr *x; 7501 /* 7502 * XXX: we need to make sure that the addresses 7503 * passed to pfr_update_stats() are the same than --- 28 unchanged lines hidden (view full) --- 7532 7533 7534 if (action == PF_SYNPROXY_DROP) { 7535 m_freem(*m0); 7536 *m0 = NULL; 7537 action = PF_PASS; 7538 } else if (r->rt) 7539 /* pf_route6 can free the mbuf causing *m0 to become NULL */ |
7192 pf_route6(m0, r, dir, ifp, s); | 7540 pf_route6(m0, r, dir, ifp, s, &pd); |
7193 7194#ifdef __FreeBSD__ 7195 PF_UNLOCK(); 7196#endif 7197 return (action); 7198} 7199#endif /* INET6 */ 7200 --- 13 unchanged lines hidden --- | 7541 7542#ifdef __FreeBSD__ 7543 PF_UNLOCK(); 7544#endif 7545 return (action); 7546} 7547#endif /* INET6 */ 7548 --- 13 unchanged lines hidden --- |