pf.c revision 193511
1/* $OpenBSD: pf.c,v 1.527 2007/02/22 15:23:23 pyr Exp $ */ 2/* add: $OpenBSD: pf.c,v 1.559 2007/09/18 18:45:59 markus 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 11 * are met: 12 * 13 * - Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * - Redistributions in binary form must reproduce the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer in the documentation and/or other materials provided 18 * with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * 33 * Effort sponsored in part by the Defense Advanced Research Projects 34 * Agency (DARPA) and Air Force Research Laboratory, Air Force 35 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 36 * 37 */ 38 39#ifdef __FreeBSD__ 40#include "opt_inet.h" 41#include "opt_inet6.h" 42 43#include <sys/cdefs.h> 44__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf.c 193511 2009-06-05 14:55:22Z rwatson $"); 45#endif 46 47#ifdef __FreeBSD__ 48#include "opt_bpf.h" 49#include "opt_pf.h" 50 51#ifdef DEV_BPF 52#define NBPFILTER DEV_BPF 53#else 54#define NBPFILTER 0 55#endif 56 57#ifdef DEV_PFLOG 58#define NPFLOG DEV_PFLOG 59#else 60#define NPFLOG 0 61#endif 62 63#ifdef DEV_PFSYNC 64#define NPFSYNC DEV_PFSYNC 65#else 66#define NPFSYNC 0 67#endif 68 69#else 70#include "bpfilter.h" 71#include "pflog.h" 72#include "pfsync.h" 73#endif 74 75#include <sys/param.h> 76#include <sys/systm.h> 77#include <sys/mbuf.h> 78#include <sys/filio.h> 79#include <sys/socket.h> 80#include <sys/socketvar.h> 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#include <sys/vimage.h> 95#else 96#include <sys/rwlock.h> 97#endif 98 99#include <net/if.h> 100#include <net/if_types.h> 101#include <net/bpf.h> 102#include <net/route.h> 103#ifndef __FreeBSD__ 104#include <net/radix_mpath.h> 105#endif 106 107#include <netinet/in.h> 108#include <netinet/in_var.h> 109#include <netinet/in_systm.h> 110#include <netinet/ip.h> 111#include <netinet/ip_var.h> 112#include <netinet/tcp.h> 113#include <netinet/tcp_seq.h> 114#include <netinet/udp.h> 115#include <netinet/ip_icmp.h> 116#include <netinet/in_pcb.h> 117#include <netinet/tcp_timer.h> 118#include <netinet/tcp_var.h> 119#include <netinet/udp_var.h> 120#include <netinet/icmp_var.h> 121#include <netinet/if_ether.h> 122#ifdef __FreeBSD__ 123#include <netinet/vinet.h> 124#endif 125 126#ifndef __FreeBSD__ 127#include <dev/rndvar.h> 128#endif 129#include <net/pfvar.h> 130#include <net/if_pflog.h> 131 132#if NPFSYNC > 0 133#include <net/if_pfsync.h> 134#endif /* NPFSYNC > 0 */ 135 136#ifdef INET6 137#include <netinet/ip6.h> 138#include <netinet/in_pcb.h> 139#include <netinet/icmp6.h> 140#include <netinet6/nd6.h> 141#ifdef __FreeBSD__ 142#include <netinet6/ip6_var.h> 143#include <netinet6/in6_pcb.h> 144#include <netinet6/vinet6.h> 145#endif 146#endif /* INET6 */ 147 148#ifdef __FreeBSD__ 149#include <machine/in_cksum.h> 150#include <sys/limits.h> 151#include <sys/ucred.h> 152#include <security/mac/mac_framework.h> 153 154extern int ip_optcopy(struct ip *, struct ip *); 155extern int debug_pfugidhack; 156#endif 157 158#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x 159 160/* 161 * Global variables 162 */ 163 164struct pf_altqqueue pf_altqs[2]; 165struct pf_palist pf_pabuf; 166struct pf_altqqueue *pf_altqs_active; 167struct pf_altqqueue *pf_altqs_inactive; 168struct pf_status pf_status; 169 170u_int32_t ticket_altqs_active; 171u_int32_t ticket_altqs_inactive; 172int altqs_inactive_open; 173u_int32_t ticket_pabuf; 174 175struct pf_anchor_stackframe { 176 struct pf_ruleset *rs; 177 struct pf_rule *r; 178 struct pf_anchor_node *parent; 179 struct pf_anchor *child; 180} pf_anchor_stack[64]; 181 182#ifdef __FreeBSD__ 183uma_zone_t pf_src_tree_pl, pf_rule_pl; 184uma_zone_t pf_state_pl, pf_altq_pl, pf_pooladdr_pl; 185#else 186struct pool pf_src_tree_pl, pf_rule_pl; 187struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl; 188#endif 189 190void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); 191 192void pf_init_threshold(struct pf_threshold *, u_int32_t, 193 u_int32_t); 194void pf_add_threshold(struct pf_threshold *); 195int pf_check_threshold(struct pf_threshold *); 196 197void pf_change_ap(struct pf_addr *, u_int16_t *, 198 u_int16_t *, u_int16_t *, struct pf_addr *, 199 u_int16_t, u_int8_t, sa_family_t); 200int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *, 201 struct tcphdr *, struct pf_state_peer *); 202#ifdef INET6 203void pf_change_a6(struct pf_addr *, u_int16_t *, 204 struct pf_addr *, u_int8_t); 205#endif /* INET6 */ 206void pf_change_icmp(struct pf_addr *, u_int16_t *, 207 struct pf_addr *, struct pf_addr *, u_int16_t, 208 u_int16_t *, u_int16_t *, u_int16_t *, 209 u_int16_t *, u_int8_t, sa_family_t); 210#ifdef __FreeBSD__ 211void pf_send_tcp(struct mbuf *, 212 const struct pf_rule *, sa_family_t, 213#else 214void pf_send_tcp(const struct pf_rule *, sa_family_t, 215#endif 216 const struct pf_addr *, const struct pf_addr *, 217 u_int16_t, u_int16_t, u_int32_t, u_int32_t, 218 u_int8_t, u_int16_t, u_int16_t, u_int8_t, int, 219 u_int16_t, struct ether_header *, struct ifnet *); 220void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t, 221 sa_family_t, struct pf_rule *); 222struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *, 223 int, int, struct pfi_kif *, 224 struct pf_addr *, u_int16_t, struct pf_addr *, 225 u_int16_t, int); 226struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *, 227 int, int, struct pfi_kif *, struct pf_src_node **, 228 struct pf_addr *, u_int16_t, 229 struct pf_addr *, u_int16_t, 230 struct pf_addr *, u_int16_t *); 231int pf_test_tcp(struct pf_rule **, struct pf_state **, 232 int, struct pfi_kif *, struct mbuf *, int, 233 void *, struct pf_pdesc *, struct pf_rule **, 234#ifdef __FreeBSD__ 235 struct pf_ruleset **, struct ifqueue *, 236 struct inpcb *); 237#else 238 struct pf_ruleset **, struct ifqueue *); 239#endif 240int pf_test_udp(struct pf_rule **, struct pf_state **, 241 int, struct pfi_kif *, struct mbuf *, int, 242 void *, struct pf_pdesc *, struct pf_rule **, 243#ifdef __FreeBSD__ 244 struct pf_ruleset **, struct ifqueue *, 245 struct inpcb *); 246#else 247 struct pf_ruleset **, struct ifqueue *); 248#endif 249int pf_test_icmp(struct pf_rule **, struct pf_state **, 250 int, struct pfi_kif *, struct mbuf *, int, 251 void *, struct pf_pdesc *, struct pf_rule **, 252 struct pf_ruleset **, struct ifqueue *); 253int pf_test_other(struct pf_rule **, struct pf_state **, 254 int, struct pfi_kif *, struct mbuf *, int, void *, 255 struct pf_pdesc *, struct pf_rule **, 256 struct pf_ruleset **, struct ifqueue *); 257int pf_test_fragment(struct pf_rule **, int, 258 struct pfi_kif *, struct mbuf *, void *, 259 struct pf_pdesc *, struct pf_rule **, 260 struct pf_ruleset **); 261int pf_test_state_tcp(struct pf_state **, int, 262 struct pfi_kif *, struct mbuf *, int, 263 void *, struct pf_pdesc *, u_short *); 264int pf_test_state_udp(struct pf_state **, int, 265 struct pfi_kif *, struct mbuf *, int, 266 void *, struct pf_pdesc *); 267int pf_test_state_icmp(struct pf_state **, int, 268 struct pfi_kif *, struct mbuf *, int, 269 void *, struct pf_pdesc *, u_short *); 270int pf_test_state_other(struct pf_state **, int, 271 struct pfi_kif *, struct pf_pdesc *); 272int pf_match_tag(struct mbuf *, struct pf_rule *, 273 struct pf_mtag *, int *); 274int pf_step_out_of_anchor(int *, struct pf_ruleset **, 275 int, struct pf_rule **, struct pf_rule **, 276 int *); 277void pf_hash(struct pf_addr *, struct pf_addr *, 278 struct pf_poolhashkey *, sa_family_t); 279int pf_map_addr(u_int8_t, struct pf_rule *, 280 struct pf_addr *, struct pf_addr *, 281 struct pf_addr *, struct pf_src_node **); 282int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *, 283 struct pf_addr *, struct pf_addr *, u_int16_t, 284 struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t, 285 struct pf_src_node **); 286void pf_route(struct mbuf **, struct pf_rule *, int, 287 struct ifnet *, struct pf_state *, 288 struct pf_pdesc *); 289void pf_route6(struct mbuf **, struct pf_rule *, int, 290 struct ifnet *, struct pf_state *, 291 struct pf_pdesc *); 292#ifdef __FreeBSD__ 293/* XXX: import */ 294#else 295int pf_socket_lookup(int, struct pf_pdesc *); 296#endif 297u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t, 298 sa_family_t); 299u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t, 300 sa_family_t); 301u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, 302 u_int16_t); 303void pf_set_rt_ifp(struct pf_state *, 304 struct pf_addr *); 305int pf_check_proto_cksum(struct mbuf *, int, int, 306 u_int8_t, sa_family_t); 307int pf_addr_wrap_neq(struct pf_addr_wrap *, 308 struct pf_addr_wrap *); 309struct pf_state *pf_find_state_recurse(struct pfi_kif *, 310 struct pf_state_cmp *, u_int8_t); 311int pf_src_connlimit(struct pf_state **); 312int pf_check_congestion(struct ifqueue *); 313 314#ifdef __FreeBSD__ 315int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len); 316 317extern int pf_end_threads; 318 319struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX]; 320#else 321extern struct pool pfr_ktable_pl; 322extern struct pool pfr_kentry_pl; 323 324struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = { 325 { &pf_state_pl, PFSTATE_HIWAT }, 326 { &pf_src_tree_pl, PFSNODE_HIWAT }, 327 { &pf_frent_pl, PFFRAG_FRENT_HIWAT }, 328 { &pfr_ktable_pl, PFR_KTABLE_HIWAT }, 329 { &pfr_kentry_pl, PFR_KENTRY_HIWAT } 330}; 331#endif 332 333#define STATE_LOOKUP() \ 334 do { \ 335 if (direction == PF_IN) \ 336 *state = pf_find_state_recurse( \ 337 kif, &key, PF_EXT_GWY); \ 338 else \ 339 *state = pf_find_state_recurse( \ 340 kif, &key, PF_LAN_EXT); \ 341 if (*state == NULL || (*state)->timeout == PFTM_PURGE) \ 342 return (PF_DROP); \ 343 if (direction == PF_OUT && \ 344 (((*state)->rule.ptr->rt == PF_ROUTETO && \ 345 (*state)->rule.ptr->direction == PF_OUT) || \ 346 ((*state)->rule.ptr->rt == PF_REPLYTO && \ 347 (*state)->rule.ptr->direction == PF_IN)) && \ 348 (*state)->rt_kif != NULL && \ 349 (*state)->rt_kif != kif) \ 350 return (PF_PASS); \ 351 } while (0) 352 353#define STATE_TRANSLATE(s) \ 354 (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \ 355 ((s)->af == AF_INET6 && \ 356 ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \ 357 (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \ 358 (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \ 359 (s)->lan.port != (s)->gwy.port 360 361#define BOUND_IFACE(r, k) \ 362 ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all 363 364#define STATE_INC_COUNTERS(s) \ 365 do { \ 366 s->rule.ptr->states++; \ 367 if (s->anchor.ptr != NULL) \ 368 s->anchor.ptr->states++; \ 369 if (s->nat_rule.ptr != NULL) \ 370 s->nat_rule.ptr->states++; \ 371 } while (0) 372 373#define STATE_DEC_COUNTERS(s) \ 374 do { \ 375 if (s->nat_rule.ptr != NULL) \ 376 s->nat_rule.ptr->states--; \ 377 if (s->anchor.ptr != NULL) \ 378 s->anchor.ptr->states--; \ 379 s->rule.ptr->states--; \ 380 } while (0) 381 382struct pf_src_tree tree_src_tracking; 383 384struct pf_state_tree_id tree_id; 385struct pf_state_queue state_list; 386 387#ifdef __FreeBSD__ 388static int pf_src_compare(struct pf_src_node *, struct pf_src_node *); 389static int pf_state_compare_lan_ext(struct pf_state *, struct pf_state *); 390static int pf_state_compare_ext_gwy(struct pf_state *, struct pf_state *); 391static int pf_state_compare_id(struct pf_state *, struct pf_state *); 392#endif 393 394RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare); 395RB_GENERATE(pf_state_tree_lan_ext, pf_state, 396 u.s.entry_lan_ext, pf_state_compare_lan_ext); 397RB_GENERATE(pf_state_tree_ext_gwy, pf_state, 398 u.s.entry_ext_gwy, pf_state_compare_ext_gwy); 399RB_GENERATE(pf_state_tree_id, pf_state, 400 u.s.entry_id, pf_state_compare_id); 401 402#ifdef __FreeBSD__ 403static int 404#else 405static __inline int 406#endif 407pf_src_compare(struct pf_src_node *a, struct pf_src_node *b) 408{ 409 int diff; 410 411 if (a->rule.ptr > b->rule.ptr) 412 return (1); 413 if (a->rule.ptr < b->rule.ptr) 414 return (-1); 415 if ((diff = a->af - b->af) != 0) 416 return (diff); 417 switch (a->af) { 418#ifdef INET 419 case AF_INET: 420 if (a->addr.addr32[0] > b->addr.addr32[0]) 421 return (1); 422 if (a->addr.addr32[0] < b->addr.addr32[0]) 423 return (-1); 424 break; 425#endif /* INET */ 426#ifdef INET6 427 case AF_INET6: 428 if (a->addr.addr32[3] > b->addr.addr32[3]) 429 return (1); 430 if (a->addr.addr32[3] < b->addr.addr32[3]) 431 return (-1); 432 if (a->addr.addr32[2] > b->addr.addr32[2]) 433 return (1); 434 if (a->addr.addr32[2] < b->addr.addr32[2]) 435 return (-1); 436 if (a->addr.addr32[1] > b->addr.addr32[1]) 437 return (1); 438 if (a->addr.addr32[1] < b->addr.addr32[1]) 439 return (-1); 440 if (a->addr.addr32[0] > b->addr.addr32[0]) 441 return (1); 442 if (a->addr.addr32[0] < b->addr.addr32[0]) 443 return (-1); 444 break; 445#endif /* INET6 */ 446 } 447 return (0); 448} 449 450#ifdef __FreeBSD__ 451static int 452#else 453static __inline int 454#endif 455pf_state_compare_lan_ext(struct pf_state *a, struct pf_state *b) 456{ 457 int diff; 458 459 if ((diff = a->proto - b->proto) != 0) 460 return (diff); 461 if ((diff = a->af - b->af) != 0) 462 return (diff); 463 switch (a->af) { 464#ifdef INET 465 case AF_INET: 466 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0]) 467 return (1); 468 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0]) 469 return (-1); 470 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) 471 return (1); 472 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) 473 return (-1); 474 break; 475#endif /* INET */ 476#ifdef INET6 477 case AF_INET6: 478 if (a->lan.addr.addr32[3] > b->lan.addr.addr32[3]) 479 return (1); 480 if (a->lan.addr.addr32[3] < b->lan.addr.addr32[3]) 481 return (-1); 482 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3]) 483 return (1); 484 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3]) 485 return (-1); 486 if (a->lan.addr.addr32[2] > b->lan.addr.addr32[2]) 487 return (1); 488 if (a->lan.addr.addr32[2] < b->lan.addr.addr32[2]) 489 return (-1); 490 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2]) 491 return (1); 492 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2]) 493 return (-1); 494 if (a->lan.addr.addr32[1] > b->lan.addr.addr32[1]) 495 return (1); 496 if (a->lan.addr.addr32[1] < b->lan.addr.addr32[1]) 497 return (-1); 498 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1]) 499 return (1); 500 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1]) 501 return (-1); 502 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0]) 503 return (1); 504 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0]) 505 return (-1); 506 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) 507 return (1); 508 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) 509 return (-1); 510 break; 511#endif /* INET6 */ 512 } 513 514 if ((diff = a->lan.port - b->lan.port) != 0) 515 return (diff); 516 if ((diff = a->ext.port - b->ext.port) != 0) 517 return (diff); 518 519 return (0); 520} 521 522#ifdef __FreeBSD__ 523static int 524#else 525static __inline int 526#endif 527pf_state_compare_ext_gwy(struct pf_state *a, struct pf_state *b) 528{ 529 int diff; 530 531 if ((diff = a->proto - b->proto) != 0) 532 return (diff); 533 if ((diff = a->af - b->af) != 0) 534 return (diff); 535 switch (a->af) { 536#ifdef INET 537 case AF_INET: 538 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) 539 return (1); 540 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) 541 return (-1); 542 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0]) 543 return (1); 544 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0]) 545 return (-1); 546 break; 547#endif /* INET */ 548#ifdef INET6 549 case AF_INET6: 550 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3]) 551 return (1); 552 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3]) 553 return (-1); 554 if (a->gwy.addr.addr32[3] > b->gwy.addr.addr32[3]) 555 return (1); 556 if (a->gwy.addr.addr32[3] < b->gwy.addr.addr32[3]) 557 return (-1); 558 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2]) 559 return (1); 560 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2]) 561 return (-1); 562 if (a->gwy.addr.addr32[2] > b->gwy.addr.addr32[2]) 563 return (1); 564 if (a->gwy.addr.addr32[2] < b->gwy.addr.addr32[2]) 565 return (-1); 566 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1]) 567 return (1); 568 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1]) 569 return (-1); 570 if (a->gwy.addr.addr32[1] > b->gwy.addr.addr32[1]) 571 return (1); 572 if (a->gwy.addr.addr32[1] < b->gwy.addr.addr32[1]) 573 return (-1); 574 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) 575 return (1); 576 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) 577 return (-1); 578 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0]) 579 return (1); 580 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0]) 581 return (-1); 582 break; 583#endif /* INET6 */ 584 } 585 586 if ((diff = a->ext.port - b->ext.port) != 0) 587 return (diff); 588 if ((diff = a->gwy.port - b->gwy.port) != 0) 589 return (diff); 590 591 return (0); 592} 593 594#ifdef __FreeBSD__ 595static int 596#else 597static __inline int 598#endif 599pf_state_compare_id(struct pf_state *a, struct pf_state *b) 600{ 601 if (a->id > b->id) 602 return (1); 603 if (a->id < b->id) 604 return (-1); 605 if (a->creatorid > b->creatorid) 606 return (1); 607 if (a->creatorid < b->creatorid) 608 return (-1); 609 610 return (0); 611} 612 613#ifdef INET6 614void 615pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af) 616{ 617 switch (af) { 618#ifdef INET 619 case AF_INET: 620 dst->addr32[0] = src->addr32[0]; 621 break; 622#endif /* INET */ 623 case AF_INET6: 624 dst->addr32[0] = src->addr32[0]; 625 dst->addr32[1] = src->addr32[1]; 626 dst->addr32[2] = src->addr32[2]; 627 dst->addr32[3] = src->addr32[3]; 628 break; 629 } 630} 631#endif /* INET6 */ 632 633struct pf_state * 634pf_find_state_byid(struct pf_state_cmp *key) 635{ 636 pf_status.fcounters[FCNT_STATE_SEARCH]++; 637 return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key)); 638} 639 640struct pf_state * 641pf_find_state_recurse(struct pfi_kif *kif, struct pf_state_cmp *key, u_int8_t tree) 642{ 643 struct pf_state *s; 644 645 pf_status.fcounters[FCNT_STATE_SEARCH]++; 646 647 switch (tree) { 648 case PF_LAN_EXT: 649 if ((s = RB_FIND(pf_state_tree_lan_ext, &kif->pfik_lan_ext, 650 (struct pf_state *)key)) != NULL) 651 return (s); 652 if ((s = RB_FIND(pf_state_tree_lan_ext, &pfi_all->pfik_lan_ext, 653 (struct pf_state *)key)) != NULL) 654 return (s); 655 return (NULL); 656 case PF_EXT_GWY: 657 if ((s = RB_FIND(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, 658 (struct pf_state *)key)) != NULL) 659 return (s); 660 if ((s = RB_FIND(pf_state_tree_ext_gwy, &pfi_all->pfik_ext_gwy, 661 (struct pf_state *)key)) != NULL) 662 return (s); 663 return (NULL); 664 default: 665 panic("pf_find_state_recurse"); 666 } 667} 668 669struct pf_state * 670pf_find_state_all(struct pf_state_cmp *key, u_int8_t tree, int *more) 671{ 672 struct pf_state *s, *ss = NULL; 673 struct pfi_kif *kif; 674 675 pf_status.fcounters[FCNT_STATE_SEARCH]++; 676 677 switch (tree) { 678 case PF_LAN_EXT: 679 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) { 680 s = RB_FIND(pf_state_tree_lan_ext, 681 &kif->pfik_lan_ext, (struct pf_state *)key); 682 if (s == NULL) 683 continue; 684 if (more == NULL) 685 return (s); 686 ss = s; 687 (*more)++; 688 } 689 return (ss); 690 case PF_EXT_GWY: 691 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) { 692 s = RB_FIND(pf_state_tree_ext_gwy, 693 &kif->pfik_ext_gwy, (struct pf_state *)key); 694 if (s == NULL) 695 continue; 696 if (more == NULL) 697 return (s); 698 ss = s; 699 (*more)++; 700 } 701 return (ss); 702 default: 703 panic("pf_find_state_all"); 704 } 705} 706 707void 708pf_init_threshold(struct pf_threshold *threshold, 709 u_int32_t limit, u_int32_t seconds) 710{ 711 threshold->limit = limit * PF_THRESHOLD_MULT; 712 threshold->seconds = seconds; 713 threshold->count = 0; 714 threshold->last = time_second; 715} 716 717void 718pf_add_threshold(struct pf_threshold *threshold) 719{ 720 u_int32_t t = time_second, diff = t - threshold->last; 721 722 if (diff >= threshold->seconds) 723 threshold->count = 0; 724 else 725 threshold->count -= threshold->count * diff / 726 threshold->seconds; 727 threshold->count += PF_THRESHOLD_MULT; 728 threshold->last = t; 729} 730 731int 732pf_check_threshold(struct pf_threshold *threshold) 733{ 734 return (threshold->count > threshold->limit); 735} 736 737int 738pf_src_connlimit(struct pf_state **state) 739{ 740 struct pf_state *s; 741 int bad = 0; 742 743 (*state)->src_node->conn++; 744 (*state)->src.tcp_est = 1; 745 pf_add_threshold(&(*state)->src_node->conn_rate); 746 747 if ((*state)->rule.ptr->max_src_conn && 748 (*state)->rule.ptr->max_src_conn < 749 (*state)->src_node->conn) { 750 pf_status.lcounters[LCNT_SRCCONN]++; 751 bad++; 752 } 753 754 if ((*state)->rule.ptr->max_src_conn_rate.limit && 755 pf_check_threshold(&(*state)->src_node->conn_rate)) { 756 pf_status.lcounters[LCNT_SRCCONNRATE]++; 757 bad++; 758 } 759 760 if (!bad) 761 return (0); 762 763 if ((*state)->rule.ptr->overload_tbl) { 764 struct pfr_addr p; 765 u_int32_t killed = 0; 766 767 pf_status.lcounters[LCNT_OVERLOAD_TABLE]++; 768 if (pf_status.debug >= PF_DEBUG_MISC) { 769 printf("pf_src_connlimit: blocking address "); 770 pf_print_host(&(*state)->src_node->addr, 0, 771 (*state)->af); 772 } 773 774 bzero(&p, sizeof(p)); 775 p.pfra_af = (*state)->af; 776 switch ((*state)->af) { 777#ifdef INET 778 case AF_INET: 779 p.pfra_net = 32; 780 p.pfra_ip4addr = (*state)->src_node->addr.v4; 781 break; 782#endif /* INET */ 783#ifdef INET6 784 case AF_INET6: 785 p.pfra_net = 128; 786 p.pfra_ip6addr = (*state)->src_node->addr.v6; 787 break; 788#endif /* INET6 */ 789 } 790 791 pfr_insert_kentry((*state)->rule.ptr->overload_tbl, 792 &p, time_second); 793 794 /* kill existing states if that's required. */ 795 if ((*state)->rule.ptr->flush) { 796 pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++; 797 798 RB_FOREACH(s, pf_state_tree_id, &tree_id) { 799 /* 800 * Kill states from this source. (Only those 801 * from the same rule if PF_FLUSH_GLOBAL is not 802 * set) 803 */ 804 if (s->af == (*state)->af && 805 (((*state)->direction == PF_OUT && 806 PF_AEQ(&(*state)->src_node->addr, 807 &s->lan.addr, s->af)) || 808 ((*state)->direction == PF_IN && 809 PF_AEQ(&(*state)->src_node->addr, 810 &s->ext.addr, s->af))) && 811 ((*state)->rule.ptr->flush & 812 PF_FLUSH_GLOBAL || 813 (*state)->rule.ptr == s->rule.ptr)) { 814 s->timeout = PFTM_PURGE; 815 s->src.state = s->dst.state = 816 TCPS_CLOSED; 817 killed++; 818 } 819 } 820 if (pf_status.debug >= PF_DEBUG_MISC) 821 printf(", %u states killed", killed); 822 } 823 if (pf_status.debug >= PF_DEBUG_MISC) 824 printf("\n"); 825 } 826 827 /* kill this state */ 828 (*state)->timeout = PFTM_PURGE; 829 (*state)->src.state = (*state)->dst.state = TCPS_CLOSED; 830 return (1); 831} 832 833int 834pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule, 835 struct pf_addr *src, sa_family_t af) 836{ 837 struct pf_src_node k; 838 839 if (*sn == NULL) { 840 k.af = af; 841 PF_ACPY(&k.addr, src, af); 842 if (rule->rule_flag & PFRULE_RULESRCTRACK || 843 rule->rpool.opts & PF_POOL_STICKYADDR) 844 k.rule.ptr = rule; 845 else 846 k.rule.ptr = NULL; 847 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++; 848 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k); 849 } 850 if (*sn == NULL) { 851 if (!rule->max_src_nodes || 852 rule->src_nodes < rule->max_src_nodes) 853 (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT); 854 else 855 pf_status.lcounters[LCNT_SRCNODES]++; 856 if ((*sn) == NULL) 857 return (-1); 858 bzero(*sn, sizeof(struct pf_src_node)); 859 860 pf_init_threshold(&(*sn)->conn_rate, 861 rule->max_src_conn_rate.limit, 862 rule->max_src_conn_rate.seconds); 863 864 (*sn)->af = af; 865 if (rule->rule_flag & PFRULE_RULESRCTRACK || 866 rule->rpool.opts & PF_POOL_STICKYADDR) 867 (*sn)->rule.ptr = rule; 868 else 869 (*sn)->rule.ptr = NULL; 870 PF_ACPY(&(*sn)->addr, src, af); 871 if (RB_INSERT(pf_src_tree, 872 &tree_src_tracking, *sn) != NULL) { 873 if (pf_status.debug >= PF_DEBUG_MISC) { 874 printf("pf: src_tree insert failed: "); 875 pf_print_host(&(*sn)->addr, 0, af); 876 printf("\n"); 877 } 878 pool_put(&pf_src_tree_pl, *sn); 879 return (-1); 880 } 881 (*sn)->creation = time_second; 882 (*sn)->ruletype = rule->action; 883 if ((*sn)->rule.ptr != NULL) 884 (*sn)->rule.ptr->src_nodes++; 885 pf_status.scounters[SCNT_SRC_NODE_INSERT]++; 886 pf_status.src_nodes++; 887 } else { 888 if (rule->max_src_states && 889 (*sn)->states >= rule->max_src_states) { 890 pf_status.lcounters[LCNT_SRCSTATES]++; 891 return (-1); 892 } 893 } 894 return (0); 895} 896 897int 898pf_insert_state(struct pfi_kif *kif, struct pf_state *state) 899{ 900 /* Thou MUST NOT insert multiple duplicate keys */ 901 state->u.s.kif = kif; 902 if (RB_INSERT(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state)) { 903 if (pf_status.debug >= PF_DEBUG_MISC) { 904 printf("pf: state insert failed: tree_lan_ext"); 905 printf(" lan: "); 906 pf_print_host(&state->lan.addr, state->lan.port, 907 state->af); 908 printf(" gwy: "); 909 pf_print_host(&state->gwy.addr, state->gwy.port, 910 state->af); 911 printf(" ext: "); 912 pf_print_host(&state->ext.addr, state->ext.port, 913 state->af); 914 if (state->sync_flags & PFSTATE_FROMSYNC) 915 printf(" (from sync)"); 916 printf("\n"); 917 } 918 return (-1); 919 } 920 921 if (RB_INSERT(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state)) { 922 if (pf_status.debug >= PF_DEBUG_MISC) { 923 printf("pf: state insert failed: tree_ext_gwy"); 924 printf(" lan: "); 925 pf_print_host(&state->lan.addr, state->lan.port, 926 state->af); 927 printf(" gwy: "); 928 pf_print_host(&state->gwy.addr, state->gwy.port, 929 state->af); 930 printf(" ext: "); 931 pf_print_host(&state->ext.addr, state->ext.port, 932 state->af); 933 if (state->sync_flags & PFSTATE_FROMSYNC) 934 printf(" (from sync)"); 935 printf("\n"); 936 } 937 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state); 938 return (-1); 939 } 940 941 if (state->id == 0 && state->creatorid == 0) { 942 state->id = htobe64(pf_status.stateid++); 943 state->creatorid = pf_status.hostid; 944 } 945 if (RB_INSERT(pf_state_tree_id, &tree_id, state) != NULL) { 946 if (pf_status.debug >= PF_DEBUG_MISC) { 947#ifdef __FreeBSD__ 948 printf("pf: state insert failed: " 949 "id: %016llx creatorid: %08x", 950 (long long)be64toh(state->id), 951 ntohl(state->creatorid)); 952#else 953 printf("pf: state insert failed: " 954 "id: %016llx creatorid: %08x", 955 betoh64(state->id), ntohl(state->creatorid)); 956#endif 957 if (state->sync_flags & PFSTATE_FROMSYNC) 958 printf(" (from sync)"); 959 printf("\n"); 960 } 961 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state); 962 RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state); 963 return (-1); 964 } 965 TAILQ_INSERT_TAIL(&state_list, state, u.s.entry_list); 966 pf_status.fcounters[FCNT_STATE_INSERT]++; 967 pf_status.states++; 968 pfi_kif_ref(kif, PFI_KIF_REF_STATE); 969#if NPFSYNC 970 pfsync_insert_state(state); 971#endif 972 return (0); 973} 974 975void 976pf_purge_thread(void *v) 977{ 978 int nloops = 0, s; 979 980 for (;;) { 981 tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz); 982 983#ifdef __FreeBSD__ 984 sx_slock(&pf_consistency_lock); 985 PF_LOCK(); 986 987 if (pf_end_threads) { 988 pf_purge_expired_states(pf_status.states); 989 pf_purge_expired_fragments(); 990 pf_purge_expired_src_nodes(0); 991 pf_end_threads++; 992 993 sx_sunlock(&pf_consistency_lock); 994 PF_UNLOCK(); 995 wakeup(pf_purge_thread); 996 kproc_exit(0); 997 } 998#endif 999 s = splsoftnet(); 1000 1001 /* process a fraction of the state table every second */ 1002 pf_purge_expired_states(1 + (pf_status.states 1003 / pf_default_rule.timeout[PFTM_INTERVAL])); 1004 1005 /* purge other expired types every PFTM_INTERVAL seconds */ 1006 if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) { 1007 pf_purge_expired_fragments(); 1008 pf_purge_expired_src_nodes(0); 1009 nloops = 0; 1010 } 1011 1012 splx(s); 1013#ifdef __FreeBSD__ 1014 PF_UNLOCK(); 1015 sx_sunlock(&pf_consistency_lock); 1016#endif 1017 } 1018} 1019 1020u_int32_t 1021pf_state_expires(const struct pf_state *state) 1022{ 1023 u_int32_t timeout; 1024 u_int32_t start; 1025 u_int32_t end; 1026 u_int32_t states; 1027 1028 /* handle all PFTM_* > PFTM_MAX here */ 1029 if (state->timeout == PFTM_PURGE) 1030 return (time_second); 1031 if (state->timeout == PFTM_UNTIL_PACKET) 1032 return (0); 1033#ifdef __FreeBSD__ 1034 KASSERT(state->timeout != PFTM_UNLINKED, 1035 ("pf_state_expires: timeout == PFTM_UNLINKED")); 1036 KASSERT((state->timeout < PFTM_MAX), 1037 ("pf_state_expires: timeout > PFTM_MAX")); 1038#else 1039 KASSERT(state->timeout != PFTM_UNLINKED); 1040 KASSERT(state->timeout < PFTM_MAX); 1041#endif 1042 timeout = state->rule.ptr->timeout[state->timeout]; 1043 if (!timeout) 1044 timeout = pf_default_rule.timeout[state->timeout]; 1045 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START]; 1046 if (start) { 1047 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END]; 1048 states = state->rule.ptr->states; 1049 } else { 1050 start = pf_default_rule.timeout[PFTM_ADAPTIVE_START]; 1051 end = pf_default_rule.timeout[PFTM_ADAPTIVE_END]; 1052 states = pf_status.states; 1053 } 1054 if (end && states > start && start < end) { 1055 if (states < end) 1056 return (state->expire + timeout * (end - states) / 1057 (end - start)); 1058 else 1059 return (time_second); 1060 } 1061 return (state->expire + timeout); 1062} 1063 1064void 1065pf_purge_expired_src_nodes(int waslocked) 1066{ 1067 struct pf_src_node *cur, *next; 1068 int locked = waslocked; 1069 1070 for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) { 1071 next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur); 1072 1073 if (cur->states <= 0 && cur->expire <= time_second) { 1074 if (! locked) { 1075#ifdef __FreeBSD__ 1076 if (!sx_try_upgrade(&pf_consistency_lock)) { 1077 PF_UNLOCK(); 1078 sx_sunlock(&pf_consistency_lock); 1079 sx_xlock(&pf_consistency_lock); 1080 PF_LOCK(); 1081 } 1082#else 1083 rw_enter_write(&pf_consistency_lock); 1084#endif 1085 next = RB_NEXT(pf_src_tree, 1086 &tree_src_tracking, cur); 1087 locked = 1; 1088 } 1089 if (cur->rule.ptr != NULL) { 1090 cur->rule.ptr->src_nodes--; 1091 if (cur->rule.ptr->states <= 0 && 1092 cur->rule.ptr->max_src_nodes <= 0) 1093 pf_rm_rule(NULL, cur->rule.ptr); 1094 } 1095 RB_REMOVE(pf_src_tree, &tree_src_tracking, cur); 1096 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 1097 pf_status.src_nodes--; 1098 pool_put(&pf_src_tree_pl, cur); 1099 } 1100 } 1101 1102 if (locked && !waslocked) 1103#ifdef __FreeBSD__ 1104 sx_downgrade(&pf_consistency_lock); 1105#else 1106 rw_exit_write(&pf_consistency_lock); 1107#endif 1108} 1109 1110void 1111pf_src_tree_remove_state(struct pf_state *s) 1112{ 1113 u_int32_t timeout; 1114 1115 if (s->src_node != NULL) { 1116 if (s->proto == IPPROTO_TCP) { 1117 if (s->src.tcp_est) 1118 --s->src_node->conn; 1119 } 1120 if (--s->src_node->states <= 0) { 1121 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE]; 1122 if (!timeout) 1123 timeout = 1124 pf_default_rule.timeout[PFTM_SRC_NODE]; 1125 s->src_node->expire = time_second + timeout; 1126 } 1127 } 1128 if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) { 1129 if (--s->nat_src_node->states <= 0) { 1130 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE]; 1131 if (!timeout) 1132 timeout = 1133 pf_default_rule.timeout[PFTM_SRC_NODE]; 1134 s->nat_src_node->expire = time_second + timeout; 1135 } 1136 } 1137 s->src_node = s->nat_src_node = NULL; 1138} 1139 1140/* callers should be at splsoftnet */ 1141void 1142pf_unlink_state(struct pf_state *cur) 1143{ 1144#ifdef __FreeBSD__ 1145 if (cur->local_flags & PFSTATE_EXPIRING) 1146 return; 1147 cur->local_flags |= PFSTATE_EXPIRING; 1148#endif 1149 if (cur->src.state == PF_TCPS_PROXY_DST) { 1150#ifdef __FreeBSD__ 1151 pf_send_tcp(NULL, cur->rule.ptr, cur->af, 1152#else 1153 pf_send_tcp(cur->rule.ptr, cur->af, 1154#endif 1155 &cur->ext.addr, &cur->lan.addr, 1156 cur->ext.port, cur->lan.port, 1157 cur->src.seqhi, cur->src.seqlo + 1, 1158 TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL); 1159 } 1160 RB_REMOVE(pf_state_tree_ext_gwy, 1161 &cur->u.s.kif->pfik_ext_gwy, cur); 1162 RB_REMOVE(pf_state_tree_lan_ext, 1163 &cur->u.s.kif->pfik_lan_ext, cur); 1164 RB_REMOVE(pf_state_tree_id, &tree_id, cur); 1165#if NPFSYNC 1166 if (cur->creatorid == pf_status.hostid) 1167 pfsync_delete_state(cur); 1168#endif 1169 cur->timeout = PFTM_UNLINKED; 1170 pf_src_tree_remove_state(cur); 1171} 1172 1173/* callers should be at splsoftnet and hold the 1174 * write_lock on pf_consistency_lock */ 1175void 1176pf_free_state(struct pf_state *cur) 1177{ 1178#if NPFSYNC 1179 if (pfsyncif != NULL && 1180 (pfsyncif->sc_bulk_send_next == cur || 1181 pfsyncif->sc_bulk_terminator == cur)) 1182 return; 1183#endif 1184#ifdef __FreeBSD__ 1185 KASSERT(cur->timeout == PFTM_UNLINKED, 1186 ("pf_free_state: cur->timeout != PFTM_UNLINKED")); 1187#else 1188 KASSERT(cur->timeout == PFTM_UNLINKED); 1189#endif 1190 if (--cur->rule.ptr->states <= 0 && 1191 cur->rule.ptr->src_nodes <= 0) 1192 pf_rm_rule(NULL, cur->rule.ptr); 1193 if (cur->nat_rule.ptr != NULL) 1194 if (--cur->nat_rule.ptr->states <= 0 && 1195 cur->nat_rule.ptr->src_nodes <= 0) 1196 pf_rm_rule(NULL, cur->nat_rule.ptr); 1197 if (cur->anchor.ptr != NULL) 1198 if (--cur->anchor.ptr->states <= 0) 1199 pf_rm_rule(NULL, cur->anchor.ptr); 1200 pf_normalize_tcp_cleanup(cur); 1201 pfi_kif_unref(cur->u.s.kif, PFI_KIF_REF_STATE); 1202 TAILQ_REMOVE(&state_list, cur, u.s.entry_list); 1203 if (cur->tag) 1204 pf_tag_unref(cur->tag); 1205 pool_put(&pf_state_pl, cur); 1206 pf_status.fcounters[FCNT_STATE_REMOVALS]++; 1207 pf_status.states--; 1208} 1209 1210void 1211pf_purge_expired_states(u_int32_t maxcheck) 1212{ 1213 static struct pf_state *cur = NULL; 1214 struct pf_state *next; 1215 int locked = 0; 1216 1217 while (maxcheck--) { 1218 /* wrap to start of list when we hit the end */ 1219 if (cur == NULL) { 1220 cur = TAILQ_FIRST(&state_list); 1221 if (cur == NULL) 1222 break; /* list empty */ 1223 } 1224 1225 /* get next state, as cur may get deleted */ 1226 next = TAILQ_NEXT(cur, u.s.entry_list); 1227 1228 if (cur->timeout == PFTM_UNLINKED) { 1229 /* free unlinked state */ 1230 if (! locked) { 1231#ifdef __FreeBSD__ 1232 if (!sx_try_upgrade(&pf_consistency_lock)) { 1233 PF_UNLOCK(); 1234 sx_sunlock(&pf_consistency_lock); 1235 sx_xlock(&pf_consistency_lock); 1236 PF_LOCK(); 1237 } 1238#else 1239 rw_enter_write(&pf_consistency_lock); 1240#endif 1241 locked = 1; 1242 } 1243 pf_free_state(cur); 1244 } else if (pf_state_expires(cur) <= time_second) { 1245 /* unlink and free expired state */ 1246 pf_unlink_state(cur); 1247 if (! locked) { 1248#ifdef __FreeBSD__ 1249 if (!sx_try_upgrade(&pf_consistency_lock)) { 1250 PF_UNLOCK(); 1251 sx_sunlock(&pf_consistency_lock); 1252 sx_xlock(&pf_consistency_lock); 1253 PF_LOCK(); 1254 } 1255#else 1256 rw_enter_write(&pf_consistency_lock); 1257#endif 1258 locked = 1; 1259 } 1260 pf_free_state(cur); 1261 } 1262 cur = next; 1263 } 1264 1265 if (locked) 1266#ifdef __FreeBSD__ 1267 sx_downgrade(&pf_consistency_lock); 1268#else 1269 rw_exit_write(&pf_consistency_lock); 1270#endif 1271} 1272 1273int 1274pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw) 1275{ 1276 if (aw->type != PF_ADDR_TABLE) 1277 return (0); 1278 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL) 1279 return (1); 1280 return (0); 1281} 1282 1283void 1284pf_tbladdr_remove(struct pf_addr_wrap *aw) 1285{ 1286 if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL) 1287 return; 1288 pfr_detach_table(aw->p.tbl); 1289 aw->p.tbl = NULL; 1290} 1291 1292void 1293pf_tbladdr_copyout(struct pf_addr_wrap *aw) 1294{ 1295 struct pfr_ktable *kt = aw->p.tbl; 1296 1297 if (aw->type != PF_ADDR_TABLE || kt == NULL) 1298 return; 1299 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL) 1300 kt = kt->pfrkt_root; 1301 aw->p.tbl = NULL; 1302 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ? 1303 kt->pfrkt_cnt : -1; 1304} 1305 1306void 1307pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af) 1308{ 1309 switch (af) { 1310#ifdef INET 1311 case AF_INET: { 1312 u_int32_t a = ntohl(addr->addr32[0]); 1313 printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255, 1314 (a>>8)&255, a&255); 1315 if (p) { 1316 p = ntohs(p); 1317 printf(":%u", p); 1318 } 1319 break; 1320 } 1321#endif /* INET */ 1322#ifdef INET6 1323 case AF_INET6: { 1324 u_int16_t b; 1325 u_int8_t i, curstart = 255, curend = 0, 1326 maxstart = 0, maxend = 0; 1327 for (i = 0; i < 8; i++) { 1328 if (!addr->addr16[i]) { 1329 if (curstart == 255) 1330 curstart = i; 1331 else 1332 curend = i; 1333 } else { 1334 if (curstart) { 1335 if ((curend - curstart) > 1336 (maxend - maxstart)) { 1337 maxstart = curstart; 1338 maxend = curend; 1339 curstart = 255; 1340 } 1341 } 1342 } 1343 } 1344 for (i = 0; i < 8; i++) { 1345 if (i >= maxstart && i <= maxend) { 1346 if (maxend != 7) { 1347 if (i == maxstart) 1348 printf(":"); 1349 } else { 1350 if (i == maxend) 1351 printf(":"); 1352 } 1353 } else { 1354 b = ntohs(addr->addr16[i]); 1355 printf("%x", b); 1356 if (i < 7) 1357 printf(":"); 1358 } 1359 } 1360 if (p) { 1361 p = ntohs(p); 1362 printf("[%u]", p); 1363 } 1364 break; 1365 } 1366#endif /* INET6 */ 1367 } 1368} 1369 1370void 1371pf_print_state(struct pf_state *s) 1372{ 1373 switch (s->proto) { 1374 case IPPROTO_TCP: 1375 printf("TCP "); 1376 break; 1377 case IPPROTO_UDP: 1378 printf("UDP "); 1379 break; 1380 case IPPROTO_ICMP: 1381 printf("ICMP "); 1382 break; 1383 case IPPROTO_ICMPV6: 1384 printf("ICMPV6 "); 1385 break; 1386 default: 1387 printf("%u ", s->proto); 1388 break; 1389 } 1390 pf_print_host(&s->lan.addr, s->lan.port, s->af); 1391 printf(" "); 1392 pf_print_host(&s->gwy.addr, s->gwy.port, s->af); 1393 printf(" "); 1394 pf_print_host(&s->ext.addr, s->ext.port, s->af); 1395 printf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo, 1396 s->src.seqhi, s->src.max_win, s->src.seqdiff); 1397 if (s->src.wscale && s->dst.wscale) 1398 printf(" wscale=%u", s->src.wscale & PF_WSCALE_MASK); 1399 printf("]"); 1400 printf(" [lo=%u high=%u win=%u modulator=%u", s->dst.seqlo, 1401 s->dst.seqhi, s->dst.max_win, s->dst.seqdiff); 1402 if (s->src.wscale && s->dst.wscale) 1403 printf(" wscale=%u", s->dst.wscale & PF_WSCALE_MASK); 1404 printf("]"); 1405 printf(" %u:%u", s->src.state, s->dst.state); 1406} 1407 1408void 1409pf_print_flags(u_int8_t f) 1410{ 1411 if (f) 1412 printf(" "); 1413 if (f & TH_FIN) 1414 printf("F"); 1415 if (f & TH_SYN) 1416 printf("S"); 1417 if (f & TH_RST) 1418 printf("R"); 1419 if (f & TH_PUSH) 1420 printf("P"); 1421 if (f & TH_ACK) 1422 printf("A"); 1423 if (f & TH_URG) 1424 printf("U"); 1425 if (f & TH_ECE) 1426 printf("E"); 1427 if (f & TH_CWR) 1428 printf("W"); 1429} 1430 1431#define PF_SET_SKIP_STEPS(i) \ 1432 do { \ 1433 while (head[i] != cur) { \ 1434 head[i]->skip[i].ptr = cur; \ 1435 head[i] = TAILQ_NEXT(head[i], entries); \ 1436 } \ 1437 } while (0) 1438 1439void 1440pf_calc_skip_steps(struct pf_rulequeue *rules) 1441{ 1442 struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT]; 1443 int i; 1444 1445 cur = TAILQ_FIRST(rules); 1446 prev = cur; 1447 for (i = 0; i < PF_SKIP_COUNT; ++i) 1448 head[i] = cur; 1449 while (cur != NULL) { 1450 1451 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot) 1452 PF_SET_SKIP_STEPS(PF_SKIP_IFP); 1453 if (cur->direction != prev->direction) 1454 PF_SET_SKIP_STEPS(PF_SKIP_DIR); 1455 if (cur->af != prev->af) 1456 PF_SET_SKIP_STEPS(PF_SKIP_AF); 1457 if (cur->proto != prev->proto) 1458 PF_SET_SKIP_STEPS(PF_SKIP_PROTO); 1459 if (cur->src.neg != prev->src.neg || 1460 pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr)) 1461 PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR); 1462 if (cur->src.port[0] != prev->src.port[0] || 1463 cur->src.port[1] != prev->src.port[1] || 1464 cur->src.port_op != prev->src.port_op) 1465 PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT); 1466 if (cur->dst.neg != prev->dst.neg || 1467 pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr)) 1468 PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR); 1469 if (cur->dst.port[0] != prev->dst.port[0] || 1470 cur->dst.port[1] != prev->dst.port[1] || 1471 cur->dst.port_op != prev->dst.port_op) 1472 PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT); 1473 1474 prev = cur; 1475 cur = TAILQ_NEXT(cur, entries); 1476 } 1477 for (i = 0; i < PF_SKIP_COUNT; ++i) 1478 PF_SET_SKIP_STEPS(i); 1479} 1480 1481int 1482pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2) 1483{ 1484 if (aw1->type != aw2->type) 1485 return (1); 1486 switch (aw1->type) { 1487 case PF_ADDR_ADDRMASK: 1488 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0)) 1489 return (1); 1490 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0)) 1491 return (1); 1492 return (0); 1493 case PF_ADDR_DYNIFTL: 1494 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt); 1495 case PF_ADDR_NOROUTE: 1496 case PF_ADDR_URPFFAILED: 1497 return (0); 1498 case PF_ADDR_TABLE: 1499 return (aw1->p.tbl != aw2->p.tbl); 1500 case PF_ADDR_RTLABEL: 1501 return (aw1->v.rtlabel != aw2->v.rtlabel); 1502 default: 1503 printf("invalid address type: %d\n", aw1->type); 1504 return (1); 1505 } 1506} 1507 1508u_int16_t 1509pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp) 1510{ 1511 u_int32_t l; 1512 1513 if (udp && !cksum) 1514 return (0x0000); 1515 l = cksum + old - new; 1516 l = (l >> 16) + (l & 65535); 1517 l = l & 65535; 1518 if (udp && !l) 1519 return (0xFFFF); 1520 return (l); 1521} 1522 1523void 1524pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc, 1525 struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af) 1526{ 1527 struct pf_addr ao; 1528 u_int16_t po = *p; 1529 1530 PF_ACPY(&ao, a, af); 1531 PF_ACPY(a, an, af); 1532 1533 *p = pn; 1534 1535 switch (af) { 1536#ifdef INET 1537 case AF_INET: 1538 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic, 1539 ao.addr16[0], an->addr16[0], 0), 1540 ao.addr16[1], an->addr16[1], 0); 1541 *p = pn; 1542 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc, 1543 ao.addr16[0], an->addr16[0], u), 1544 ao.addr16[1], an->addr16[1], u), 1545 po, pn, u); 1546 break; 1547#endif /* INET */ 1548#ifdef INET6 1549 case AF_INET6: 1550 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1551 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1552 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc, 1553 ao.addr16[0], an->addr16[0], u), 1554 ao.addr16[1], an->addr16[1], u), 1555 ao.addr16[2], an->addr16[2], u), 1556 ao.addr16[3], an->addr16[3], u), 1557 ao.addr16[4], an->addr16[4], u), 1558 ao.addr16[5], an->addr16[5], u), 1559 ao.addr16[6], an->addr16[6], u), 1560 ao.addr16[7], an->addr16[7], u), 1561 po, pn, u); 1562 break; 1563#endif /* INET6 */ 1564 } 1565} 1566 1567 1568/* Changes a u_int32_t. Uses a void * so there are no align restrictions */ 1569void 1570pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u) 1571{ 1572 u_int32_t ao; 1573 1574 memcpy(&ao, a, sizeof(ao)); 1575 memcpy(a, &an, sizeof(u_int32_t)); 1576 *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u), 1577 ao % 65536, an % 65536, u); 1578} 1579 1580#ifdef INET6 1581void 1582pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u) 1583{ 1584 struct pf_addr ao; 1585 1586 PF_ACPY(&ao, a, AF_INET6); 1587 PF_ACPY(a, an, AF_INET6); 1588 1589 *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1590 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1591 pf_cksum_fixup(pf_cksum_fixup(*c, 1592 ao.addr16[0], an->addr16[0], u), 1593 ao.addr16[1], an->addr16[1], u), 1594 ao.addr16[2], an->addr16[2], u), 1595 ao.addr16[3], an->addr16[3], u), 1596 ao.addr16[4], an->addr16[4], u), 1597 ao.addr16[5], an->addr16[5], u), 1598 ao.addr16[6], an->addr16[6], u), 1599 ao.addr16[7], an->addr16[7], u); 1600} 1601#endif /* INET6 */ 1602 1603void 1604pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa, 1605 struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c, 1606 u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af) 1607{ 1608 struct pf_addr oia, ooa; 1609 1610 PF_ACPY(&oia, ia, af); 1611 PF_ACPY(&ooa, oa, af); 1612 1613 /* Change inner protocol port, fix inner protocol checksum. */ 1614 if (ip != NULL) { 1615 u_int16_t oip = *ip; 1616 u_int32_t opc = 0; /* make the compiler happy */ 1617 1618 if (pc != NULL) 1619 opc = *pc; 1620 *ip = np; 1621 if (pc != NULL) 1622 *pc = pf_cksum_fixup(*pc, oip, *ip, u); 1623 *ic = pf_cksum_fixup(*ic, oip, *ip, 0); 1624 if (pc != NULL) 1625 *ic = pf_cksum_fixup(*ic, opc, *pc, 0); 1626 } 1627 /* Change inner ip address, fix inner ip and icmp checksums. */ 1628 PF_ACPY(ia, na, af); 1629 switch (af) { 1630#ifdef INET 1631 case AF_INET: { 1632 u_int32_t oh2c = *h2c; 1633 1634 *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c, 1635 oia.addr16[0], ia->addr16[0], 0), 1636 oia.addr16[1], ia->addr16[1], 0); 1637 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic, 1638 oia.addr16[0], ia->addr16[0], 0), 1639 oia.addr16[1], ia->addr16[1], 0); 1640 *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0); 1641 break; 1642 } 1643#endif /* INET */ 1644#ifdef INET6 1645 case AF_INET6: 1646 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1647 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1648 pf_cksum_fixup(pf_cksum_fixup(*ic, 1649 oia.addr16[0], ia->addr16[0], u), 1650 oia.addr16[1], ia->addr16[1], u), 1651 oia.addr16[2], ia->addr16[2], u), 1652 oia.addr16[3], ia->addr16[3], u), 1653 oia.addr16[4], ia->addr16[4], u), 1654 oia.addr16[5], ia->addr16[5], u), 1655 oia.addr16[6], ia->addr16[6], u), 1656 oia.addr16[7], ia->addr16[7], u); 1657 break; 1658#endif /* INET6 */ 1659 } 1660 /* Change outer ip address, fix outer ip or icmpv6 checksum. */ 1661 PF_ACPY(oa, na, af); 1662 switch (af) { 1663#ifdef INET 1664 case AF_INET: 1665 *hc = pf_cksum_fixup(pf_cksum_fixup(*hc, 1666 ooa.addr16[0], oa->addr16[0], 0), 1667 ooa.addr16[1], oa->addr16[1], 0); 1668 break; 1669#endif /* INET */ 1670#ifdef INET6 1671 case AF_INET6: 1672 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1673 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1674 pf_cksum_fixup(pf_cksum_fixup(*ic, 1675 ooa.addr16[0], oa->addr16[0], u), 1676 ooa.addr16[1], oa->addr16[1], u), 1677 ooa.addr16[2], oa->addr16[2], u), 1678 ooa.addr16[3], oa->addr16[3], u), 1679 ooa.addr16[4], oa->addr16[4], u), 1680 ooa.addr16[5], oa->addr16[5], u), 1681 ooa.addr16[6], oa->addr16[6], u), 1682 ooa.addr16[7], oa->addr16[7], u); 1683 break; 1684#endif /* INET6 */ 1685 } 1686} 1687 1688 1689/* 1690 * Need to modulate the sequence numbers in the TCP SACK option 1691 * (credits to Krzysztof Pfaff for report and patch) 1692 */ 1693int 1694pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd, 1695 struct tcphdr *th, struct pf_state_peer *dst) 1696{ 1697 int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen; 1698#ifdef __FreeBSD__ 1699 u_int8_t opts[TCP_MAXOLEN], *opt = opts; 1700#else 1701 u_int8_t opts[MAX_TCPOPTLEN], *opt = opts; 1702#endif 1703 int copyback = 0, i, olen; 1704 struct sackblk sack; 1705 1706#define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2) 1707 if (hlen < TCPOLEN_SACKLEN || 1708 !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af)) 1709 return 0; 1710 1711 while (hlen >= TCPOLEN_SACKLEN) { 1712 olen = opt[1]; 1713 switch (*opt) { 1714 case TCPOPT_EOL: /* FALLTHROUGH */ 1715 case TCPOPT_NOP: 1716 opt++; 1717 hlen--; 1718 break; 1719 case TCPOPT_SACK: 1720 if (olen > hlen) 1721 olen = hlen; 1722 if (olen >= TCPOLEN_SACKLEN) { 1723 for (i = 2; i + TCPOLEN_SACK <= olen; 1724 i += TCPOLEN_SACK) { 1725 memcpy(&sack, &opt[i], sizeof(sack)); 1726 pf_change_a(&sack.start, &th->th_sum, 1727 htonl(ntohl(sack.start) - 1728 dst->seqdiff), 0); 1729 pf_change_a(&sack.end, &th->th_sum, 1730 htonl(ntohl(sack.end) - 1731 dst->seqdiff), 0); 1732 memcpy(&opt[i], &sack, sizeof(sack)); 1733 } 1734 copyback = 1; 1735 } 1736 /* FALLTHROUGH */ 1737 default: 1738 if (olen < 2) 1739 olen = 2; 1740 hlen -= olen; 1741 opt += olen; 1742 } 1743 } 1744 1745 if (copyback) 1746#ifdef __FreeBSD__ 1747 m_copyback(m, off + sizeof(*th), thoptlen, (caddr_t)opts); 1748#else 1749 m_copyback(m, off + sizeof(*th), thoptlen, opts); 1750#endif 1751 return (copyback); 1752} 1753 1754void 1755#ifdef __FreeBSD__ 1756pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af, 1757#else 1758pf_send_tcp(const struct pf_rule *r, sa_family_t af, 1759#endif 1760 const struct pf_addr *saddr, const struct pf_addr *daddr, 1761 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack, 1762 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag, 1763 u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp) 1764{ 1765 INIT_VNET_INET(curvnet); 1766 struct mbuf *m; 1767 int len, tlen; 1768#ifdef INET 1769 struct ip *h; 1770#endif /* INET */ 1771#ifdef INET6 1772 struct ip6_hdr *h6; 1773#endif /* INET6 */ 1774 struct tcphdr *th; 1775 char *opt; 1776 struct pf_mtag *pf_mtag; 1777 1778#ifdef __FreeBSD__ 1779 KASSERT( 1780#ifdef INET 1781 af == AF_INET 1782#else 1783 0 1784#endif 1785 || 1786#ifdef INET6 1787 af == AF_INET6 1788#else 1789 0 1790#endif 1791 , ("Unsupported AF %d", af)); 1792 len = 0; 1793 th = NULL; 1794#ifdef INET 1795 h = NULL; 1796#endif 1797#ifdef INET6 1798 h6 = NULL; 1799#endif 1800#endif 1801 1802 /* maximum segment size tcp option */ 1803 tlen = sizeof(struct tcphdr); 1804 if (mss) 1805 tlen += 4; 1806 1807 switch (af) { 1808#ifdef INET 1809 case AF_INET: 1810 len = sizeof(struct ip) + tlen; 1811 break; 1812#endif /* INET */ 1813#ifdef INET6 1814 case AF_INET6: 1815 len = sizeof(struct ip6_hdr) + tlen; 1816 break; 1817#endif /* INET6 */ 1818 } 1819 1820 /* create outgoing mbuf */ 1821 m = m_gethdr(M_DONTWAIT, MT_HEADER); 1822 if (m == NULL) 1823 return; 1824#ifdef __FreeBSD__ 1825#ifdef MAC 1826 if (replyto) 1827 mac_netinet_firewall_reply(replyto, m); 1828 else 1829 mac_netinet_firewall_send(m); 1830#else 1831 (void)replyto; 1832#endif 1833#endif 1834 if ((pf_mtag = pf_get_mtag(m)) == NULL) { 1835 m_freem(m); 1836 return; 1837 } 1838 if (tag) 1839#ifdef __FreeBSD__ 1840 m->m_flags |= M_SKIP_FIREWALL; 1841#else 1842 pf_mtag->flags |= PF_TAG_GENERATED; 1843#endif 1844 1845 pf_mtag->tag = rtag; 1846 1847 if (r != NULL && r->rtableid >= 0) 1848#ifdef __FreeBSD__ 1849 { 1850 M_SETFIB(m, r->rtableid); 1851#endif 1852 pf_mtag->rtableid = r->rtableid; 1853#ifdef __FreeBSD__ 1854 } 1855#endif 1856#ifdef ALTQ 1857 if (r != NULL && r->qid) { 1858 pf_mtag->qid = r->qid; 1859 /* add hints for ecn */ 1860 pf_mtag->af = af; 1861 pf_mtag->hdr = mtod(m, struct ip *); 1862 } 1863#endif /* ALTQ */ 1864 m->m_data += max_linkhdr; 1865 m->m_pkthdr.len = m->m_len = len; 1866 m->m_pkthdr.rcvif = NULL; 1867 bzero(m->m_data, len); 1868 switch (af) { 1869#ifdef INET 1870 case AF_INET: 1871 h = mtod(m, struct ip *); 1872 1873 /* IP header fields included in the TCP checksum */ 1874 h->ip_p = IPPROTO_TCP; 1875 h->ip_len = htons(tlen); 1876 h->ip_src.s_addr = saddr->v4.s_addr; 1877 h->ip_dst.s_addr = daddr->v4.s_addr; 1878 1879 th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip)); 1880 break; 1881#endif /* INET */ 1882#ifdef INET6 1883 case AF_INET6: 1884 h6 = mtod(m, struct ip6_hdr *); 1885 1886 /* IP header fields included in the TCP checksum */ 1887 h6->ip6_nxt = IPPROTO_TCP; 1888 h6->ip6_plen = htons(tlen); 1889 memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr)); 1890 memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr)); 1891 1892 th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr)); 1893 break; 1894#endif /* INET6 */ 1895 } 1896 1897 /* TCP header */ 1898 th->th_sport = sport; 1899 th->th_dport = dport; 1900 th->th_seq = htonl(seq); 1901 th->th_ack = htonl(ack); 1902 th->th_off = tlen >> 2; 1903 th->th_flags = flags; 1904 th->th_win = htons(win); 1905 1906 if (mss) { 1907 opt = (char *)(th + 1); 1908 opt[0] = TCPOPT_MAXSEG; 1909 opt[1] = 4; 1910 HTONS(mss); 1911 bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2); 1912 } 1913 1914 switch (af) { 1915#ifdef INET 1916 case AF_INET: 1917 /* TCP checksum */ 1918 th->th_sum = in_cksum(m, len); 1919 1920 /* Finish the IP header */ 1921 h->ip_v = 4; 1922 h->ip_hl = sizeof(*h) >> 2; 1923 h->ip_tos = IPTOS_LOWDELAY; 1924#ifdef __FreeBSD__ 1925 h->ip_off = V_path_mtu_discovery ? IP_DF : 0; 1926 h->ip_len = len; 1927#else 1928 h->ip_off = htons(ip_mtudisc ? IP_DF : 0); 1929 h->ip_len = htons(len); 1930#endif 1931 h->ip_ttl = ttl ? ttl : V_ip_defttl; 1932 h->ip_sum = 0; 1933 if (eh == NULL) { 1934#ifdef __FreeBSD__ 1935 PF_UNLOCK(); 1936 ip_output(m, (void *)NULL, (void *)NULL, 0, 1937 (void *)NULL, (void *)NULL); 1938 PF_LOCK(); 1939#else /* ! __FreeBSD__ */ 1940 ip_output(m, (void *)NULL, (void *)NULL, 0, 1941 (void *)NULL, (void *)NULL); 1942#endif 1943 } else { 1944 struct route ro; 1945 struct rtentry rt; 1946 struct ether_header *e = (void *)ro.ro_dst.sa_data; 1947 1948 if (ifp == NULL) { 1949 m_freem(m); 1950 return; 1951 } 1952 rt.rt_ifp = ifp; 1953 ro.ro_rt = &rt; 1954 ro.ro_dst.sa_len = sizeof(ro.ro_dst); 1955 ro.ro_dst.sa_family = pseudo_AF_HDRCMPLT; 1956 bcopy(eh->ether_dhost, e->ether_shost, ETHER_ADDR_LEN); 1957 bcopy(eh->ether_shost, e->ether_dhost, ETHER_ADDR_LEN); 1958 e->ether_type = eh->ether_type; 1959#ifdef __FreeBSD__ 1960 PF_UNLOCK(); 1961 /* XXX_IMPORT: later */ 1962 ip_output(m, (void *)NULL, &ro, 0, 1963 (void *)NULL, (void *)NULL); 1964 PF_LOCK(); 1965#else /* ! __FreeBSD__ */ 1966 ip_output(m, (void *)NULL, &ro, IP_ROUTETOETHER, 1967 (void *)NULL, (void *)NULL); 1968#endif 1969 } 1970 break; 1971#endif /* INET */ 1972#ifdef INET6 1973 case AF_INET6: 1974 /* TCP checksum */ 1975 th->th_sum = in6_cksum(m, IPPROTO_TCP, 1976 sizeof(struct ip6_hdr), tlen); 1977 1978 h6->ip6_vfc |= IPV6_VERSION; 1979 h6->ip6_hlim = IPV6_DEFHLIM; 1980 1981#ifdef __FreeBSD__ 1982 PF_UNLOCK(); 1983 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); 1984 PF_LOCK(); 1985#else 1986 ip6_output(m, NULL, NULL, 0, NULL, NULL); 1987#endif 1988 break; 1989#endif /* INET6 */ 1990 } 1991} 1992 1993void 1994pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, 1995 struct pf_rule *r) 1996{ 1997 struct pf_mtag *pf_mtag; 1998 struct mbuf *m0; 1999#ifdef __FreeBSD__ 2000 struct ip *ip; 2001#endif 2002 2003#ifdef __FreeBSD__ 2004 m0 = m_copypacket(m, M_DONTWAIT); 2005 if (m0 == NULL) 2006 return; 2007#else 2008 m0 = m_copy(m, 0, M_COPYALL); 2009#endif 2010 if ((pf_mtag = pf_get_mtag(m0)) == NULL) 2011 return; 2012#ifdef __FreeBSD__ 2013 /* XXX: revisit */ 2014 m0->m_flags |= M_SKIP_FIREWALL; 2015#else 2016 pf_mtag->flags |= PF_TAG_GENERATED; 2017#endif 2018 2019 if (r->rtableid >= 0) 2020#ifdef __FreeBSD__ 2021 { 2022 M_SETFIB(m0, r->rtableid); 2023#endif 2024 pf_mtag->rtableid = r->rtableid; 2025#ifdef __FreeBSD__ 2026 } 2027#endif 2028 2029#ifdef ALTQ 2030 if (r->qid) { 2031 pf_mtag->qid = r->qid; 2032 /* add hints for ecn */ 2033 pf_mtag->af = af; 2034 pf_mtag->hdr = mtod(m0, struct ip *); 2035 } 2036#endif /* ALTQ */ 2037 2038 switch (af) { 2039#ifdef INET 2040 case AF_INET: 2041#ifdef __FreeBSD__ 2042 /* icmp_error() expects host byte ordering */ 2043 ip = mtod(m0, struct ip *); 2044 NTOHS(ip->ip_len); 2045 NTOHS(ip->ip_off); 2046 PF_UNLOCK(); 2047 icmp_error(m0, type, code, 0, 0); 2048 PF_LOCK(); 2049#else 2050 icmp_error(m0, type, code, 0, 0); 2051#endif 2052 break; 2053#endif /* INET */ 2054#ifdef INET6 2055 case AF_INET6: 2056#ifdef __FreeBSD__ 2057 PF_UNLOCK(); 2058#endif 2059 icmp6_error(m0, type, code, 0); 2060#ifdef __FreeBSD__ 2061 PF_LOCK(); 2062#endif 2063 break; 2064#endif /* INET6 */ 2065 } 2066} 2067 2068/* 2069 * Return 1 if the addresses a and b match (with mask m), otherwise return 0. 2070 * If n is 0, they match if they are equal. If n is != 0, they match if they 2071 * are different. 2072 */ 2073int 2074pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m, 2075 struct pf_addr *b, sa_family_t af) 2076{ 2077 int match = 0; 2078 2079 switch (af) { 2080#ifdef INET 2081 case AF_INET: 2082 if ((a->addr32[0] & m->addr32[0]) == 2083 (b->addr32[0] & m->addr32[0])) 2084 match++; 2085 break; 2086#endif /* INET */ 2087#ifdef INET6 2088 case AF_INET6: 2089 if (((a->addr32[0] & m->addr32[0]) == 2090 (b->addr32[0] & m->addr32[0])) && 2091 ((a->addr32[1] & m->addr32[1]) == 2092 (b->addr32[1] & m->addr32[1])) && 2093 ((a->addr32[2] & m->addr32[2]) == 2094 (b->addr32[2] & m->addr32[2])) && 2095 ((a->addr32[3] & m->addr32[3]) == 2096 (b->addr32[3] & m->addr32[3]))) 2097 match++; 2098 break; 2099#endif /* INET6 */ 2100 } 2101 if (match) { 2102 if (n) 2103 return (0); 2104 else 2105 return (1); 2106 } else { 2107 if (n) 2108 return (1); 2109 else 2110 return (0); 2111 } 2112} 2113 2114int 2115pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p) 2116{ 2117 switch (op) { 2118 case PF_OP_IRG: 2119 return ((p > a1) && (p < a2)); 2120 case PF_OP_XRG: 2121 return ((p < a1) || (p > a2)); 2122 case PF_OP_RRG: 2123 return ((p >= a1) && (p <= a2)); 2124 case PF_OP_EQ: 2125 return (p == a1); 2126 case PF_OP_NE: 2127 return (p != a1); 2128 case PF_OP_LT: 2129 return (p < a1); 2130 case PF_OP_LE: 2131 return (p <= a1); 2132 case PF_OP_GT: 2133 return (p > a1); 2134 case PF_OP_GE: 2135 return (p >= a1); 2136 } 2137 return (0); /* never reached */ 2138} 2139 2140int 2141pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p) 2142{ 2143 NTOHS(a1); 2144 NTOHS(a2); 2145 NTOHS(p); 2146 return (pf_match(op, a1, a2, p)); 2147} 2148 2149int 2150pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u) 2151{ 2152 if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 2153 return (0); 2154 return (pf_match(op, a1, a2, u)); 2155} 2156 2157int 2158pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g) 2159{ 2160 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 2161 return (0); 2162 return (pf_match(op, a1, a2, g)); 2163} 2164 2165#ifndef __FreeBSD__ 2166struct pf_mtag * 2167pf_find_mtag(struct mbuf *m) 2168{ 2169 struct m_tag *mtag; 2170 2171 if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) 2172 return (NULL); 2173 2174 return ((struct pf_mtag *)(mtag + 1)); 2175} 2176 2177struct pf_mtag * 2178pf_get_mtag(struct mbuf *m) 2179{ 2180 struct m_tag *mtag; 2181 2182 if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) { 2183 mtag = m_tag_get(PACKET_TAG_PF, sizeof(struct pf_mtag), 2184 M_NOWAIT); 2185 if (mtag == NULL) 2186 return (NULL); 2187 bzero(mtag + 1, sizeof(struct pf_mtag)); 2188 m_tag_prepend(m, mtag); 2189 } 2190 2191 return ((struct pf_mtag *)(mtag + 1)); 2192} 2193#endif 2194 2195int 2196pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_mtag *pf_mtag, 2197 int *tag) 2198{ 2199 if (*tag == -1) 2200 *tag = pf_mtag->tag; 2201 2202 return ((!r->match_tag_not && r->match_tag == *tag) || 2203 (r->match_tag_not && r->match_tag != *tag)); 2204} 2205 2206int 2207pf_tag_packet(struct mbuf *m, struct pf_mtag *pf_mtag, int tag, int rtableid) 2208{ 2209 if (tag <= 0 && rtableid < 0) 2210 return (0); 2211 2212 if (pf_mtag == NULL) 2213 if ((pf_mtag = pf_get_mtag(m)) == NULL) 2214 return (1); 2215 if (tag > 0) 2216 pf_mtag->tag = tag; 2217 if (rtableid >= 0) 2218#ifdef __FreeBSD__ 2219 { 2220 M_SETFIB(m, rtableid); 2221#endif 2222 pf_mtag->rtableid = rtableid; 2223#ifdef __FreeBSD__ 2224 } 2225#endif 2226 2227 return (0); 2228} 2229 2230static void 2231pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n, 2232 struct pf_rule **r, struct pf_rule **a, int *match) 2233{ 2234 struct pf_anchor_stackframe *f; 2235 2236 (*r)->anchor->match = 0; 2237 if (match) 2238 *match = 0; 2239 if (*depth >= sizeof(pf_anchor_stack) / 2240 sizeof(pf_anchor_stack[0])) { 2241 printf("pf_step_into_anchor: stack overflow\n"); 2242 *r = TAILQ_NEXT(*r, entries); 2243 return; 2244 } else if (*depth == 0 && a != NULL) 2245 *a = *r; 2246 f = pf_anchor_stack + (*depth)++; 2247 f->rs = *rs; 2248 f->r = *r; 2249 if ((*r)->anchor_wildcard) { 2250 f->parent = &(*r)->anchor->children; 2251 if ((f->child = RB_MIN(pf_anchor_node, f->parent)) == 2252 NULL) { 2253 *r = NULL; 2254 return; 2255 } 2256 *rs = &f->child->ruleset; 2257 } else { 2258 f->parent = NULL; 2259 f->child = NULL; 2260 *rs = &(*r)->anchor->ruleset; 2261 } 2262 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2263} 2264 2265int 2266pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n, 2267 struct pf_rule **r, struct pf_rule **a, int *match) 2268{ 2269 struct pf_anchor_stackframe *f; 2270 int quick = 0; 2271 2272 do { 2273 if (*depth <= 0) 2274 break; 2275 f = pf_anchor_stack + *depth - 1; 2276 if (f->parent != NULL && f->child != NULL) { 2277 if (f->child->match || 2278 (match != NULL && *match)) { 2279 f->r->anchor->match = 1; 2280 *match = 0; 2281 } 2282 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child); 2283 if (f->child != NULL) { 2284 *rs = &f->child->ruleset; 2285 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2286 if (*r == NULL) 2287 continue; 2288 else 2289 break; 2290 } 2291 } 2292 (*depth)--; 2293 if (*depth == 0 && a != NULL) 2294 *a = NULL; 2295 *rs = f->rs; 2296 if (f->r->anchor->match || (match != NULL && *match)) 2297 quick = f->r->quick; 2298 *r = TAILQ_NEXT(f->r, entries); 2299 } while (*r == NULL); 2300 2301 return (quick); 2302} 2303 2304#ifdef INET6 2305void 2306pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr, 2307 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af) 2308{ 2309 switch (af) { 2310#ifdef INET 2311 case AF_INET: 2312 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) | 2313 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]); 2314 break; 2315#endif /* INET */ 2316 case AF_INET6: 2317 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) | 2318 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]); 2319 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) | 2320 ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]); 2321 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) | 2322 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]); 2323 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) | 2324 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]); 2325 break; 2326 } 2327} 2328 2329void 2330pf_addr_inc(struct pf_addr *addr, sa_family_t af) 2331{ 2332 switch (af) { 2333#ifdef INET 2334 case AF_INET: 2335 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1); 2336 break; 2337#endif /* INET */ 2338 case AF_INET6: 2339 if (addr->addr32[3] == 0xffffffff) { 2340 addr->addr32[3] = 0; 2341 if (addr->addr32[2] == 0xffffffff) { 2342 addr->addr32[2] = 0; 2343 if (addr->addr32[1] == 0xffffffff) { 2344 addr->addr32[1] = 0; 2345 addr->addr32[0] = 2346 htonl(ntohl(addr->addr32[0]) + 1); 2347 } else 2348 addr->addr32[1] = 2349 htonl(ntohl(addr->addr32[1]) + 1); 2350 } else 2351 addr->addr32[2] = 2352 htonl(ntohl(addr->addr32[2]) + 1); 2353 } else 2354 addr->addr32[3] = 2355 htonl(ntohl(addr->addr32[3]) + 1); 2356 break; 2357 } 2358} 2359#endif /* INET6 */ 2360 2361#define mix(a,b,c) \ 2362 do { \ 2363 a -= b; a -= c; a ^= (c >> 13); \ 2364 b -= c; b -= a; b ^= (a << 8); \ 2365 c -= a; c -= b; c ^= (b >> 13); \ 2366 a -= b; a -= c; a ^= (c >> 12); \ 2367 b -= c; b -= a; b ^= (a << 16); \ 2368 c -= a; c -= b; c ^= (b >> 5); \ 2369 a -= b; a -= c; a ^= (c >> 3); \ 2370 b -= c; b -= a; b ^= (a << 10); \ 2371 c -= a; c -= b; c ^= (b >> 15); \ 2372 } while (0) 2373 2374/* 2375 * hash function based on bridge_hash in if_bridge.c 2376 */ 2377void 2378pf_hash(struct pf_addr *inaddr, struct pf_addr *hash, 2379 struct pf_poolhashkey *key, sa_family_t af) 2380{ 2381 u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0]; 2382 2383 switch (af) { 2384#ifdef INET 2385 case AF_INET: 2386 a += inaddr->addr32[0]; 2387 b += key->key32[1]; 2388 mix(a, b, c); 2389 hash->addr32[0] = c + key->key32[2]; 2390 break; 2391#endif /* INET */ 2392#ifdef INET6 2393 case AF_INET6: 2394 a += inaddr->addr32[0]; 2395 b += inaddr->addr32[2]; 2396 mix(a, b, c); 2397 hash->addr32[0] = c; 2398 a += inaddr->addr32[1]; 2399 b += inaddr->addr32[3]; 2400 c += key->key32[1]; 2401 mix(a, b, c); 2402 hash->addr32[1] = c; 2403 a += inaddr->addr32[2]; 2404 b += inaddr->addr32[1]; 2405 c += key->key32[2]; 2406 mix(a, b, c); 2407 hash->addr32[2] = c; 2408 a += inaddr->addr32[3]; 2409 b += inaddr->addr32[0]; 2410 c += key->key32[3]; 2411 mix(a, b, c); 2412 hash->addr32[3] = c; 2413 break; 2414#endif /* INET6 */ 2415 } 2416} 2417 2418int 2419pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr, 2420 struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn) 2421{ 2422 unsigned char hash[16]; 2423 struct pf_pool *rpool = &r->rpool; 2424 struct pf_addr *raddr = &rpool->cur->addr.v.a.addr; 2425 struct pf_addr *rmask = &rpool->cur->addr.v.a.mask; 2426 struct pf_pooladdr *acur = rpool->cur; 2427 struct pf_src_node k; 2428 2429 if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR && 2430 (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { 2431 k.af = af; 2432 PF_ACPY(&k.addr, saddr, af); 2433 if (r->rule_flag & PFRULE_RULESRCTRACK || 2434 r->rpool.opts & PF_POOL_STICKYADDR) 2435 k.rule.ptr = r; 2436 else 2437 k.rule.ptr = NULL; 2438 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++; 2439 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k); 2440 if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) { 2441 PF_ACPY(naddr, &(*sn)->raddr, af); 2442 if (pf_status.debug >= PF_DEBUG_MISC) { 2443 printf("pf_map_addr: src tracking maps "); 2444 pf_print_host(&k.addr, 0, af); 2445 printf(" to "); 2446 pf_print_host(naddr, 0, af); 2447 printf("\n"); 2448 } 2449 return (0); 2450 } 2451 } 2452 2453 if (rpool->cur->addr.type == PF_ADDR_NOROUTE) 2454 return (1); 2455 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 2456 switch (af) { 2457#ifdef INET 2458 case AF_INET: 2459 if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 && 2460 (rpool->opts & PF_POOL_TYPEMASK) != 2461 PF_POOL_ROUNDROBIN) 2462 return (1); 2463 raddr = &rpool->cur->addr.p.dyn->pfid_addr4; 2464 rmask = &rpool->cur->addr.p.dyn->pfid_mask4; 2465 break; 2466#endif /* INET */ 2467#ifdef INET6 2468 case AF_INET6: 2469 if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 && 2470 (rpool->opts & PF_POOL_TYPEMASK) != 2471 PF_POOL_ROUNDROBIN) 2472 return (1); 2473 raddr = &rpool->cur->addr.p.dyn->pfid_addr6; 2474 rmask = &rpool->cur->addr.p.dyn->pfid_mask6; 2475 break; 2476#endif /* INET6 */ 2477 } 2478 } else if (rpool->cur->addr.type == PF_ADDR_TABLE) { 2479 if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN) 2480 return (1); /* unsupported */ 2481 } else { 2482 raddr = &rpool->cur->addr.v.a.addr; 2483 rmask = &rpool->cur->addr.v.a.mask; 2484 } 2485 2486 switch (rpool->opts & PF_POOL_TYPEMASK) { 2487 case PF_POOL_NONE: 2488 PF_ACPY(naddr, raddr, af); 2489 break; 2490 case PF_POOL_BITMASK: 2491 PF_POOLMASK(naddr, raddr, rmask, saddr, af); 2492 break; 2493 case PF_POOL_RANDOM: 2494 if (init_addr != NULL && PF_AZERO(init_addr, af)) { 2495 switch (af) { 2496#ifdef INET 2497 case AF_INET: 2498 rpool->counter.addr32[0] = htonl(arc4random()); 2499 break; 2500#endif /* INET */ 2501#ifdef INET6 2502 case AF_INET6: 2503 if (rmask->addr32[3] != 0xffffffff) 2504 rpool->counter.addr32[3] = 2505 htonl(arc4random()); 2506 else 2507 break; 2508 if (rmask->addr32[2] != 0xffffffff) 2509 rpool->counter.addr32[2] = 2510 htonl(arc4random()); 2511 else 2512 break; 2513 if (rmask->addr32[1] != 0xffffffff) 2514 rpool->counter.addr32[1] = 2515 htonl(arc4random()); 2516 else 2517 break; 2518 if (rmask->addr32[0] != 0xffffffff) 2519 rpool->counter.addr32[0] = 2520 htonl(arc4random()); 2521 break; 2522#endif /* INET6 */ 2523 } 2524 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af); 2525 PF_ACPY(init_addr, naddr, af); 2526 2527 } else { 2528 PF_AINC(&rpool->counter, af); 2529 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af); 2530 } 2531 break; 2532 case PF_POOL_SRCHASH: 2533 pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af); 2534 PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af); 2535 break; 2536 case PF_POOL_ROUNDROBIN: 2537 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 2538 if (!pfr_pool_get(rpool->cur->addr.p.tbl, 2539 &rpool->tblidx, &rpool->counter, 2540 &raddr, &rmask, af)) 2541 goto get_addr; 2542 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 2543 if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 2544 &rpool->tblidx, &rpool->counter, 2545 &raddr, &rmask, af)) 2546 goto get_addr; 2547 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af)) 2548 goto get_addr; 2549 2550 try_next: 2551 if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL) 2552 rpool->cur = TAILQ_FIRST(&rpool->list); 2553 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 2554 rpool->tblidx = -1; 2555 if (pfr_pool_get(rpool->cur->addr.p.tbl, 2556 &rpool->tblidx, &rpool->counter, 2557 &raddr, &rmask, af)) { 2558 /* table contains no address of type 'af' */ 2559 if (rpool->cur != acur) 2560 goto try_next; 2561 return (1); 2562 } 2563 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 2564 rpool->tblidx = -1; 2565 if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 2566 &rpool->tblidx, &rpool->counter, 2567 &raddr, &rmask, af)) { 2568 /* table contains no address of type 'af' */ 2569 if (rpool->cur != acur) 2570 goto try_next; 2571 return (1); 2572 } 2573 } else { 2574 raddr = &rpool->cur->addr.v.a.addr; 2575 rmask = &rpool->cur->addr.v.a.mask; 2576 PF_ACPY(&rpool->counter, raddr, af); 2577 } 2578 2579 get_addr: 2580 PF_ACPY(naddr, &rpool->counter, af); 2581 if (init_addr != NULL && PF_AZERO(init_addr, af)) 2582 PF_ACPY(init_addr, naddr, af); 2583 PF_AINC(&rpool->counter, af); 2584 break; 2585 } 2586 if (*sn != NULL) 2587 PF_ACPY(&(*sn)->raddr, naddr, af); 2588 2589 if (pf_status.debug >= PF_DEBUG_MISC && 2590 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { 2591 printf("pf_map_addr: selected address "); 2592 pf_print_host(naddr, 0, af); 2593 printf("\n"); 2594 } 2595 2596 return (0); 2597} 2598 2599int 2600pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, 2601 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport, 2602 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high, 2603 struct pf_src_node **sn) 2604{ 2605 struct pf_state_cmp key; 2606 struct pf_addr init_addr; 2607 u_int16_t cut; 2608 2609 bzero(&init_addr, sizeof(init_addr)); 2610 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) 2611 return (1); 2612 2613 if (proto == IPPROTO_ICMP) { 2614 low = 1; 2615 high = 65535; 2616 } 2617 2618 do { 2619 key.af = af; 2620 key.proto = proto; 2621 PF_ACPY(&key.ext.addr, daddr, key.af); 2622 PF_ACPY(&key.gwy.addr, naddr, key.af); 2623 key.ext.port = dport; 2624 2625 /* 2626 * port search; start random, step; 2627 * similar 2 portloop in in_pcbbind 2628 */ 2629 if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP || 2630 proto == IPPROTO_ICMP)) { 2631 key.gwy.port = dport; 2632 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) 2633 return (0); 2634 } else if (low == 0 && high == 0) { 2635 key.gwy.port = *nport; 2636 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) 2637 return (0); 2638 } else if (low == high) { 2639 key.gwy.port = htons(low); 2640 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) { 2641 *nport = htons(low); 2642 return (0); 2643 } 2644 } else { 2645 u_int16_t tmp; 2646 2647 if (low > high) { 2648 tmp = low; 2649 low = high; 2650 high = tmp; 2651 } 2652 /* low < high */ 2653 cut = htonl(arc4random()) % (1 + high - low) + low; 2654 /* low <= cut <= high */ 2655 for (tmp = cut; tmp <= high; ++(tmp)) { 2656 key.gwy.port = htons(tmp); 2657 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == 2658 NULL) { 2659 *nport = htons(tmp); 2660 return (0); 2661 } 2662 } 2663 for (tmp = cut - 1; tmp >= low; --(tmp)) { 2664 key.gwy.port = htons(tmp); 2665 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == 2666 NULL) { 2667 *nport = htons(tmp); 2668 return (0); 2669 } 2670 } 2671 } 2672 2673 switch (r->rpool.opts & PF_POOL_TYPEMASK) { 2674 case PF_POOL_RANDOM: 2675 case PF_POOL_ROUNDROBIN: 2676 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) 2677 return (1); 2678 break; 2679 case PF_POOL_NONE: 2680 case PF_POOL_SRCHASH: 2681 case PF_POOL_BITMASK: 2682 default: 2683 return (1); 2684 } 2685 } while (! PF_AEQ(&init_addr, naddr, af) ); 2686 2687 return (1); /* none available */ 2688} 2689 2690struct pf_rule * 2691pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, 2692 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport, 2693 struct pf_addr *daddr, u_int16_t dport, int rs_num) 2694{ 2695 struct pf_rule *r, *rm = NULL; 2696 struct pf_ruleset *ruleset = NULL; 2697 int tag = -1; 2698 int rtableid = -1; 2699 int asd = 0; 2700 2701 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr); 2702 while (r && rm == NULL) { 2703 struct pf_rule_addr *src = NULL, *dst = NULL; 2704 struct pf_addr_wrap *xdst = NULL; 2705 2706 if (r->action == PF_BINAT && direction == PF_IN) { 2707 src = &r->dst; 2708 if (r->rpool.cur != NULL) 2709 xdst = &r->rpool.cur->addr; 2710 } else { 2711 src = &r->src; 2712 dst = &r->dst; 2713 } 2714 2715 r->evaluations++; 2716 if (pfi_kif_match(r->kif, kif) == r->ifnot) 2717 r = r->skip[PF_SKIP_IFP].ptr; 2718 else if (r->direction && r->direction != direction) 2719 r = r->skip[PF_SKIP_DIR].ptr; 2720 else if (r->af && r->af != pd->af) 2721 r = r->skip[PF_SKIP_AF].ptr; 2722 else if (r->proto && r->proto != pd->proto) 2723 r = r->skip[PF_SKIP_PROTO].ptr; 2724 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, 2725 src->neg, kif)) 2726 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR : 2727 PF_SKIP_DST_ADDR].ptr; 2728 else if (src->port_op && !pf_match_port(src->port_op, 2729 src->port[0], src->port[1], sport)) 2730 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT : 2731 PF_SKIP_DST_PORT].ptr; 2732 else if (dst != NULL && 2733 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL)) 2734 r = r->skip[PF_SKIP_DST_ADDR].ptr; 2735 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, 2736 0, NULL)) 2737 r = TAILQ_NEXT(r, entries); 2738 else if (dst != NULL && dst->port_op && 2739 !pf_match_port(dst->port_op, dst->port[0], 2740 dst->port[1], dport)) 2741 r = r->skip[PF_SKIP_DST_PORT].ptr; 2742 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 2743 r = TAILQ_NEXT(r, entries); 2744 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto != 2745 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m, 2746 off, pd->hdr.tcp), r->os_fingerprint))) 2747 r = TAILQ_NEXT(r, entries); 2748 else { 2749 if (r->tag) 2750 tag = r->tag; 2751 if (r->rtableid >= 0) 2752 rtableid = r->rtableid; 2753 if (r->anchor == NULL) { 2754 rm = r; 2755 } else 2756 pf_step_into_anchor(&asd, &ruleset, rs_num, 2757 &r, NULL, NULL); 2758 } 2759 if (r == NULL) 2760 pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r, 2761 NULL, NULL); 2762 } 2763 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) 2764 return (NULL); 2765 if (rm != NULL && (rm->action == PF_NONAT || 2766 rm->action == PF_NORDR || rm->action == PF_NOBINAT)) 2767 return (NULL); 2768 return (rm); 2769} 2770 2771struct pf_rule * 2772pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, 2773 struct pfi_kif *kif, struct pf_src_node **sn, 2774 struct pf_addr *saddr, u_int16_t sport, 2775 struct pf_addr *daddr, u_int16_t dport, 2776 struct pf_addr *naddr, u_int16_t *nport) 2777{ 2778 struct pf_rule *r = NULL; 2779 2780 if (direction == PF_OUT) { 2781 r = pf_match_translation(pd, m, off, direction, kif, saddr, 2782 sport, daddr, dport, PF_RULESET_BINAT); 2783 if (r == NULL) 2784 r = pf_match_translation(pd, m, off, direction, kif, 2785 saddr, sport, daddr, dport, PF_RULESET_NAT); 2786 } else { 2787 r = pf_match_translation(pd, m, off, direction, kif, saddr, 2788 sport, daddr, dport, PF_RULESET_RDR); 2789 if (r == NULL) 2790 r = pf_match_translation(pd, m, off, direction, kif, 2791 saddr, sport, daddr, dport, PF_RULESET_BINAT); 2792 } 2793 2794 if (r != NULL) { 2795 switch (r->action) { 2796 case PF_NONAT: 2797 case PF_NOBINAT: 2798 case PF_NORDR: 2799 return (NULL); 2800 case PF_NAT: 2801 if (pf_get_sport(pd->af, pd->proto, r, saddr, 2802 daddr, dport, naddr, nport, r->rpool.proxy_port[0], 2803 r->rpool.proxy_port[1], sn)) { 2804 DPFPRINTF(PF_DEBUG_MISC, 2805 ("pf: NAT proxy port allocation " 2806 "(%u-%u) failed\n", 2807 r->rpool.proxy_port[0], 2808 r->rpool.proxy_port[1])); 2809 return (NULL); 2810 } 2811 break; 2812 case PF_BINAT: 2813 switch (direction) { 2814 case PF_OUT: 2815 if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){ 2816 switch (pd->af) { 2817#ifdef INET 2818 case AF_INET: 2819 if (r->rpool.cur->addr.p.dyn-> 2820 pfid_acnt4 < 1) 2821 return (NULL); 2822 PF_POOLMASK(naddr, 2823 &r->rpool.cur->addr.p.dyn-> 2824 pfid_addr4, 2825 &r->rpool.cur->addr.p.dyn-> 2826 pfid_mask4, 2827 saddr, AF_INET); 2828 break; 2829#endif /* INET */ 2830#ifdef INET6 2831 case AF_INET6: 2832 if (r->rpool.cur->addr.p.dyn-> 2833 pfid_acnt6 < 1) 2834 return (NULL); 2835 PF_POOLMASK(naddr, 2836 &r->rpool.cur->addr.p.dyn-> 2837 pfid_addr6, 2838 &r->rpool.cur->addr.p.dyn-> 2839 pfid_mask6, 2840 saddr, AF_INET6); 2841 break; 2842#endif /* INET6 */ 2843 } 2844 } else 2845 PF_POOLMASK(naddr, 2846 &r->rpool.cur->addr.v.a.addr, 2847 &r->rpool.cur->addr.v.a.mask, 2848 saddr, pd->af); 2849 break; 2850 case PF_IN: 2851 if (r->src.addr.type == PF_ADDR_DYNIFTL) { 2852 switch (pd->af) { 2853#ifdef INET 2854 case AF_INET: 2855 if (r->src.addr.p.dyn-> 2856 pfid_acnt4 < 1) 2857 return (NULL); 2858 PF_POOLMASK(naddr, 2859 &r->src.addr.p.dyn-> 2860 pfid_addr4, 2861 &r->src.addr.p.dyn-> 2862 pfid_mask4, 2863 daddr, AF_INET); 2864 break; 2865#endif /* INET */ 2866#ifdef INET6 2867 case AF_INET6: 2868 if (r->src.addr.p.dyn-> 2869 pfid_acnt6 < 1) 2870 return (NULL); 2871 PF_POOLMASK(naddr, 2872 &r->src.addr.p.dyn-> 2873 pfid_addr6, 2874 &r->src.addr.p.dyn-> 2875 pfid_mask6, 2876 daddr, AF_INET6); 2877 break; 2878#endif /* INET6 */ 2879 } 2880 } else 2881 PF_POOLMASK(naddr, 2882 &r->src.addr.v.a.addr, 2883 &r->src.addr.v.a.mask, daddr, 2884 pd->af); 2885 break; 2886 } 2887 break; 2888 case PF_RDR: { 2889 if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn)) 2890 return (NULL); 2891 if ((r->rpool.opts & PF_POOL_TYPEMASK) == 2892 PF_POOL_BITMASK) 2893 PF_POOLMASK(naddr, naddr, 2894 &r->rpool.cur->addr.v.a.mask, daddr, 2895 pd->af); 2896 2897 if (r->rpool.proxy_port[1]) { 2898 u_int32_t tmp_nport; 2899 2900 tmp_nport = ((ntohs(dport) - 2901 ntohs(r->dst.port[0])) % 2902 (r->rpool.proxy_port[1] - 2903 r->rpool.proxy_port[0] + 1)) + 2904 r->rpool.proxy_port[0]; 2905 2906 /* wrap around if necessary */ 2907 if (tmp_nport > 65535) 2908 tmp_nport -= 65535; 2909 *nport = htons((u_int16_t)tmp_nport); 2910 } else if (r->rpool.proxy_port[0]) 2911 *nport = htons(r->rpool.proxy_port[0]); 2912 break; 2913 } 2914 default: 2915 return (NULL); 2916 } 2917 } 2918 2919 return (r); 2920} 2921 2922int 2923#ifdef __FreeBSD__ 2924pf_socket_lookup(int direction, struct pf_pdesc *pd, struct inpcb *inp_arg) 2925#else 2926pf_socket_lookup(int direction, struct pf_pdesc *pd) 2927#endif 2928{ 2929 INIT_VNET_INET(curvnet); 2930 struct pf_addr *saddr, *daddr; 2931 u_int16_t sport, dport; 2932#ifdef __FreeBSD__ 2933 struct inpcbinfo *pi; 2934#else 2935 struct inpcbtable *tb; 2936#endif 2937 struct inpcb *inp; 2938 2939 if (pd == NULL) 2940 return (-1); 2941 pd->lookup.uid = UID_MAX; 2942 pd->lookup.gid = GID_MAX; 2943 pd->lookup.pid = NO_PID; /* XXX: revisit */ 2944#ifdef __FreeBSD__ 2945 if (inp_arg != NULL) { 2946 INP_LOCK_ASSERT(inp_arg); 2947 pd->lookup.uid = inp_arg->inp_cred->cr_uid; 2948 pd->lookup.gid = inp_arg->inp_cred->cr_groups[0]; 2949 return (1); 2950 } 2951#endif 2952 switch (pd->proto) { 2953 case IPPROTO_TCP: 2954 if (pd->hdr.tcp == NULL) 2955 return (-1); 2956 sport = pd->hdr.tcp->th_sport; 2957 dport = pd->hdr.tcp->th_dport; 2958#ifdef __FreeBSD__ 2959 pi = &V_tcbinfo; 2960#else 2961 tb = &tcbtable; 2962#endif 2963 break; 2964 case IPPROTO_UDP: 2965 if (pd->hdr.udp == NULL) 2966 return (-1); 2967 sport = pd->hdr.udp->uh_sport; 2968 dport = pd->hdr.udp->uh_dport; 2969#ifdef __FreeBSD__ 2970 pi = &V_udbinfo; 2971#else 2972 tb = &udbtable; 2973#endif 2974 break; 2975 default: 2976 return (-1); 2977 } 2978 if (direction == PF_IN) { 2979 saddr = pd->src; 2980 daddr = pd->dst; 2981 } else { 2982 u_int16_t p; 2983 2984 p = sport; 2985 sport = dport; 2986 dport = p; 2987 saddr = pd->dst; 2988 daddr = pd->src; 2989 } 2990 switch (pd->af) { 2991#ifdef INET 2992 case AF_INET: 2993#ifdef __FreeBSD__ 2994 INP_INFO_RLOCK(pi); /* XXX LOR */ 2995 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4, 2996 dport, 0, NULL); 2997 if (inp == NULL) { 2998 inp = in_pcblookup_hash(pi, saddr->v4, sport, 2999 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL); 3000 if(inp == NULL) { 3001 INP_INFO_RUNLOCK(pi); 3002 return (-1); 3003 } 3004 } 3005#else 3006 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); 3007 if (inp == NULL) { 3008 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0); 3009 if (inp == NULL) 3010 return (-1); 3011 } 3012#endif 3013 break; 3014#endif /* INET */ 3015#ifdef INET6 3016 case AF_INET6: 3017#ifdef __FreeBSD__ 3018 INP_INFO_RLOCK(pi); 3019 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 3020 &daddr->v6, dport, 0, NULL); 3021 if (inp == NULL) { 3022 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 3023 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL); 3024 if (inp == NULL) { 3025 INP_INFO_RUNLOCK(pi); 3026 return (-1); 3027 } 3028 } 3029#else 3030 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, 3031 dport); 3032 if (inp == NULL) { 3033 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0); 3034 if (inp == NULL) 3035 return (-1); 3036 } 3037#endif 3038 break; 3039#endif /* INET6 */ 3040 3041 default: 3042 return (-1); 3043 } 3044#ifdef __FreeBSD__ 3045 pd->lookup.uid = inp->inp_cred->cr_uid; 3046 pd->lookup.gid = inp->inp_cred->cr_groups[0]; 3047 INP_INFO_RUNLOCK(pi); 3048#else 3049 pd->lookup.uid = inp->inp_socket->so_euid; 3050 pd->lookup.gid = inp->inp_socket->so_egid; 3051 pd->lookup.pid = inp->inp_socket->so_cpid; 3052#endif 3053 return (1); 3054} 3055 3056u_int8_t 3057pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 3058{ 3059 int hlen; 3060 u_int8_t hdr[60]; 3061 u_int8_t *opt, optlen; 3062 u_int8_t wscale = 0; 3063 3064 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 3065 if (hlen <= sizeof(struct tcphdr)) 3066 return (0); 3067 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 3068 return (0); 3069 opt = hdr + sizeof(struct tcphdr); 3070 hlen -= sizeof(struct tcphdr); 3071 while (hlen >= 3) { 3072 switch (*opt) { 3073 case TCPOPT_EOL: 3074 case TCPOPT_NOP: 3075 ++opt; 3076 --hlen; 3077 break; 3078 case TCPOPT_WINDOW: 3079 wscale = opt[2]; 3080 if (wscale > TCP_MAX_WINSHIFT) 3081 wscale = TCP_MAX_WINSHIFT; 3082 wscale |= PF_WSCALE_FLAG; 3083 /* FALLTHROUGH */ 3084 default: 3085 optlen = opt[1]; 3086 if (optlen < 2) 3087 optlen = 2; 3088 hlen -= optlen; 3089 opt += optlen; 3090 break; 3091 } 3092 } 3093 return (wscale); 3094} 3095 3096u_int16_t 3097pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 3098{ 3099 INIT_VNET_INET(curvnet); 3100 int hlen; 3101 u_int8_t hdr[60]; 3102 u_int8_t *opt, optlen; 3103 u_int16_t mss = V_tcp_mssdflt; 3104 3105 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 3106 if (hlen <= sizeof(struct tcphdr)) 3107 return (0); 3108 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 3109 return (0); 3110 opt = hdr + sizeof(struct tcphdr); 3111 hlen -= sizeof(struct tcphdr); 3112 while (hlen >= TCPOLEN_MAXSEG) { 3113 switch (*opt) { 3114 case TCPOPT_EOL: 3115 case TCPOPT_NOP: 3116 ++opt; 3117 --hlen; 3118 break; 3119 case TCPOPT_MAXSEG: 3120 bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2); 3121 NTOHS(mss); 3122 /* FALLTHROUGH */ 3123 default: 3124 optlen = opt[1]; 3125 if (optlen < 2) 3126 optlen = 2; 3127 hlen -= optlen; 3128 opt += optlen; 3129 break; 3130 } 3131 } 3132 return (mss); 3133} 3134 3135u_int16_t 3136pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) 3137{ 3138#ifdef INET 3139 INIT_VNET_INET(curvnet); 3140 struct sockaddr_in *dst; 3141 struct route ro; 3142#endif /* INET */ 3143#ifdef INET6 3144 struct sockaddr_in6 *dst6; 3145 struct route_in6 ro6; 3146#endif /* INET6 */ 3147 struct rtentry *rt = NULL; 3148 int hlen = 0; /* make the compiler happy */ 3149 u_int16_t mss = V_tcp_mssdflt; 3150 3151 switch (af) { 3152#ifdef INET 3153 case AF_INET: 3154 hlen = sizeof(struct ip); 3155 bzero(&ro, sizeof(ro)); 3156 dst = (struct sockaddr_in *)&ro.ro_dst; 3157 dst->sin_family = AF_INET; 3158 dst->sin_len = sizeof(*dst); 3159 dst->sin_addr = addr->v4; 3160#ifdef __FreeBSD__ 3161#ifdef RTF_PRCLONING 3162 rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING)); 3163#else /* !RTF_PRCLONING */ 3164 in_rtalloc_ign(&ro, 0, 0); 3165#endif 3166#else /* ! __FreeBSD__ */ 3167 rtalloc_noclone(&ro, NO_CLONING); 3168#endif 3169 rt = ro.ro_rt; 3170 break; 3171#endif /* INET */ 3172#ifdef INET6 3173 case AF_INET6: 3174 hlen = sizeof(struct ip6_hdr); 3175 bzero(&ro6, sizeof(ro6)); 3176 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst; 3177 dst6->sin6_family = AF_INET6; 3178 dst6->sin6_len = sizeof(*dst6); 3179 dst6->sin6_addr = addr->v6; 3180#ifdef __FreeBSD__ 3181#ifdef RTF_PRCLONING 3182 rtalloc_ign((struct route *)&ro6, 3183 (RTF_CLONING | RTF_PRCLONING)); 3184#else /* !RTF_PRCLONING */ 3185 rtalloc_ign((struct route *)&ro6, 0); 3186#endif 3187#else /* ! __FreeBSD__ */ 3188 rtalloc_noclone((struct route *)&ro6, NO_CLONING); 3189#endif 3190 rt = ro6.ro_rt; 3191 break; 3192#endif /* INET6 */ 3193 } 3194 3195 if (rt && rt->rt_ifp) { 3196 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr); 3197 mss = max(V_tcp_mssdflt, mss); 3198 RTFREE(rt); 3199 } 3200 mss = min(mss, offer); 3201 mss = max(mss, 64); /* sanity - at least max opt space */ 3202 return (mss); 3203} 3204 3205void 3206pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr) 3207{ 3208 struct pf_rule *r = s->rule.ptr; 3209 3210 s->rt_kif = NULL; 3211 if (!r->rt || r->rt == PF_FASTROUTE) 3212 return; 3213 switch (s->af) { 3214#ifdef INET 3215 case AF_INET: 3216 pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, 3217 &s->nat_src_node); 3218 s->rt_kif = r->rpool.cur->kif; 3219 break; 3220#endif /* INET */ 3221#ifdef INET6 3222 case AF_INET6: 3223 pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, 3224 &s->nat_src_node); 3225 s->rt_kif = r->rpool.cur->kif; 3226 break; 3227#endif /* INET6 */ 3228 } 3229} 3230 3231int 3232pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction, 3233 struct pfi_kif *kif, struct mbuf *m, int off, void *h, 3234#ifdef __FreeBSD__ 3235 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3236 struct ifqueue *ifq, struct inpcb *inp) 3237#else 3238 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3239 struct ifqueue *ifq) 3240#endif 3241{ 3242 INIT_VNET_INET(curvnet); 3243 struct pf_rule *nr = NULL; 3244 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3245 struct tcphdr *th = pd->hdr.tcp; 3246 u_int16_t bport, nport = 0; 3247 sa_family_t af = pd->af; 3248 struct pf_rule *r, *a = NULL; 3249 struct pf_ruleset *ruleset = NULL; 3250 struct pf_src_node *nsn = NULL; 3251 u_short reason; 3252 int rewrite = 0; 3253 int tag = -1, rtableid = -1; 3254 u_int16_t mss = V_tcp_mssdflt; 3255 int asd = 0; 3256 int match = 0; 3257 3258 if (pf_check_congestion(ifq)) { 3259 REASON_SET(&reason, PFRES_CONGEST); 3260 return (PF_DROP); 3261 } 3262 3263#ifdef __FreeBSD__ 3264 if (inp != NULL) 3265 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3266 else if (debug_pfugidhack) { 3267 PF_UNLOCK(); 3268 DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n")); 3269 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3270 PF_LOCK(); 3271 } 3272#endif 3273 3274 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3275 3276 if (direction == PF_OUT) { 3277 bport = nport = th->th_sport; 3278 /* check outgoing packet for BINAT/NAT */ 3279 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 3280 saddr, th->th_sport, daddr, th->th_dport, 3281 &pd->naddr, &nport)) != NULL) { 3282 PF_ACPY(&pd->baddr, saddr, af); 3283 pf_change_ap(saddr, &th->th_sport, pd->ip_sum, 3284 &th->th_sum, &pd->naddr, nport, 0, af); 3285 rewrite++; 3286 if (nr->natpass) 3287 r = NULL; 3288 pd->nat_rule = nr; 3289 } 3290 } else { 3291 bport = nport = th->th_dport; 3292 /* check incoming packet for BINAT/RDR */ 3293 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 3294 saddr, th->th_sport, daddr, th->th_dport, 3295 &pd->naddr, &nport)) != NULL) { 3296 PF_ACPY(&pd->baddr, daddr, af); 3297 pf_change_ap(daddr, &th->th_dport, pd->ip_sum, 3298 &th->th_sum, &pd->naddr, nport, 0, af); 3299 rewrite++; 3300 if (nr->natpass) 3301 r = NULL; 3302 pd->nat_rule = nr; 3303 } 3304 } 3305 3306 while (r != NULL) { 3307 r->evaluations++; 3308 if (pfi_kif_match(r->kif, kif) == r->ifnot) 3309 r = r->skip[PF_SKIP_IFP].ptr; 3310 else if (r->direction && r->direction != direction) 3311 r = r->skip[PF_SKIP_DIR].ptr; 3312 else if (r->af && r->af != af) 3313 r = r->skip[PF_SKIP_AF].ptr; 3314 else if (r->proto && r->proto != IPPROTO_TCP) 3315 r = r->skip[PF_SKIP_PROTO].ptr; 3316 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, 3317 r->src.neg, kif)) 3318 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3319 else if (r->src.port_op && !pf_match_port(r->src.port_op, 3320 r->src.port[0], r->src.port[1], th->th_sport)) 3321 r = r->skip[PF_SKIP_SRC_PORT].ptr; 3322 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, 3323 r->dst.neg, NULL)) 3324 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3325 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 3326 r->dst.port[0], r->dst.port[1], th->th_dport)) 3327 r = r->skip[PF_SKIP_DST_PORT].ptr; 3328 else if (r->tos && !(r->tos == pd->tos)) 3329 r = TAILQ_NEXT(r, entries); 3330 else if (r->rule_flag & PFRULE_FRAGMENT) 3331 r = TAILQ_NEXT(r, entries); 3332 else if ((r->flagset & th->th_flags) != r->flags) 3333 r = TAILQ_NEXT(r, entries); 3334 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done = 3335#ifdef __FreeBSD__ 3336 pf_socket_lookup(direction, pd, inp), 1)) && 3337#else 3338 pf_socket_lookup(direction, pd), 1)) && 3339#endif 3340 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 3341 pd->lookup.uid)) 3342 r = TAILQ_NEXT(r, entries); 3343 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done = 3344#ifdef __FreeBSD__ 3345 pf_socket_lookup(direction, pd, inp), 1)) && 3346#else 3347 pf_socket_lookup(direction, pd), 1)) && 3348#endif 3349 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 3350 pd->lookup.gid)) 3351 r = TAILQ_NEXT(r, entries); 3352 else if (r->prob && r->prob <= arc4random()) 3353 r = TAILQ_NEXT(r, entries); 3354 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 3355 r = TAILQ_NEXT(r, entries); 3356 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match( 3357 pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint)) 3358 r = TAILQ_NEXT(r, entries); 3359 else { 3360 if (r->tag) 3361 tag = r->tag; 3362 if (r->rtableid >= 0) 3363 rtableid = r->rtableid; 3364 if (r->anchor == NULL) { 3365 match = 1; 3366 *rm = r; 3367 *am = a; 3368 *rsm = ruleset; 3369 if ((*rm)->quick) 3370 break; 3371 r = TAILQ_NEXT(r, entries); 3372 } else 3373 pf_step_into_anchor(&asd, &ruleset, 3374 PF_RULESET_FILTER, &r, &a, &match); 3375 } 3376 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 3377 PF_RULESET_FILTER, &r, &a, &match)) 3378 break; 3379 } 3380 r = *rm; 3381 a = *am; 3382 ruleset = *rsm; 3383 3384 REASON_SET(&reason, PFRES_MATCH); 3385 3386 if (r->log || (nr != NULL && nr->natpass && nr->log)) { 3387 if (rewrite) 3388#ifdef __FreeBSD__ 3389 m_copyback(m, off, sizeof(*th), (caddr_t)th); 3390#else 3391 m_copyback(m, off, sizeof(*th), th); 3392#endif 3393 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 3394 a, ruleset, pd); 3395 } 3396 3397 if ((r->action == PF_DROP) && 3398 ((r->rule_flag & PFRULE_RETURNRST) || 3399 (r->rule_flag & PFRULE_RETURNICMP) || 3400 (r->rule_flag & PFRULE_RETURN))) { 3401 /* undo NAT changes, if they have taken place */ 3402 if (nr != NULL) { 3403 if (direction == PF_OUT) { 3404 pf_change_ap(saddr, &th->th_sport, pd->ip_sum, 3405 &th->th_sum, &pd->baddr, bport, 0, af); 3406 rewrite++; 3407 } else { 3408 pf_change_ap(daddr, &th->th_dport, pd->ip_sum, 3409 &th->th_sum, &pd->baddr, bport, 0, af); 3410 rewrite++; 3411 } 3412 } 3413 if (((r->rule_flag & PFRULE_RETURNRST) || 3414 (r->rule_flag & PFRULE_RETURN)) && 3415 !(th->th_flags & TH_RST)) { 3416 u_int32_t ack = ntohl(th->th_seq) + pd->p_len; 3417 3418 if (th->th_flags & TH_SYN) 3419 ack++; 3420 if (th->th_flags & TH_FIN) 3421 ack++; 3422#ifdef __FreeBSD__ 3423 pf_send_tcp(m, r, af, pd->dst, 3424#else 3425 pf_send_tcp(r, af, pd->dst, 3426#endif 3427 pd->src, th->th_dport, th->th_sport, 3428 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0, 3429 r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp); 3430 } else if ((af == AF_INET) && r->return_icmp) 3431 pf_send_icmp(m, r->return_icmp >> 8, 3432 r->return_icmp & 255, af, r); 3433 else if ((af == AF_INET6) && r->return_icmp6) 3434 pf_send_icmp(m, r->return_icmp6 >> 8, 3435 r->return_icmp6 & 255, af, r); 3436 } 3437 3438 if (r->action == PF_DROP) 3439 return (PF_DROP); 3440 3441 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) { 3442 REASON_SET(&reason, PFRES_MEMORY); 3443 return (PF_DROP); 3444 } 3445 3446 if (r->keep_state || nr != NULL || 3447 (pd->flags & PFDESC_TCP_NORM)) { 3448 /* create new state */ 3449 u_int16_t len; 3450 struct pf_state *s = NULL; 3451 struct pf_src_node *sn = NULL; 3452 3453 len = pd->tot_len - off - (th->th_off << 2); 3454 3455 /* check maximums */ 3456 if (r->max_states && (r->states >= r->max_states)) { 3457 pf_status.lcounters[LCNT_STATES]++; 3458 REASON_SET(&reason, PFRES_MAXSTATES); 3459 goto cleanup; 3460 } 3461 /* src node for filter rule */ 3462 if ((r->rule_flag & PFRULE_SRCTRACK || 3463 r->rpool.opts & PF_POOL_STICKYADDR) && 3464 pf_insert_src_node(&sn, r, saddr, af) != 0) { 3465 REASON_SET(&reason, PFRES_SRCLIMIT); 3466 goto cleanup; 3467 } 3468 /* src node for translation rule */ 3469 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 3470 ((direction == PF_OUT && 3471 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 3472 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) { 3473 REASON_SET(&reason, PFRES_SRCLIMIT); 3474 goto cleanup; 3475 } 3476 s = pool_get(&pf_state_pl, PR_NOWAIT); 3477 if (s == NULL) { 3478 REASON_SET(&reason, PFRES_MEMORY); 3479cleanup: 3480 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 3481 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 3482 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3483 pf_status.src_nodes--; 3484 pool_put(&pf_src_tree_pl, sn); 3485 } 3486 if (nsn != sn && nsn != NULL && nsn->states == 0 && 3487 nsn->expire == 0) { 3488 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 3489 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3490 pf_status.src_nodes--; 3491 pool_put(&pf_src_tree_pl, nsn); 3492 } 3493 return (PF_DROP); 3494 } 3495 bzero(s, sizeof(*s)); 3496 s->rule.ptr = r; 3497 s->nat_rule.ptr = nr; 3498 s->anchor.ptr = a; 3499 STATE_INC_COUNTERS(s); 3500 s->allow_opts = r->allow_opts; 3501 s->log = r->log & PF_LOG_ALL; 3502 if (nr != NULL) 3503 s->log |= nr->log & PF_LOG_ALL; 3504 s->proto = IPPROTO_TCP; 3505 s->direction = direction; 3506 s->af = af; 3507 if (direction == PF_OUT) { 3508 PF_ACPY(&s->gwy.addr, saddr, af); 3509 s->gwy.port = th->th_sport; /* sport */ 3510 PF_ACPY(&s->ext.addr, daddr, af); 3511 s->ext.port = th->th_dport; 3512 if (nr != NULL) { 3513 PF_ACPY(&s->lan.addr, &pd->baddr, af); 3514 s->lan.port = bport; 3515 } else { 3516 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 3517 s->lan.port = s->gwy.port; 3518 } 3519 } else { 3520 PF_ACPY(&s->lan.addr, daddr, af); 3521 s->lan.port = th->th_dport; 3522 PF_ACPY(&s->ext.addr, saddr, af); 3523 s->ext.port = th->th_sport; 3524 if (nr != NULL) { 3525 PF_ACPY(&s->gwy.addr, &pd->baddr, af); 3526 s->gwy.port = bport; 3527 } else { 3528 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3529 s->gwy.port = s->lan.port; 3530 } 3531 } 3532 3533 s->src.seqlo = ntohl(th->th_seq); 3534 s->src.seqhi = s->src.seqlo + len + 1; 3535 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 3536 r->keep_state == PF_STATE_MODULATE) { 3537 /* Generate sequence number modulator */ 3538#ifdef __FreeBSD__ 3539 while ((s->src.seqdiff = 3540 pf_new_isn(s) - s->src.seqlo) == 0) 3541 ; 3542#else 3543 while ((s->src.seqdiff = 3544 tcp_rndiss_next() - s->src.seqlo) == 0) 3545 ; 3546#endif 3547 pf_change_a(&th->th_seq, &th->th_sum, 3548 htonl(s->src.seqlo + s->src.seqdiff), 0); 3549 rewrite = 1; 3550 } else 3551 s->src.seqdiff = 0; 3552 if (th->th_flags & TH_SYN) { 3553 s->src.seqhi++; 3554 s->src.wscale = pf_get_wscale(m, off, th->th_off, af); 3555 } 3556 s->src.max_win = MAX(ntohs(th->th_win), 1); 3557 if (s->src.wscale & PF_WSCALE_MASK) { 3558 /* Remove scale factor from initial window */ 3559 int win = s->src.max_win; 3560 win += 1 << (s->src.wscale & PF_WSCALE_MASK); 3561 s->src.max_win = (win - 1) >> 3562 (s->src.wscale & PF_WSCALE_MASK); 3563 } 3564 if (th->th_flags & TH_FIN) 3565 s->src.seqhi++; 3566 s->dst.seqhi = 1; 3567 s->dst.max_win = 1; 3568 s->src.state = TCPS_SYN_SENT; 3569 s->dst.state = TCPS_CLOSED; 3570 s->creation = time_second; 3571 s->expire = time_second; 3572 s->timeout = PFTM_TCP_FIRST_PACKET; 3573 pf_set_rt_ifp(s, saddr); 3574 if (sn != NULL) { 3575 s->src_node = sn; 3576 s->src_node->states++; 3577 } 3578 if (nsn != NULL) { 3579 PF_ACPY(&nsn->raddr, &pd->naddr, af); 3580 s->nat_src_node = nsn; 3581 s->nat_src_node->states++; 3582 } 3583 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m, 3584 off, pd, th, &s->src, &s->dst)) { 3585 REASON_SET(&reason, PFRES_MEMORY); 3586 pf_src_tree_remove_state(s); 3587 STATE_DEC_COUNTERS(s); 3588 pool_put(&pf_state_pl, s); 3589 return (PF_DROP); 3590 } 3591 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub && 3592 pf_normalize_tcp_stateful(m, off, pd, &reason, th, s, 3593 &s->src, &s->dst, &rewrite)) { 3594 /* This really shouldn't happen!!! */ 3595 DPFPRINTF(PF_DEBUG_URGENT, 3596 ("pf_normalize_tcp_stateful failed on first pkt")); 3597 pf_normalize_tcp_cleanup(s); 3598 pf_src_tree_remove_state(s); 3599 STATE_DEC_COUNTERS(s); 3600 pool_put(&pf_state_pl, s); 3601 return (PF_DROP); 3602 } 3603 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { 3604 pf_normalize_tcp_cleanup(s); 3605 REASON_SET(&reason, PFRES_STATEINS); 3606 pf_src_tree_remove_state(s); 3607 STATE_DEC_COUNTERS(s); 3608 pool_put(&pf_state_pl, s); 3609 return (PF_DROP); 3610 } else 3611 *sm = s; 3612 if (tag > 0) { 3613 pf_tag_ref(tag); 3614 s->tag = tag; 3615 } 3616 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 3617 r->keep_state == PF_STATE_SYNPROXY) { 3618 s->src.state = PF_TCPS_PROXY_SRC; 3619 if (nr != NULL) { 3620 if (direction == PF_OUT) { 3621 pf_change_ap(saddr, &th->th_sport, 3622 pd->ip_sum, &th->th_sum, &pd->baddr, 3623 bport, 0, af); 3624 } else { 3625 pf_change_ap(daddr, &th->th_dport, 3626 pd->ip_sum, &th->th_sum, &pd->baddr, 3627 bport, 0, af); 3628 } 3629 } 3630 s->src.seqhi = htonl(arc4random()); 3631 /* Find mss option */ 3632 mss = pf_get_mss(m, off, th->th_off, af); 3633 mss = pf_calc_mss(saddr, af, mss); 3634 mss = pf_calc_mss(daddr, af, mss); 3635 s->src.mss = mss; 3636#ifdef __FreeBSD__ 3637 pf_send_tcp(NULL, r, af, daddr, saddr, th->th_dport, 3638#else 3639 pf_send_tcp(r, af, daddr, saddr, th->th_dport, 3640#endif 3641 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1, 3642 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL); 3643 REASON_SET(&reason, PFRES_SYNPROXY); 3644 return (PF_SYNPROXY_DROP); 3645 } 3646 } 3647 3648 /* copy back packet headers if we performed NAT operations */ 3649 if (rewrite) 3650 m_copyback(m, off, sizeof(*th), (caddr_t)th); 3651 3652 return (PF_PASS); 3653} 3654 3655int 3656pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction, 3657 struct pfi_kif *kif, struct mbuf *m, int off, void *h, 3658#ifdef __FreeBSD__ 3659 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3660 struct ifqueue *ifq, struct inpcb *inp) 3661#else 3662 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3663 struct ifqueue *ifq) 3664#endif 3665{ 3666 struct pf_rule *nr = NULL; 3667 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3668 struct udphdr *uh = pd->hdr.udp; 3669 u_int16_t bport, nport = 0; 3670 sa_family_t af = pd->af; 3671 struct pf_rule *r, *a = NULL; 3672 struct pf_ruleset *ruleset = NULL; 3673 struct pf_src_node *nsn = NULL; 3674 u_short reason; 3675 int rewrite = 0; 3676 int tag = -1, rtableid = -1; 3677 int asd = 0; 3678 int match = 0; 3679 3680 if (pf_check_congestion(ifq)) { 3681 REASON_SET(&reason, PFRES_CONGEST); 3682 return (PF_DROP); 3683 } 3684 3685#ifdef __FreeBSD__ 3686 if (inp != NULL) 3687 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3688 else if (debug_pfugidhack) { 3689 PF_UNLOCK(); 3690 DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n")); 3691 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3692 PF_LOCK(); 3693 } 3694#endif 3695 3696 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3697 3698 if (direction == PF_OUT) { 3699 bport = nport = uh->uh_sport; 3700 /* check outgoing packet for BINAT/NAT */ 3701 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 3702 saddr, uh->uh_sport, daddr, uh->uh_dport, 3703 &pd->naddr, &nport)) != NULL) { 3704 PF_ACPY(&pd->baddr, saddr, af); 3705 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, 3706 &uh->uh_sum, &pd->naddr, nport, 1, af); 3707 rewrite++; 3708 if (nr->natpass) 3709 r = NULL; 3710 pd->nat_rule = nr; 3711 } 3712 } else { 3713 bport = nport = uh->uh_dport; 3714 /* check incoming packet for BINAT/RDR */ 3715 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 3716 saddr, uh->uh_sport, daddr, uh->uh_dport, &pd->naddr, 3717 &nport)) != NULL) { 3718 PF_ACPY(&pd->baddr, daddr, af); 3719 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, 3720 &uh->uh_sum, &pd->naddr, nport, 1, af); 3721 rewrite++; 3722 if (nr->natpass) 3723 r = NULL; 3724 pd->nat_rule = nr; 3725 } 3726 } 3727 3728 while (r != NULL) { 3729 r->evaluations++; 3730 if (pfi_kif_match(r->kif, kif) == r->ifnot) 3731 r = r->skip[PF_SKIP_IFP].ptr; 3732 else if (r->direction && r->direction != direction) 3733 r = r->skip[PF_SKIP_DIR].ptr; 3734 else if (r->af && r->af != af) 3735 r = r->skip[PF_SKIP_AF].ptr; 3736 else if (r->proto && r->proto != IPPROTO_UDP) 3737 r = r->skip[PF_SKIP_PROTO].ptr; 3738 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, 3739 r->src.neg, kif)) 3740 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3741 else if (r->src.port_op && !pf_match_port(r->src.port_op, 3742 r->src.port[0], r->src.port[1], uh->uh_sport)) 3743 r = r->skip[PF_SKIP_SRC_PORT].ptr; 3744 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, 3745 r->dst.neg, NULL)) 3746 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3747 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 3748 r->dst.port[0], r->dst.port[1], uh->uh_dport)) 3749 r = r->skip[PF_SKIP_DST_PORT].ptr; 3750 else if (r->tos && !(r->tos == pd->tos)) 3751 r = TAILQ_NEXT(r, entries); 3752 else if (r->rule_flag & PFRULE_FRAGMENT) 3753 r = TAILQ_NEXT(r, entries); 3754 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done = 3755#ifdef __FreeBSD__ 3756 pf_socket_lookup(direction, pd, inp), 1)) && 3757#else 3758 pf_socket_lookup(direction, pd), 1)) && 3759#endif 3760 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 3761 pd->lookup.uid)) 3762 r = TAILQ_NEXT(r, entries); 3763 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done = 3764#ifdef __FreeBSD__ 3765 pf_socket_lookup(direction, pd, inp), 1)) && 3766#else 3767 pf_socket_lookup(direction, pd), 1)) && 3768#endif 3769 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 3770 pd->lookup.gid)) 3771 r = TAILQ_NEXT(r, entries); 3772 else if (r->prob && r->prob <= arc4random()) 3773 r = TAILQ_NEXT(r, entries); 3774 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 3775 r = TAILQ_NEXT(r, entries); 3776 else if (r->os_fingerprint != PF_OSFP_ANY) 3777 r = TAILQ_NEXT(r, entries); 3778 else { 3779 if (r->tag) 3780 tag = r->tag; 3781 if (r->rtableid >= 0) 3782 rtableid = r->rtableid; 3783 if (r->anchor == NULL) { 3784 match = 1; 3785 *rm = r; 3786 *am = a; 3787 *rsm = ruleset; 3788 if ((*rm)->quick) 3789 break; 3790 r = TAILQ_NEXT(r, entries); 3791 } else 3792 pf_step_into_anchor(&asd, &ruleset, 3793 PF_RULESET_FILTER, &r, &a, &match); 3794 } 3795 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 3796 PF_RULESET_FILTER, &r, &a, &match)) 3797 break; 3798 } 3799 r = *rm; 3800 a = *am; 3801 ruleset = *rsm; 3802 3803 REASON_SET(&reason, PFRES_MATCH); 3804 3805 if (r->log || (nr != NULL && nr->natpass && nr->log)) { 3806 if (rewrite) 3807#ifdef __FreeBSD__ 3808 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 3809#else 3810 m_copyback(m, off, sizeof(*uh), uh); 3811#endif 3812 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 3813 a, ruleset, pd); 3814 } 3815 3816 if ((r->action == PF_DROP) && 3817 ((r->rule_flag & PFRULE_RETURNICMP) || 3818 (r->rule_flag & PFRULE_RETURN))) { 3819 /* undo NAT changes, if they have taken place */ 3820 if (nr != NULL) { 3821 if (direction == PF_OUT) { 3822 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, 3823 &uh->uh_sum, &pd->baddr, bport, 1, af); 3824 rewrite++; 3825 } else { 3826 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, 3827 &uh->uh_sum, &pd->baddr, bport, 1, af); 3828 rewrite++; 3829 } 3830 } 3831 if ((af == AF_INET) && r->return_icmp) 3832 pf_send_icmp(m, r->return_icmp >> 8, 3833 r->return_icmp & 255, af, r); 3834 else if ((af == AF_INET6) && r->return_icmp6) 3835 pf_send_icmp(m, r->return_icmp6 >> 8, 3836 r->return_icmp6 & 255, af, r); 3837 } 3838 3839 if (r->action == PF_DROP) 3840 return (PF_DROP); 3841 3842 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) { 3843 REASON_SET(&reason, PFRES_MEMORY); 3844 return (PF_DROP); 3845 } 3846 3847 if (r->keep_state || nr != NULL) { 3848 /* create new state */ 3849 struct pf_state *s = NULL; 3850 struct pf_src_node *sn = NULL; 3851 3852 /* check maximums */ 3853 if (r->max_states && (r->states >= r->max_states)) { 3854 pf_status.lcounters[LCNT_STATES]++; 3855 REASON_SET(&reason, PFRES_MAXSTATES); 3856 goto cleanup; 3857 } 3858 /* src node for filter rule */ 3859 if ((r->rule_flag & PFRULE_SRCTRACK || 3860 r->rpool.opts & PF_POOL_STICKYADDR) && 3861 pf_insert_src_node(&sn, r, saddr, af) != 0) { 3862 REASON_SET(&reason, PFRES_SRCLIMIT); 3863 goto cleanup; 3864 } 3865 /* src node for translation rule */ 3866 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 3867 ((direction == PF_OUT && 3868 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 3869 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) { 3870 REASON_SET(&reason, PFRES_SRCLIMIT); 3871 goto cleanup; 3872 } 3873 s = pool_get(&pf_state_pl, PR_NOWAIT); 3874 if (s == NULL) { 3875 REASON_SET(&reason, PFRES_MEMORY); 3876cleanup: 3877 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 3878 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 3879 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3880 pf_status.src_nodes--; 3881 pool_put(&pf_src_tree_pl, sn); 3882 } 3883 if (nsn != sn && nsn != NULL && nsn->states == 0 && 3884 nsn->expire == 0) { 3885 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 3886 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3887 pf_status.src_nodes--; 3888 pool_put(&pf_src_tree_pl, nsn); 3889 } 3890 return (PF_DROP); 3891 } 3892 bzero(s, sizeof(*s)); 3893 s->rule.ptr = r; 3894 s->nat_rule.ptr = nr; 3895 s->anchor.ptr = a; 3896 STATE_INC_COUNTERS(s); 3897 s->allow_opts = r->allow_opts; 3898 s->log = r->log & PF_LOG_ALL; 3899 if (nr != NULL) 3900 s->log |= nr->log & PF_LOG_ALL; 3901 s->proto = IPPROTO_UDP; 3902 s->direction = direction; 3903 s->af = af; 3904 if (direction == PF_OUT) { 3905 PF_ACPY(&s->gwy.addr, saddr, af); 3906 s->gwy.port = uh->uh_sport; 3907 PF_ACPY(&s->ext.addr, daddr, af); 3908 s->ext.port = uh->uh_dport; 3909 if (nr != NULL) { 3910 PF_ACPY(&s->lan.addr, &pd->baddr, af); 3911 s->lan.port = bport; 3912 } else { 3913 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 3914 s->lan.port = s->gwy.port; 3915 } 3916 } else { 3917 PF_ACPY(&s->lan.addr, daddr, af); 3918 s->lan.port = uh->uh_dport; 3919 PF_ACPY(&s->ext.addr, saddr, af); 3920 s->ext.port = uh->uh_sport; 3921 if (nr != NULL) { 3922 PF_ACPY(&s->gwy.addr, &pd->baddr, af); 3923 s->gwy.port = bport; 3924 } else { 3925 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3926 s->gwy.port = s->lan.port; 3927 } 3928 } 3929 s->src.state = PFUDPS_SINGLE; 3930 s->dst.state = PFUDPS_NO_TRAFFIC; 3931 s->creation = time_second; 3932 s->expire = time_second; 3933 s->timeout = PFTM_UDP_FIRST_PACKET; 3934 pf_set_rt_ifp(s, saddr); 3935 if (sn != NULL) { 3936 s->src_node = sn; 3937 s->src_node->states++; 3938 } 3939 if (nsn != NULL) { 3940 PF_ACPY(&nsn->raddr, &pd->naddr, af); 3941 s->nat_src_node = nsn; 3942 s->nat_src_node->states++; 3943 } 3944 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { 3945 REASON_SET(&reason, PFRES_STATEINS); 3946 pf_src_tree_remove_state(s); 3947 STATE_DEC_COUNTERS(s); 3948 pool_put(&pf_state_pl, s); 3949 return (PF_DROP); 3950 } else 3951 *sm = s; 3952 if (tag > 0) { 3953 pf_tag_ref(tag); 3954 s->tag = tag; 3955 } 3956 } 3957 3958 /* copy back packet headers if we performed NAT operations */ 3959 if (rewrite) 3960 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 3961 3962 return (PF_PASS); 3963} 3964 3965int 3966pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction, 3967 struct pfi_kif *kif, struct mbuf *m, int off, void *h, 3968 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3969 struct ifqueue *ifq) 3970{ 3971 struct pf_rule *nr = NULL; 3972 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3973 struct pf_rule *r, *a = NULL; 3974 struct pf_ruleset *ruleset = NULL; 3975 struct pf_src_node *nsn = NULL; 3976 u_short reason; 3977 u_int16_t icmpid = 0, bport, nport = 0; 3978 sa_family_t af = pd->af; 3979 u_int8_t icmptype = 0; /* make the compiler happy */ 3980 u_int8_t icmpcode = 0; /* make the compiler happy */ 3981 int state_icmp = 0; 3982 int tag = -1, rtableid = -1; 3983#ifdef INET6 3984 int rewrite = 0; 3985#endif /* INET6 */ 3986 int asd = 0; 3987 int match = 0; 3988 3989 if (pf_check_congestion(ifq)) { 3990 REASON_SET(&reason, PFRES_CONGEST); 3991 return (PF_DROP); 3992 } 3993 3994 switch (pd->proto) { 3995#ifdef INET 3996 case IPPROTO_ICMP: 3997 icmptype = pd->hdr.icmp->icmp_type; 3998 icmpcode = pd->hdr.icmp->icmp_code; 3999 icmpid = pd->hdr.icmp->icmp_id; 4000 4001 if (icmptype == ICMP_UNREACH || 4002 icmptype == ICMP_SOURCEQUENCH || 4003 icmptype == ICMP_REDIRECT || 4004 icmptype == ICMP_TIMXCEED || 4005 icmptype == ICMP_PARAMPROB) 4006 state_icmp++; 4007 break; 4008#endif /* INET */ 4009#ifdef INET6 4010 case IPPROTO_ICMPV6: 4011 icmptype = pd->hdr.icmp6->icmp6_type; 4012 icmpcode = pd->hdr.icmp6->icmp6_code; 4013 icmpid = pd->hdr.icmp6->icmp6_id; 4014 4015 if (icmptype == ICMP6_DST_UNREACH || 4016 icmptype == ICMP6_PACKET_TOO_BIG || 4017 icmptype == ICMP6_TIME_EXCEEDED || 4018 icmptype == ICMP6_PARAM_PROB) 4019 state_icmp++; 4020 break; 4021#endif /* INET6 */ 4022 } 4023 4024 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 4025 4026 if (direction == PF_OUT) { 4027 bport = nport = icmpid; 4028 /* check outgoing packet for BINAT/NAT */ 4029 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 4030 saddr, icmpid, daddr, icmpid, &pd->naddr, &nport)) != 4031 NULL) { 4032 PF_ACPY(&pd->baddr, saddr, af); 4033 switch (af) { 4034#ifdef INET 4035 case AF_INET: 4036 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, 4037 pd->naddr.v4.s_addr, 0); 4038 pd->hdr.icmp->icmp_cksum = pf_cksum_fixup( 4039 pd->hdr.icmp->icmp_cksum, icmpid, nport, 0); 4040 pd->hdr.icmp->icmp_id = nport; 4041 m_copyback(m, off, ICMP_MINLEN, 4042 (caddr_t)pd->hdr.icmp); 4043 break; 4044#endif /* INET */ 4045#ifdef INET6 4046 case AF_INET6: 4047 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum, 4048 &pd->naddr, 0); 4049 rewrite++; 4050 break; 4051#endif /* INET6 */ 4052 } 4053 if (nr->natpass) 4054 r = NULL; 4055 pd->nat_rule = nr; 4056 } 4057 } else { 4058 bport = nport = icmpid; 4059 /* check incoming packet for BINAT/RDR */ 4060 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 4061 saddr, icmpid, daddr, icmpid, &pd->naddr, &nport)) != 4062 NULL) { 4063 PF_ACPY(&pd->baddr, daddr, af); 4064 switch (af) { 4065#ifdef INET 4066 case AF_INET: 4067 pf_change_a(&daddr->v4.s_addr, 4068 pd->ip_sum, pd->naddr.v4.s_addr, 0); 4069 break; 4070#endif /* INET */ 4071#ifdef INET6 4072 case AF_INET6: 4073 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, 4074 &pd->naddr, 0); 4075 rewrite++; 4076 break; 4077#endif /* INET6 */ 4078 } 4079 if (nr->natpass) 4080 r = NULL; 4081 pd->nat_rule = nr; 4082 } 4083 } 4084 4085 while (r != NULL) { 4086 r->evaluations++; 4087 if (pfi_kif_match(r->kif, kif) == r->ifnot) 4088 r = r->skip[PF_SKIP_IFP].ptr; 4089 else if (r->direction && r->direction != direction) 4090 r = r->skip[PF_SKIP_DIR].ptr; 4091 else if (r->af && r->af != af) 4092 r = r->skip[PF_SKIP_AF].ptr; 4093 else if (r->proto && r->proto != pd->proto) 4094 r = r->skip[PF_SKIP_PROTO].ptr; 4095 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, 4096 r->src.neg, kif)) 4097 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 4098 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, 4099 r->dst.neg, NULL)) 4100 r = r->skip[PF_SKIP_DST_ADDR].ptr; 4101 else if (r->type && r->type != icmptype + 1) 4102 r = TAILQ_NEXT(r, entries); 4103 else if (r->code && r->code != icmpcode + 1) 4104 r = TAILQ_NEXT(r, entries); 4105 else if (r->tos && !(r->tos == pd->tos)) 4106 r = TAILQ_NEXT(r, entries); 4107 else if (r->rule_flag & PFRULE_FRAGMENT) 4108 r = TAILQ_NEXT(r, entries); 4109 else if (r->prob && r->prob <= arc4random()) 4110 r = TAILQ_NEXT(r, entries); 4111 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 4112 r = TAILQ_NEXT(r, entries); 4113 else if (r->os_fingerprint != PF_OSFP_ANY) 4114 r = TAILQ_NEXT(r, entries); 4115 else { 4116 if (r->tag) 4117 tag = r->tag; 4118 if (r->rtableid >= 0) 4119 rtableid = r->rtableid; 4120 if (r->anchor == NULL) { 4121 match = 1; 4122 *rm = r; 4123 *am = a; 4124 *rsm = ruleset; 4125 if ((*rm)->quick) 4126 break; 4127 r = TAILQ_NEXT(r, entries); 4128 } else 4129 pf_step_into_anchor(&asd, &ruleset, 4130 PF_RULESET_FILTER, &r, &a, &match); 4131 } 4132 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 4133 PF_RULESET_FILTER, &r, &a, &match)) 4134 break; 4135 } 4136 r = *rm; 4137 a = *am; 4138 ruleset = *rsm; 4139 4140 REASON_SET(&reason, PFRES_MATCH); 4141 4142 if (r->log || (nr != NULL && nr->natpass && nr->log)) { 4143#ifdef INET6 4144 if (rewrite) 4145 m_copyback(m, off, sizeof(struct icmp6_hdr), 4146 (caddr_t)pd->hdr.icmp6); 4147#endif /* INET6 */ 4148 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 4149 a, ruleset, pd); 4150 } 4151 4152 if (r->action != PF_PASS) 4153 return (PF_DROP); 4154 4155 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) { 4156 REASON_SET(&reason, PFRES_MEMORY); 4157 return (PF_DROP); 4158 } 4159 4160 if (!state_icmp && (r->keep_state || nr != NULL)) { 4161 /* create new state */ 4162 struct pf_state *s = NULL; 4163 struct pf_src_node *sn = NULL; 4164 4165 /* check maximums */ 4166 if (r->max_states && (r->states >= r->max_states)) { 4167 pf_status.lcounters[LCNT_STATES]++; 4168 REASON_SET(&reason, PFRES_MAXSTATES); 4169 goto cleanup; 4170 } 4171 /* src node for filter rule */ 4172 if ((r->rule_flag & PFRULE_SRCTRACK || 4173 r->rpool.opts & PF_POOL_STICKYADDR) && 4174 pf_insert_src_node(&sn, r, saddr, af) != 0) { 4175 REASON_SET(&reason, PFRES_SRCLIMIT); 4176 goto cleanup; 4177 } 4178 /* src node for translation rule */ 4179 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 4180 ((direction == PF_OUT && 4181 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 4182 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) { 4183 REASON_SET(&reason, PFRES_SRCLIMIT); 4184 goto cleanup; 4185 } 4186 s = pool_get(&pf_state_pl, PR_NOWAIT); 4187 if (s == NULL) { 4188 REASON_SET(&reason, PFRES_MEMORY); 4189cleanup: 4190 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 4191 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 4192 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4193 pf_status.src_nodes--; 4194 pool_put(&pf_src_tree_pl, sn); 4195 } 4196 if (nsn != sn && nsn != NULL && nsn->states == 0 && 4197 nsn->expire == 0) { 4198 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 4199 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4200 pf_status.src_nodes--; 4201 pool_put(&pf_src_tree_pl, nsn); 4202 } 4203 return (PF_DROP); 4204 } 4205 bzero(s, sizeof(*s)); 4206 s->rule.ptr = r; 4207 s->nat_rule.ptr = nr; 4208 s->anchor.ptr = a; 4209 STATE_INC_COUNTERS(s); 4210 s->allow_opts = r->allow_opts; 4211 s->log = r->log & PF_LOG_ALL; 4212 if (nr != NULL) 4213 s->log |= nr->log & PF_LOG_ALL; 4214 s->proto = pd->proto; 4215 s->direction = direction; 4216 s->af = af; 4217 if (direction == PF_OUT) { 4218 PF_ACPY(&s->gwy.addr, saddr, af); 4219 s->gwy.port = nport; 4220 PF_ACPY(&s->ext.addr, daddr, af); 4221 s->ext.port = 0; 4222 if (nr != NULL) { 4223 PF_ACPY(&s->lan.addr, &pd->baddr, af); 4224 s->lan.port = bport; 4225 } else { 4226 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 4227 s->lan.port = s->gwy.port; 4228 } 4229 } else { 4230 PF_ACPY(&s->lan.addr, daddr, af); 4231 s->lan.port = nport; 4232 PF_ACPY(&s->ext.addr, saddr, af); 4233 s->ext.port = 0; 4234 if (nr != NULL) { 4235 PF_ACPY(&s->gwy.addr, &pd->baddr, af); 4236 s->gwy.port = bport; 4237 } else { 4238 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 4239 s->gwy.port = s->lan.port; 4240 } 4241 } 4242 s->creation = time_second; 4243 s->expire = time_second; 4244 s->timeout = PFTM_ICMP_FIRST_PACKET; 4245 pf_set_rt_ifp(s, saddr); 4246 if (sn != NULL) { 4247 s->src_node = sn; 4248 s->src_node->states++; 4249 } 4250 if (nsn != NULL) { 4251 PF_ACPY(&nsn->raddr, &pd->naddr, af); 4252 s->nat_src_node = nsn; 4253 s->nat_src_node->states++; 4254 } 4255 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { 4256 REASON_SET(&reason, PFRES_STATEINS); 4257 pf_src_tree_remove_state(s); 4258 STATE_DEC_COUNTERS(s); 4259 pool_put(&pf_state_pl, s); 4260 return (PF_DROP); 4261 } else 4262 *sm = s; 4263 if (tag > 0) { 4264 pf_tag_ref(tag); 4265 s->tag = tag; 4266 } 4267 } 4268 4269#ifdef INET6 4270 /* copy back packet headers if we performed IPv6 NAT operations */ 4271 if (rewrite) 4272 m_copyback(m, off, sizeof(struct icmp6_hdr), 4273 (caddr_t)pd->hdr.icmp6); 4274#endif /* INET6 */ 4275 4276 return (PF_PASS); 4277} 4278 4279int 4280pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction, 4281 struct pfi_kif *kif, struct mbuf *m, int off, void *h, struct pf_pdesc *pd, 4282 struct pf_rule **am, struct pf_ruleset **rsm, struct ifqueue *ifq) 4283{ 4284 struct pf_rule *nr = NULL; 4285 struct pf_rule *r, *a = NULL; 4286 struct pf_ruleset *ruleset = NULL; 4287 struct pf_src_node *nsn = NULL; 4288 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 4289 sa_family_t af = pd->af; 4290 u_short reason; 4291 int tag = -1, rtableid = -1; 4292 int asd = 0; 4293 int match = 0; 4294 4295 if (pf_check_congestion(ifq)) { 4296 REASON_SET(&reason, PFRES_CONGEST); 4297 return (PF_DROP); 4298 } 4299 4300 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 4301 4302 if (direction == PF_OUT) { 4303 /* check outgoing packet for BINAT/NAT */ 4304 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 4305 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { 4306 PF_ACPY(&pd->baddr, saddr, af); 4307 switch (af) { 4308#ifdef INET 4309 case AF_INET: 4310 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, 4311 pd->naddr.v4.s_addr, 0); 4312 break; 4313#endif /* INET */ 4314#ifdef INET6 4315 case AF_INET6: 4316 PF_ACPY(saddr, &pd->naddr, af); 4317 break; 4318#endif /* INET6 */ 4319 } 4320 if (nr->natpass) 4321 r = NULL; 4322 pd->nat_rule = nr; 4323 } 4324 } else { 4325 /* check incoming packet for BINAT/RDR */ 4326 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 4327 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { 4328 PF_ACPY(&pd->baddr, daddr, af); 4329 switch (af) { 4330#ifdef INET 4331 case AF_INET: 4332 pf_change_a(&daddr->v4.s_addr, 4333 pd->ip_sum, pd->naddr.v4.s_addr, 0); 4334 break; 4335#endif /* INET */ 4336#ifdef INET6 4337 case AF_INET6: 4338 PF_ACPY(daddr, &pd->naddr, af); 4339 break; 4340#endif /* INET6 */ 4341 } 4342 if (nr->natpass) 4343 r = NULL; 4344 pd->nat_rule = nr; 4345 } 4346 } 4347 4348 while (r != NULL) { 4349 r->evaluations++; 4350 if (pfi_kif_match(r->kif, kif) == r->ifnot) 4351 r = r->skip[PF_SKIP_IFP].ptr; 4352 else if (r->direction && r->direction != direction) 4353 r = r->skip[PF_SKIP_DIR].ptr; 4354 else if (r->af && r->af != af) 4355 r = r->skip[PF_SKIP_AF].ptr; 4356 else if (r->proto && r->proto != pd->proto) 4357 r = r->skip[PF_SKIP_PROTO].ptr; 4358 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, 4359 r->src.neg, kif)) 4360 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 4361 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, 4362 r->dst.neg, NULL)) 4363 r = r->skip[PF_SKIP_DST_ADDR].ptr; 4364 else if (r->tos && !(r->tos == pd->tos)) 4365 r = TAILQ_NEXT(r, entries); 4366 else if (r->rule_flag & PFRULE_FRAGMENT) 4367 r = TAILQ_NEXT(r, entries); 4368 else if (r->prob && r->prob <= arc4random()) 4369 r = TAILQ_NEXT(r, entries); 4370 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 4371 r = TAILQ_NEXT(r, entries); 4372 else if (r->os_fingerprint != PF_OSFP_ANY) 4373 r = TAILQ_NEXT(r, entries); 4374 else { 4375 if (r->tag) 4376 tag = r->tag; 4377 if (r->rtableid >= 0) 4378 rtableid = r->rtableid; 4379 if (r->anchor == NULL) { 4380 match = 1; 4381 *rm = r; 4382 *am = a; 4383 *rsm = ruleset; 4384 if ((*rm)->quick) 4385 break; 4386 r = TAILQ_NEXT(r, entries); 4387 } else 4388 pf_step_into_anchor(&asd, &ruleset, 4389 PF_RULESET_FILTER, &r, &a, &match); 4390 } 4391 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 4392 PF_RULESET_FILTER, &r, &a, &match)) 4393 break; 4394 } 4395 r = *rm; 4396 a = *am; 4397 ruleset = *rsm; 4398 4399 REASON_SET(&reason, PFRES_MATCH); 4400 4401 if (r->log || (nr != NULL && nr->natpass && nr->log)) 4402 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 4403 a, ruleset, pd); 4404 4405 if ((r->action == PF_DROP) && 4406 ((r->rule_flag & PFRULE_RETURNICMP) || 4407 (r->rule_flag & PFRULE_RETURN))) { 4408 struct pf_addr *a = NULL; 4409 4410 if (nr != NULL) { 4411 if (direction == PF_OUT) 4412 a = saddr; 4413 else 4414 a = daddr; 4415 } 4416 if (a != NULL) { 4417 switch (af) { 4418#ifdef INET 4419 case AF_INET: 4420 pf_change_a(&a->v4.s_addr, pd->ip_sum, 4421 pd->baddr.v4.s_addr, 0); 4422 break; 4423#endif /* INET */ 4424#ifdef INET6 4425 case AF_INET6: 4426 PF_ACPY(a, &pd->baddr, af); 4427 break; 4428#endif /* INET6 */ 4429 } 4430 } 4431 if ((af == AF_INET) && r->return_icmp) 4432 pf_send_icmp(m, r->return_icmp >> 8, 4433 r->return_icmp & 255, af, r); 4434 else if ((af == AF_INET6) && r->return_icmp6) 4435 pf_send_icmp(m, r->return_icmp6 >> 8, 4436 r->return_icmp6 & 255, af, r); 4437 } 4438 4439 if (r->action != PF_PASS) 4440 return (PF_DROP); 4441 4442 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) { 4443 REASON_SET(&reason, PFRES_MEMORY); 4444 return (PF_DROP); 4445 } 4446 4447 if (r->keep_state || nr != NULL) { 4448 /* create new state */ 4449 struct pf_state *s = NULL; 4450 struct pf_src_node *sn = NULL; 4451 4452 /* check maximums */ 4453 if (r->max_states && (r->states >= r->max_states)) { 4454 pf_status.lcounters[LCNT_STATES]++; 4455 REASON_SET(&reason, PFRES_MAXSTATES); 4456 goto cleanup; 4457 } 4458 /* src node for filter rule */ 4459 if ((r->rule_flag & PFRULE_SRCTRACK || 4460 r->rpool.opts & PF_POOL_STICKYADDR) && 4461 pf_insert_src_node(&sn, r, saddr, af) != 0) { 4462 REASON_SET(&reason, PFRES_SRCLIMIT); 4463 goto cleanup; 4464 } 4465 /* src node for translation rule */ 4466 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 4467 ((direction == PF_OUT && 4468 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 4469 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) { 4470 REASON_SET(&reason, PFRES_SRCLIMIT); 4471 goto cleanup; 4472 } 4473 s = pool_get(&pf_state_pl, PR_NOWAIT); 4474 if (s == NULL) { 4475 REASON_SET(&reason, PFRES_MEMORY); 4476cleanup: 4477 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 4478 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 4479 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4480 pf_status.src_nodes--; 4481 pool_put(&pf_src_tree_pl, sn); 4482 } 4483 if (nsn != sn && nsn != NULL && nsn->states == 0 && 4484 nsn->expire == 0) { 4485 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 4486 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4487 pf_status.src_nodes--; 4488 pool_put(&pf_src_tree_pl, nsn); 4489 } 4490 return (PF_DROP); 4491 } 4492 bzero(s, sizeof(*s)); 4493 s->rule.ptr = r; 4494 s->nat_rule.ptr = nr; 4495 s->anchor.ptr = a; 4496 STATE_INC_COUNTERS(s); 4497 s->allow_opts = r->allow_opts; 4498 s->log = r->log & PF_LOG_ALL; 4499 if (nr != NULL) 4500 s->log |= nr->log & PF_LOG_ALL; 4501 s->proto = pd->proto; 4502 s->direction = direction; 4503 s->af = af; 4504 if (direction == PF_OUT) { 4505 PF_ACPY(&s->gwy.addr, saddr, af); 4506 PF_ACPY(&s->ext.addr, daddr, af); 4507 if (nr != NULL) 4508 PF_ACPY(&s->lan.addr, &pd->baddr, af); 4509 else 4510 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 4511 } else { 4512 PF_ACPY(&s->lan.addr, daddr, af); 4513 PF_ACPY(&s->ext.addr, saddr, af); 4514 if (nr != NULL) 4515 PF_ACPY(&s->gwy.addr, &pd->baddr, af); 4516 else 4517 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 4518 } 4519 s->src.state = PFOTHERS_SINGLE; 4520 s->dst.state = PFOTHERS_NO_TRAFFIC; 4521 s->creation = time_second; 4522 s->expire = time_second; 4523 s->timeout = PFTM_OTHER_FIRST_PACKET; 4524 pf_set_rt_ifp(s, saddr); 4525 if (sn != NULL) { 4526 s->src_node = sn; 4527 s->src_node->states++; 4528 } 4529 if (nsn != NULL) { 4530 PF_ACPY(&nsn->raddr, &pd->naddr, af); 4531 s->nat_src_node = nsn; 4532 s->nat_src_node->states++; 4533 } 4534 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { 4535 REASON_SET(&reason, PFRES_STATEINS); 4536 pf_src_tree_remove_state(s); 4537 STATE_DEC_COUNTERS(s); 4538 pool_put(&pf_state_pl, s); 4539 return (PF_DROP); 4540 } else 4541 *sm = s; 4542 if (tag > 0) { 4543 pf_tag_ref(tag); 4544 s->tag = tag; 4545 } 4546 } 4547 4548 return (PF_PASS); 4549} 4550 4551int 4552pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, 4553 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, 4554 struct pf_ruleset **rsm) 4555{ 4556 struct pf_rule *r, *a = NULL; 4557 struct pf_ruleset *ruleset = NULL; 4558 sa_family_t af = pd->af; 4559 u_short reason; 4560 int tag = -1; 4561 int asd = 0; 4562 int match = 0; 4563 4564 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 4565 while (r != NULL) { 4566 r->evaluations++; 4567 if (pfi_kif_match(r->kif, kif) == r->ifnot) 4568 r = r->skip[PF_SKIP_IFP].ptr; 4569 else if (r->direction && r->direction != direction) 4570 r = r->skip[PF_SKIP_DIR].ptr; 4571 else if (r->af && r->af != af) 4572 r = r->skip[PF_SKIP_AF].ptr; 4573 else if (r->proto && r->proto != pd->proto) 4574 r = r->skip[PF_SKIP_PROTO].ptr; 4575 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, 4576 r->src.neg, kif)) 4577 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 4578 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, 4579 r->dst.neg, NULL)) 4580 r = r->skip[PF_SKIP_DST_ADDR].ptr; 4581 else if (r->tos && !(r->tos == pd->tos)) 4582 r = TAILQ_NEXT(r, entries); 4583 else if (r->os_fingerprint != PF_OSFP_ANY) 4584 r = TAILQ_NEXT(r, entries); 4585 else if (pd->proto == IPPROTO_UDP && 4586 (r->src.port_op || r->dst.port_op)) 4587 r = TAILQ_NEXT(r, entries); 4588 else if (pd->proto == IPPROTO_TCP && 4589 (r->src.port_op || r->dst.port_op || r->flagset)) 4590 r = TAILQ_NEXT(r, entries); 4591 else if ((pd->proto == IPPROTO_ICMP || 4592 pd->proto == IPPROTO_ICMPV6) && 4593 (r->type || r->code)) 4594 r = TAILQ_NEXT(r, entries); 4595 else if (r->prob && r->prob <= arc4random()) 4596 r = TAILQ_NEXT(r, entries); 4597 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 4598 r = TAILQ_NEXT(r, entries); 4599 else { 4600 if (r->anchor == NULL) { 4601 match = 1; 4602 *rm = r; 4603 *am = a; 4604 *rsm = ruleset; 4605 if ((*rm)->quick) 4606 break; 4607 r = TAILQ_NEXT(r, entries); 4608 } else 4609 pf_step_into_anchor(&asd, &ruleset, 4610 PF_RULESET_FILTER, &r, &a, &match); 4611 } 4612 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 4613 PF_RULESET_FILTER, &r, &a, &match)) 4614 break; 4615 } 4616 r = *rm; 4617 a = *am; 4618 ruleset = *rsm; 4619 4620 REASON_SET(&reason, PFRES_MATCH); 4621 4622 if (r->log) 4623 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset, 4624 pd); 4625 4626 if (r->action != PF_PASS) 4627 return (PF_DROP); 4628 4629 if (pf_tag_packet(m, pd->pf_mtag, tag, -1)) { 4630 REASON_SET(&reason, PFRES_MEMORY); 4631 return (PF_DROP); 4632 } 4633 4634 return (PF_PASS); 4635} 4636 4637int 4638pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, 4639 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, 4640 u_short *reason) 4641{ 4642 struct pf_state_cmp key; 4643 struct tcphdr *th = pd->hdr.tcp; 4644 u_int16_t win = ntohs(th->th_win); 4645 u_int32_t ack, end, seq, orig_seq; 4646 u_int8_t sws, dws; 4647 int ackskew; 4648 int copyback = 0; 4649 struct pf_state_peer *src, *dst; 4650 4651 key.af = pd->af; 4652 key.proto = IPPROTO_TCP; 4653 if (direction == PF_IN) { 4654 PF_ACPY(&key.ext.addr, pd->src, key.af); 4655 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 4656 key.ext.port = th->th_sport; 4657 key.gwy.port = th->th_dport; 4658 } else { 4659 PF_ACPY(&key.lan.addr, pd->src, key.af); 4660 PF_ACPY(&key.ext.addr, pd->dst, key.af); 4661 key.lan.port = th->th_sport; 4662 key.ext.port = th->th_dport; 4663 } 4664 4665 STATE_LOOKUP(); 4666 4667 if (direction == (*state)->direction) { 4668 src = &(*state)->src; 4669 dst = &(*state)->dst; 4670 } else { 4671 src = &(*state)->dst; 4672 dst = &(*state)->src; 4673 } 4674 4675 if ((*state)->src.state == PF_TCPS_PROXY_SRC) { 4676 if (direction != (*state)->direction) { 4677 REASON_SET(reason, PFRES_SYNPROXY); 4678 return (PF_SYNPROXY_DROP); 4679 } 4680 if (th->th_flags & TH_SYN) { 4681 if (ntohl(th->th_seq) != (*state)->src.seqlo) { 4682 REASON_SET(reason, PFRES_SYNPROXY); 4683 return (PF_DROP); 4684 } 4685#ifdef __FreeBSD__ 4686 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst, 4687#else 4688 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4689#endif 4690 pd->src, th->th_dport, th->th_sport, 4691 (*state)->src.seqhi, ntohl(th->th_seq) + 1, 4692 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1, 4693 0, NULL, NULL); 4694 REASON_SET(reason, PFRES_SYNPROXY); 4695 return (PF_SYNPROXY_DROP); 4696 } else if (!(th->th_flags & TH_ACK) || 4697 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 4698 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) { 4699 REASON_SET(reason, PFRES_SYNPROXY); 4700 return (PF_DROP); 4701 } else if ((*state)->src_node != NULL && 4702 pf_src_connlimit(state)) { 4703 REASON_SET(reason, PFRES_SRCLIMIT); 4704 return (PF_DROP); 4705 } else 4706 (*state)->src.state = PF_TCPS_PROXY_DST; 4707 } 4708 if ((*state)->src.state == PF_TCPS_PROXY_DST) { 4709 struct pf_state_host *src, *dst; 4710 4711 if (direction == PF_OUT) { 4712 src = &(*state)->gwy; 4713 dst = &(*state)->ext; 4714 } else { 4715 src = &(*state)->ext; 4716 dst = &(*state)->lan; 4717 } 4718 if (direction == (*state)->direction) { 4719 if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) || 4720 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 4721 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) { 4722 REASON_SET(reason, PFRES_SYNPROXY); 4723 return (PF_DROP); 4724 } 4725 (*state)->src.max_win = MAX(ntohs(th->th_win), 1); 4726 if ((*state)->dst.seqhi == 1) 4727 (*state)->dst.seqhi = htonl(arc4random()); 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)->dst.seqhi, 0, TH_SYN, 0, 4736 (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL); 4737 REASON_SET(reason, PFRES_SYNPROXY); 4738 return (PF_SYNPROXY_DROP); 4739 } else if (((th->th_flags & (TH_SYN|TH_ACK)) != 4740 (TH_SYN|TH_ACK)) || 4741 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) { 4742 REASON_SET(reason, PFRES_SYNPROXY); 4743 return (PF_DROP); 4744 } else { 4745 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1); 4746 (*state)->dst.seqlo = ntohl(th->th_seq); 4747#ifdef __FreeBSD__ 4748 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst, 4749#else 4750 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4751#endif 4752 pd->src, th->th_dport, th->th_sport, 4753 ntohl(th->th_ack), ntohl(th->th_seq) + 1, 4754 TH_ACK, (*state)->src.max_win, 0, 0, 0, 4755 (*state)->tag, NULL, NULL); 4756#ifdef __FreeBSD__ 4757 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4758 &src->addr, 4759#else 4760 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 4761#endif 4762 &dst->addr, src->port, dst->port, 4763 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1, 4764 TH_ACK, (*state)->dst.max_win, 0, 0, 1, 4765 0, NULL, NULL); 4766 (*state)->src.seqdiff = (*state)->dst.seqhi - 4767 (*state)->src.seqlo; 4768 (*state)->dst.seqdiff = (*state)->src.seqhi - 4769 (*state)->dst.seqlo; 4770 (*state)->src.seqhi = (*state)->src.seqlo + 4771 (*state)->dst.max_win; 4772 (*state)->dst.seqhi = (*state)->dst.seqlo + 4773 (*state)->src.max_win; 4774 (*state)->src.wscale = (*state)->dst.wscale = 0; 4775 (*state)->src.state = (*state)->dst.state = 4776 TCPS_ESTABLISHED; 4777 REASON_SET(reason, PFRES_SYNPROXY); 4778 return (PF_SYNPROXY_DROP); 4779 } 4780 } 4781 4782 if (((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) && 4783 dst->state >= TCPS_FIN_WAIT_2 && 4784 src->state >= TCPS_FIN_WAIT_2) { 4785 if (pf_status.debug >= PF_DEBUG_MISC) { 4786 printf("pf: state reuse "); 4787 pf_print_state(*state); 4788 pf_print_flags(th->th_flags); 4789 printf("\n"); 4790 } 4791 /* XXX make sure it's the same direction ?? */ 4792 (*state)->src.state = (*state)->dst.state = TCPS_CLOSED; 4793 pf_unlink_state(*state); 4794 *state = NULL; 4795 return (PF_DROP); 4796 } 4797 4798 if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) { 4799 sws = src->wscale & PF_WSCALE_MASK; 4800 dws = dst->wscale & PF_WSCALE_MASK; 4801 } else 4802 sws = dws = 0; 4803 4804 /* 4805 * Sequence tracking algorithm from Guido van Rooij's paper: 4806 * http://www.madison-gurkha.com/publications/tcp_filtering/ 4807 * tcp_filtering.ps 4808 */ 4809 4810 orig_seq = seq = ntohl(th->th_seq); 4811 if (src->seqlo == 0) { 4812 /* First packet from this end. Set its state */ 4813 4814 if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) && 4815 src->scrub == NULL) { 4816 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) { 4817 REASON_SET(reason, PFRES_MEMORY); 4818 return (PF_DROP); 4819 } 4820 } 4821 4822 /* Deferred generation of sequence number modulator */ 4823 if (dst->seqdiff && !src->seqdiff) { 4824#ifdef __FreeBSD__ 4825 while ((src->seqdiff = pf_new_isn(*state) - seq) == 0) 4826 ; 4827#else 4828 while ((src->seqdiff = tcp_rndiss_next() - seq) == 0) 4829 ; 4830#endif 4831 ack = ntohl(th->th_ack) - dst->seqdiff; 4832 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4833 src->seqdiff), 0); 4834 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4835 copyback = 1; 4836 } else { 4837 ack = ntohl(th->th_ack); 4838 } 4839 4840 end = seq + pd->p_len; 4841 if (th->th_flags & TH_SYN) { 4842 end++; 4843 if (dst->wscale & PF_WSCALE_FLAG) { 4844 src->wscale = pf_get_wscale(m, off, th->th_off, 4845 pd->af); 4846 if (src->wscale & PF_WSCALE_FLAG) { 4847 /* Remove scale factor from initial 4848 * window */ 4849 sws = src->wscale & PF_WSCALE_MASK; 4850 win = ((u_int32_t)win + (1 << sws) - 1) 4851 >> sws; 4852 dws = dst->wscale & PF_WSCALE_MASK; 4853 } else { 4854 /* fixup other window */ 4855 dst->max_win <<= dst->wscale & 4856 PF_WSCALE_MASK; 4857 /* in case of a retrans SYN|ACK */ 4858 dst->wscale = 0; 4859 } 4860 } 4861 } 4862 if (th->th_flags & TH_FIN) 4863 end++; 4864 4865 src->seqlo = seq; 4866 if (src->state < TCPS_SYN_SENT) 4867 src->state = TCPS_SYN_SENT; 4868 4869 /* 4870 * May need to slide the window (seqhi may have been set by 4871 * the crappy stack check or if we picked up the connection 4872 * after establishment) 4873 */ 4874 if (src->seqhi == 1 || 4875 SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi)) 4876 src->seqhi = end + MAX(1, dst->max_win << dws); 4877 if (win > src->max_win) 4878 src->max_win = win; 4879 4880 } else { 4881 ack = ntohl(th->th_ack) - dst->seqdiff; 4882 if (src->seqdiff) { 4883 /* Modulate sequence numbers */ 4884 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4885 src->seqdiff), 0); 4886 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4887 copyback = 1; 4888 } 4889 end = seq + pd->p_len; 4890 if (th->th_flags & TH_SYN) 4891 end++; 4892 if (th->th_flags & TH_FIN) 4893 end++; 4894 } 4895 4896 if ((th->th_flags & TH_ACK) == 0) { 4897 /* Let it pass through the ack skew check */ 4898 ack = dst->seqlo; 4899 } else if ((ack == 0 && 4900 (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) || 4901 /* broken tcp stacks do not set ack */ 4902 (dst->state < TCPS_SYN_SENT)) { 4903 /* 4904 * Many stacks (ours included) will set the ACK number in an 4905 * FIN|ACK if the SYN times out -- no sequence to ACK. 4906 */ 4907 ack = dst->seqlo; 4908 } 4909 4910 if (seq == end) { 4911 /* Ease sequencing restrictions on no data packets */ 4912 seq = src->seqlo; 4913 end = seq; 4914 } 4915 4916 ackskew = dst->seqlo - ack; 4917 4918 4919 /* 4920 * Need to demodulate the sequence numbers in any TCP SACK options 4921 * (Selective ACK). We could optionally validate the SACK values 4922 * against the current ACK window, either forwards or backwards, but 4923 * I'm not confident that SACK has been implemented properly 4924 * everywhere. It wouldn't surprise me if several stacks accidently 4925 * SACK too far backwards of previously ACKed data. There really aren't 4926 * any security implications of bad SACKing unless the target stack 4927 * doesn't validate the option length correctly. Someone trying to 4928 * spoof into a TCP connection won't bother blindly sending SACK 4929 * options anyway. 4930 */ 4931 if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) { 4932 if (pf_modulate_sack(m, off, pd, th, dst)) 4933 copyback = 1; 4934 } 4935 4936 4937#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */ 4938 if (SEQ_GEQ(src->seqhi, end) && 4939 /* Last octet inside other's window space */ 4940 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) && 4941 /* Retrans: not more than one window back */ 4942 (ackskew >= -MAXACKWINDOW) && 4943 /* Acking not more than one reassembled fragment backwards */ 4944 (ackskew <= (MAXACKWINDOW << sws)) && 4945 /* Acking not more than one window forward */ 4946 ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo || 4947 (orig_seq == src->seqlo + 1) || (pd->flags & PFDESC_IP_REAS) == 0)) { 4948 /* Require an exact/+1 sequence match on resets when possible */ 4949 4950 if (dst->scrub || src->scrub) { 4951 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 4952 *state, src, dst, ©back)) 4953 return (PF_DROP); 4954 } 4955 4956 /* update max window */ 4957 if (src->max_win < win) 4958 src->max_win = win; 4959 /* synchronize sequencing */ 4960 if (SEQ_GT(end, src->seqlo)) 4961 src->seqlo = end; 4962 /* slide the window of what the other end can send */ 4963 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) 4964 dst->seqhi = ack + MAX((win << sws), 1); 4965 4966 4967 /* update states */ 4968 if (th->th_flags & TH_SYN) 4969 if (src->state < TCPS_SYN_SENT) 4970 src->state = TCPS_SYN_SENT; 4971 if (th->th_flags & TH_FIN) 4972 if (src->state < TCPS_CLOSING) 4973 src->state = TCPS_CLOSING; 4974 if (th->th_flags & TH_ACK) { 4975 if (dst->state == TCPS_SYN_SENT) { 4976 dst->state = TCPS_ESTABLISHED; 4977 if (src->state == TCPS_ESTABLISHED && 4978 (*state)->src_node != NULL && 4979 pf_src_connlimit(state)) { 4980 REASON_SET(reason, PFRES_SRCLIMIT); 4981 return (PF_DROP); 4982 } 4983 } else if (dst->state == TCPS_CLOSING) 4984 dst->state = TCPS_FIN_WAIT_2; 4985 } 4986 if (th->th_flags & TH_RST) 4987 src->state = dst->state = TCPS_TIME_WAIT; 4988 4989 /* update expire time */ 4990 (*state)->expire = time_second; 4991 if (src->state >= TCPS_FIN_WAIT_2 && 4992 dst->state >= TCPS_FIN_WAIT_2) 4993 (*state)->timeout = PFTM_TCP_CLOSED; 4994 else if (src->state >= TCPS_CLOSING && 4995 dst->state >= TCPS_CLOSING) 4996 (*state)->timeout = PFTM_TCP_FIN_WAIT; 4997 else if (src->state < TCPS_ESTABLISHED || 4998 dst->state < TCPS_ESTABLISHED) 4999 (*state)->timeout = PFTM_TCP_OPENING; 5000 else if (src->state >= TCPS_CLOSING || 5001 dst->state >= TCPS_CLOSING) 5002 (*state)->timeout = PFTM_TCP_CLOSING; 5003 else 5004 (*state)->timeout = PFTM_TCP_ESTABLISHED; 5005 5006 /* Fall through to PASS packet */ 5007 5008 } else if ((dst->state < TCPS_SYN_SENT || 5009 dst->state >= TCPS_FIN_WAIT_2 || 5010 src->state >= TCPS_FIN_WAIT_2) && 5011 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) && 5012 /* Within a window forward of the originating packet */ 5013 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) { 5014 /* Within a window backward of the originating packet */ 5015 5016 /* 5017 * This currently handles three situations: 5018 * 1) Stupid stacks will shotgun SYNs before their peer 5019 * replies. 5020 * 2) When PF catches an already established stream (the 5021 * firewall rebooted, the state table was flushed, routes 5022 * changed...) 5023 * 3) Packets get funky immediately after the connection 5024 * closes (this should catch Solaris spurious ACK|FINs 5025 * that web servers like to spew after a close) 5026 * 5027 * This must be a little more careful than the above code 5028 * since packet floods will also be caught here. We don't 5029 * update the TTL here to mitigate the damage of a packet 5030 * flood and so the same code can handle awkward establishment 5031 * and a loosened connection close. 5032 * In the establishment case, a correct peer response will 5033 * validate the connection, go through the normal state code 5034 * and keep updating the state TTL. 5035 */ 5036 5037 if (pf_status.debug >= PF_DEBUG_MISC) { 5038 printf("pf: loose state match: "); 5039 pf_print_state(*state); 5040 pf_print_flags(th->th_flags); 5041 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d " 5042 "pkts=%llu:%llu\n", seq, orig_seq, ack, pd->p_len, 5043#ifdef __FreeBSD__ 5044 ackskew, (unsigned long long)(*state)->packets[0], 5045 (unsigned long long)(*state)->packets[1]); 5046#else 5047 ackskew, (*state)->packets[0], 5048 (*state)->packets[1]); 5049#endif 5050 } 5051 5052 if (dst->scrub || src->scrub) { 5053 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 5054 *state, src, dst, ©back)) 5055 return (PF_DROP); 5056 } 5057 5058 /* update max window */ 5059 if (src->max_win < win) 5060 src->max_win = win; 5061 /* synchronize sequencing */ 5062 if (SEQ_GT(end, src->seqlo)) 5063 src->seqlo = end; 5064 /* slide the window of what the other end can send */ 5065 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) 5066 dst->seqhi = ack + MAX((win << sws), 1); 5067 5068 /* 5069 * Cannot set dst->seqhi here since this could be a shotgunned 5070 * SYN and not an already established connection. 5071 */ 5072 5073 if (th->th_flags & TH_FIN) 5074 if (src->state < TCPS_CLOSING) 5075 src->state = TCPS_CLOSING; 5076 if (th->th_flags & TH_RST) 5077 src->state = dst->state = TCPS_TIME_WAIT; 5078 5079 /* Fall through to PASS packet */ 5080 5081 } else { 5082 if ((*state)->dst.state == TCPS_SYN_SENT && 5083 (*state)->src.state == TCPS_SYN_SENT) { 5084 /* Send RST for state mismatches during handshake */ 5085 if (!(th->th_flags & TH_RST)) 5086#ifdef __FreeBSD__ 5087 pf_send_tcp(m, (*state)->rule.ptr, pd->af, 5088#else 5089 pf_send_tcp((*state)->rule.ptr, pd->af, 5090#endif 5091 pd->dst, pd->src, th->th_dport, 5092 th->th_sport, ntohl(th->th_ack), 0, 5093 TH_RST, 0, 0, 5094 (*state)->rule.ptr->return_ttl, 1, 0, 5095 pd->eh, kif->pfik_ifp); 5096 src->seqlo = 0; 5097 src->seqhi = 1; 5098 src->max_win = 1; 5099 } else if (pf_status.debug >= PF_DEBUG_MISC) { 5100 printf("pf: BAD state: "); 5101 pf_print_state(*state); 5102 pf_print_flags(th->th_flags); 5103 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d " 5104 "pkts=%llu:%llu dir=%s,%s\n", 5105 seq, orig_seq, ack, pd->p_len, ackskew, 5106#ifdef __FreeBSD__ 5107 (unsigned long long)(*state)->packets[0], 5108 (unsigned long long)(*state)->packets[1], 5109#else 5110 (*state)->packets[0], (*state)->packets[1], 5111#endif 5112 direction == PF_IN ? "in" : "out", 5113 direction == (*state)->direction ? "fwd" : "rev"); 5114 printf("pf: State failure on: %c %c %c %c | %c %c\n", 5115 SEQ_GEQ(src->seqhi, end) ? ' ' : '1', 5116 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ? 5117 ' ': '2', 5118 (ackskew >= -MAXACKWINDOW) ? ' ' : '3', 5119 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4', 5120 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5', 5121 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6'); 5122 } 5123 REASON_SET(reason, PFRES_BADSTATE); 5124 return (PF_DROP); 5125 } 5126 5127 /* Any packets which have gotten here are to be passed */ 5128 5129 /* translate source/destination address, if necessary */ 5130 if (STATE_TRANSLATE(*state)) { 5131 if (direction == PF_OUT) 5132 pf_change_ap(pd->src, &th->th_sport, pd->ip_sum, 5133 &th->th_sum, &(*state)->gwy.addr, 5134 (*state)->gwy.port, 0, pd->af); 5135 else 5136 pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, 5137 &th->th_sum, &(*state)->lan.addr, 5138 (*state)->lan.port, 0, pd->af); 5139 m_copyback(m, off, sizeof(*th), (caddr_t)th); 5140 } else if (copyback) { 5141 /* Copyback sequence modulation or stateful scrub changes */ 5142 m_copyback(m, off, sizeof(*th), (caddr_t)th); 5143 } 5144 5145 return (PF_PASS); 5146} 5147 5148int 5149pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, 5150 struct mbuf *m, int off, void *h, struct pf_pdesc *pd) 5151{ 5152 struct pf_state_peer *src, *dst; 5153 struct pf_state_cmp key; 5154 struct udphdr *uh = pd->hdr.udp; 5155 5156 key.af = pd->af; 5157 key.proto = IPPROTO_UDP; 5158 if (direction == PF_IN) { 5159 PF_ACPY(&key.ext.addr, pd->src, key.af); 5160 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 5161 key.ext.port = uh->uh_sport; 5162 key.gwy.port = uh->uh_dport; 5163 } else { 5164 PF_ACPY(&key.lan.addr, pd->src, key.af); 5165 PF_ACPY(&key.ext.addr, pd->dst, key.af); 5166 key.lan.port = uh->uh_sport; 5167 key.ext.port = uh->uh_dport; 5168 } 5169 5170 STATE_LOOKUP(); 5171 5172 if (direction == (*state)->direction) { 5173 src = &(*state)->src; 5174 dst = &(*state)->dst; 5175 } else { 5176 src = &(*state)->dst; 5177 dst = &(*state)->src; 5178 } 5179 5180 /* update states */ 5181 if (src->state < PFUDPS_SINGLE) 5182 src->state = PFUDPS_SINGLE; 5183 if (dst->state == PFUDPS_SINGLE) 5184 dst->state = PFUDPS_MULTIPLE; 5185 5186 /* update expire time */ 5187 (*state)->expire = time_second; 5188 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE) 5189 (*state)->timeout = PFTM_UDP_MULTIPLE; 5190 else 5191 (*state)->timeout = PFTM_UDP_SINGLE; 5192 5193 /* translate source/destination address, if necessary */ 5194 if (STATE_TRANSLATE(*state)) { 5195 if (direction == PF_OUT) 5196 pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum, 5197 &uh->uh_sum, &(*state)->gwy.addr, 5198 (*state)->gwy.port, 1, pd->af); 5199 else 5200 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, 5201 &uh->uh_sum, &(*state)->lan.addr, 5202 (*state)->lan.port, 1, pd->af); 5203 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 5204 } 5205 5206 return (PF_PASS); 5207} 5208 5209int 5210pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, 5211 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason) 5212{ 5213 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 5214 u_int16_t icmpid = 0; /* make the compiler happy */ 5215 u_int16_t *icmpsum = NULL; /* make the compiler happy */ 5216 u_int8_t icmptype = 0; /* make the compiler happy */ 5217 int state_icmp = 0; 5218 struct pf_state_cmp key; 5219 5220 switch (pd->proto) { 5221#ifdef INET 5222 case IPPROTO_ICMP: 5223 icmptype = pd->hdr.icmp->icmp_type; 5224 icmpid = pd->hdr.icmp->icmp_id; 5225 icmpsum = &pd->hdr.icmp->icmp_cksum; 5226 5227 if (icmptype == ICMP_UNREACH || 5228 icmptype == ICMP_SOURCEQUENCH || 5229 icmptype == ICMP_REDIRECT || 5230 icmptype == ICMP_TIMXCEED || 5231 icmptype == ICMP_PARAMPROB) 5232 state_icmp++; 5233 break; 5234#endif /* INET */ 5235#ifdef INET6 5236 case IPPROTO_ICMPV6: 5237 icmptype = pd->hdr.icmp6->icmp6_type; 5238 icmpid = pd->hdr.icmp6->icmp6_id; 5239 icmpsum = &pd->hdr.icmp6->icmp6_cksum; 5240 5241 if (icmptype == ICMP6_DST_UNREACH || 5242 icmptype == ICMP6_PACKET_TOO_BIG || 5243 icmptype == ICMP6_TIME_EXCEEDED || 5244 icmptype == ICMP6_PARAM_PROB) 5245 state_icmp++; 5246 break; 5247#endif /* INET6 */ 5248 } 5249 5250 if (!state_icmp) { 5251 5252 /* 5253 * ICMP query/reply message not related to a TCP/UDP packet. 5254 * Search for an ICMP state. 5255 */ 5256 key.af = pd->af; 5257 key.proto = pd->proto; 5258 if (direction == PF_IN) { 5259 PF_ACPY(&key.ext.addr, pd->src, key.af); 5260 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 5261 key.ext.port = 0; 5262 key.gwy.port = icmpid; 5263 } else { 5264 PF_ACPY(&key.lan.addr, pd->src, key.af); 5265 PF_ACPY(&key.ext.addr, pd->dst, key.af); 5266 key.lan.port = icmpid; 5267 key.ext.port = 0; 5268 } 5269 5270 STATE_LOOKUP(); 5271 5272 (*state)->expire = time_second; 5273 (*state)->timeout = PFTM_ICMP_ERROR_REPLY; 5274 5275 /* translate source/destination address, if necessary */ 5276 if (STATE_TRANSLATE(*state)) { 5277 if (direction == PF_OUT) { 5278 switch (pd->af) { 5279#ifdef INET 5280 case AF_INET: 5281 pf_change_a(&saddr->v4.s_addr, 5282 pd->ip_sum, 5283 (*state)->gwy.addr.v4.s_addr, 0); 5284 pd->hdr.icmp->icmp_cksum = 5285 pf_cksum_fixup( 5286 pd->hdr.icmp->icmp_cksum, icmpid, 5287 (*state)->gwy.port, 0); 5288 pd->hdr.icmp->icmp_id = 5289 (*state)->gwy.port; 5290 m_copyback(m, off, ICMP_MINLEN, 5291 (caddr_t)pd->hdr.icmp); 5292 break; 5293#endif /* INET */ 5294#ifdef INET6 5295 case AF_INET6: 5296 pf_change_a6(saddr, 5297 &pd->hdr.icmp6->icmp6_cksum, 5298 &(*state)->gwy.addr, 0); 5299 m_copyback(m, off, 5300 sizeof(struct icmp6_hdr), 5301 (caddr_t)pd->hdr.icmp6); 5302 break; 5303#endif /* INET6 */ 5304 } 5305 } else { 5306 switch (pd->af) { 5307#ifdef INET 5308 case AF_INET: 5309 pf_change_a(&daddr->v4.s_addr, 5310 pd->ip_sum, 5311 (*state)->lan.addr.v4.s_addr, 0); 5312 pd->hdr.icmp->icmp_cksum = 5313 pf_cksum_fixup( 5314 pd->hdr.icmp->icmp_cksum, icmpid, 5315 (*state)->lan.port, 0); 5316 pd->hdr.icmp->icmp_id = 5317 (*state)->lan.port; 5318 m_copyback(m, off, ICMP_MINLEN, 5319 (caddr_t)pd->hdr.icmp); 5320 break; 5321#endif /* INET */ 5322#ifdef INET6 5323 case AF_INET6: 5324 pf_change_a6(daddr, 5325 &pd->hdr.icmp6->icmp6_cksum, 5326 &(*state)->lan.addr, 0); 5327 m_copyback(m, off, 5328 sizeof(struct icmp6_hdr), 5329 (caddr_t)pd->hdr.icmp6); 5330 break; 5331#endif /* INET6 */ 5332 } 5333 } 5334 } 5335 5336 return (PF_PASS); 5337 5338 } else { 5339 /* 5340 * ICMP error message in response to a TCP/UDP packet. 5341 * Extract the inner TCP/UDP header and search for that state. 5342 */ 5343 5344 struct pf_pdesc pd2; 5345#ifdef INET 5346 struct ip h2; 5347#endif /* INET */ 5348#ifdef INET6 5349 struct ip6_hdr h2_6; 5350 int terminal = 0; 5351#endif /* INET6 */ 5352 int ipoff2 = 0; /* make the compiler happy */ 5353 int off2 = 0; /* make the compiler happy */ 5354 5355 pd2.af = pd->af; 5356 switch (pd->af) { 5357#ifdef INET 5358 case AF_INET: 5359 /* offset of h2 in mbuf chain */ 5360 ipoff2 = off + ICMP_MINLEN; 5361 5362 if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2), 5363 NULL, reason, pd2.af)) { 5364 DPFPRINTF(PF_DEBUG_MISC, 5365 ("pf: ICMP error message too short " 5366 "(ip)\n")); 5367 return (PF_DROP); 5368 } 5369 /* 5370 * ICMP error messages don't refer to non-first 5371 * fragments 5372 */ 5373 if (h2.ip_off & htons(IP_OFFMASK)) { 5374 REASON_SET(reason, PFRES_FRAG); 5375 return (PF_DROP); 5376 } 5377 5378 /* offset of protocol header that follows h2 */ 5379 off2 = ipoff2 + (h2.ip_hl << 2); 5380 5381 pd2.proto = h2.ip_p; 5382 pd2.src = (struct pf_addr *)&h2.ip_src; 5383 pd2.dst = (struct pf_addr *)&h2.ip_dst; 5384 pd2.ip_sum = &h2.ip_sum; 5385 break; 5386#endif /* INET */ 5387#ifdef INET6 5388 case AF_INET6: 5389 ipoff2 = off + sizeof(struct icmp6_hdr); 5390 5391 if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6), 5392 NULL, reason, pd2.af)) { 5393 DPFPRINTF(PF_DEBUG_MISC, 5394 ("pf: ICMP error message too short " 5395 "(ip6)\n")); 5396 return (PF_DROP); 5397 } 5398 pd2.proto = h2_6.ip6_nxt; 5399 pd2.src = (struct pf_addr *)&h2_6.ip6_src; 5400 pd2.dst = (struct pf_addr *)&h2_6.ip6_dst; 5401 pd2.ip_sum = NULL; 5402 off2 = ipoff2 + sizeof(h2_6); 5403 do { 5404 switch (pd2.proto) { 5405 case IPPROTO_FRAGMENT: 5406 /* 5407 * ICMPv6 error messages for 5408 * non-first fragments 5409 */ 5410 REASON_SET(reason, PFRES_FRAG); 5411 return (PF_DROP); 5412 case IPPROTO_AH: 5413 case IPPROTO_HOPOPTS: 5414 case IPPROTO_ROUTING: 5415 case IPPROTO_DSTOPTS: { 5416 /* get next header and header length */ 5417 struct ip6_ext opt6; 5418 5419 if (!pf_pull_hdr(m, off2, &opt6, 5420 sizeof(opt6), NULL, reason, 5421 pd2.af)) { 5422 DPFPRINTF(PF_DEBUG_MISC, 5423 ("pf: ICMPv6 short opt\n")); 5424 return (PF_DROP); 5425 } 5426 if (pd2.proto == IPPROTO_AH) 5427 off2 += (opt6.ip6e_len + 2) * 4; 5428 else 5429 off2 += (opt6.ip6e_len + 1) * 8; 5430 pd2.proto = opt6.ip6e_nxt; 5431 /* goto the next header */ 5432 break; 5433 } 5434 default: 5435 terminal++; 5436 break; 5437 } 5438 } while (!terminal); 5439 break; 5440#endif /* INET6 */ 5441#ifdef __FreeBSD__ 5442 default: 5443 panic("AF not supported: %d", pd->af); 5444#endif 5445 } 5446 5447 switch (pd2.proto) { 5448 case IPPROTO_TCP: { 5449 struct tcphdr th; 5450 u_int32_t seq; 5451 struct pf_state_peer *src, *dst; 5452 u_int8_t dws; 5453 int copyback = 0; 5454 5455 /* 5456 * Only the first 8 bytes of the TCP header can be 5457 * expected. Don't access any TCP header fields after 5458 * th_seq, an ackskew test is not possible. 5459 */ 5460 if (!pf_pull_hdr(m, off2, &th, 8, NULL, reason, 5461 pd2.af)) { 5462 DPFPRINTF(PF_DEBUG_MISC, 5463 ("pf: ICMP error message too short " 5464 "(tcp)\n")); 5465 return (PF_DROP); 5466 } 5467 5468 key.af = pd2.af; 5469 key.proto = IPPROTO_TCP; 5470 if (direction == PF_IN) { 5471 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 5472 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 5473 key.ext.port = th.th_dport; 5474 key.gwy.port = th.th_sport; 5475 } else { 5476 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 5477 PF_ACPY(&key.ext.addr, pd2.src, key.af); 5478 key.lan.port = th.th_dport; 5479 key.ext.port = th.th_sport; 5480 } 5481 5482 STATE_LOOKUP(); 5483 5484 if (direction == (*state)->direction) { 5485 src = &(*state)->dst; 5486 dst = &(*state)->src; 5487 } else { 5488 src = &(*state)->src; 5489 dst = &(*state)->dst; 5490 } 5491 5492 if (src->wscale && dst->wscale) 5493 dws = dst->wscale & PF_WSCALE_MASK; 5494 else 5495 dws = 0; 5496 5497 /* Demodulate sequence number */ 5498 seq = ntohl(th.th_seq) - src->seqdiff; 5499 if (src->seqdiff) { 5500 pf_change_a(&th.th_seq, icmpsum, 5501 htonl(seq), 0); 5502 copyback = 1; 5503 } 5504 5505 if (!SEQ_GEQ(src->seqhi, seq) || 5506 !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws))) { 5507 if (pf_status.debug >= PF_DEBUG_MISC) { 5508 printf("pf: BAD ICMP %d:%d ", 5509 icmptype, pd->hdr.icmp->icmp_code); 5510 pf_print_host(pd->src, 0, pd->af); 5511 printf(" -> "); 5512 pf_print_host(pd->dst, 0, pd->af); 5513 printf(" state: "); 5514 pf_print_state(*state); 5515 printf(" seq=%u\n", seq); 5516 } 5517 REASON_SET(reason, PFRES_BADSTATE); 5518 return (PF_DROP); 5519 } 5520 5521 if (STATE_TRANSLATE(*state)) { 5522 if (direction == PF_IN) { 5523 pf_change_icmp(pd2.src, &th.th_sport, 5524 daddr, &(*state)->lan.addr, 5525 (*state)->lan.port, NULL, 5526 pd2.ip_sum, icmpsum, 5527 pd->ip_sum, 0, pd2.af); 5528 } else { 5529 pf_change_icmp(pd2.dst, &th.th_dport, 5530 saddr, &(*state)->gwy.addr, 5531 (*state)->gwy.port, NULL, 5532 pd2.ip_sum, icmpsum, 5533 pd->ip_sum, 0, pd2.af); 5534 } 5535 copyback = 1; 5536 } 5537 5538 if (copyback) { 5539 switch (pd2.af) { 5540#ifdef INET 5541 case AF_INET: 5542 m_copyback(m, off, ICMP_MINLEN, 5543 (caddr_t)pd->hdr.icmp); 5544 m_copyback(m, ipoff2, sizeof(h2), 5545 (caddr_t)&h2); 5546 break; 5547#endif /* INET */ 5548#ifdef INET6 5549 case AF_INET6: 5550 m_copyback(m, off, 5551 sizeof(struct icmp6_hdr), 5552 (caddr_t)pd->hdr.icmp6); 5553 m_copyback(m, ipoff2, sizeof(h2_6), 5554 (caddr_t)&h2_6); 5555 break; 5556#endif /* INET6 */ 5557 } 5558 m_copyback(m, off2, 8, (caddr_t)&th); 5559 } 5560 5561 return (PF_PASS); 5562 break; 5563 } 5564 case IPPROTO_UDP: { 5565 struct udphdr uh; 5566 5567 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh), 5568 NULL, reason, pd2.af)) { 5569 DPFPRINTF(PF_DEBUG_MISC, 5570 ("pf: ICMP error message too short " 5571 "(udp)\n")); 5572 return (PF_DROP); 5573 } 5574 5575 key.af = pd2.af; 5576 key.proto = IPPROTO_UDP; 5577 if (direction == PF_IN) { 5578 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 5579 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 5580 key.ext.port = uh.uh_dport; 5581 key.gwy.port = uh.uh_sport; 5582 } else { 5583 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 5584 PF_ACPY(&key.ext.addr, pd2.src, key.af); 5585 key.lan.port = uh.uh_dport; 5586 key.ext.port = uh.uh_sport; 5587 } 5588 5589 STATE_LOOKUP(); 5590 5591 if (STATE_TRANSLATE(*state)) { 5592 if (direction == PF_IN) { 5593 pf_change_icmp(pd2.src, &uh.uh_sport, 5594 daddr, &(*state)->lan.addr, 5595 (*state)->lan.port, &uh.uh_sum, 5596 pd2.ip_sum, icmpsum, 5597 pd->ip_sum, 1, pd2.af); 5598 } else { 5599 pf_change_icmp(pd2.dst, &uh.uh_dport, 5600 saddr, &(*state)->gwy.addr, 5601 (*state)->gwy.port, &uh.uh_sum, 5602 pd2.ip_sum, icmpsum, 5603 pd->ip_sum, 1, pd2.af); 5604 } 5605 switch (pd2.af) { 5606#ifdef INET 5607 case AF_INET: 5608 m_copyback(m, off, ICMP_MINLEN, 5609 (caddr_t)pd->hdr.icmp); 5610 m_copyback(m, ipoff2, sizeof(h2), 5611 (caddr_t)&h2); 5612 break; 5613#endif /* INET */ 5614#ifdef INET6 5615 case AF_INET6: 5616 m_copyback(m, off, 5617 sizeof(struct icmp6_hdr), 5618 (caddr_t)pd->hdr.icmp6); 5619 m_copyback(m, ipoff2, sizeof(h2_6), 5620 (caddr_t)&h2_6); 5621 break; 5622#endif /* INET6 */ 5623 } 5624 m_copyback(m, off2, sizeof(uh), 5625 (caddr_t)&uh); 5626 } 5627 5628 return (PF_PASS); 5629 break; 5630 } 5631#ifdef INET 5632 case IPPROTO_ICMP: { 5633 struct icmp iih; 5634 5635 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN, 5636 NULL, reason, pd2.af)) { 5637 DPFPRINTF(PF_DEBUG_MISC, 5638 ("pf: ICMP error message too short i" 5639 "(icmp)\n")); 5640 return (PF_DROP); 5641 } 5642 5643 key.af = pd2.af; 5644 key.proto = IPPROTO_ICMP; 5645 if (direction == PF_IN) { 5646 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 5647 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 5648 key.ext.port = 0; 5649 key.gwy.port = iih.icmp_id; 5650 } else { 5651 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 5652 PF_ACPY(&key.ext.addr, pd2.src, key.af); 5653 key.lan.port = iih.icmp_id; 5654 key.ext.port = 0; 5655 } 5656 5657 STATE_LOOKUP(); 5658 5659 if (STATE_TRANSLATE(*state)) { 5660 if (direction == PF_IN) { 5661 pf_change_icmp(pd2.src, &iih.icmp_id, 5662 daddr, &(*state)->lan.addr, 5663 (*state)->lan.port, NULL, 5664 pd2.ip_sum, icmpsum, 5665 pd->ip_sum, 0, AF_INET); 5666 } else { 5667 pf_change_icmp(pd2.dst, &iih.icmp_id, 5668 saddr, &(*state)->gwy.addr, 5669 (*state)->gwy.port, NULL, 5670 pd2.ip_sum, icmpsum, 5671 pd->ip_sum, 0, AF_INET); 5672 } 5673 m_copyback(m, off, ICMP_MINLEN, 5674 (caddr_t)pd->hdr.icmp); 5675 m_copyback(m, ipoff2, sizeof(h2), 5676 (caddr_t)&h2); 5677 m_copyback(m, off2, ICMP_MINLEN, 5678 (caddr_t)&iih); 5679 } 5680 5681 return (PF_PASS); 5682 break; 5683 } 5684#endif /* INET */ 5685#ifdef INET6 5686 case IPPROTO_ICMPV6: { 5687 struct icmp6_hdr iih; 5688 5689 if (!pf_pull_hdr(m, off2, &iih, 5690 sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) { 5691 DPFPRINTF(PF_DEBUG_MISC, 5692 ("pf: ICMP error message too short " 5693 "(icmp6)\n")); 5694 return (PF_DROP); 5695 } 5696 5697 key.af = pd2.af; 5698 key.proto = IPPROTO_ICMPV6; 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 = iih.icmp6_id; 5704 } else { 5705 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 5706 PF_ACPY(&key.ext.addr, pd2.src, key.af); 5707 key.lan.port = iih.icmp6_id; 5708 key.ext.port = 0; 5709 } 5710 5711 STATE_LOOKUP(); 5712 5713 if (STATE_TRANSLATE(*state)) { 5714 if (direction == PF_IN) { 5715 pf_change_icmp(pd2.src, &iih.icmp6_id, 5716 daddr, &(*state)->lan.addr, 5717 (*state)->lan.port, NULL, 5718 pd2.ip_sum, icmpsum, 5719 pd->ip_sum, 0, AF_INET6); 5720 } else { 5721 pf_change_icmp(pd2.dst, &iih.icmp6_id, 5722 saddr, &(*state)->gwy.addr, 5723 (*state)->gwy.port, NULL, 5724 pd2.ip_sum, icmpsum, 5725 pd->ip_sum, 0, AF_INET6); 5726 } 5727 m_copyback(m, off, sizeof(struct icmp6_hdr), 5728 (caddr_t)pd->hdr.icmp6); 5729 m_copyback(m, ipoff2, sizeof(h2_6), 5730 (caddr_t)&h2_6); 5731 m_copyback(m, off2, sizeof(struct icmp6_hdr), 5732 (caddr_t)&iih); 5733 } 5734 5735 return (PF_PASS); 5736 break; 5737 } 5738#endif /* INET6 */ 5739 default: { 5740 key.af = pd2.af; 5741 key.proto = pd2.proto; 5742 if (direction == PF_IN) { 5743 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 5744 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 5745 key.ext.port = 0; 5746 key.gwy.port = 0; 5747 } else { 5748 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 5749 PF_ACPY(&key.ext.addr, pd2.src, key.af); 5750 key.lan.port = 0; 5751 key.ext.port = 0; 5752 } 5753 5754 STATE_LOOKUP(); 5755 5756 if (STATE_TRANSLATE(*state)) { 5757 if (direction == PF_IN) { 5758 pf_change_icmp(pd2.src, NULL, 5759 daddr, &(*state)->lan.addr, 5760 0, NULL, 5761 pd2.ip_sum, icmpsum, 5762 pd->ip_sum, 0, pd2.af); 5763 } else { 5764 pf_change_icmp(pd2.dst, NULL, 5765 saddr, &(*state)->gwy.addr, 5766 0, NULL, 5767 pd2.ip_sum, icmpsum, 5768 pd->ip_sum, 0, pd2.af); 5769 } 5770 switch (pd2.af) { 5771#ifdef INET 5772 case AF_INET: 5773 m_copyback(m, off, ICMP_MINLEN, 5774 (caddr_t)pd->hdr.icmp); 5775 m_copyback(m, ipoff2, sizeof(h2), 5776 (caddr_t)&h2); 5777 break; 5778#endif /* INET */ 5779#ifdef INET6 5780 case AF_INET6: 5781 m_copyback(m, off, 5782 sizeof(struct icmp6_hdr), 5783 (caddr_t)pd->hdr.icmp6); 5784 m_copyback(m, ipoff2, sizeof(h2_6), 5785 (caddr_t)&h2_6); 5786 break; 5787#endif /* INET6 */ 5788 } 5789 } 5790 5791 return (PF_PASS); 5792 break; 5793 } 5794 } 5795 } 5796} 5797 5798int 5799pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, 5800 struct pf_pdesc *pd) 5801{ 5802 struct pf_state_peer *src, *dst; 5803 struct pf_state_cmp key; 5804 5805 key.af = pd->af; 5806 key.proto = pd->proto; 5807 if (direction == PF_IN) { 5808 PF_ACPY(&key.ext.addr, pd->src, key.af); 5809 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 5810 key.ext.port = 0; 5811 key.gwy.port = 0; 5812 } else { 5813 PF_ACPY(&key.lan.addr, pd->src, key.af); 5814 PF_ACPY(&key.ext.addr, pd->dst, key.af); 5815 key.lan.port = 0; 5816 key.ext.port = 0; 5817 } 5818 5819 STATE_LOOKUP(); 5820 5821 if (direction == (*state)->direction) { 5822 src = &(*state)->src; 5823 dst = &(*state)->dst; 5824 } else { 5825 src = &(*state)->dst; 5826 dst = &(*state)->src; 5827 } 5828 5829 /* update states */ 5830 if (src->state < PFOTHERS_SINGLE) 5831 src->state = PFOTHERS_SINGLE; 5832 if (dst->state == PFOTHERS_SINGLE) 5833 dst->state = PFOTHERS_MULTIPLE; 5834 5835 /* update expire time */ 5836 (*state)->expire = time_second; 5837 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE) 5838 (*state)->timeout = PFTM_OTHER_MULTIPLE; 5839 else 5840 (*state)->timeout = PFTM_OTHER_SINGLE; 5841 5842 /* translate source/destination address, if necessary */ 5843 if (STATE_TRANSLATE(*state)) { 5844 if (direction == PF_OUT) 5845 switch (pd->af) { 5846#ifdef INET 5847 case AF_INET: 5848 pf_change_a(&pd->src->v4.s_addr, 5849 pd->ip_sum, (*state)->gwy.addr.v4.s_addr, 5850 0); 5851 break; 5852#endif /* INET */ 5853#ifdef INET6 5854 case AF_INET6: 5855 PF_ACPY(pd->src, &(*state)->gwy.addr, pd->af); 5856 break; 5857#endif /* INET6 */ 5858 } 5859 else 5860 switch (pd->af) { 5861#ifdef INET 5862 case AF_INET: 5863 pf_change_a(&pd->dst->v4.s_addr, 5864 pd->ip_sum, (*state)->lan.addr.v4.s_addr, 5865 0); 5866 break; 5867#endif /* INET */ 5868#ifdef INET6 5869 case AF_INET6: 5870 PF_ACPY(pd->dst, &(*state)->lan.addr, pd->af); 5871 break; 5872#endif /* INET6 */ 5873 } 5874 } 5875 5876 return (PF_PASS); 5877} 5878 5879/* 5880 * ipoff and off are measured from the start of the mbuf chain. 5881 * h must be at "ipoff" on the mbuf chain. 5882 */ 5883void * 5884pf_pull_hdr(struct mbuf *m, int off, void *p, int len, 5885 u_short *actionp, u_short *reasonp, sa_family_t af) 5886{ 5887 switch (af) { 5888#ifdef INET 5889 case AF_INET: { 5890 struct ip *h = mtod(m, struct ip *); 5891 u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3; 5892 5893 if (fragoff) { 5894 if (fragoff >= len) 5895 ACTION_SET(actionp, PF_PASS); 5896 else { 5897 ACTION_SET(actionp, PF_DROP); 5898 REASON_SET(reasonp, PFRES_FRAG); 5899 } 5900 return (NULL); 5901 } 5902 if (m->m_pkthdr.len < off + len || 5903 ntohs(h->ip_len) < off + len) { 5904 ACTION_SET(actionp, PF_DROP); 5905 REASON_SET(reasonp, PFRES_SHORT); 5906 return (NULL); 5907 } 5908 break; 5909 } 5910#endif /* INET */ 5911#ifdef INET6 5912 case AF_INET6: { 5913 struct ip6_hdr *h = mtod(m, struct ip6_hdr *); 5914 5915 if (m->m_pkthdr.len < off + len || 5916 (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) < 5917 (unsigned)(off + len)) { 5918 ACTION_SET(actionp, PF_DROP); 5919 REASON_SET(reasonp, PFRES_SHORT); 5920 return (NULL); 5921 } 5922 break; 5923 } 5924#endif /* INET6 */ 5925 } 5926 m_copydata(m, off, len, p); 5927 return (p); 5928} 5929 5930int 5931pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif) 5932{ 5933 struct sockaddr_in *dst; 5934 int ret = 1; 5935 int check_mpath; 5936#ifndef __FreeBSD__ 5937 extern int ipmultipath; 5938#endif 5939#ifdef INET6 5940#ifndef __FreeBSD__ 5941 extern int ip6_multipath; 5942#endif 5943 struct sockaddr_in6 *dst6; 5944 struct route_in6 ro; 5945#else 5946 struct route ro; 5947#endif 5948 struct radix_node *rn; 5949 struct rtentry *rt; 5950 struct ifnet *ifp; 5951 5952 check_mpath = 0; 5953 bzero(&ro, sizeof(ro)); 5954 switch (af) { 5955 case AF_INET: 5956 dst = satosin(&ro.ro_dst); 5957 dst->sin_family = AF_INET; 5958 dst->sin_len = sizeof(*dst); 5959 dst->sin_addr = addr->v4; 5960#ifndef __FreeBSD__ /* MULTIPATH_ROUTING */ 5961 if (ipmultipath) 5962 check_mpath = 1; 5963#endif 5964 break; 5965#ifdef INET6 5966 case AF_INET6: 5967 dst6 = (struct sockaddr_in6 *)&ro.ro_dst; 5968 dst6->sin6_family = AF_INET6; 5969 dst6->sin6_len = sizeof(*dst6); 5970 dst6->sin6_addr = addr->v6; 5971#ifndef __FreeBSD__ /* MULTIPATH_ROUTING */ 5972 if (ip6_multipath) 5973 check_mpath = 1; 5974#endif 5975 break; 5976#endif /* INET6 */ 5977 default: 5978 return (0); 5979 } 5980 5981 /* Skip checks for ipsec interfaces */ 5982 if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC) 5983 goto out; 5984 5985#ifdef __FreeBSD__ 5986/* XXX MRT not always INET */ /* stick with table 0 though */ 5987 if (af == AF_INET) 5988 in_rtalloc_ign((struct route *)&ro, 0, 0); 5989 else 5990 rtalloc_ign((struct route *)&ro, 0); 5991#else /* ! __FreeBSD__ */ 5992 rtalloc_noclone((struct route *)&ro, NO_CLONING); 5993#endif 5994 5995 if (ro.ro_rt != NULL) { 5996 /* No interface given, this is a no-route check */ 5997 if (kif == NULL) 5998 goto out; 5999 6000 if (kif->pfik_ifp == NULL) { 6001 ret = 0; 6002 goto out; 6003 } 6004 6005 /* Perform uRPF check if passed input interface */ 6006 ret = 0; 6007 rn = (struct radix_node *)ro.ro_rt; 6008 do { 6009 rt = (struct rtentry *)rn; 6010#ifndef __FreeBSD__ /* CARPDEV */ 6011 if (rt->rt_ifp->if_type == IFT_CARP) 6012 ifp = rt->rt_ifp->if_carpdev; 6013 else 6014#endif 6015 ifp = rt->rt_ifp; 6016 6017 if (kif->pfik_ifp == ifp) 6018 ret = 1; 6019#ifdef __FreeBSD__ /* MULTIPATH_ROUTING */ 6020 rn = NULL; 6021#else 6022 rn = rn_mpath_next(rn); 6023#endif 6024 } while (check_mpath == 1 && rn != NULL && ret == 0); 6025 } else 6026 ret = 0; 6027out: 6028 if (ro.ro_rt != NULL) 6029 RTFREE(ro.ro_rt); 6030 return (ret); 6031} 6032 6033int 6034pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw) 6035{ 6036 struct sockaddr_in *dst; 6037#ifdef INET6 6038 struct sockaddr_in6 *dst6; 6039 struct route_in6 ro; 6040#else 6041 struct route ro; 6042#endif 6043 int ret = 0; 6044 6045 bzero(&ro, sizeof(ro)); 6046 switch (af) { 6047 case AF_INET: 6048 dst = satosin(&ro.ro_dst); 6049 dst->sin_family = AF_INET; 6050 dst->sin_len = sizeof(*dst); 6051 dst->sin_addr = addr->v4; 6052 break; 6053#ifdef INET6 6054 case AF_INET6: 6055 dst6 = (struct sockaddr_in6 *)&ro.ro_dst; 6056 dst6->sin6_family = AF_INET6; 6057 dst6->sin6_len = sizeof(*dst6); 6058 dst6->sin6_addr = addr->v6; 6059 break; 6060#endif /* INET6 */ 6061 default: 6062 return (0); 6063 } 6064 6065#ifdef __FreeBSD__ 6066# ifdef RTF_PRCLONING 6067 rtalloc_ign((struct route *)&ro, (RTF_CLONING|RTF_PRCLONING)); 6068# else /* !RTF_PRCLONING */ 6069 if (af == AF_INET) 6070 in_rtalloc_ign((struct route *)&ro, 0, 0); 6071 else 6072 rtalloc_ign((struct route *)&ro, 0); 6073# endif 6074#else /* ! __FreeBSD__ */ 6075 rtalloc_noclone((struct route *)&ro, NO_CLONING); 6076#endif 6077 6078 if (ro.ro_rt != NULL) { 6079#ifdef __FreeBSD__ 6080 /* XXX_IMPORT: later */ 6081#else 6082 if (ro.ro_rt->rt_labelid == aw->v.rtlabel) 6083 ret = 1; 6084#endif 6085 RTFREE(ro.ro_rt); 6086 } 6087 6088 return (ret); 6089} 6090 6091#ifdef INET 6092 6093void 6094pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 6095 struct pf_state *s, struct pf_pdesc *pd) 6096{ 6097 INIT_VNET_INET(curvnet); 6098 struct mbuf *m0, *m1; 6099 struct route iproute; 6100 struct route *ro = NULL; 6101 struct sockaddr_in *dst; 6102 struct ip *ip; 6103 struct ifnet *ifp = NULL; 6104 struct pf_addr naddr; 6105 struct pf_src_node *sn = NULL; 6106 int error = 0; 6107#ifdef __FreeBSD__ 6108 int sw_csum; 6109#endif 6110#ifdef IPSEC 6111 struct m_tag *mtag; 6112#endif /* IPSEC */ 6113 6114 if (m == NULL || *m == NULL || r == NULL || 6115 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 6116 panic("pf_route: invalid parameters"); 6117 6118 if (pd->pf_mtag->routed++ > 3) { 6119 m0 = *m; 6120 *m = NULL; 6121 goto bad; 6122 } 6123 6124 if (r->rt == PF_DUPTO) { 6125#ifdef __FreeBSD__ 6126 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 6127#else 6128 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 6129#endif 6130 return; 6131 } else { 6132 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 6133 return; 6134 m0 = *m; 6135 } 6136 6137 if (m0->m_len < sizeof(struct ip)) { 6138 DPFPRINTF(PF_DEBUG_URGENT, 6139 ("pf_route: m0->m_len < sizeof(struct ip)\n")); 6140 goto bad; 6141 } 6142 6143 ip = mtod(m0, struct ip *); 6144 6145 ro = &iproute; 6146 bzero((caddr_t)ro, sizeof(*ro)); 6147 dst = satosin(&ro->ro_dst); 6148 dst->sin_family = AF_INET; 6149 dst->sin_len = sizeof(*dst); 6150 dst->sin_addr = ip->ip_dst; 6151 6152 if (r->rt == PF_FASTROUTE) { 6153 in_rtalloc(ro, 0); 6154 if (ro->ro_rt == 0) { 6155 IPSTAT_INC(ips_noroute); 6156 goto bad; 6157 } 6158 6159 ifp = ro->ro_rt->rt_ifp; 6160 ro->ro_rt->rt_use++; 6161 6162 if (ro->ro_rt->rt_flags & RTF_GATEWAY) 6163 dst = satosin(ro->ro_rt->rt_gateway); 6164 } else { 6165 if (TAILQ_EMPTY(&r->rpool.list)) { 6166 DPFPRINTF(PF_DEBUG_URGENT, 6167 ("pf_route: TAILQ_EMPTY(&r->rpool.list)\n")); 6168 goto bad; 6169 } 6170 if (s == NULL) { 6171 pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src, 6172 &naddr, NULL, &sn); 6173 if (!PF_AZERO(&naddr, AF_INET)) 6174 dst->sin_addr.s_addr = naddr.v4.s_addr; 6175 ifp = r->rpool.cur->kif ? 6176 r->rpool.cur->kif->pfik_ifp : NULL; 6177 } else { 6178 if (!PF_AZERO(&s->rt_addr, AF_INET)) 6179 dst->sin_addr.s_addr = 6180 s->rt_addr.v4.s_addr; 6181 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; 6182 } 6183 } 6184 if (ifp == NULL) 6185 goto bad; 6186 6187 if (oifp != ifp) { 6188#ifdef __FreeBSD__ 6189 PF_UNLOCK(); 6190 if (pf_test(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) { 6191 PF_LOCK(); 6192 goto bad; 6193 } else if (m0 == NULL) { 6194 PF_LOCK(); 6195 goto done; 6196 } 6197 PF_LOCK(); 6198#else 6199 if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS) 6200 goto bad; 6201 else if (m0 == NULL) 6202 goto done; 6203#endif 6204 if (m0->m_len < sizeof(struct ip)) { 6205 DPFPRINTF(PF_DEBUG_URGENT, 6206 ("pf_route: m0->m_len < sizeof(struct ip)\n")); 6207 goto bad; 6208 } 6209 ip = mtod(m0, struct ip *); 6210 } 6211 6212#ifdef __FreeBSD__ 6213 /* Copied from FreeBSD 5.1-CURRENT ip_output. */ 6214 m0->m_pkthdr.csum_flags |= CSUM_IP; 6215 sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist; 6216 if (sw_csum & CSUM_DELAY_DATA) { 6217 /* 6218 * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least) 6219 */ 6220 NTOHS(ip->ip_len); 6221 NTOHS(ip->ip_off); /* XXX: needed? */ 6222 in_delayed_cksum(m0); 6223 HTONS(ip->ip_len); 6224 HTONS(ip->ip_off); 6225 sw_csum &= ~CSUM_DELAY_DATA; 6226 } 6227 m0->m_pkthdr.csum_flags &= ifp->if_hwassist; 6228 6229 if (ntohs(ip->ip_len) <= ifp->if_mtu || 6230 (ifp->if_hwassist & CSUM_FRAGMENT && 6231 ((ip->ip_off & htons(IP_DF)) == 0))) { 6232 /* 6233 * ip->ip_len = htons(ip->ip_len); 6234 * ip->ip_off = htons(ip->ip_off); 6235 */ 6236 ip->ip_sum = 0; 6237 if (sw_csum & CSUM_DELAY_IP) { 6238 /* From KAME */ 6239 if (ip->ip_v == IPVERSION && 6240 (ip->ip_hl << 2) == sizeof(*ip)) { 6241 ip->ip_sum = in_cksum_hdr(ip); 6242 } else { 6243 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 6244 } 6245 } 6246 PF_UNLOCK(); 6247 error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro); 6248 PF_LOCK(); 6249 goto done; 6250 } 6251 6252#else 6253 /* Copied from ip_output. */ 6254#ifdef IPSEC 6255 /* 6256 * If deferred crypto processing is needed, check that the 6257 * interface supports it. 6258 */ 6259 if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL)) 6260 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) { 6261 /* Notify IPsec to do its own crypto. */ 6262 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); 6263 goto bad; 6264 } 6265#endif /* IPSEC */ 6266 6267 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */ 6268 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) { 6269 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) || 6270 ifp->if_bridge != NULL) { 6271 in_delayed_cksum(m0); 6272 m0->m_pkthdr.csum_flags &= ~M_TCPV4_CSUM_OUT; /* Clear */ 6273 } 6274 } else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) { 6275 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) || 6276 ifp->if_bridge != NULL) { 6277 in_delayed_cksum(m0); 6278 m0->m_pkthdr.csum_flags &= ~M_UDPV4_CSUM_OUT; /* Clear */ 6279 } 6280 } 6281 6282 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 6283 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 6284 ifp->if_bridge == NULL) { 6285 m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; 6286 IPSTAT_INC(ips_outhwcsum); 6287 } else { 6288 ip->ip_sum = 0; 6289 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 6290 } 6291 /* Update relevant hardware checksum stats for TCP/UDP */ 6292 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) 6293 TCPSTAT_INC(tcpstat.tcps_outhwcsum); 6294 else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) 6295 UDPSTAT_INC(udps_outhwcsum); 6296 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); 6297 goto done; 6298 } 6299#endif 6300 /* 6301 * Too large for interface; fragment if possible. 6302 * Must be able to put at least 8 bytes per fragment. 6303 */ 6304 if (ip->ip_off & htons(IP_DF)) { 6305 IPSTAT_INC(ips_cantfrag); 6306 if (r->rt != PF_DUPTO) { 6307#ifdef __FreeBSD__ 6308 /* icmp_error() expects host byte ordering */ 6309 NTOHS(ip->ip_len); 6310 NTOHS(ip->ip_off); 6311 PF_UNLOCK(); 6312 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 6313 ifp->if_mtu); 6314 PF_LOCK(); 6315#else 6316 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 6317 ifp->if_mtu); 6318#endif 6319 goto done; 6320 } else 6321 goto bad; 6322 } 6323 6324 m1 = m0; 6325#ifdef __FreeBSD__ 6326 /* 6327 * XXX: is cheaper + less error prone than own function 6328 */ 6329 NTOHS(ip->ip_len); 6330 NTOHS(ip->ip_off); 6331 error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum); 6332#else 6333 error = ip_fragment(m0, ifp, ifp->if_mtu); 6334#endif 6335 if (error) { 6336#ifndef __FreeBSD__ /* ip_fragment does not do m_freem() on FreeBSD */ 6337 m0 = NULL; 6338#endif 6339 goto bad; 6340 } 6341 6342 for (m0 = m1; m0; m0 = m1) { 6343 m1 = m0->m_nextpkt; 6344 m0->m_nextpkt = 0; 6345#ifdef __FreeBSD__ 6346 if (error == 0) { 6347 PF_UNLOCK(); 6348 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 6349 NULL); 6350 PF_LOCK(); 6351 } else 6352#else 6353 if (error == 0) 6354 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 6355 NULL); 6356 else 6357#endif 6358 m_freem(m0); 6359 } 6360 6361 if (error == 0) 6362 IPSTAT_INC(ips_fragmented); 6363 6364done: 6365 if (r->rt != PF_DUPTO) 6366 *m = NULL; 6367 if (ro == &iproute && ro->ro_rt) 6368 RTFREE(ro->ro_rt); 6369 return; 6370 6371bad: 6372 m_freem(m0); 6373 goto done; 6374} 6375#endif /* INET */ 6376 6377#ifdef INET6 6378void 6379pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 6380 struct pf_state *s, struct pf_pdesc *pd) 6381{ 6382 struct mbuf *m0; 6383 struct route_in6 ip6route; 6384 struct route_in6 *ro; 6385 struct sockaddr_in6 *dst; 6386 struct ip6_hdr *ip6; 6387 struct ifnet *ifp = NULL; 6388 struct pf_addr naddr; 6389 struct pf_src_node *sn = NULL; 6390 int error = 0; 6391 6392 if (m == NULL || *m == NULL || r == NULL || 6393 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 6394 panic("pf_route6: invalid parameters"); 6395 6396 if (pd->pf_mtag->routed++ > 3) { 6397 m0 = *m; 6398 *m = NULL; 6399 goto bad; 6400 } 6401 6402 if (r->rt == PF_DUPTO) { 6403#ifdef __FreeBSD__ 6404 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 6405#else 6406 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 6407#endif 6408 return; 6409 } else { 6410 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 6411 return; 6412 m0 = *m; 6413 } 6414 6415 if (m0->m_len < sizeof(struct ip6_hdr)) { 6416 DPFPRINTF(PF_DEBUG_URGENT, 6417 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n")); 6418 goto bad; 6419 } 6420 ip6 = mtod(m0, struct ip6_hdr *); 6421 6422 ro = &ip6route; 6423 bzero((caddr_t)ro, sizeof(*ro)); 6424 dst = (struct sockaddr_in6 *)&ro->ro_dst; 6425 dst->sin6_family = AF_INET6; 6426 dst->sin6_len = sizeof(*dst); 6427 dst->sin6_addr = ip6->ip6_dst; 6428 6429 /* Cheat. XXX why only in the v6 case??? */ 6430 if (r->rt == PF_FASTROUTE) { 6431#ifdef __FreeBSD__ 6432 m0->m_flags |= M_SKIP_FIREWALL; 6433 PF_UNLOCK(); 6434 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 6435 PF_LOCK(); 6436#else 6437 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 6438 if (mtag == NULL) 6439 goto bad; 6440 m_tag_prepend(m0, mtag); 6441 pd->pf_mtag->flags |= PF_TAG_GENERATED; 6442 ip6_output(m0, NULL, NULL, 0, NULL, NULL); 6443#endif 6444 return; 6445 } 6446 6447 if (TAILQ_EMPTY(&r->rpool.list)) { 6448 DPFPRINTF(PF_DEBUG_URGENT, 6449 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n")); 6450 goto bad; 6451 } 6452 if (s == NULL) { 6453 pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, 6454 &naddr, NULL, &sn); 6455 if (!PF_AZERO(&naddr, AF_INET6)) 6456 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 6457 &naddr, AF_INET6); 6458 ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; 6459 } else { 6460 if (!PF_AZERO(&s->rt_addr, AF_INET6)) 6461 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 6462 &s->rt_addr, AF_INET6); 6463 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; 6464 } 6465 if (ifp == NULL) 6466 goto bad; 6467 6468 if (oifp != ifp) { 6469#ifdef __FreeBSD__ 6470 PF_UNLOCK(); 6471 if (pf_test6(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) { 6472 PF_LOCK(); 6473 goto bad; 6474 } else if (m0 == NULL) { 6475 PF_LOCK(); 6476 goto done; 6477 } 6478 PF_LOCK(); 6479#else 6480 if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS) 6481 goto bad; 6482 else if (m0 == NULL) 6483 goto done; 6484#endif 6485 if (m0->m_len < sizeof(struct ip6_hdr)) { 6486 DPFPRINTF(PF_DEBUG_URGENT, 6487 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n")); 6488 goto bad; 6489 } 6490 ip6 = mtod(m0, struct ip6_hdr *); 6491 } 6492 6493 /* 6494 * If the packet is too large for the outgoing interface, 6495 * send back an icmp6 error. 6496 */ 6497 if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr)) 6498 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); 6499 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { 6500#ifdef __FreeBSD__ 6501 PF_UNLOCK(); 6502#endif 6503 error = nd6_output(ifp, ifp, m0, dst, NULL); 6504#ifdef __FreeBSD__ 6505 PF_LOCK(); 6506#endif 6507 } else { 6508 in6_ifstat_inc(ifp, ifs6_in_toobig); 6509#ifdef __FreeBSD__ 6510 if (r->rt != PF_DUPTO) { 6511 PF_UNLOCK(); 6512 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 6513 PF_LOCK(); 6514 } else 6515#else 6516 if (r->rt != PF_DUPTO) 6517 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 6518 else 6519#endif 6520 goto bad; 6521 } 6522 6523done: 6524 if (r->rt != PF_DUPTO) 6525 *m = NULL; 6526 return; 6527 6528bad: 6529 m_freem(m0); 6530 goto done; 6531} 6532#endif /* INET6 */ 6533 6534 6535#ifdef __FreeBSD__ 6536/* 6537 * FreeBSD supports cksum offloads for the following drivers. 6538 * em(4), fxp(4), ixgb(4), lge(4), ndis(4), nge(4), re(4), 6539 * ti(4), txp(4), xl(4) 6540 * 6541 * CSUM_DATA_VALID | CSUM_PSEUDO_HDR : 6542 * network driver performed cksum including pseudo header, need to verify 6543 * csum_data 6544 * CSUM_DATA_VALID : 6545 * network driver performed cksum, needs to additional pseudo header 6546 * cksum computation with partial csum_data(i.e. lack of H/W support for 6547 * pseudo header, for instance hme(4), sk(4) and possibly gem(4)) 6548 * 6549 * After validating the cksum of packet, set both flag CSUM_DATA_VALID and 6550 * CSUM_PSEUDO_HDR in order to avoid recomputation of the cksum in upper 6551 * TCP/UDP layer. 6552 * Also, set csum_data to 0xffff to force cksum validation. 6553 */ 6554int 6555pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) 6556{ 6557 u_int16_t sum = 0; 6558 int hw_assist = 0; 6559 struct ip *ip; 6560 6561 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 6562 return (1); 6563 if (m->m_pkthdr.len < off + len) 6564 return (1); 6565 6566 switch (p) { 6567 case IPPROTO_TCP: 6568 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 6569 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 6570 sum = m->m_pkthdr.csum_data; 6571 } else { 6572 ip = mtod(m, struct ip *); 6573 sum = in_pseudo(ip->ip_src.s_addr, 6574 ip->ip_dst.s_addr, htonl((u_short)len + 6575 m->m_pkthdr.csum_data + IPPROTO_TCP)); 6576 } 6577 sum ^= 0xffff; 6578 ++hw_assist; 6579 } 6580 break; 6581 case IPPROTO_UDP: 6582 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 6583 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 6584 sum = m->m_pkthdr.csum_data; 6585 } else { 6586 ip = mtod(m, struct ip *); 6587 sum = in_pseudo(ip->ip_src.s_addr, 6588 ip->ip_dst.s_addr, htonl((u_short)len + 6589 m->m_pkthdr.csum_data + IPPROTO_UDP)); 6590 } 6591 sum ^= 0xffff; 6592 ++hw_assist; 6593 } 6594 break; 6595 case IPPROTO_ICMP: 6596#ifdef INET6 6597 case IPPROTO_ICMPV6: 6598#endif /* INET6 */ 6599 break; 6600 default: 6601 return (1); 6602 } 6603 6604 if (!hw_assist) { 6605 switch (af) { 6606 case AF_INET: 6607 if (p == IPPROTO_ICMP) { 6608 if (m->m_len < off) 6609 return (1); 6610 m->m_data += off; 6611 m->m_len -= off; 6612 sum = in_cksum(m, len); 6613 m->m_data -= off; 6614 m->m_len += off; 6615 } else { 6616 if (m->m_len < sizeof(struct ip)) 6617 return (1); 6618 sum = in4_cksum(m, p, off, len); 6619 } 6620 break; 6621#ifdef INET6 6622 case AF_INET6: 6623 if (m->m_len < sizeof(struct ip6_hdr)) 6624 return (1); 6625 sum = in6_cksum(m, p, off, len); 6626 break; 6627#endif /* INET6 */ 6628 default: 6629 return (1); 6630 } 6631 } 6632 if (sum) { 6633 switch (p) { 6634 case IPPROTO_TCP: 6635 { 6636 INIT_VNET_INET(curvnet); 6637 TCPSTAT_INC(tcps_rcvbadsum); 6638 break; 6639 } 6640 case IPPROTO_UDP: 6641 { 6642 INIT_VNET_INET(curvnet); 6643 UDPSTAT_INC(udps_badsum); 6644 break; 6645 } 6646 case IPPROTO_ICMP: 6647 { 6648 INIT_VNET_INET(curvnet); 6649 ICMPSTAT_INC(icps_checksum); 6650 break; 6651 } 6652#ifdef INET6 6653 case IPPROTO_ICMPV6: 6654 { 6655 INIT_VNET_INET6(curvnet); 6656 ICMP6STAT_INC(icp6s_checksum); 6657 break; 6658 } 6659#endif /* INET6 */ 6660 } 6661 return (1); 6662 } else { 6663 if (p == IPPROTO_TCP || p == IPPROTO_UDP) { 6664 m->m_pkthdr.csum_flags |= 6665 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); 6666 m->m_pkthdr.csum_data = 0xffff; 6667 } 6668 } 6669 return (0); 6670} 6671#else /* !__FreeBSD__ */ 6672/* 6673 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 6674 * off is the offset where the protocol header starts 6675 * len is the total length of protocol header plus payload 6676 * returns 0 when the checksum is valid, otherwise returns 1. 6677 */ 6678int 6679pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, 6680 sa_family_t af) 6681{ 6682 u_int16_t flag_ok, flag_bad; 6683 u_int16_t sum; 6684 6685 switch (p) { 6686 case IPPROTO_TCP: 6687 flag_ok = M_TCP_CSUM_IN_OK; 6688 flag_bad = M_TCP_CSUM_IN_BAD; 6689 break; 6690 case IPPROTO_UDP: 6691 flag_ok = M_UDP_CSUM_IN_OK; 6692 flag_bad = M_UDP_CSUM_IN_BAD; 6693 break; 6694 case IPPROTO_ICMP: 6695#ifdef INET6 6696 case IPPROTO_ICMPV6: 6697#endif /* INET6 */ 6698 flag_ok = flag_bad = 0; 6699 break; 6700 default: 6701 return (1); 6702 } 6703 if (m->m_pkthdr.csum_flags & flag_ok) 6704 return (0); 6705 if (m->m_pkthdr.csum_flags & flag_bad) 6706 return (1); 6707 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 6708 return (1); 6709 if (m->m_pkthdr.len < off + len) 6710 return (1); 6711 switch (af) { 6712#ifdef INET 6713 case AF_INET: 6714 if (p == IPPROTO_ICMP) { 6715 if (m->m_len < off) 6716 return (1); 6717 m->m_data += off; 6718 m->m_len -= off; 6719 sum = in_cksum(m, len); 6720 m->m_data -= off; 6721 m->m_len += off; 6722 } else { 6723 if (m->m_len < sizeof(struct ip)) 6724 return (1); 6725 sum = in4_cksum(m, p, off, len); 6726 } 6727 break; 6728#endif /* INET */ 6729#ifdef INET6 6730 case AF_INET6: 6731 if (m->m_len < sizeof(struct ip6_hdr)) 6732 return (1); 6733 sum = in6_cksum(m, p, off, len); 6734 break; 6735#endif /* INET6 */ 6736 default: 6737 return (1); 6738 } 6739 if (sum) { 6740 m->m_pkthdr.csum_flags |= flag_bad; 6741 switch (p) { 6742 case IPPROTO_TCP: 6743 TCPSTAT_INC(tcps_rcvbadsum); 6744 break; 6745 case IPPROTO_UDP: 6746 UDPSTAT_INC(udps_badsum); 6747 break; 6748 case IPPROTO_ICMP: 6749 ICMPSTAT_INC(icps_checksum); 6750 break; 6751#ifdef INET6 6752 case IPPROTO_ICMPV6: 6753 ICMP6STAT_INC(icp6s_checksum); 6754 break; 6755#endif /* INET6 */ 6756 } 6757 return (1); 6758 } 6759 m->m_pkthdr.csum_flags |= flag_ok; 6760 return (0); 6761} 6762#endif /* __FreeBSD__ */ 6763 6764#ifdef INET 6765int 6766#ifdef __FreeBSD__ 6767pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6768 struct ether_header *eh, struct inpcb *inp) 6769#else 6770pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6771 struct ether_header *eh) 6772#endif 6773{ 6774 struct pfi_kif *kif; 6775 u_short action, reason = 0, log = 0; 6776 struct mbuf *m = *m0; 6777 struct ip *h = NULL; /* make the compiler happy */ 6778 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 6779 struct pf_state *s = NULL; 6780 struct pf_ruleset *ruleset = NULL; 6781 struct pf_pdesc pd; 6782 int off, dirndx, pqid = 0; 6783 6784#ifdef __FreeBSD__ 6785 PF_LOCK(); 6786#endif 6787 if (!pf_status.running) 6788#ifdef __FreeBSD__ 6789 { 6790 PF_UNLOCK(); 6791#endif 6792 return (PF_PASS); 6793#ifdef __FreeBSD__ 6794 } 6795#endif 6796 6797 memset(&pd, 0, sizeof(pd)); 6798 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) { 6799#ifdef __FreeBSD__ 6800 PF_UNLOCK(); 6801#endif 6802 DPFPRINTF(PF_DEBUG_URGENT, 6803 ("pf_test: pf_get_mtag returned NULL\n")); 6804 return (PF_DROP); 6805 } 6806#ifdef __FreeBSD__ 6807 if (m->m_flags & M_SKIP_FIREWALL) { 6808 PF_UNLOCK(); 6809 return (PF_PASS); 6810 } 6811#else 6812 if (pd.pf_mtag->flags & PF_TAG_GENERATED) 6813 return (PF_PASS); 6814#endif 6815 6816#ifdef __FreeBSD__ 6817 /* XXX_IMPORT: later */ 6818#else 6819 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 6820 ifp = ifp->if_carpdev; 6821#endif 6822 6823 kif = (struct pfi_kif *)ifp->if_pf_kif; 6824 if (kif == NULL) { 6825#ifdef __FreeBSD__ 6826 PF_UNLOCK(); 6827#endif 6828 DPFPRINTF(PF_DEBUG_URGENT, 6829 ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname)); 6830 return (PF_DROP); 6831 } 6832 if (kif->pfik_flags & PFI_IFLAG_SKIP) { 6833#ifdef __FreeBSD__ 6834 PF_UNLOCK(); 6835#endif 6836 return (PF_PASS); 6837 } 6838 6839#ifdef __FreeBSD__ 6840 M_ASSERTPKTHDR(m); 6841#else 6842#ifdef DIAGNOSTIC 6843 if ((m->m_flags & M_PKTHDR) == 0) 6844 panic("non-M_PKTHDR is passed to pf_test"); 6845#endif /* DIAGNOSTIC */ 6846#endif /* __FreeBSD__ */ 6847 6848 if (m->m_pkthdr.len < (int)sizeof(*h)) { 6849 action = PF_DROP; 6850 REASON_SET(&reason, PFRES_SHORT); 6851 log = 1; 6852 goto done; 6853 } 6854 6855 /* We do IP header normalization and packet reassembly here */ 6856 if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) { 6857 action = PF_DROP; 6858 goto done; 6859 } 6860 m = *m0; 6861 h = mtod(m, struct ip *); 6862 6863 off = h->ip_hl << 2; 6864 if (off < (int)sizeof(*h)) { 6865 action = PF_DROP; 6866 REASON_SET(&reason, PFRES_SHORT); 6867 log = 1; 6868 goto done; 6869 } 6870 6871 pd.src = (struct pf_addr *)&h->ip_src; 6872 pd.dst = (struct pf_addr *)&h->ip_dst; 6873 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET); 6874 pd.ip_sum = &h->ip_sum; 6875 pd.proto = h->ip_p; 6876 pd.af = AF_INET; 6877 pd.tos = h->ip_tos; 6878 pd.tot_len = ntohs(h->ip_len); 6879 pd.eh = eh; 6880 6881 /* handle fragments that didn't get reassembled by normalization */ 6882 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) { 6883 action = pf_test_fragment(&r, dir, kif, m, h, 6884 &pd, &a, &ruleset); 6885 goto done; 6886 } 6887 6888 switch (h->ip_p) { 6889 6890 case IPPROTO_TCP: { 6891 struct tcphdr th; 6892 6893 pd.hdr.tcp = &th; 6894 if (!pf_pull_hdr(m, off, &th, sizeof(th), 6895 &action, &reason, AF_INET)) { 6896 log = action != PF_PASS; 6897 goto done; 6898 } 6899 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6900 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) { 6901 REASON_SET(&reason, PFRES_PROTCKSUM); 6902 action = PF_DROP; 6903 goto done; 6904 } 6905 pd.p_len = pd.tot_len - off - (th.th_off << 2); 6906 if ((th.th_flags & TH_ACK) && pd.p_len == 0) 6907 pqid = 1; 6908 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 6909 if (action == PF_DROP) 6910 goto done; 6911 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, 6912 &reason); 6913 if (action == PF_PASS) { 6914#if NPFSYNC 6915 pfsync_update_state(s); 6916#endif /* NPFSYNC */ 6917 r = s->rule.ptr; 6918 a = s->anchor.ptr; 6919 log = s->log; 6920 } else if (s == NULL) 6921#ifdef __FreeBSD__ 6922 action = pf_test_tcp(&r, &s, dir, kif, 6923 m, off, h, &pd, &a, &ruleset, NULL, inp); 6924#else 6925 action = pf_test_tcp(&r, &s, dir, kif, 6926 m, off, h, &pd, &a, &ruleset, &ipintrq); 6927#endif 6928 break; 6929 } 6930 6931 case IPPROTO_UDP: { 6932 struct udphdr uh; 6933 6934 pd.hdr.udp = &uh; 6935 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 6936 &action, &reason, AF_INET)) { 6937 log = action != PF_PASS; 6938 goto done; 6939 } 6940 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 6941 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) { 6942 action = PF_DROP; 6943 REASON_SET(&reason, PFRES_PROTCKSUM); 6944 goto done; 6945 } 6946 if (uh.uh_dport == 0 || 6947 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 6948 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 6949 action = PF_DROP; 6950 REASON_SET(&reason, PFRES_SHORT); 6951 goto done; 6952 } 6953 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 6954 if (action == PF_PASS) { 6955#if NPFSYNC 6956 pfsync_update_state(s); 6957#endif /* NPFSYNC */ 6958 r = s->rule.ptr; 6959 a = s->anchor.ptr; 6960 log = s->log; 6961 } else if (s == NULL) 6962#ifdef __FreeBSD__ 6963 action = pf_test_udp(&r, &s, dir, kif, 6964 m, off, h, &pd, &a, &ruleset, NULL, inp); 6965#else 6966 action = pf_test_udp(&r, &s, dir, kif, 6967 m, off, h, &pd, &a, &ruleset, &ipintrq); 6968#endif 6969 break; 6970 } 6971 6972 case IPPROTO_ICMP: { 6973 struct icmp ih; 6974 6975 pd.hdr.icmp = &ih; 6976 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN, 6977 &action, &reason, AF_INET)) { 6978 log = action != PF_PASS; 6979 goto done; 6980 } 6981 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6982 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) { 6983 action = PF_DROP; 6984 REASON_SET(&reason, PFRES_PROTCKSUM); 6985 goto done; 6986 } 6987 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd, 6988 &reason); 6989 if (action == PF_PASS) { 6990#if NPFSYNC 6991 pfsync_update_state(s); 6992#endif /* NPFSYNC */ 6993 r = s->rule.ptr; 6994 a = s->anchor.ptr; 6995 log = s->log; 6996 } else if (s == NULL) 6997#ifdef __FreeBSD__ 6998 action = pf_test_icmp(&r, &s, dir, kif, 6999 m, off, h, &pd, &a, &ruleset, NULL); 7000#else 7001 action = pf_test_icmp(&r, &s, dir, kif, 7002 m, off, h, &pd, &a, &ruleset, &ipintrq); 7003#endif 7004 break; 7005 } 7006 7007 default: 7008 action = pf_test_state_other(&s, dir, kif, &pd); 7009 if (action == PF_PASS) { 7010#if NPFSYNC 7011 pfsync_update_state(s); 7012#endif /* NPFSYNC */ 7013 r = s->rule.ptr; 7014 a = s->anchor.ptr; 7015 log = s->log; 7016 } else if (s == NULL) 7017#ifdef __FreeBSD__ 7018 action = pf_test_other(&r, &s, dir, kif, m, off, h, 7019 &pd, &a, &ruleset, NULL); 7020#else 7021 action = pf_test_other(&r, &s, dir, kif, m, off, h, 7022 &pd, &a, &ruleset, &ipintrq); 7023#endif 7024 break; 7025 } 7026 7027done: 7028 if (action == PF_PASS && h->ip_hl > 5 && 7029 !((s && s->allow_opts) || r->allow_opts)) { 7030 action = PF_DROP; 7031 REASON_SET(&reason, PFRES_IPOPTIONS); 7032 log = 1; 7033 DPFPRINTF(PF_DEBUG_MISC, 7034 ("pf: dropping packet with ip options\n")); 7035 } 7036 7037 if ((s && s->tag) || r->rtableid) 7038 pf_tag_packet(m, pd.pf_mtag, s ? s->tag : 0, r->rtableid); 7039 7040#ifdef ALTQ 7041 if (action == PF_PASS && r->qid) { 7042 if (pqid || (pd.tos & IPTOS_LOWDELAY)) 7043 pd.pf_mtag->qid = r->pqid; 7044 else 7045 pd.pf_mtag->qid = r->qid; 7046 /* add hints for ecn */ 7047 pd.pf_mtag->af = AF_INET; 7048 pd.pf_mtag->hdr = h; 7049 } 7050#endif /* ALTQ */ 7051 7052 /* 7053 * connections redirected to loopback should not match sockets 7054 * bound specifically to loopback due to security implications, 7055 * see tcp_input() and in_pcblookup_listen(). 7056 */ 7057 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 7058 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 7059 (s->nat_rule.ptr->action == PF_RDR || 7060 s->nat_rule.ptr->action == PF_BINAT) && 7061 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 7062 pd.pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST; 7063 7064 if (log) { 7065 struct pf_rule *lr; 7066 7067 if (s != NULL && s->nat_rule.ptr != NULL && 7068 s->nat_rule.ptr->log & PF_LOG_ALL) 7069 lr = s->nat_rule.ptr; 7070 else 7071 lr = r; 7072 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, lr, a, ruleset, 7073 &pd); 7074 } 7075 7076 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7077 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++; 7078 7079 if (action == PF_PASS || r->action == PF_DROP) { 7080 dirndx = (dir == PF_OUT); 7081 r->packets[dirndx]++; 7082 r->bytes[dirndx] += pd.tot_len; 7083 if (a != NULL) { 7084 a->packets[dirndx]++; 7085 a->bytes[dirndx] += pd.tot_len; 7086 } 7087 if (s != NULL) { 7088 if (s->nat_rule.ptr != NULL) { 7089 s->nat_rule.ptr->packets[dirndx]++; 7090 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; 7091 } 7092 if (s->src_node != NULL) { 7093 s->src_node->packets[dirndx]++; 7094 s->src_node->bytes[dirndx] += pd.tot_len; 7095 } 7096 if (s->nat_src_node != NULL) { 7097 s->nat_src_node->packets[dirndx]++; 7098 s->nat_src_node->bytes[dirndx] += pd.tot_len; 7099 } 7100 dirndx = (dir == s->direction) ? 0 : 1; 7101 s->packets[dirndx]++; 7102 s->bytes[dirndx] += pd.tot_len; 7103 } 7104 tr = r; 7105 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7106 if (nr != NULL) { 7107 struct pf_addr *x; 7108 /* 7109 * XXX: we need to make sure that the addresses 7110 * passed to pfr_update_stats() are the same than 7111 * the addresses used during matching (pfr_match) 7112 */ 7113 if (r == &pf_default_rule) { 7114 tr = nr; 7115 x = (s == NULL || s->direction == dir) ? 7116 &pd.baddr : &pd.naddr; 7117 } else 7118 x = (s == NULL || s->direction == dir) ? 7119 &pd.naddr : &pd.baddr; 7120 if (x == &pd.baddr || s == NULL) { 7121 /* we need to change the address */ 7122 if (dir == PF_OUT) 7123 pd.src = x; 7124 else 7125 pd.dst = x; 7126 } 7127 } 7128 if (tr->src.addr.type == PF_ADDR_TABLE) 7129 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL || 7130 s->direction == dir) ? pd.src : pd.dst, pd.af, 7131 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 7132 tr->src.neg); 7133 if (tr->dst.addr.type == PF_ADDR_TABLE) 7134 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL || 7135 s->direction == dir) ? pd.dst : pd.src, pd.af, 7136 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 7137 tr->dst.neg); 7138 } 7139 7140 7141 if (action == PF_SYNPROXY_DROP) { 7142 m_freem(*m0); 7143 *m0 = NULL; 7144 action = PF_PASS; 7145 } else if (r->rt) 7146 /* pf_route can free the mbuf causing *m0 to become NULL */ 7147 pf_route(m0, r, dir, ifp, s, &pd); 7148 7149#ifdef __FreeBSD__ 7150 PF_UNLOCK(); 7151#endif 7152 7153 return (action); 7154} 7155#endif /* INET */ 7156 7157#ifdef INET6 7158int 7159#ifdef __FreeBSD__ 7160pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, 7161 struct ether_header *eh, struct inpcb *inp) 7162#else 7163pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, 7164 struct ether_header *eh) 7165#endif 7166{ 7167 struct pfi_kif *kif; 7168 u_short action, reason = 0, log = 0; 7169 struct mbuf *m = *m0, *n = NULL; 7170 struct ip6_hdr *h; 7171 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 7172 struct pf_state *s = NULL; 7173 struct pf_ruleset *ruleset = NULL; 7174 struct pf_pdesc pd; 7175 int off, terminal = 0, dirndx, rh_cnt = 0; 7176 7177#ifdef __FreeBSD__ 7178 PF_LOCK(); 7179#endif 7180 7181 if (!pf_status.running) 7182#ifdef __FreeBSD__ 7183 { 7184 PF_UNLOCK(); 7185#endif 7186 return (PF_PASS); 7187#ifdef __FreeBSD__ 7188 } 7189#endif 7190 7191 memset(&pd, 0, sizeof(pd)); 7192 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) { 7193#ifdef __FreeBSD__ 7194 PF_UNLOCK(); 7195#endif 7196 DPFPRINTF(PF_DEBUG_URGENT, 7197 ("pf_test6: pf_get_mtag returned NULL\n")); 7198 return (PF_DROP); 7199 } 7200 if (pd.pf_mtag->flags & PF_TAG_GENERATED) 7201 return (PF_PASS); 7202 7203#ifdef __FreeBSD__ 7204 /* XXX_IMPORT: later */ 7205#else 7206 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 7207 ifp = ifp->if_carpdev; 7208#endif 7209 7210 kif = (struct pfi_kif *)ifp->if_pf_kif; 7211 if (kif == NULL) { 7212#ifdef __FreeBSD__ 7213 PF_UNLOCK(); 7214#endif 7215 DPFPRINTF(PF_DEBUG_URGENT, 7216 ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname)); 7217 return (PF_DROP); 7218 } 7219 if (kif->pfik_flags & PFI_IFLAG_SKIP) { 7220#ifdef __FreeBSD__ 7221 PF_UNLOCK(); 7222#endif 7223 return (PF_PASS); 7224 } 7225 7226#ifdef __FreeBSD__ 7227 M_ASSERTPKTHDR(m); 7228#else 7229#ifdef DIAGNOSTIC 7230 if ((m->m_flags & M_PKTHDR) == 0) 7231 panic("non-M_PKTHDR is passed to pf_test6"); 7232#endif /* DIAGNOSTIC */ 7233#endif 7234 7235#ifdef __FreeBSD__ 7236 h = NULL; /* make the compiler happy */ 7237#endif 7238 7239 if (m->m_pkthdr.len < (int)sizeof(*h)) { 7240 action = PF_DROP; 7241 REASON_SET(&reason, PFRES_SHORT); 7242 log = 1; 7243 goto done; 7244 } 7245 7246 /* We do IP header normalization and packet reassembly here */ 7247 if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) { 7248 action = PF_DROP; 7249 goto done; 7250 } 7251 m = *m0; 7252 h = mtod(m, struct ip6_hdr *); 7253 7254#if 1 7255 /* 7256 * we do not support jumbogram yet. if we keep going, zero ip6_plen 7257 * will do something bad, so drop the packet for now. 7258 */ 7259 if (htons(h->ip6_plen) == 0) { 7260 action = PF_DROP; 7261 REASON_SET(&reason, PFRES_NORM); /*XXX*/ 7262 goto done; 7263 } 7264#endif 7265 7266 pd.src = (struct pf_addr *)&h->ip6_src; 7267 pd.dst = (struct pf_addr *)&h->ip6_dst; 7268 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET6); 7269 pd.ip_sum = NULL; 7270 pd.af = AF_INET6; 7271 pd.tos = 0; 7272 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr); 7273 pd.eh = eh; 7274 7275 off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr); 7276 pd.proto = h->ip6_nxt; 7277 do { 7278 switch (pd.proto) { 7279 case IPPROTO_FRAGMENT: 7280 action = pf_test_fragment(&r, dir, kif, m, h, 7281 &pd, &a, &ruleset); 7282 if (action == PF_DROP) 7283 REASON_SET(&reason, PFRES_FRAG); 7284 goto done; 7285 case IPPROTO_ROUTING: { 7286 struct ip6_rthdr rthdr; 7287 7288 if (rh_cnt++) { 7289 DPFPRINTF(PF_DEBUG_MISC, 7290 ("pf: IPv6 more than one rthdr\n")); 7291 action = PF_DROP; 7292 REASON_SET(&reason, PFRES_IPOPTIONS); 7293 log = 1; 7294 goto done; 7295 } 7296 if (!pf_pull_hdr(m, off, &rthdr, sizeof(rthdr), NULL, 7297 &reason, pd.af)) { 7298 DPFPRINTF(PF_DEBUG_MISC, 7299 ("pf: IPv6 short rthdr\n")); 7300 action = PF_DROP; 7301 REASON_SET(&reason, PFRES_SHORT); 7302 log = 1; 7303 goto done; 7304 } 7305 if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) { 7306 DPFPRINTF(PF_DEBUG_MISC, 7307 ("pf: IPv6 rthdr0\n")); 7308 action = PF_DROP; 7309 REASON_SET(&reason, PFRES_IPOPTIONS); 7310 log = 1; 7311 goto done; 7312 } 7313 /* fallthrough */ 7314 } 7315 case IPPROTO_AH: 7316 case IPPROTO_HOPOPTS: 7317 case IPPROTO_DSTOPTS: { 7318 /* get next header and header length */ 7319 struct ip6_ext opt6; 7320 7321 if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6), 7322 NULL, &reason, pd.af)) { 7323 DPFPRINTF(PF_DEBUG_MISC, 7324 ("pf: IPv6 short opt\n")); 7325 action = PF_DROP; 7326 log = 1; 7327 goto done; 7328 } 7329 if (pd.proto == IPPROTO_AH) 7330 off += (opt6.ip6e_len + 2) * 4; 7331 else 7332 off += (opt6.ip6e_len + 1) * 8; 7333 pd.proto = opt6.ip6e_nxt; 7334 /* goto the next header */ 7335 break; 7336 } 7337 default: 7338 terminal++; 7339 break; 7340 } 7341 } while (!terminal); 7342 7343 /* if there's no routing header, use unmodified mbuf for checksumming */ 7344 if (!n) 7345 n = m; 7346 7347 switch (pd.proto) { 7348 7349 case IPPROTO_TCP: { 7350 struct tcphdr th; 7351 7352 pd.hdr.tcp = &th; 7353 if (!pf_pull_hdr(m, off, &th, sizeof(th), 7354 &action, &reason, AF_INET6)) { 7355 log = action != PF_PASS; 7356 goto done; 7357 } 7358 if (dir == PF_IN && pf_check_proto_cksum(n, off, 7359 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7360 IPPROTO_TCP, AF_INET6)) { 7361 action = PF_DROP; 7362 REASON_SET(&reason, PFRES_PROTCKSUM); 7363 goto done; 7364 } 7365 pd.p_len = pd.tot_len - off - (th.th_off << 2); 7366 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 7367 if (action == PF_DROP) 7368 goto done; 7369 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, 7370 &reason); 7371 if (action == PF_PASS) { 7372#if NPFSYNC 7373 pfsync_update_state(s); 7374#endif /* NPFSYNC */ 7375 r = s->rule.ptr; 7376 a = s->anchor.ptr; 7377 log = s->log; 7378 } else if (s == NULL) 7379#ifdef __FreeBSD__ 7380 action = pf_test_tcp(&r, &s, dir, kif, 7381 m, off, h, &pd, &a, &ruleset, NULL, inp); 7382#else 7383 action = pf_test_tcp(&r, &s, dir, kif, 7384 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7385#endif 7386 break; 7387 } 7388 7389 case IPPROTO_UDP: { 7390 struct udphdr uh; 7391 7392 pd.hdr.udp = &uh; 7393 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 7394 &action, &reason, AF_INET6)) { 7395 log = action != PF_PASS; 7396 goto done; 7397 } 7398 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(n, 7399 off, ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7400 IPPROTO_UDP, AF_INET6)) { 7401 action = PF_DROP; 7402 REASON_SET(&reason, PFRES_PROTCKSUM); 7403 goto done; 7404 } 7405 if (uh.uh_dport == 0 || 7406 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 7407 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 7408 action = PF_DROP; 7409 REASON_SET(&reason, PFRES_SHORT); 7410 goto done; 7411 } 7412 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 7413 if (action == PF_PASS) { 7414#if NPFSYNC 7415 pfsync_update_state(s); 7416#endif /* NPFSYNC */ 7417 r = s->rule.ptr; 7418 a = s->anchor.ptr; 7419 log = s->log; 7420 } else if (s == NULL) 7421#ifdef __FreeBSD__ 7422 action = pf_test_udp(&r, &s, dir, kif, 7423 m, off, h, &pd, &a, &ruleset, NULL, inp); 7424#else 7425 action = pf_test_udp(&r, &s, dir, kif, 7426 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7427#endif 7428 break; 7429 } 7430 7431 case IPPROTO_ICMPV6: { 7432 struct icmp6_hdr ih; 7433 7434 pd.hdr.icmp6 = &ih; 7435 if (!pf_pull_hdr(m, off, &ih, sizeof(ih), 7436 &action, &reason, AF_INET6)) { 7437 log = action != PF_PASS; 7438 goto done; 7439 } 7440 if (dir == PF_IN && pf_check_proto_cksum(n, off, 7441 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7442 IPPROTO_ICMPV6, AF_INET6)) { 7443 action = PF_DROP; 7444 REASON_SET(&reason, PFRES_PROTCKSUM); 7445 goto done; 7446 } 7447 action = pf_test_state_icmp(&s, dir, kif, 7448 m, off, h, &pd, &reason); 7449 if (action == PF_PASS) { 7450#if NPFSYNC 7451 pfsync_update_state(s); 7452#endif /* NPFSYNC */ 7453 r = s->rule.ptr; 7454 a = s->anchor.ptr; 7455 log = s->log; 7456 } else if (s == NULL) 7457#ifdef __FreeBSD__ 7458 action = pf_test_icmp(&r, &s, dir, kif, 7459 m, off, h, &pd, &a, &ruleset, NULL); 7460#else 7461 action = pf_test_icmp(&r, &s, dir, kif, 7462 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7463#endif 7464 break; 7465 } 7466 7467 default: 7468 action = pf_test_state_other(&s, dir, kif, &pd); 7469 if (action == PF_PASS) { 7470#if NPFSYNC 7471 pfsync_update_state(s); 7472#endif /* NPFSYNC */ 7473 r = s->rule.ptr; 7474 a = s->anchor.ptr; 7475 log = s->log; 7476 } else if (s == NULL) 7477#ifdef __FreeBSD__ 7478 action = pf_test_other(&r, &s, dir, kif, m, off, h, 7479 &pd, &a, &ruleset, NULL); 7480#else 7481 action = pf_test_other(&r, &s, dir, kif, m, off, h, 7482 &pd, &a, &ruleset, &ip6intrq); 7483#endif 7484 break; 7485 } 7486 7487done: 7488 /* handle dangerous IPv6 extension headers. */ 7489 if (action == PF_PASS && rh_cnt && 7490 !((s && s->allow_opts) || r->allow_opts)) { 7491 action = PF_DROP; 7492 REASON_SET(&reason, PFRES_IPOPTIONS); 7493 log = 1; 7494 DPFPRINTF(PF_DEBUG_MISC, 7495 ("pf: dropping packet with dangerous v6 headers\n")); 7496 } 7497 7498 if ((s && s->tag) || r->rtableid) 7499 pf_tag_packet(m, pd.pf_mtag, s ? s->tag : 0, r->rtableid); 7500 7501#ifdef ALTQ 7502 if (action == PF_PASS && r->qid) { 7503 if (pd.tos & IPTOS_LOWDELAY) 7504 pd.pf_mtag->qid = r->pqid; 7505 else 7506 pd.pf_mtag->qid = r->qid; 7507 /* add hints for ecn */ 7508 pd.pf_mtag->af = AF_INET6; 7509 pd.pf_mtag->hdr = h; 7510 } 7511#endif /* ALTQ */ 7512 7513 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 7514 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 7515 (s->nat_rule.ptr->action == PF_RDR || 7516 s->nat_rule.ptr->action == PF_BINAT) && 7517 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6)) 7518 pd.pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST; 7519 7520 if (log) { 7521 struct pf_rule *lr; 7522 7523 if (s != NULL && s->nat_rule.ptr != NULL && 7524 s->nat_rule.ptr->log & PF_LOG_ALL) 7525 lr = s->nat_rule.ptr; 7526 else 7527 lr = r; 7528 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, lr, a, ruleset, 7529 &pd); 7530 } 7531 7532 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7533 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++; 7534 7535 if (action == PF_PASS || r->action == PF_DROP) { 7536 dirndx = (dir == PF_OUT); 7537 r->packets[dirndx]++; 7538 r->bytes[dirndx] += pd.tot_len; 7539 if (a != NULL) { 7540 a->packets[dirndx]++; 7541 a->bytes[dirndx] += pd.tot_len; 7542 } 7543 if (s != NULL) { 7544 if (s->nat_rule.ptr != NULL) { 7545 s->nat_rule.ptr->packets[dirndx]++; 7546 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; 7547 } 7548 if (s->src_node != NULL) { 7549 s->src_node->packets[dirndx]++; 7550 s->src_node->bytes[dirndx] += pd.tot_len; 7551 } 7552 if (s->nat_src_node != NULL) { 7553 s->nat_src_node->packets[dirndx]++; 7554 s->nat_src_node->bytes[dirndx] += pd.tot_len; 7555 } 7556 dirndx = (dir == s->direction) ? 0 : 1; 7557 s->packets[dirndx]++; 7558 s->bytes[dirndx] += pd.tot_len; 7559 } 7560 tr = r; 7561 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7562 if (nr != NULL) { 7563 struct pf_addr *x; 7564 /* 7565 * XXX: we need to make sure that the addresses 7566 * passed to pfr_update_stats() are the same than 7567 * the addresses used during matching (pfr_match) 7568 */ 7569 if (r == &pf_default_rule) { 7570 tr = nr; 7571 x = (s == NULL || s->direction == dir) ? 7572 &pd.baddr : &pd.naddr; 7573 } else { 7574 x = (s == NULL || s->direction == dir) ? 7575 &pd.naddr : &pd.baddr; 7576 } 7577 if (x == &pd.baddr || s == NULL) { 7578 if (dir == PF_OUT) 7579 pd.src = x; 7580 else 7581 pd.dst = x; 7582 } 7583 } 7584 if (tr->src.addr.type == PF_ADDR_TABLE) 7585 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL || 7586 s->direction == dir) ? pd.src : pd.dst, pd.af, 7587 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 7588 tr->src.neg); 7589 if (tr->dst.addr.type == PF_ADDR_TABLE) 7590 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL || 7591 s->direction == dir) ? pd.dst : pd.src, pd.af, 7592 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 7593 tr->dst.neg); 7594 } 7595 7596 7597 if (action == PF_SYNPROXY_DROP) { 7598 m_freem(*m0); 7599 *m0 = NULL; 7600 action = PF_PASS; 7601 } else if (r->rt) 7602 /* pf_route6 can free the mbuf causing *m0 to become NULL */ 7603 pf_route6(m0, r, dir, ifp, s, &pd); 7604 7605#ifdef __FreeBSD__ 7606 PF_UNLOCK(); 7607#endif 7608 return (action); 7609} 7610#endif /* INET6 */ 7611 7612int 7613pf_check_congestion(struct ifqueue *ifq) 7614{ 7615#ifdef __FreeBSD__ 7616 /* XXX_IMPORT: later */ 7617 return (0); 7618#else 7619 if (ifq->ifq_congestion) 7620 return (1); 7621 else 7622 return (0); 7623#endif 7624} 7625