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