pf.c revision 186119
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 186119 2008-12-15 06:10:57Z qingli $"); 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#include <sys/vimage.h> 96#else 97#include <sys/rwlock.h> 98#endif 99 100#include <net/if.h> 101#include <net/if_types.h> 102#include <net/bpf.h> 103#include <net/route.h> 104#ifndef __FreeBSD__ 105#include <net/radix_mpath.h> 106#endif 107 108#include <netinet/in.h> 109#include <netinet/in_var.h> 110#include <netinet/in_systm.h> 111#include <netinet/ip.h> 112#include <netinet/ip_var.h> 113#include <netinet/tcp.h> 114#include <netinet/tcp_seq.h> 115#include <netinet/udp.h> 116#include <netinet/ip_icmp.h> 117#include <netinet/in_pcb.h> 118#include <netinet/tcp_timer.h> 119#include <netinet/tcp_var.h> 120#include <netinet/udp_var.h> 121#include <netinet/icmp_var.h> 122#include <netinet/if_ether.h> 123#ifdef __FreeBSD__ 124#include <netinet/vinet.h> 125#endif 126 127#ifndef __FreeBSD__ 128#include <dev/rndvar.h> 129#endif 130#include <net/pfvar.h> 131#include <net/if_pflog.h> 132 133#if NPFSYNC > 0 134#include <net/if_pfsync.h> 135#endif /* NPFSYNC > 0 */ 136 137#ifdef INET6 138#include <netinet/ip6.h> 139#include <netinet/in_pcb.h> 140#include <netinet/icmp6.h> 141#include <netinet6/nd6.h> 142#ifdef __FreeBSD__ 143#include <netinet6/ip6_var.h> 144#include <netinet6/in6_pcb.h> 145#include <netinet6/vinet6.h> 146#endif 147#endif /* INET6 */ 148 149#ifdef __FreeBSD__ 150#include <machine/in_cksum.h> 151#include <sys/limits.h> 152#include <sys/ucred.h> 153#include <security/mac/mac_framework.h> 154 155extern int ip_optcopy(struct ip *, struct ip *); 156extern int debug_pfugidhack; 157#endif 158 159#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x 160 161/* 162 * Global variables 163 */ 164 165struct pf_altqqueue pf_altqs[2]; 166struct pf_palist pf_pabuf; 167struct pf_altqqueue *pf_altqs_active; 168struct pf_altqqueue *pf_altqs_inactive; 169struct pf_status pf_status; 170 171u_int32_t ticket_altqs_active; 172u_int32_t ticket_altqs_inactive; 173int altqs_inactive_open; 174u_int32_t ticket_pabuf; 175 176struct pf_anchor_stackframe { 177 struct pf_ruleset *rs; 178 struct pf_rule *r; 179 struct pf_anchor_node *parent; 180 struct pf_anchor *child; 181} pf_anchor_stack[64]; 182 183#ifdef __FreeBSD__ 184uma_zone_t pf_src_tree_pl, pf_rule_pl; 185uma_zone_t pf_state_pl, pf_altq_pl, pf_pooladdr_pl; 186#else 187struct pool pf_src_tree_pl, pf_rule_pl; 188struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl; 189#endif 190 191void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); 192 193void pf_init_threshold(struct pf_threshold *, u_int32_t, 194 u_int32_t); 195void pf_add_threshold(struct pf_threshold *); 196int pf_check_threshold(struct pf_threshold *); 197 198void pf_change_ap(struct pf_addr *, u_int16_t *, 199 u_int16_t *, u_int16_t *, struct pf_addr *, 200 u_int16_t, u_int8_t, sa_family_t); 201int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *, 202 struct tcphdr *, struct pf_state_peer *); 203#ifdef INET6 204void pf_change_a6(struct pf_addr *, u_int16_t *, 205 struct pf_addr *, u_int8_t); 206#endif /* INET6 */ 207void pf_change_icmp(struct pf_addr *, u_int16_t *, 208 struct pf_addr *, struct pf_addr *, u_int16_t, 209 u_int16_t *, u_int16_t *, u_int16_t *, 210 u_int16_t *, u_int8_t, sa_family_t); 211#ifdef __FreeBSD__ 212void pf_send_tcp(struct mbuf *, 213 const struct pf_rule *, sa_family_t, 214#else 215void pf_send_tcp(const struct pf_rule *, sa_family_t, 216#endif 217 const struct pf_addr *, const struct pf_addr *, 218 u_int16_t, u_int16_t, u_int32_t, u_int32_t, 219 u_int8_t, u_int16_t, u_int16_t, u_int8_t, int, 220 u_int16_t, struct ether_header *, struct ifnet *); 221void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t, 222 sa_family_t, struct pf_rule *); 223struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *, 224 int, int, struct pfi_kif *, 225 struct pf_addr *, u_int16_t, struct pf_addr *, 226 u_int16_t, int); 227struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *, 228 int, int, struct pfi_kif *, struct pf_src_node **, 229 struct pf_addr *, u_int16_t, 230 struct pf_addr *, u_int16_t, 231 struct pf_addr *, u_int16_t *); 232int pf_test_tcp(struct pf_rule **, struct pf_state **, 233 int, struct pfi_kif *, struct mbuf *, int, 234 void *, struct pf_pdesc *, struct pf_rule **, 235#ifdef __FreeBSD__ 236 struct pf_ruleset **, struct ifqueue *, 237 struct inpcb *); 238#else 239 struct pf_ruleset **, struct ifqueue *); 240#endif 241int pf_test_udp(struct pf_rule **, struct pf_state **, 242 int, struct pfi_kif *, struct mbuf *, int, 243 void *, struct pf_pdesc *, struct pf_rule **, 244#ifdef __FreeBSD__ 245 struct pf_ruleset **, struct ifqueue *, 246 struct inpcb *); 247#else 248 struct pf_ruleset **, struct ifqueue *); 249#endif 250int pf_test_icmp(struct pf_rule **, struct pf_state **, 251 int, struct pfi_kif *, struct mbuf *, int, 252 void *, struct pf_pdesc *, struct pf_rule **, 253 struct pf_ruleset **, struct ifqueue *); 254int pf_test_other(struct pf_rule **, struct pf_state **, 255 int, struct pfi_kif *, struct mbuf *, int, void *, 256 struct pf_pdesc *, struct pf_rule **, 257 struct pf_ruleset **, struct ifqueue *); 258int pf_test_fragment(struct pf_rule **, int, 259 struct pfi_kif *, struct mbuf *, void *, 260 struct pf_pdesc *, struct pf_rule **, 261 struct pf_ruleset **); 262int pf_test_state_tcp(struct pf_state **, int, 263 struct pfi_kif *, struct mbuf *, int, 264 void *, struct pf_pdesc *, u_short *); 265int pf_test_state_udp(struct pf_state **, int, 266 struct pfi_kif *, struct mbuf *, int, 267 void *, struct pf_pdesc *); 268int pf_test_state_icmp(struct pf_state **, int, 269 struct pfi_kif *, struct mbuf *, int, 270 void *, struct pf_pdesc *, u_short *); 271int pf_test_state_other(struct pf_state **, int, 272 struct pfi_kif *, struct pf_pdesc *); 273int pf_match_tag(struct mbuf *, struct pf_rule *, 274 struct pf_mtag *, int *); 275int pf_step_out_of_anchor(int *, struct pf_ruleset **, 276 int, struct pf_rule **, struct pf_rule **, 277 int *); 278void pf_hash(struct pf_addr *, struct pf_addr *, 279 struct pf_poolhashkey *, sa_family_t); 280int pf_map_addr(u_int8_t, struct pf_rule *, 281 struct pf_addr *, struct pf_addr *, 282 struct pf_addr *, struct pf_src_node **); 283int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *, 284 struct pf_addr *, struct pf_addr *, u_int16_t, 285 struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t, 286 struct pf_src_node **); 287void pf_route(struct mbuf **, struct pf_rule *, int, 288 struct ifnet *, struct pf_state *, 289 struct pf_pdesc *); 290void pf_route6(struct mbuf **, struct pf_rule *, int, 291 struct ifnet *, struct pf_state *, 292 struct pf_pdesc *); 293#ifdef __FreeBSD__ 294/* XXX: import */ 295#else 296int pf_socket_lookup(int, struct pf_pdesc *); 297#endif 298u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t, 299 sa_family_t); 300u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t, 301 sa_family_t); 302u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, 303 u_int16_t); 304void pf_set_rt_ifp(struct pf_state *, 305 struct pf_addr *); 306int pf_check_proto_cksum(struct mbuf *, int, int, 307 u_int8_t, sa_family_t); 308int pf_addr_wrap_neq(struct pf_addr_wrap *, 309 struct pf_addr_wrap *); 310struct pf_state *pf_find_state_recurse(struct pfi_kif *, 311 struct pf_state_cmp *, u_int8_t); 312int pf_src_connlimit(struct pf_state **); 313int pf_check_congestion(struct ifqueue *); 314 315#ifdef __FreeBSD__ 316int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len); 317 318extern int pf_end_threads; 319 320struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX]; 321#else 322extern struct pool pfr_ktable_pl; 323extern struct pool pfr_kentry_pl; 324 325struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = { 326 { &pf_state_pl, PFSTATE_HIWAT }, 327 { &pf_src_tree_pl, PFSNODE_HIWAT }, 328 { &pf_frent_pl, PFFRAG_FRENT_HIWAT }, 329 { &pfr_ktable_pl, PFR_KTABLE_HIWAT }, 330 { &pfr_kentry_pl, PFR_KENTRY_HIWAT } 331}; 332#endif 333 334#define STATE_LOOKUP() \ 335 do { \ 336 if (direction == PF_IN) \ 337 *state = pf_find_state_recurse( \ 338 kif, &key, PF_EXT_GWY); \ 339 else \ 340 *state = pf_find_state_recurse( \ 341 kif, &key, PF_LAN_EXT); \ 342 if (*state == NULL || (*state)->timeout == PFTM_PURGE) \ 343 return (PF_DROP); \ 344 if (direction == PF_OUT && \ 345 (((*state)->rule.ptr->rt == PF_ROUTETO && \ 346 (*state)->rule.ptr->direction == PF_OUT) || \ 347 ((*state)->rule.ptr->rt == PF_REPLYTO && \ 348 (*state)->rule.ptr->direction == PF_IN)) && \ 349 (*state)->rt_kif != NULL && \ 350 (*state)->rt_kif != kif) \ 351 return (PF_PASS); \ 352 } while (0) 353 354#define STATE_TRANSLATE(s) \ 355 (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \ 356 ((s)->af == AF_INET6 && \ 357 ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \ 358 (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \ 359 (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \ 360 (s)->lan.port != (s)->gwy.port 361 362#define BOUND_IFACE(r, k) \ 363 ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all 364 365#define STATE_INC_COUNTERS(s) \ 366 do { \ 367 s->rule.ptr->states++; \ 368 if (s->anchor.ptr != NULL) \ 369 s->anchor.ptr->states++; \ 370 if (s->nat_rule.ptr != NULL) \ 371 s->nat_rule.ptr->states++; \ 372 } while (0) 373 374#define STATE_DEC_COUNTERS(s) \ 375 do { \ 376 if (s->nat_rule.ptr != NULL) \ 377 s->nat_rule.ptr->states--; \ 378 if (s->anchor.ptr != NULL) \ 379 s->anchor.ptr->states--; \ 380 s->rule.ptr->states--; \ 381 } while (0) 382 383struct pf_src_tree tree_src_tracking; 384 385struct pf_state_tree_id tree_id; 386struct pf_state_queue state_list; 387 388#ifdef __FreeBSD__ 389static int pf_src_compare(struct pf_src_node *, struct pf_src_node *); 390static int pf_state_compare_lan_ext(struct pf_state *, struct pf_state *); 391static int pf_state_compare_ext_gwy(struct pf_state *, struct pf_state *); 392static int pf_state_compare_id(struct pf_state *, struct pf_state *); 393#endif 394 395RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare); 396RB_GENERATE(pf_state_tree_lan_ext, pf_state, 397 u.s.entry_lan_ext, pf_state_compare_lan_ext); 398RB_GENERATE(pf_state_tree_ext_gwy, pf_state, 399 u.s.entry_ext_gwy, pf_state_compare_ext_gwy); 400RB_GENERATE(pf_state_tree_id, pf_state, 401 u.s.entry_id, pf_state_compare_id); 402 403#ifdef __FreeBSD__ 404static int 405#else 406static __inline int 407#endif 408pf_src_compare(struct pf_src_node *a, struct pf_src_node *b) 409{ 410 int diff; 411 412 if (a->rule.ptr > b->rule.ptr) 413 return (1); 414 if (a->rule.ptr < b->rule.ptr) 415 return (-1); 416 if ((diff = a->af - b->af) != 0) 417 return (diff); 418 switch (a->af) { 419#ifdef INET 420 case AF_INET: 421 if (a->addr.addr32[0] > b->addr.addr32[0]) 422 return (1); 423 if (a->addr.addr32[0] < b->addr.addr32[0]) 424 return (-1); 425 break; 426#endif /* INET */ 427#ifdef INET6 428 case AF_INET6: 429 if (a->addr.addr32[3] > b->addr.addr32[3]) 430 return (1); 431 if (a->addr.addr32[3] < b->addr.addr32[3]) 432 return (-1); 433 if (a->addr.addr32[2] > b->addr.addr32[2]) 434 return (1); 435 if (a->addr.addr32[2] < b->addr.addr32[2]) 436 return (-1); 437 if (a->addr.addr32[1] > b->addr.addr32[1]) 438 return (1); 439 if (a->addr.addr32[1] < b->addr.addr32[1]) 440 return (-1); 441 if (a->addr.addr32[0] > b->addr.addr32[0]) 442 return (1); 443 if (a->addr.addr32[0] < b->addr.addr32[0]) 444 return (-1); 445 break; 446#endif /* INET6 */ 447 } 448 return (0); 449} 450 451#ifdef __FreeBSD__ 452static int 453#else 454static __inline int 455#endif 456pf_state_compare_lan_ext(struct pf_state *a, struct pf_state *b) 457{ 458 int diff; 459 460 if ((diff = a->proto - b->proto) != 0) 461 return (diff); 462 if ((diff = a->af - b->af) != 0) 463 return (diff); 464 switch (a->af) { 465#ifdef INET 466 case AF_INET: 467 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0]) 468 return (1); 469 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0]) 470 return (-1); 471 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) 472 return (1); 473 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) 474 return (-1); 475 break; 476#endif /* INET */ 477#ifdef INET6 478 case AF_INET6: 479 if (a->lan.addr.addr32[3] > b->lan.addr.addr32[3]) 480 return (1); 481 if (a->lan.addr.addr32[3] < b->lan.addr.addr32[3]) 482 return (-1); 483 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3]) 484 return (1); 485 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3]) 486 return (-1); 487 if (a->lan.addr.addr32[2] > b->lan.addr.addr32[2]) 488 return (1); 489 if (a->lan.addr.addr32[2] < b->lan.addr.addr32[2]) 490 return (-1); 491 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2]) 492 return (1); 493 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2]) 494 return (-1); 495 if (a->lan.addr.addr32[1] > b->lan.addr.addr32[1]) 496 return (1); 497 if (a->lan.addr.addr32[1] < b->lan.addr.addr32[1]) 498 return (-1); 499 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1]) 500 return (1); 501 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1]) 502 return (-1); 503 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0]) 504 return (1); 505 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0]) 506 return (-1); 507 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) 508 return (1); 509 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) 510 return (-1); 511 break; 512#endif /* INET6 */ 513 } 514 515 if ((diff = a->lan.port - b->lan.port) != 0) 516 return (diff); 517 if ((diff = a->ext.port - b->ext.port) != 0) 518 return (diff); 519 520 return (0); 521} 522 523#ifdef __FreeBSD__ 524static int 525#else 526static __inline int 527#endif 528pf_state_compare_ext_gwy(struct pf_state *a, struct pf_state *b) 529{ 530 int diff; 531 532 if ((diff = a->proto - b->proto) != 0) 533 return (diff); 534 if ((diff = a->af - b->af) != 0) 535 return (diff); 536 switch (a->af) { 537#ifdef INET 538 case AF_INET: 539 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) 540 return (1); 541 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) 542 return (-1); 543 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0]) 544 return (1); 545 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0]) 546 return (-1); 547 break; 548#endif /* INET */ 549#ifdef INET6 550 case AF_INET6: 551 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3]) 552 return (1); 553 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3]) 554 return (-1); 555 if (a->gwy.addr.addr32[3] > b->gwy.addr.addr32[3]) 556 return (1); 557 if (a->gwy.addr.addr32[3] < b->gwy.addr.addr32[3]) 558 return (-1); 559 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2]) 560 return (1); 561 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2]) 562 return (-1); 563 if (a->gwy.addr.addr32[2] > b->gwy.addr.addr32[2]) 564 return (1); 565 if (a->gwy.addr.addr32[2] < b->gwy.addr.addr32[2]) 566 return (-1); 567 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1]) 568 return (1); 569 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1]) 570 return (-1); 571 if (a->gwy.addr.addr32[1] > b->gwy.addr.addr32[1]) 572 return (1); 573 if (a->gwy.addr.addr32[1] < b->gwy.addr.addr32[1]) 574 return (-1); 575 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) 576 return (1); 577 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) 578 return (-1); 579 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0]) 580 return (1); 581 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0]) 582 return (-1); 583 break; 584#endif /* INET6 */ 585 } 586 587 if ((diff = a->ext.port - b->ext.port) != 0) 588 return (diff); 589 if ((diff = a->gwy.port - b->gwy.port) != 0) 590 return (diff); 591 592 return (0); 593} 594 595#ifdef __FreeBSD__ 596static int 597#else 598static __inline int 599#endif 600pf_state_compare_id(struct pf_state *a, struct pf_state *b) 601{ 602 if (a->id > b->id) 603 return (1); 604 if (a->id < b->id) 605 return (-1); 606 if (a->creatorid > b->creatorid) 607 return (1); 608 if (a->creatorid < b->creatorid) 609 return (-1); 610 611 return (0); 612} 613 614#ifdef INET6 615void 616pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af) 617{ 618 switch (af) { 619#ifdef INET 620 case AF_INET: 621 dst->addr32[0] = src->addr32[0]; 622 break; 623#endif /* INET */ 624 case AF_INET6: 625 dst->addr32[0] = src->addr32[0]; 626 dst->addr32[1] = src->addr32[1]; 627 dst->addr32[2] = src->addr32[2]; 628 dst->addr32[3] = src->addr32[3]; 629 break; 630 } 631} 632#endif /* INET6 */ 633 634struct pf_state * 635pf_find_state_byid(struct pf_state_cmp *key) 636{ 637 pf_status.fcounters[FCNT_STATE_SEARCH]++; 638 return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key)); 639} 640 641struct pf_state * 642pf_find_state_recurse(struct pfi_kif *kif, struct pf_state_cmp *key, u_int8_t tree) 643{ 644 struct pf_state *s; 645 646 pf_status.fcounters[FCNT_STATE_SEARCH]++; 647 648 switch (tree) { 649 case PF_LAN_EXT: 650 if ((s = RB_FIND(pf_state_tree_lan_ext, &kif->pfik_lan_ext, 651 (struct pf_state *)key)) != NULL) 652 return (s); 653 if ((s = RB_FIND(pf_state_tree_lan_ext, &pfi_all->pfik_lan_ext, 654 (struct pf_state *)key)) != NULL) 655 return (s); 656 return (NULL); 657 case PF_EXT_GWY: 658 if ((s = RB_FIND(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, 659 (struct pf_state *)key)) != NULL) 660 return (s); 661 if ((s = RB_FIND(pf_state_tree_ext_gwy, &pfi_all->pfik_ext_gwy, 662 (struct pf_state *)key)) != NULL) 663 return (s); 664 return (NULL); 665 default: 666 panic("pf_find_state_recurse"); 667 } 668} 669 670struct pf_state * 671pf_find_state_all(struct pf_state_cmp *key, u_int8_t tree, int *more) 672{ 673 struct pf_state *s, *ss = NULL; 674 struct pfi_kif *kif; 675 676 pf_status.fcounters[FCNT_STATE_SEARCH]++; 677 678 switch (tree) { 679 case PF_LAN_EXT: 680 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) { 681 s = RB_FIND(pf_state_tree_lan_ext, 682 &kif->pfik_lan_ext, (struct pf_state *)key); 683 if (s == NULL) 684 continue; 685 if (more == NULL) 686 return (s); 687 ss = s; 688 (*more)++; 689 } 690 return (ss); 691 case PF_EXT_GWY: 692 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) { 693 s = RB_FIND(pf_state_tree_ext_gwy, 694 &kif->pfik_ext_gwy, (struct pf_state *)key); 695 if (s == NULL) 696 continue; 697 if (more == NULL) 698 return (s); 699 ss = s; 700 (*more)++; 701 } 702 return (ss); 703 default: 704 panic("pf_find_state_all"); 705 } 706} 707 708void 709pf_init_threshold(struct pf_threshold *threshold, 710 u_int32_t limit, u_int32_t seconds) 711{ 712 threshold->limit = limit * PF_THRESHOLD_MULT; 713 threshold->seconds = seconds; 714 threshold->count = 0; 715 threshold->last = time_second; 716} 717 718void 719pf_add_threshold(struct pf_threshold *threshold) 720{ 721 u_int32_t t = time_second, diff = t - threshold->last; 722 723 if (diff >= threshold->seconds) 724 threshold->count = 0; 725 else 726 threshold->count -= threshold->count * diff / 727 threshold->seconds; 728 threshold->count += PF_THRESHOLD_MULT; 729 threshold->last = t; 730} 731 732int 733pf_check_threshold(struct pf_threshold *threshold) 734{ 735 return (threshold->count > threshold->limit); 736} 737 738int 739pf_src_connlimit(struct pf_state **state) 740{ 741 struct pf_state *s; 742 int bad = 0; 743 744 (*state)->src_node->conn++; 745 (*state)->src.tcp_est = 1; 746 pf_add_threshold(&(*state)->src_node->conn_rate); 747 748 if ((*state)->rule.ptr->max_src_conn && 749 (*state)->rule.ptr->max_src_conn < 750 (*state)->src_node->conn) { 751 pf_status.lcounters[LCNT_SRCCONN]++; 752 bad++; 753 } 754 755 if ((*state)->rule.ptr->max_src_conn_rate.limit && 756 pf_check_threshold(&(*state)->src_node->conn_rate)) { 757 pf_status.lcounters[LCNT_SRCCONNRATE]++; 758 bad++; 759 } 760 761 if (!bad) 762 return (0); 763 764 if ((*state)->rule.ptr->overload_tbl) { 765 struct pfr_addr p; 766 u_int32_t killed = 0; 767 768 pf_status.lcounters[LCNT_OVERLOAD_TABLE]++; 769 if (pf_status.debug >= PF_DEBUG_MISC) { 770 printf("pf_src_connlimit: blocking address "); 771 pf_print_host(&(*state)->src_node->addr, 0, 772 (*state)->af); 773 } 774 775 bzero(&p, sizeof(p)); 776 p.pfra_af = (*state)->af; 777 switch ((*state)->af) { 778#ifdef INET 779 case AF_INET: 780 p.pfra_net = 32; 781 p.pfra_ip4addr = (*state)->src_node->addr.v4; 782 break; 783#endif /* INET */ 784#ifdef INET6 785 case AF_INET6: 786 p.pfra_net = 128; 787 p.pfra_ip6addr = (*state)->src_node->addr.v6; 788 break; 789#endif /* INET6 */ 790 } 791 792 pfr_insert_kentry((*state)->rule.ptr->overload_tbl, 793 &p, time_second); 794 795 /* kill existing states if that's required. */ 796 if ((*state)->rule.ptr->flush) { 797 pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++; 798 799 RB_FOREACH(s, pf_state_tree_id, &tree_id) { 800 /* 801 * Kill states from this source. (Only those 802 * from the same rule if PF_FLUSH_GLOBAL is not 803 * set) 804 */ 805 if (s->af == (*state)->af && 806 (((*state)->direction == PF_OUT && 807 PF_AEQ(&(*state)->src_node->addr, 808 &s->lan.addr, s->af)) || 809 ((*state)->direction == PF_IN && 810 PF_AEQ(&(*state)->src_node->addr, 811 &s->ext.addr, s->af))) && 812 ((*state)->rule.ptr->flush & 813 PF_FLUSH_GLOBAL || 814 (*state)->rule.ptr == s->rule.ptr)) { 815 s->timeout = PFTM_PURGE; 816 s->src.state = s->dst.state = 817 TCPS_CLOSED; 818 killed++; 819 } 820 } 821 if (pf_status.debug >= PF_DEBUG_MISC) 822 printf(", %u states killed", killed); 823 } 824 if (pf_status.debug >= PF_DEBUG_MISC) 825 printf("\n"); 826 } 827 828 /* kill this state */ 829 (*state)->timeout = PFTM_PURGE; 830 (*state)->src.state = (*state)->dst.state = TCPS_CLOSED; 831 return (1); 832} 833 834int 835pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule, 836 struct pf_addr *src, sa_family_t af) 837{ 838 struct pf_src_node k; 839 840 if (*sn == NULL) { 841 k.af = af; 842 PF_ACPY(&k.addr, src, af); 843 if (rule->rule_flag & PFRULE_RULESRCTRACK || 844 rule->rpool.opts & PF_POOL_STICKYADDR) 845 k.rule.ptr = rule; 846 else 847 k.rule.ptr = NULL; 848 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++; 849 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k); 850 } 851 if (*sn == NULL) { 852 if (!rule->max_src_nodes || 853 rule->src_nodes < rule->max_src_nodes) 854 (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT); 855 else 856 pf_status.lcounters[LCNT_SRCNODES]++; 857 if ((*sn) == NULL) 858 return (-1); 859 bzero(*sn, sizeof(struct pf_src_node)); 860 861 pf_init_threshold(&(*sn)->conn_rate, 862 rule->max_src_conn_rate.limit, 863 rule->max_src_conn_rate.seconds); 864 865 (*sn)->af = af; 866 if (rule->rule_flag & PFRULE_RULESRCTRACK || 867 rule->rpool.opts & PF_POOL_STICKYADDR) 868 (*sn)->rule.ptr = rule; 869 else 870 (*sn)->rule.ptr = NULL; 871 PF_ACPY(&(*sn)->addr, src, af); 872 if (RB_INSERT(pf_src_tree, 873 &tree_src_tracking, *sn) != NULL) { 874 if (pf_status.debug >= PF_DEBUG_MISC) { 875 printf("pf: src_tree insert failed: "); 876 pf_print_host(&(*sn)->addr, 0, af); 877 printf("\n"); 878 } 879 pool_put(&pf_src_tree_pl, *sn); 880 return (-1); 881 } 882 (*sn)->creation = time_second; 883 (*sn)->ruletype = rule->action; 884 if ((*sn)->rule.ptr != NULL) 885 (*sn)->rule.ptr->src_nodes++; 886 pf_status.scounters[SCNT_SRC_NODE_INSERT]++; 887 pf_status.src_nodes++; 888 } else { 889 if (rule->max_src_states && 890 (*sn)->states >= rule->max_src_states) { 891 pf_status.lcounters[LCNT_SRCSTATES]++; 892 return (-1); 893 } 894 } 895 return (0); 896} 897 898int 899pf_insert_state(struct pfi_kif *kif, struct pf_state *state) 900{ 901 /* Thou MUST NOT insert multiple duplicate keys */ 902 state->u.s.kif = kif; 903 if (RB_INSERT(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state)) { 904 if (pf_status.debug >= PF_DEBUG_MISC) { 905 printf("pf: state insert failed: tree_lan_ext"); 906 printf(" lan: "); 907 pf_print_host(&state->lan.addr, state->lan.port, 908 state->af); 909 printf(" gwy: "); 910 pf_print_host(&state->gwy.addr, state->gwy.port, 911 state->af); 912 printf(" ext: "); 913 pf_print_host(&state->ext.addr, state->ext.port, 914 state->af); 915 if (state->sync_flags & PFSTATE_FROMSYNC) 916 printf(" (from sync)"); 917 printf("\n"); 918 } 919 return (-1); 920 } 921 922 if (RB_INSERT(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state)) { 923 if (pf_status.debug >= PF_DEBUG_MISC) { 924 printf("pf: state insert failed: tree_ext_gwy"); 925 printf(" lan: "); 926 pf_print_host(&state->lan.addr, state->lan.port, 927 state->af); 928 printf(" gwy: "); 929 pf_print_host(&state->gwy.addr, state->gwy.port, 930 state->af); 931 printf(" ext: "); 932 pf_print_host(&state->ext.addr, state->ext.port, 933 state->af); 934 if (state->sync_flags & PFSTATE_FROMSYNC) 935 printf(" (from sync)"); 936 printf("\n"); 937 } 938 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state); 939 return (-1); 940 } 941 942 if (state->id == 0 && state->creatorid == 0) { 943 state->id = htobe64(pf_status.stateid++); 944 state->creatorid = pf_status.hostid; 945 } 946 if (RB_INSERT(pf_state_tree_id, &tree_id, state) != NULL) { 947 if (pf_status.debug >= PF_DEBUG_MISC) { 948#ifdef __FreeBSD__ 949 printf("pf: state insert failed: " 950 "id: %016llx creatorid: %08x", 951 (long long)be64toh(state->id), 952 ntohl(state->creatorid)); 953#else 954 printf("pf: state insert failed: " 955 "id: %016llx creatorid: %08x", 956 betoh64(state->id), ntohl(state->creatorid)); 957#endif 958 if (state->sync_flags & PFSTATE_FROMSYNC) 959 printf(" (from sync)"); 960 printf("\n"); 961 } 962 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state); 963 RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state); 964 return (-1); 965 } 966 TAILQ_INSERT_TAIL(&state_list, state, u.s.entry_list); 967 pf_status.fcounters[FCNT_STATE_INSERT]++; 968 pf_status.states++; 969 pfi_kif_ref(kif, PFI_KIF_REF_STATE); 970#if NPFSYNC 971 pfsync_insert_state(state); 972#endif 973 return (0); 974} 975 976void 977pf_purge_thread(void *v) 978{ 979 int nloops = 0, s; 980 981 for (;;) { 982 tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz); 983 984#ifdef __FreeBSD__ 985 sx_slock(&pf_consistency_lock); 986 PF_LOCK(); 987 988 if (pf_end_threads) { 989 pf_purge_expired_states(pf_status.states); 990 pf_purge_expired_fragments(); 991 pf_purge_expired_src_nodes(0); 992 pf_end_threads++; 993 994 sx_sunlock(&pf_consistency_lock); 995 PF_UNLOCK(); 996 wakeup(pf_purge_thread); 997 kproc_exit(0); 998 } 999#endif 1000 s = splsoftnet(); 1001 1002 /* process a fraction of the state table every second */ 1003 pf_purge_expired_states(1 + (pf_status.states 1004 / pf_default_rule.timeout[PFTM_INTERVAL])); 1005 1006 /* purge other expired types every PFTM_INTERVAL seconds */ 1007 if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) { 1008 pf_purge_expired_fragments(); 1009 pf_purge_expired_src_nodes(0); 1010 nloops = 0; 1011 } 1012 1013 splx(s); 1014#ifdef __FreeBSD__ 1015 PF_UNLOCK(); 1016 sx_sunlock(&pf_consistency_lock); 1017#endif 1018 } 1019} 1020 1021u_int32_t 1022pf_state_expires(const struct pf_state *state) 1023{ 1024 u_int32_t timeout; 1025 u_int32_t start; 1026 u_int32_t end; 1027 u_int32_t states; 1028 1029 /* handle all PFTM_* > PFTM_MAX here */ 1030 if (state->timeout == PFTM_PURGE) 1031 return (time_second); 1032 if (state->timeout == PFTM_UNTIL_PACKET) 1033 return (0); 1034#ifdef __FreeBSD__ 1035 KASSERT(state->timeout != PFTM_UNLINKED, 1036 ("pf_state_expires: timeout == PFTM_UNLINKED")); 1037 KASSERT((state->timeout < PFTM_MAX), 1038 ("pf_state_expires: timeout > PFTM_MAX")); 1039#else 1040 KASSERT(state->timeout != PFTM_UNLINKED); 1041 KASSERT(state->timeout < PFTM_MAX); 1042#endif 1043 timeout = state->rule.ptr->timeout[state->timeout]; 1044 if (!timeout) 1045 timeout = pf_default_rule.timeout[state->timeout]; 1046 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START]; 1047 if (start) { 1048 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END]; 1049 states = state->rule.ptr->states; 1050 } else { 1051 start = pf_default_rule.timeout[PFTM_ADAPTIVE_START]; 1052 end = pf_default_rule.timeout[PFTM_ADAPTIVE_END]; 1053 states = pf_status.states; 1054 } 1055 if (end && states > start && start < end) { 1056 if (states < end) 1057 return (state->expire + timeout * (end - states) / 1058 (end - start)); 1059 else 1060 return (time_second); 1061 } 1062 return (state->expire + timeout); 1063} 1064 1065void 1066pf_purge_expired_src_nodes(int waslocked) 1067{ 1068 struct pf_src_node *cur, *next; 1069 int locked = waslocked; 1070 1071 for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) { 1072 next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur); 1073 1074 if (cur->states <= 0 && cur->expire <= time_second) { 1075 if (! locked) { 1076#ifdef __FreeBSD__ 1077 if (!sx_try_upgrade(&pf_consistency_lock)) { 1078 PF_UNLOCK(); 1079 sx_sunlock(&pf_consistency_lock); 1080 sx_xlock(&pf_consistency_lock); 1081 PF_LOCK(); 1082 } 1083#else 1084 rw_enter_write(&pf_consistency_lock); 1085#endif 1086 next = RB_NEXT(pf_src_tree, 1087 &tree_src_tracking, cur); 1088 locked = 1; 1089 } 1090 if (cur->rule.ptr != NULL) { 1091 cur->rule.ptr->src_nodes--; 1092 if (cur->rule.ptr->states <= 0 && 1093 cur->rule.ptr->max_src_nodes <= 0) 1094 pf_rm_rule(NULL, cur->rule.ptr); 1095 } 1096 RB_REMOVE(pf_src_tree, &tree_src_tracking, cur); 1097 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 1098 pf_status.src_nodes--; 1099 pool_put(&pf_src_tree_pl, cur); 1100 } 1101 } 1102 1103 if (locked && !waslocked) 1104#ifdef __FreeBSD__ 1105 sx_downgrade(&pf_consistency_lock); 1106#else 1107 rw_exit_write(&pf_consistency_lock); 1108#endif 1109} 1110 1111void 1112pf_src_tree_remove_state(struct pf_state *s) 1113{ 1114 u_int32_t timeout; 1115 1116 if (s->src_node != NULL) { 1117 if (s->proto == IPPROTO_TCP) { 1118 if (s->src.tcp_est) 1119 --s->src_node->conn; 1120 } 1121 if (--s->src_node->states <= 0) { 1122 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE]; 1123 if (!timeout) 1124 timeout = 1125 pf_default_rule.timeout[PFTM_SRC_NODE]; 1126 s->src_node->expire = time_second + timeout; 1127 } 1128 } 1129 if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) { 1130 if (--s->nat_src_node->states <= 0) { 1131 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE]; 1132 if (!timeout) 1133 timeout = 1134 pf_default_rule.timeout[PFTM_SRC_NODE]; 1135 s->nat_src_node->expire = time_second + timeout; 1136 } 1137 } 1138 s->src_node = s->nat_src_node = NULL; 1139} 1140 1141/* callers should be at splsoftnet */ 1142void 1143pf_unlink_state(struct pf_state *cur) 1144{ 1145#ifdef __FreeBSD__ 1146 if (cur->local_flags & PFSTATE_EXPIRING) 1147 return; 1148 cur->local_flags |= PFSTATE_EXPIRING; 1149#endif 1150 if (cur->src.state == PF_TCPS_PROXY_DST) { 1151#ifdef __FreeBSD__ 1152 pf_send_tcp(NULL, cur->rule.ptr, cur->af, 1153#else 1154 pf_send_tcp(cur->rule.ptr, cur->af, 1155#endif 1156 &cur->ext.addr, &cur->lan.addr, 1157 cur->ext.port, cur->lan.port, 1158 cur->src.seqhi, cur->src.seqlo + 1, 1159 TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL); 1160 } 1161 RB_REMOVE(pf_state_tree_ext_gwy, 1162 &cur->u.s.kif->pfik_ext_gwy, cur); 1163 RB_REMOVE(pf_state_tree_lan_ext, 1164 &cur->u.s.kif->pfik_lan_ext, cur); 1165 RB_REMOVE(pf_state_tree_id, &tree_id, cur); 1166#if NPFSYNC 1167 if (cur->creatorid == pf_status.hostid) 1168 pfsync_delete_state(cur); 1169#endif 1170 cur->timeout = PFTM_UNLINKED; 1171 pf_src_tree_remove_state(cur); 1172} 1173 1174/* callers should be at splsoftnet and hold the 1175 * write_lock on pf_consistency_lock */ 1176void 1177pf_free_state(struct pf_state *cur) 1178{ 1179#if NPFSYNC 1180 if (pfsyncif != NULL && 1181 (pfsyncif->sc_bulk_send_next == cur || 1182 pfsyncif->sc_bulk_terminator == cur)) 1183 return; 1184#endif 1185#ifdef __FreeBSD__ 1186 KASSERT(cur->timeout == PFTM_UNLINKED, 1187 ("pf_free_state: cur->timeout != PFTM_UNLINKED")); 1188#else 1189 KASSERT(cur->timeout == PFTM_UNLINKED); 1190#endif 1191 if (--cur->rule.ptr->states <= 0 && 1192 cur->rule.ptr->src_nodes <= 0) 1193 pf_rm_rule(NULL, cur->rule.ptr); 1194 if (cur->nat_rule.ptr != NULL) 1195 if (--cur->nat_rule.ptr->states <= 0 && 1196 cur->nat_rule.ptr->src_nodes <= 0) 1197 pf_rm_rule(NULL, cur->nat_rule.ptr); 1198 if (cur->anchor.ptr != NULL) 1199 if (--cur->anchor.ptr->states <= 0) 1200 pf_rm_rule(NULL, cur->anchor.ptr); 1201 pf_normalize_tcp_cleanup(cur); 1202 pfi_kif_unref(cur->u.s.kif, PFI_KIF_REF_STATE); 1203 TAILQ_REMOVE(&state_list, cur, u.s.entry_list); 1204 if (cur->tag) 1205 pf_tag_unref(cur->tag); 1206 pool_put(&pf_state_pl, cur); 1207 pf_status.fcounters[FCNT_STATE_REMOVALS]++; 1208 pf_status.states--; 1209} 1210 1211void 1212pf_purge_expired_states(u_int32_t maxcheck) 1213{ 1214 static struct pf_state *cur = NULL; 1215 struct pf_state *next; 1216 int locked = 0; 1217 1218 while (maxcheck--) { 1219 /* wrap to start of list when we hit the end */ 1220 if (cur == NULL) { 1221 cur = TAILQ_FIRST(&state_list); 1222 if (cur == NULL) 1223 break; /* list empty */ 1224 } 1225 1226 /* get next state, as cur may get deleted */ 1227 next = TAILQ_NEXT(cur, u.s.entry_list); 1228 1229 if (cur->timeout == PFTM_UNLINKED) { 1230 /* free unlinked state */ 1231 if (! locked) { 1232#ifdef __FreeBSD__ 1233 if (!sx_try_upgrade(&pf_consistency_lock)) { 1234 PF_UNLOCK(); 1235 sx_sunlock(&pf_consistency_lock); 1236 sx_xlock(&pf_consistency_lock); 1237 PF_LOCK(); 1238 } 1239#else 1240 rw_enter_write(&pf_consistency_lock); 1241#endif 1242 locked = 1; 1243 } 1244 pf_free_state(cur); 1245 } else if (pf_state_expires(cur) <= time_second) { 1246 /* unlink and free expired state */ 1247 pf_unlink_state(cur); 1248 if (! locked) { 1249#ifdef __FreeBSD__ 1250 if (!sx_try_upgrade(&pf_consistency_lock)) { 1251 PF_UNLOCK(); 1252 sx_sunlock(&pf_consistency_lock); 1253 sx_xlock(&pf_consistency_lock); 1254 PF_LOCK(); 1255 } 1256#else 1257 rw_enter_write(&pf_consistency_lock); 1258#endif 1259 locked = 1; 1260 } 1261 pf_free_state(cur); 1262 } 1263 cur = next; 1264 } 1265 1266 if (locked) 1267#ifdef __FreeBSD__ 1268 sx_downgrade(&pf_consistency_lock); 1269#else 1270 rw_exit_write(&pf_consistency_lock); 1271#endif 1272} 1273 1274int 1275pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw) 1276{ 1277 if (aw->type != PF_ADDR_TABLE) 1278 return (0); 1279 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL) 1280 return (1); 1281 return (0); 1282} 1283 1284void 1285pf_tbladdr_remove(struct pf_addr_wrap *aw) 1286{ 1287 if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL) 1288 return; 1289 pfr_detach_table(aw->p.tbl); 1290 aw->p.tbl = NULL; 1291} 1292 1293void 1294pf_tbladdr_copyout(struct pf_addr_wrap *aw) 1295{ 1296 struct pfr_ktable *kt = aw->p.tbl; 1297 1298 if (aw->type != PF_ADDR_TABLE || kt == NULL) 1299 return; 1300 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL) 1301 kt = kt->pfrkt_root; 1302 aw->p.tbl = NULL; 1303 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ? 1304 kt->pfrkt_cnt : -1; 1305} 1306 1307void 1308pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af) 1309{ 1310 switch (af) { 1311#ifdef INET 1312 case AF_INET: { 1313 u_int32_t a = ntohl(addr->addr32[0]); 1314 printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255, 1315 (a>>8)&255, a&255); 1316 if (p) { 1317 p = ntohs(p); 1318 printf(":%u", p); 1319 } 1320 break; 1321 } 1322#endif /* INET */ 1323#ifdef INET6 1324 case AF_INET6: { 1325 u_int16_t b; 1326 u_int8_t i, curstart = 255, curend = 0, 1327 maxstart = 0, maxend = 0; 1328 for (i = 0; i < 8; i++) { 1329 if (!addr->addr16[i]) { 1330 if (curstart == 255) 1331 curstart = i; 1332 else 1333 curend = i; 1334 } else { 1335 if (curstart) { 1336 if ((curend - curstart) > 1337 (maxend - maxstart)) { 1338 maxstart = curstart; 1339 maxend = curend; 1340 curstart = 255; 1341 } 1342 } 1343 } 1344 } 1345 for (i = 0; i < 8; i++) { 1346 if (i >= maxstart && i <= maxend) { 1347 if (maxend != 7) { 1348 if (i == maxstart) 1349 printf(":"); 1350 } else { 1351 if (i == maxend) 1352 printf(":"); 1353 } 1354 } else { 1355 b = ntohs(addr->addr16[i]); 1356 printf("%x", b); 1357 if (i < 7) 1358 printf(":"); 1359 } 1360 } 1361 if (p) { 1362 p = ntohs(p); 1363 printf("[%u]", p); 1364 } 1365 break; 1366 } 1367#endif /* INET6 */ 1368 } 1369} 1370 1371void 1372pf_print_state(struct pf_state *s) 1373{ 1374 switch (s->proto) { 1375 case IPPROTO_TCP: 1376 printf("TCP "); 1377 break; 1378 case IPPROTO_UDP: 1379 printf("UDP "); 1380 break; 1381 case IPPROTO_ICMP: 1382 printf("ICMP "); 1383 break; 1384 case IPPROTO_ICMPV6: 1385 printf("ICMPV6 "); 1386 break; 1387 default: 1388 printf("%u ", s->proto); 1389 break; 1390 } 1391 pf_print_host(&s->lan.addr, s->lan.port, s->af); 1392 printf(" "); 1393 pf_print_host(&s->gwy.addr, s->gwy.port, s->af); 1394 printf(" "); 1395 pf_print_host(&s->ext.addr, s->ext.port, s->af); 1396 printf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo, 1397 s->src.seqhi, s->src.max_win, s->src.seqdiff); 1398 if (s->src.wscale && s->dst.wscale) 1399 printf(" wscale=%u", s->src.wscale & PF_WSCALE_MASK); 1400 printf("]"); 1401 printf(" [lo=%u high=%u win=%u modulator=%u", s->dst.seqlo, 1402 s->dst.seqhi, s->dst.max_win, s->dst.seqdiff); 1403 if (s->src.wscale && s->dst.wscale) 1404 printf(" wscale=%u", s->dst.wscale & PF_WSCALE_MASK); 1405 printf("]"); 1406 printf(" %u:%u", s->src.state, s->dst.state); 1407} 1408 1409void 1410pf_print_flags(u_int8_t f) 1411{ 1412 if (f) 1413 printf(" "); 1414 if (f & TH_FIN) 1415 printf("F"); 1416 if (f & TH_SYN) 1417 printf("S"); 1418 if (f & TH_RST) 1419 printf("R"); 1420 if (f & TH_PUSH) 1421 printf("P"); 1422 if (f & TH_ACK) 1423 printf("A"); 1424 if (f & TH_URG) 1425 printf("U"); 1426 if (f & TH_ECE) 1427 printf("E"); 1428 if (f & TH_CWR) 1429 printf("W"); 1430} 1431 1432#define PF_SET_SKIP_STEPS(i) \ 1433 do { \ 1434 while (head[i] != cur) { \ 1435 head[i]->skip[i].ptr = cur; \ 1436 head[i] = TAILQ_NEXT(head[i], entries); \ 1437 } \ 1438 } while (0) 1439 1440void 1441pf_calc_skip_steps(struct pf_rulequeue *rules) 1442{ 1443 struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT]; 1444 int i; 1445 1446 cur = TAILQ_FIRST(rules); 1447 prev = cur; 1448 for (i = 0; i < PF_SKIP_COUNT; ++i) 1449 head[i] = cur; 1450 while (cur != NULL) { 1451 1452 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot) 1453 PF_SET_SKIP_STEPS(PF_SKIP_IFP); 1454 if (cur->direction != prev->direction) 1455 PF_SET_SKIP_STEPS(PF_SKIP_DIR); 1456 if (cur->af != prev->af) 1457 PF_SET_SKIP_STEPS(PF_SKIP_AF); 1458 if (cur->proto != prev->proto) 1459 PF_SET_SKIP_STEPS(PF_SKIP_PROTO); 1460 if (cur->src.neg != prev->src.neg || 1461 pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr)) 1462 PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR); 1463 if (cur->src.port[0] != prev->src.port[0] || 1464 cur->src.port[1] != prev->src.port[1] || 1465 cur->src.port_op != prev->src.port_op) 1466 PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT); 1467 if (cur->dst.neg != prev->dst.neg || 1468 pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr)) 1469 PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR); 1470 if (cur->dst.port[0] != prev->dst.port[0] || 1471 cur->dst.port[1] != prev->dst.port[1] || 1472 cur->dst.port_op != prev->dst.port_op) 1473 PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT); 1474 1475 prev = cur; 1476 cur = TAILQ_NEXT(cur, entries); 1477 } 1478 for (i = 0; i < PF_SKIP_COUNT; ++i) 1479 PF_SET_SKIP_STEPS(i); 1480} 1481 1482int 1483pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2) 1484{ 1485 if (aw1->type != aw2->type) 1486 return (1); 1487 switch (aw1->type) { 1488 case PF_ADDR_ADDRMASK: 1489 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0)) 1490 return (1); 1491 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0)) 1492 return (1); 1493 return (0); 1494 case PF_ADDR_DYNIFTL: 1495 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt); 1496 case PF_ADDR_NOROUTE: 1497 case PF_ADDR_URPFFAILED: 1498 return (0); 1499 case PF_ADDR_TABLE: 1500 return (aw1->p.tbl != aw2->p.tbl); 1501 case PF_ADDR_RTLABEL: 1502 return (aw1->v.rtlabel != aw2->v.rtlabel); 1503 default: 1504 printf("invalid address type: %d\n", aw1->type); 1505 return (1); 1506 } 1507} 1508 1509u_int16_t 1510pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp) 1511{ 1512 u_int32_t l; 1513 1514 if (udp && !cksum) 1515 return (0x0000); 1516 l = cksum + old - new; 1517 l = (l >> 16) + (l & 65535); 1518 l = l & 65535; 1519 if (udp && !l) 1520 return (0xFFFF); 1521 return (l); 1522} 1523 1524void 1525pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc, 1526 struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af) 1527{ 1528 struct pf_addr ao; 1529 u_int16_t po = *p; 1530 1531 PF_ACPY(&ao, a, af); 1532 PF_ACPY(a, an, af); 1533 1534 *p = pn; 1535 1536 switch (af) { 1537#ifdef INET 1538 case AF_INET: 1539 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic, 1540 ao.addr16[0], an->addr16[0], 0), 1541 ao.addr16[1], an->addr16[1], 0); 1542 *p = pn; 1543 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc, 1544 ao.addr16[0], an->addr16[0], u), 1545 ao.addr16[1], an->addr16[1], u), 1546 po, pn, u); 1547 break; 1548#endif /* INET */ 1549#ifdef INET6 1550 case AF_INET6: 1551 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1552 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1553 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc, 1554 ao.addr16[0], an->addr16[0], u), 1555 ao.addr16[1], an->addr16[1], u), 1556 ao.addr16[2], an->addr16[2], u), 1557 ao.addr16[3], an->addr16[3], u), 1558 ao.addr16[4], an->addr16[4], u), 1559 ao.addr16[5], an->addr16[5], u), 1560 ao.addr16[6], an->addr16[6], u), 1561 ao.addr16[7], an->addr16[7], u), 1562 po, pn, u); 1563 break; 1564#endif /* INET6 */ 1565 } 1566} 1567 1568 1569/* Changes a u_int32_t. Uses a void * so there are no align restrictions */ 1570void 1571pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u) 1572{ 1573 u_int32_t ao; 1574 1575 memcpy(&ao, a, sizeof(ao)); 1576 memcpy(a, &an, sizeof(u_int32_t)); 1577 *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u), 1578 ao % 65536, an % 65536, u); 1579} 1580 1581#ifdef INET6 1582void 1583pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u) 1584{ 1585 struct pf_addr ao; 1586 1587 PF_ACPY(&ao, a, AF_INET6); 1588 PF_ACPY(a, an, AF_INET6); 1589 1590 *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1591 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1592 pf_cksum_fixup(pf_cksum_fixup(*c, 1593 ao.addr16[0], an->addr16[0], u), 1594 ao.addr16[1], an->addr16[1], u), 1595 ao.addr16[2], an->addr16[2], u), 1596 ao.addr16[3], an->addr16[3], u), 1597 ao.addr16[4], an->addr16[4], u), 1598 ao.addr16[5], an->addr16[5], u), 1599 ao.addr16[6], an->addr16[6], u), 1600 ao.addr16[7], an->addr16[7], u); 1601} 1602#endif /* INET6 */ 1603 1604void 1605pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa, 1606 struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c, 1607 u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af) 1608{ 1609 struct pf_addr oia, ooa; 1610 1611 PF_ACPY(&oia, ia, af); 1612 PF_ACPY(&ooa, oa, af); 1613 1614 /* Change inner protocol port, fix inner protocol checksum. */ 1615 if (ip != NULL) { 1616 u_int16_t oip = *ip; 1617 u_int32_t opc = 0; /* make the compiler happy */ 1618 1619 if (pc != NULL) 1620 opc = *pc; 1621 *ip = np; 1622 if (pc != NULL) 1623 *pc = pf_cksum_fixup(*pc, oip, *ip, u); 1624 *ic = pf_cksum_fixup(*ic, oip, *ip, 0); 1625 if (pc != NULL) 1626 *ic = pf_cksum_fixup(*ic, opc, *pc, 0); 1627 } 1628 /* Change inner ip address, fix inner ip and icmp checksums. */ 1629 PF_ACPY(ia, na, af); 1630 switch (af) { 1631#ifdef INET 1632 case AF_INET: { 1633 u_int32_t oh2c = *h2c; 1634 1635 *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c, 1636 oia.addr16[0], ia->addr16[0], 0), 1637 oia.addr16[1], ia->addr16[1], 0); 1638 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic, 1639 oia.addr16[0], ia->addr16[0], 0), 1640 oia.addr16[1], ia->addr16[1], 0); 1641 *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0); 1642 break; 1643 } 1644#endif /* INET */ 1645#ifdef INET6 1646 case AF_INET6: 1647 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1648 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1649 pf_cksum_fixup(pf_cksum_fixup(*ic, 1650 oia.addr16[0], ia->addr16[0], u), 1651 oia.addr16[1], ia->addr16[1], u), 1652 oia.addr16[2], ia->addr16[2], u), 1653 oia.addr16[3], ia->addr16[3], u), 1654 oia.addr16[4], ia->addr16[4], u), 1655 oia.addr16[5], ia->addr16[5], u), 1656 oia.addr16[6], ia->addr16[6], u), 1657 oia.addr16[7], ia->addr16[7], u); 1658 break; 1659#endif /* INET6 */ 1660 } 1661 /* Change outer ip address, fix outer ip or icmpv6 checksum. */ 1662 PF_ACPY(oa, na, af); 1663 switch (af) { 1664#ifdef INET 1665 case AF_INET: 1666 *hc = pf_cksum_fixup(pf_cksum_fixup(*hc, 1667 ooa.addr16[0], oa->addr16[0], 0), 1668 ooa.addr16[1], oa->addr16[1], 0); 1669 break; 1670#endif /* INET */ 1671#ifdef INET6 1672 case AF_INET6: 1673 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1674 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1675 pf_cksum_fixup(pf_cksum_fixup(*ic, 1676 ooa.addr16[0], oa->addr16[0], u), 1677 ooa.addr16[1], oa->addr16[1], u), 1678 ooa.addr16[2], oa->addr16[2], u), 1679 ooa.addr16[3], oa->addr16[3], u), 1680 ooa.addr16[4], oa->addr16[4], u), 1681 ooa.addr16[5], oa->addr16[5], u), 1682 ooa.addr16[6], oa->addr16[6], u), 1683 ooa.addr16[7], oa->addr16[7], u); 1684 break; 1685#endif /* INET6 */ 1686 } 1687} 1688 1689 1690/* 1691 * Need to modulate the sequence numbers in the TCP SACK option 1692 * (credits to Krzysztof Pfaff for report and patch) 1693 */ 1694int 1695pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd, 1696 struct tcphdr *th, struct pf_state_peer *dst) 1697{ 1698 int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen; 1699#ifdef __FreeBSD__ 1700 u_int8_t opts[TCP_MAXOLEN], *opt = opts; 1701#else 1702 u_int8_t opts[MAX_TCPOPTLEN], *opt = opts; 1703#endif 1704 int copyback = 0, i, olen; 1705 struct sackblk sack; 1706 1707#define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2) 1708 if (hlen < TCPOLEN_SACKLEN || 1709 !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af)) 1710 return 0; 1711 1712 while (hlen >= TCPOLEN_SACKLEN) { 1713 olen = opt[1]; 1714 switch (*opt) { 1715 case TCPOPT_EOL: /* FALLTHROUGH */ 1716 case TCPOPT_NOP: 1717 opt++; 1718 hlen--; 1719 break; 1720 case TCPOPT_SACK: 1721 if (olen > hlen) 1722 olen = hlen; 1723 if (olen >= TCPOLEN_SACKLEN) { 1724 for (i = 2; i + TCPOLEN_SACK <= olen; 1725 i += TCPOLEN_SACK) { 1726 memcpy(&sack, &opt[i], sizeof(sack)); 1727 pf_change_a(&sack.start, &th->th_sum, 1728 htonl(ntohl(sack.start) - 1729 dst->seqdiff), 0); 1730 pf_change_a(&sack.end, &th->th_sum, 1731 htonl(ntohl(sack.end) - 1732 dst->seqdiff), 0); 1733 memcpy(&opt[i], &sack, sizeof(sack)); 1734 } 1735 copyback = 1; 1736 } 1737 /* FALLTHROUGH */ 1738 default: 1739 if (olen < 2) 1740 olen = 2; 1741 hlen -= olen; 1742 opt += olen; 1743 } 1744 } 1745 1746 if (copyback) 1747#ifdef __FreeBSD__ 1748 m_copyback(m, off + sizeof(*th), thoptlen, (caddr_t)opts); 1749#else 1750 m_copyback(m, off + sizeof(*th), thoptlen, opts); 1751#endif 1752 return (copyback); 1753} 1754 1755void 1756#ifdef __FreeBSD__ 1757pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af, 1758#else 1759pf_send_tcp(const struct pf_rule *r, sa_family_t af, 1760#endif 1761 const struct pf_addr *saddr, const struct pf_addr *daddr, 1762 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack, 1763 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag, 1764 u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp) 1765{ 1766 INIT_VNET_INET(curvnet); 1767 struct mbuf *m; 1768 int len, tlen; 1769#ifdef INET 1770 struct ip *h; 1771#endif /* INET */ 1772#ifdef INET6 1773 struct ip6_hdr *h6; 1774#endif /* INET6 */ 1775 struct tcphdr *th; 1776 char *opt; 1777 struct pf_mtag *pf_mtag; 1778 1779#ifdef __FreeBSD__ 1780 KASSERT( 1781#ifdef INET 1782 af == AF_INET 1783#else 1784 0 1785#endif 1786 || 1787#ifdef INET6 1788 af == AF_INET6 1789#else 1790 0 1791#endif 1792 , ("Unsupported AF %d", af)); 1793 len = 0; 1794 th = NULL; 1795#ifdef INET 1796 h = NULL; 1797#endif 1798#ifdef INET6 1799 h6 = NULL; 1800#endif 1801#endif 1802 1803 /* maximum segment size tcp option */ 1804 tlen = sizeof(struct tcphdr); 1805 if (mss) 1806 tlen += 4; 1807 1808 switch (af) { 1809#ifdef INET 1810 case AF_INET: 1811 len = sizeof(struct ip) + tlen; 1812 break; 1813#endif /* INET */ 1814#ifdef INET6 1815 case AF_INET6: 1816 len = sizeof(struct ip6_hdr) + tlen; 1817 break; 1818#endif /* INET6 */ 1819 } 1820 1821 /* create outgoing mbuf */ 1822 m = m_gethdr(M_DONTWAIT, MT_HEADER); 1823 if (m == NULL) 1824 return; 1825#ifdef __FreeBSD__ 1826#ifdef MAC 1827 if (replyto) 1828 mac_netinet_firewall_reply(replyto, m); 1829 else 1830 mac_netinet_firewall_send(m); 1831#else 1832 (void)replyto; 1833#endif 1834#endif 1835 if ((pf_mtag = pf_get_mtag(m)) == NULL) { 1836 m_freem(m); 1837 return; 1838 } 1839 if (tag) 1840#ifdef __FreeBSD__ 1841 m->m_flags |= M_SKIP_FIREWALL; 1842#else 1843 pf_mtag->flags |= PF_TAG_GENERATED; 1844#endif 1845 1846 pf_mtag->tag = rtag; 1847 1848 if (r != NULL && r->rtableid >= 0) 1849#ifdef __FreeBSD__ 1850 { 1851 M_SETFIB(m, r->rtableid); 1852#endif 1853 pf_mtag->rtableid = r->rtableid; 1854#ifdef __FreeBSD__ 1855 } 1856#endif 1857#ifdef ALTQ 1858 if (r != NULL && r->qid) { 1859 pf_mtag->qid = r->qid; 1860 /* add hints for ecn */ 1861 pf_mtag->af = af; 1862 pf_mtag->hdr = mtod(m, struct ip *); 1863 } 1864#endif /* ALTQ */ 1865 m->m_data += max_linkhdr; 1866 m->m_pkthdr.len = m->m_len = len; 1867 m->m_pkthdr.rcvif = NULL; 1868 bzero(m->m_data, len); 1869 switch (af) { 1870#ifdef INET 1871 case AF_INET: 1872 h = mtod(m, struct ip *); 1873 1874 /* IP header fields included in the TCP checksum */ 1875 h->ip_p = IPPROTO_TCP; 1876 h->ip_len = htons(tlen); 1877 h->ip_src.s_addr = saddr->v4.s_addr; 1878 h->ip_dst.s_addr = daddr->v4.s_addr; 1879 1880 th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip)); 1881 break; 1882#endif /* INET */ 1883#ifdef INET6 1884 case AF_INET6: 1885 h6 = mtod(m, struct ip6_hdr *); 1886 1887 /* IP header fields included in the TCP checksum */ 1888 h6->ip6_nxt = IPPROTO_TCP; 1889 h6->ip6_plen = htons(tlen); 1890 memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr)); 1891 memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr)); 1892 1893 th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr)); 1894 break; 1895#endif /* INET6 */ 1896 } 1897 1898 /* TCP header */ 1899 th->th_sport = sport; 1900 th->th_dport = dport; 1901 th->th_seq = htonl(seq); 1902 th->th_ack = htonl(ack); 1903 th->th_off = tlen >> 2; 1904 th->th_flags = flags; 1905 th->th_win = htons(win); 1906 1907 if (mss) { 1908 opt = (char *)(th + 1); 1909 opt[0] = TCPOPT_MAXSEG; 1910 opt[1] = 4; 1911 HTONS(mss); 1912 bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2); 1913 } 1914 1915 switch (af) { 1916#ifdef INET 1917 case AF_INET: 1918 /* TCP checksum */ 1919 th->th_sum = in_cksum(m, len); 1920 1921 /* Finish the IP header */ 1922 h->ip_v = 4; 1923 h->ip_hl = sizeof(*h) >> 2; 1924 h->ip_tos = IPTOS_LOWDELAY; 1925#ifdef __FreeBSD__ 1926 h->ip_off = V_path_mtu_discovery ? IP_DF : 0; 1927 h->ip_len = len; 1928#else 1929 h->ip_off = htons(ip_mtudisc ? IP_DF : 0); 1930 h->ip_len = htons(len); 1931#endif 1932 h->ip_ttl = ttl ? ttl : V_ip_defttl; 1933 h->ip_sum = 0; 1934 if (eh == NULL) { 1935#ifdef __FreeBSD__ 1936 PF_UNLOCK(); 1937 ip_output(m, (void *)NULL, (void *)NULL, 0, 1938 (void *)NULL, (void *)NULL); 1939 PF_LOCK(); 1940#else /* ! __FreeBSD__ */ 1941 ip_output(m, (void *)NULL, (void *)NULL, 0, 1942 (void *)NULL, (void *)NULL); 1943#endif 1944 } else { 1945 struct route ro; 1946 struct rtentry rt; 1947 struct ether_header *e = (void *)ro.ro_dst.sa_data; 1948 1949 if (ifp == NULL) { 1950 m_freem(m); 1951 return; 1952 } 1953 rt.rt_ifp = ifp; 1954 ro.ro_rt = &rt; 1955 ro.ro_dst.sa_len = sizeof(ro.ro_dst); 1956 ro.ro_dst.sa_family = pseudo_AF_HDRCMPLT; 1957 bcopy(eh->ether_dhost, e->ether_shost, ETHER_ADDR_LEN); 1958 bcopy(eh->ether_shost, e->ether_dhost, ETHER_ADDR_LEN); 1959 e->ether_type = eh->ether_type; 1960#ifdef __FreeBSD__ 1961 PF_UNLOCK(); 1962 /* XXX_IMPORT: later */ 1963 ip_output(m, (void *)NULL, &ro, 0, 1964 (void *)NULL, (void *)NULL); 1965 PF_LOCK(); 1966#else /* ! __FreeBSD__ */ 1967 ip_output(m, (void *)NULL, &ro, IP_ROUTETOETHER, 1968 (void *)NULL, (void *)NULL); 1969#endif 1970 } 1971 break; 1972#endif /* INET */ 1973#ifdef INET6 1974 case AF_INET6: 1975 /* TCP checksum */ 1976 th->th_sum = in6_cksum(m, IPPROTO_TCP, 1977 sizeof(struct ip6_hdr), tlen); 1978 1979 h6->ip6_vfc |= IPV6_VERSION; 1980 h6->ip6_hlim = IPV6_DEFHLIM; 1981 1982#ifdef __FreeBSD__ 1983 PF_UNLOCK(); 1984 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); 1985 PF_LOCK(); 1986#else 1987 ip6_output(m, NULL, NULL, 0, NULL, NULL); 1988#endif 1989 break; 1990#endif /* INET6 */ 1991 } 1992} 1993 1994void 1995pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, 1996 struct pf_rule *r) 1997{ 1998 struct pf_mtag *pf_mtag; 1999 struct mbuf *m0; 2000#ifdef __FreeBSD__ 2001 struct ip *ip; 2002#endif 2003 2004#ifdef __FreeBSD__ 2005 m0 = m_copypacket(m, M_DONTWAIT); 2006 if (m0 == NULL) 2007 return; 2008#else 2009 m0 = m_copy(m, 0, M_COPYALL); 2010#endif 2011 if ((pf_mtag = pf_get_mtag(m0)) == NULL) 2012 return; 2013#ifdef __FreeBSD__ 2014 /* XXX: revisit */ 2015 m0->m_flags |= M_SKIP_FIREWALL; 2016#else 2017 pf_mtag->flags |= PF_TAG_GENERATED; 2018#endif 2019 2020 if (r->rtableid >= 0) 2021#ifdef __FreeBSD__ 2022 { 2023 M_SETFIB(m0, r->rtableid); 2024#endif 2025 pf_mtag->rtableid = r->rtableid; 2026#ifdef __FreeBSD__ 2027 } 2028#endif 2029 2030#ifdef ALTQ 2031 if (r->qid) { 2032 pf_mtag->qid = r->qid; 2033 /* add hints for ecn */ 2034 pf_mtag->af = af; 2035 pf_mtag->hdr = mtod(m0, struct ip *); 2036 } 2037#endif /* ALTQ */ 2038 2039 switch (af) { 2040#ifdef INET 2041 case AF_INET: 2042#ifdef __FreeBSD__ 2043 /* icmp_error() expects host byte ordering */ 2044 ip = mtod(m0, struct ip *); 2045 NTOHS(ip->ip_len); 2046 NTOHS(ip->ip_off); 2047 PF_UNLOCK(); 2048 icmp_error(m0, type, code, 0, 0); 2049 PF_LOCK(); 2050#else 2051 icmp_error(m0, type, code, 0, 0); 2052#endif 2053 break; 2054#endif /* INET */ 2055#ifdef INET6 2056 case AF_INET6: 2057#ifdef __FreeBSD__ 2058 PF_UNLOCK(); 2059#endif 2060 icmp6_error(m0, type, code, 0); 2061#ifdef __FreeBSD__ 2062 PF_LOCK(); 2063#endif 2064 break; 2065#endif /* INET6 */ 2066 } 2067} 2068 2069/* 2070 * Return 1 if the addresses a and b match (with mask m), otherwise return 0. 2071 * If n is 0, they match if they are equal. If n is != 0, they match if they 2072 * are different. 2073 */ 2074int 2075pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m, 2076 struct pf_addr *b, sa_family_t af) 2077{ 2078 int match = 0; 2079 2080 switch (af) { 2081#ifdef INET 2082 case AF_INET: 2083 if ((a->addr32[0] & m->addr32[0]) == 2084 (b->addr32[0] & m->addr32[0])) 2085 match++; 2086 break; 2087#endif /* INET */ 2088#ifdef INET6 2089 case AF_INET6: 2090 if (((a->addr32[0] & m->addr32[0]) == 2091 (b->addr32[0] & m->addr32[0])) && 2092 ((a->addr32[1] & m->addr32[1]) == 2093 (b->addr32[1] & m->addr32[1])) && 2094 ((a->addr32[2] & m->addr32[2]) == 2095 (b->addr32[2] & m->addr32[2])) && 2096 ((a->addr32[3] & m->addr32[3]) == 2097 (b->addr32[3] & m->addr32[3]))) 2098 match++; 2099 break; 2100#endif /* INET6 */ 2101 } 2102 if (match) { 2103 if (n) 2104 return (0); 2105 else 2106 return (1); 2107 } else { 2108 if (n) 2109 return (1); 2110 else 2111 return (0); 2112 } 2113} 2114 2115int 2116pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p) 2117{ 2118 switch (op) { 2119 case PF_OP_IRG: 2120 return ((p > a1) && (p < a2)); 2121 case PF_OP_XRG: 2122 return ((p < a1) || (p > a2)); 2123 case PF_OP_RRG: 2124 return ((p >= a1) && (p <= a2)); 2125 case PF_OP_EQ: 2126 return (p == a1); 2127 case PF_OP_NE: 2128 return (p != a1); 2129 case PF_OP_LT: 2130 return (p < a1); 2131 case PF_OP_LE: 2132 return (p <= a1); 2133 case PF_OP_GT: 2134 return (p > a1); 2135 case PF_OP_GE: 2136 return (p >= a1); 2137 } 2138 return (0); /* never reached */ 2139} 2140 2141int 2142pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p) 2143{ 2144 NTOHS(a1); 2145 NTOHS(a2); 2146 NTOHS(p); 2147 return (pf_match(op, a1, a2, p)); 2148} 2149 2150int 2151pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u) 2152{ 2153 if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 2154 return (0); 2155 return (pf_match(op, a1, a2, u)); 2156} 2157 2158int 2159pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g) 2160{ 2161 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 2162 return (0); 2163 return (pf_match(op, a1, a2, g)); 2164} 2165 2166#ifndef __FreeBSD__ 2167struct pf_mtag * 2168pf_find_mtag(struct mbuf *m) 2169{ 2170 struct m_tag *mtag; 2171 2172 if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) 2173 return (NULL); 2174 2175 return ((struct pf_mtag *)(mtag + 1)); 2176} 2177 2178struct pf_mtag * 2179pf_get_mtag(struct mbuf *m) 2180{ 2181 struct m_tag *mtag; 2182 2183 if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) { 2184 mtag = m_tag_get(PACKET_TAG_PF, sizeof(struct pf_mtag), 2185 M_NOWAIT); 2186 if (mtag == NULL) 2187 return (NULL); 2188 bzero(mtag + 1, sizeof(struct pf_mtag)); 2189 m_tag_prepend(m, mtag); 2190 } 2191 2192 return ((struct pf_mtag *)(mtag + 1)); 2193} 2194#endif 2195 2196int 2197pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_mtag *pf_mtag, 2198 int *tag) 2199{ 2200 if (*tag == -1) 2201 *tag = pf_mtag->tag; 2202 2203 return ((!r->match_tag_not && r->match_tag == *tag) || 2204 (r->match_tag_not && r->match_tag != *tag)); 2205} 2206 2207int 2208pf_tag_packet(struct mbuf *m, struct pf_mtag *pf_mtag, int tag, int rtableid) 2209{ 2210 if (tag <= 0 && rtableid < 0) 2211 return (0); 2212 2213 if (pf_mtag == NULL) 2214 if ((pf_mtag = pf_get_mtag(m)) == NULL) 2215 return (1); 2216 if (tag > 0) 2217 pf_mtag->tag = tag; 2218 if (rtableid >= 0) 2219#ifdef __FreeBSD__ 2220 { 2221 M_SETFIB(m, rtableid); 2222#endif 2223 pf_mtag->rtableid = rtableid; 2224#ifdef __FreeBSD__ 2225 } 2226#endif 2227 2228 return (0); 2229} 2230 2231static void 2232pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n, 2233 struct pf_rule **r, struct pf_rule **a, int *match) 2234{ 2235 struct pf_anchor_stackframe *f; 2236 2237 (*r)->anchor->match = 0; 2238 if (match) 2239 *match = 0; 2240 if (*depth >= sizeof(pf_anchor_stack) / 2241 sizeof(pf_anchor_stack[0])) { 2242 printf("pf_step_into_anchor: stack overflow\n"); 2243 *r = TAILQ_NEXT(*r, entries); 2244 return; 2245 } else if (*depth == 0 && a != NULL) 2246 *a = *r; 2247 f = pf_anchor_stack + (*depth)++; 2248 f->rs = *rs; 2249 f->r = *r; 2250 if ((*r)->anchor_wildcard) { 2251 f->parent = &(*r)->anchor->children; 2252 if ((f->child = RB_MIN(pf_anchor_node, f->parent)) == 2253 NULL) { 2254 *r = NULL; 2255 return; 2256 } 2257 *rs = &f->child->ruleset; 2258 } else { 2259 f->parent = NULL; 2260 f->child = NULL; 2261 *rs = &(*r)->anchor->ruleset; 2262 } 2263 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2264} 2265 2266int 2267pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n, 2268 struct pf_rule **r, struct pf_rule **a, int *match) 2269{ 2270 struct pf_anchor_stackframe *f; 2271 int quick = 0; 2272 2273 do { 2274 if (*depth <= 0) 2275 break; 2276 f = pf_anchor_stack + *depth - 1; 2277 if (f->parent != NULL && f->child != NULL) { 2278 if (f->child->match || 2279 (match != NULL && *match)) { 2280 f->r->anchor->match = 1; 2281 *match = 0; 2282 } 2283 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child); 2284 if (f->child != NULL) { 2285 *rs = &f->child->ruleset; 2286 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2287 if (*r == NULL) 2288 continue; 2289 else 2290 break; 2291 } 2292 } 2293 (*depth)--; 2294 if (*depth == 0 && a != NULL) 2295 *a = NULL; 2296 *rs = f->rs; 2297 if (f->r->anchor->match || (match != NULL && *match)) 2298 quick = f->r->quick; 2299 *r = TAILQ_NEXT(f->r, entries); 2300 } while (*r == NULL); 2301 2302 return (quick); 2303} 2304 2305#ifdef INET6 2306void 2307pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr, 2308 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af) 2309{ 2310 switch (af) { 2311#ifdef INET 2312 case AF_INET: 2313 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) | 2314 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]); 2315 break; 2316#endif /* INET */ 2317 case AF_INET6: 2318 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) | 2319 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]); 2320 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) | 2321 ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]); 2322 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) | 2323 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]); 2324 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) | 2325 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]); 2326 break; 2327 } 2328} 2329 2330void 2331pf_addr_inc(struct pf_addr *addr, sa_family_t af) 2332{ 2333 switch (af) { 2334#ifdef INET 2335 case AF_INET: 2336 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1); 2337 break; 2338#endif /* INET */ 2339 case AF_INET6: 2340 if (addr->addr32[3] == 0xffffffff) { 2341 addr->addr32[3] = 0; 2342 if (addr->addr32[2] == 0xffffffff) { 2343 addr->addr32[2] = 0; 2344 if (addr->addr32[1] == 0xffffffff) { 2345 addr->addr32[1] = 0; 2346 addr->addr32[0] = 2347 htonl(ntohl(addr->addr32[0]) + 1); 2348 } else 2349 addr->addr32[1] = 2350 htonl(ntohl(addr->addr32[1]) + 1); 2351 } else 2352 addr->addr32[2] = 2353 htonl(ntohl(addr->addr32[2]) + 1); 2354 } else 2355 addr->addr32[3] = 2356 htonl(ntohl(addr->addr32[3]) + 1); 2357 break; 2358 } 2359} 2360#endif /* INET6 */ 2361 2362#define mix(a,b,c) \ 2363 do { \ 2364 a -= b; a -= c; a ^= (c >> 13); \ 2365 b -= c; b -= a; b ^= (a << 8); \ 2366 c -= a; c -= b; c ^= (b >> 13); \ 2367 a -= b; a -= c; a ^= (c >> 12); \ 2368 b -= c; b -= a; b ^= (a << 16); \ 2369 c -= a; c -= b; c ^= (b >> 5); \ 2370 a -= b; a -= c; a ^= (c >> 3); \ 2371 b -= c; b -= a; b ^= (a << 10); \ 2372 c -= a; c -= b; c ^= (b >> 15); \ 2373 } while (0) 2374 2375/* 2376 * hash function based on bridge_hash in if_bridge.c 2377 */ 2378void 2379pf_hash(struct pf_addr *inaddr, struct pf_addr *hash, 2380 struct pf_poolhashkey *key, sa_family_t af) 2381{ 2382 u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0]; 2383 2384 switch (af) { 2385#ifdef INET 2386 case AF_INET: 2387 a += inaddr->addr32[0]; 2388 b += key->key32[1]; 2389 mix(a, b, c); 2390 hash->addr32[0] = c + key->key32[2]; 2391 break; 2392#endif /* INET */ 2393#ifdef INET6 2394 case AF_INET6: 2395 a += inaddr->addr32[0]; 2396 b += inaddr->addr32[2]; 2397 mix(a, b, c); 2398 hash->addr32[0] = c; 2399 a += inaddr->addr32[1]; 2400 b += inaddr->addr32[3]; 2401 c += key->key32[1]; 2402 mix(a, b, c); 2403 hash->addr32[1] = c; 2404 a += inaddr->addr32[2]; 2405 b += inaddr->addr32[1]; 2406 c += key->key32[2]; 2407 mix(a, b, c); 2408 hash->addr32[2] = c; 2409 a += inaddr->addr32[3]; 2410 b += inaddr->addr32[0]; 2411 c += key->key32[3]; 2412 mix(a, b, c); 2413 hash->addr32[3] = c; 2414 break; 2415#endif /* INET6 */ 2416 } 2417} 2418 2419int 2420pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr, 2421 struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn) 2422{ 2423 unsigned char hash[16]; 2424 struct pf_pool *rpool = &r->rpool; 2425 struct pf_addr *raddr = &rpool->cur->addr.v.a.addr; 2426 struct pf_addr *rmask = &rpool->cur->addr.v.a.mask; 2427 struct pf_pooladdr *acur = rpool->cur; 2428 struct pf_src_node k; 2429 2430 if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR && 2431 (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { 2432 k.af = af; 2433 PF_ACPY(&k.addr, saddr, af); 2434 if (r->rule_flag & PFRULE_RULESRCTRACK || 2435 r->rpool.opts & PF_POOL_STICKYADDR) 2436 k.rule.ptr = r; 2437 else 2438 k.rule.ptr = NULL; 2439 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++; 2440 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k); 2441 if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) { 2442 PF_ACPY(naddr, &(*sn)->raddr, af); 2443 if (pf_status.debug >= PF_DEBUG_MISC) { 2444 printf("pf_map_addr: src tracking maps "); 2445 pf_print_host(&k.addr, 0, af); 2446 printf(" to "); 2447 pf_print_host(naddr, 0, af); 2448 printf("\n"); 2449 } 2450 return (0); 2451 } 2452 } 2453 2454 if (rpool->cur->addr.type == PF_ADDR_NOROUTE) 2455 return (1); 2456 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 2457 switch (af) { 2458#ifdef INET 2459 case AF_INET: 2460 if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 && 2461 (rpool->opts & PF_POOL_TYPEMASK) != 2462 PF_POOL_ROUNDROBIN) 2463 return (1); 2464 raddr = &rpool->cur->addr.p.dyn->pfid_addr4; 2465 rmask = &rpool->cur->addr.p.dyn->pfid_mask4; 2466 break; 2467#endif /* INET */ 2468#ifdef INET6 2469 case AF_INET6: 2470 if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 && 2471 (rpool->opts & PF_POOL_TYPEMASK) != 2472 PF_POOL_ROUNDROBIN) 2473 return (1); 2474 raddr = &rpool->cur->addr.p.dyn->pfid_addr6; 2475 rmask = &rpool->cur->addr.p.dyn->pfid_mask6; 2476 break; 2477#endif /* INET6 */ 2478 } 2479 } else if (rpool->cur->addr.type == PF_ADDR_TABLE) { 2480 if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN) 2481 return (1); /* unsupported */ 2482 } else { 2483 raddr = &rpool->cur->addr.v.a.addr; 2484 rmask = &rpool->cur->addr.v.a.mask; 2485 } 2486 2487 switch (rpool->opts & PF_POOL_TYPEMASK) { 2488 case PF_POOL_NONE: 2489 PF_ACPY(naddr, raddr, af); 2490 break; 2491 case PF_POOL_BITMASK: 2492 PF_POOLMASK(naddr, raddr, rmask, saddr, af); 2493 break; 2494 case PF_POOL_RANDOM: 2495 if (init_addr != NULL && PF_AZERO(init_addr, af)) { 2496 switch (af) { 2497#ifdef INET 2498 case AF_INET: 2499 rpool->counter.addr32[0] = htonl(arc4random()); 2500 break; 2501#endif /* INET */ 2502#ifdef INET6 2503 case AF_INET6: 2504 if (rmask->addr32[3] != 0xffffffff) 2505 rpool->counter.addr32[3] = 2506 htonl(arc4random()); 2507 else 2508 break; 2509 if (rmask->addr32[2] != 0xffffffff) 2510 rpool->counter.addr32[2] = 2511 htonl(arc4random()); 2512 else 2513 break; 2514 if (rmask->addr32[1] != 0xffffffff) 2515 rpool->counter.addr32[1] = 2516 htonl(arc4random()); 2517 else 2518 break; 2519 if (rmask->addr32[0] != 0xffffffff) 2520 rpool->counter.addr32[0] = 2521 htonl(arc4random()); 2522 break; 2523#endif /* INET6 */ 2524 } 2525 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af); 2526 PF_ACPY(init_addr, naddr, af); 2527 2528 } else { 2529 PF_AINC(&rpool->counter, af); 2530 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af); 2531 } 2532 break; 2533 case PF_POOL_SRCHASH: 2534 pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af); 2535 PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af); 2536 break; 2537 case PF_POOL_ROUNDROBIN: 2538 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 2539 if (!pfr_pool_get(rpool->cur->addr.p.tbl, 2540 &rpool->tblidx, &rpool->counter, 2541 &raddr, &rmask, af)) 2542 goto get_addr; 2543 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 2544 if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 2545 &rpool->tblidx, &rpool->counter, 2546 &raddr, &rmask, af)) 2547 goto get_addr; 2548 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af)) 2549 goto get_addr; 2550 2551 try_next: 2552 if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL) 2553 rpool->cur = TAILQ_FIRST(&rpool->list); 2554 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 2555 rpool->tblidx = -1; 2556 if (pfr_pool_get(rpool->cur->addr.p.tbl, 2557 &rpool->tblidx, &rpool->counter, 2558 &raddr, &rmask, af)) { 2559 /* table contains no address of type 'af' */ 2560 if (rpool->cur != acur) 2561 goto try_next; 2562 return (1); 2563 } 2564 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 2565 rpool->tblidx = -1; 2566 if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 2567 &rpool->tblidx, &rpool->counter, 2568 &raddr, &rmask, af)) { 2569 /* table contains no address of type 'af' */ 2570 if (rpool->cur != acur) 2571 goto try_next; 2572 return (1); 2573 } 2574 } else { 2575 raddr = &rpool->cur->addr.v.a.addr; 2576 rmask = &rpool->cur->addr.v.a.mask; 2577 PF_ACPY(&rpool->counter, raddr, af); 2578 } 2579 2580 get_addr: 2581 PF_ACPY(naddr, &rpool->counter, af); 2582 if (init_addr != NULL && PF_AZERO(init_addr, af)) 2583 PF_ACPY(init_addr, naddr, af); 2584 PF_AINC(&rpool->counter, af); 2585 break; 2586 } 2587 if (*sn != NULL) 2588 PF_ACPY(&(*sn)->raddr, naddr, af); 2589 2590 if (pf_status.debug >= PF_DEBUG_MISC && 2591 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { 2592 printf("pf_map_addr: selected address "); 2593 pf_print_host(naddr, 0, af); 2594 printf("\n"); 2595 } 2596 2597 return (0); 2598} 2599 2600int 2601pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, 2602 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport, 2603 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high, 2604 struct pf_src_node **sn) 2605{ 2606 struct pf_state_cmp key; 2607 struct pf_addr init_addr; 2608 u_int16_t cut; 2609 2610 bzero(&init_addr, sizeof(init_addr)); 2611 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) 2612 return (1); 2613 2614 if (proto == IPPROTO_ICMP) { 2615 low = 1; 2616 high = 65535; 2617 } 2618 2619 do { 2620 key.af = af; 2621 key.proto = proto; 2622 PF_ACPY(&key.ext.addr, daddr, key.af); 2623 PF_ACPY(&key.gwy.addr, naddr, key.af); 2624 key.ext.port = dport; 2625 2626 /* 2627 * port search; start random, step; 2628 * similar 2 portloop in in_pcbbind 2629 */ 2630 if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP || 2631 proto == IPPROTO_ICMP)) { 2632 key.gwy.port = dport; 2633 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) 2634 return (0); 2635 } else if (low == 0 && high == 0) { 2636 key.gwy.port = *nport; 2637 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) 2638 return (0); 2639 } else if (low == high) { 2640 key.gwy.port = htons(low); 2641 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) { 2642 *nport = htons(low); 2643 return (0); 2644 } 2645 } else { 2646 u_int16_t tmp; 2647 2648 if (low > high) { 2649 tmp = low; 2650 low = high; 2651 high = tmp; 2652 } 2653 /* low < high */ 2654 cut = htonl(arc4random()) % (1 + high - low) + low; 2655 /* low <= cut <= high */ 2656 for (tmp = cut; tmp <= high; ++(tmp)) { 2657 key.gwy.port = htons(tmp); 2658 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == 2659 NULL) { 2660 *nport = htons(tmp); 2661 return (0); 2662 } 2663 } 2664 for (tmp = cut - 1; tmp >= low; --(tmp)) { 2665 key.gwy.port = htons(tmp); 2666 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == 2667 NULL) { 2668 *nport = htons(tmp); 2669 return (0); 2670 } 2671 } 2672 } 2673 2674 switch (r->rpool.opts & PF_POOL_TYPEMASK) { 2675 case PF_POOL_RANDOM: 2676 case PF_POOL_ROUNDROBIN: 2677 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) 2678 return (1); 2679 break; 2680 case PF_POOL_NONE: 2681 case PF_POOL_SRCHASH: 2682 case PF_POOL_BITMASK: 2683 default: 2684 return (1); 2685 } 2686 } while (! PF_AEQ(&init_addr, naddr, af) ); 2687 2688 return (1); /* none available */ 2689} 2690 2691struct pf_rule * 2692pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, 2693 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport, 2694 struct pf_addr *daddr, u_int16_t dport, int rs_num) 2695{ 2696 struct pf_rule *r, *rm = NULL; 2697 struct pf_ruleset *ruleset = NULL; 2698 int tag = -1; 2699 int rtableid = -1; 2700 int asd = 0; 2701 2702 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr); 2703 while (r && rm == NULL) { 2704 struct pf_rule_addr *src = NULL, *dst = NULL; 2705 struct pf_addr_wrap *xdst = NULL; 2706 2707 if (r->action == PF_BINAT && direction == PF_IN) { 2708 src = &r->dst; 2709 if (r->rpool.cur != NULL) 2710 xdst = &r->rpool.cur->addr; 2711 } else { 2712 src = &r->src; 2713 dst = &r->dst; 2714 } 2715 2716 r->evaluations++; 2717 if (pfi_kif_match(r->kif, kif) == r->ifnot) 2718 r = r->skip[PF_SKIP_IFP].ptr; 2719 else if (r->direction && r->direction != direction) 2720 r = r->skip[PF_SKIP_DIR].ptr; 2721 else if (r->af && r->af != pd->af) 2722 r = r->skip[PF_SKIP_AF].ptr; 2723 else if (r->proto && r->proto != pd->proto) 2724 r = r->skip[PF_SKIP_PROTO].ptr; 2725 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, 2726 src->neg, kif)) 2727 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR : 2728 PF_SKIP_DST_ADDR].ptr; 2729 else if (src->port_op && !pf_match_port(src->port_op, 2730 src->port[0], src->port[1], sport)) 2731 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT : 2732 PF_SKIP_DST_PORT].ptr; 2733 else if (dst != NULL && 2734 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL)) 2735 r = r->skip[PF_SKIP_DST_ADDR].ptr; 2736 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, 2737 0, NULL)) 2738 r = TAILQ_NEXT(r, entries); 2739 else if (dst != NULL && dst->port_op && 2740 !pf_match_port(dst->port_op, dst->port[0], 2741 dst->port[1], dport)) 2742 r = r->skip[PF_SKIP_DST_PORT].ptr; 2743 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 2744 r = TAILQ_NEXT(r, entries); 2745 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto != 2746 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m, 2747 off, pd->hdr.tcp), r->os_fingerprint))) 2748 r = TAILQ_NEXT(r, entries); 2749 else { 2750 if (r->tag) 2751 tag = r->tag; 2752 if (r->rtableid >= 0) 2753 rtableid = r->rtableid; 2754 if (r->anchor == NULL) { 2755 rm = r; 2756 } else 2757 pf_step_into_anchor(&asd, &ruleset, rs_num, 2758 &r, NULL, NULL); 2759 } 2760 if (r == NULL) 2761 pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r, 2762 NULL, NULL); 2763 } 2764 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) 2765 return (NULL); 2766 if (rm != NULL && (rm->action == PF_NONAT || 2767 rm->action == PF_NORDR || rm->action == PF_NOBINAT)) 2768 return (NULL); 2769 return (rm); 2770} 2771 2772struct pf_rule * 2773pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, 2774 struct pfi_kif *kif, struct pf_src_node **sn, 2775 struct pf_addr *saddr, u_int16_t sport, 2776 struct pf_addr *daddr, u_int16_t dport, 2777 struct pf_addr *naddr, u_int16_t *nport) 2778{ 2779 struct pf_rule *r = NULL; 2780 2781 if (direction == PF_OUT) { 2782 r = pf_match_translation(pd, m, off, direction, kif, saddr, 2783 sport, daddr, dport, PF_RULESET_BINAT); 2784 if (r == NULL) 2785 r = pf_match_translation(pd, m, off, direction, kif, 2786 saddr, sport, daddr, dport, PF_RULESET_NAT); 2787 } else { 2788 r = pf_match_translation(pd, m, off, direction, kif, saddr, 2789 sport, daddr, dport, PF_RULESET_RDR); 2790 if (r == NULL) 2791 r = pf_match_translation(pd, m, off, direction, kif, 2792 saddr, sport, daddr, dport, PF_RULESET_BINAT); 2793 } 2794 2795 if (r != NULL) { 2796 switch (r->action) { 2797 case PF_NONAT: 2798 case PF_NOBINAT: 2799 case PF_NORDR: 2800 return (NULL); 2801 case PF_NAT: 2802 if (pf_get_sport(pd->af, pd->proto, r, saddr, 2803 daddr, dport, naddr, nport, r->rpool.proxy_port[0], 2804 r->rpool.proxy_port[1], sn)) { 2805 DPFPRINTF(PF_DEBUG_MISC, 2806 ("pf: NAT proxy port allocation " 2807 "(%u-%u) failed\n", 2808 r->rpool.proxy_port[0], 2809 r->rpool.proxy_port[1])); 2810 return (NULL); 2811 } 2812 break; 2813 case PF_BINAT: 2814 switch (direction) { 2815 case PF_OUT: 2816 if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){ 2817 switch (pd->af) { 2818#ifdef INET 2819 case AF_INET: 2820 if (r->rpool.cur->addr.p.dyn-> 2821 pfid_acnt4 < 1) 2822 return (NULL); 2823 PF_POOLMASK(naddr, 2824 &r->rpool.cur->addr.p.dyn-> 2825 pfid_addr4, 2826 &r->rpool.cur->addr.p.dyn-> 2827 pfid_mask4, 2828 saddr, AF_INET); 2829 break; 2830#endif /* INET */ 2831#ifdef INET6 2832 case AF_INET6: 2833 if (r->rpool.cur->addr.p.dyn-> 2834 pfid_acnt6 < 1) 2835 return (NULL); 2836 PF_POOLMASK(naddr, 2837 &r->rpool.cur->addr.p.dyn-> 2838 pfid_addr6, 2839 &r->rpool.cur->addr.p.dyn-> 2840 pfid_mask6, 2841 saddr, AF_INET6); 2842 break; 2843#endif /* INET6 */ 2844 } 2845 } else 2846 PF_POOLMASK(naddr, 2847 &r->rpool.cur->addr.v.a.addr, 2848 &r->rpool.cur->addr.v.a.mask, 2849 saddr, pd->af); 2850 break; 2851 case PF_IN: 2852 if (r->src.addr.type == PF_ADDR_DYNIFTL) { 2853 switch (pd->af) { 2854#ifdef INET 2855 case AF_INET: 2856 if (r->src.addr.p.dyn-> 2857 pfid_acnt4 < 1) 2858 return (NULL); 2859 PF_POOLMASK(naddr, 2860 &r->src.addr.p.dyn-> 2861 pfid_addr4, 2862 &r->src.addr.p.dyn-> 2863 pfid_mask4, 2864 daddr, AF_INET); 2865 break; 2866#endif /* INET */ 2867#ifdef INET6 2868 case AF_INET6: 2869 if (r->src.addr.p.dyn-> 2870 pfid_acnt6 < 1) 2871 return (NULL); 2872 PF_POOLMASK(naddr, 2873 &r->src.addr.p.dyn-> 2874 pfid_addr6, 2875 &r->src.addr.p.dyn-> 2876 pfid_mask6, 2877 daddr, AF_INET6); 2878 break; 2879#endif /* INET6 */ 2880 } 2881 } else 2882 PF_POOLMASK(naddr, 2883 &r->src.addr.v.a.addr, 2884 &r->src.addr.v.a.mask, daddr, 2885 pd->af); 2886 break; 2887 } 2888 break; 2889 case PF_RDR: { 2890 if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn)) 2891 return (NULL); 2892 if ((r->rpool.opts & PF_POOL_TYPEMASK) == 2893 PF_POOL_BITMASK) 2894 PF_POOLMASK(naddr, naddr, 2895 &r->rpool.cur->addr.v.a.mask, daddr, 2896 pd->af); 2897 2898 if (r->rpool.proxy_port[1]) { 2899 u_int32_t tmp_nport; 2900 2901 tmp_nport = ((ntohs(dport) - 2902 ntohs(r->dst.port[0])) % 2903 (r->rpool.proxy_port[1] - 2904 r->rpool.proxy_port[0] + 1)) + 2905 r->rpool.proxy_port[0]; 2906 2907 /* wrap around if necessary */ 2908 if (tmp_nport > 65535) 2909 tmp_nport -= 65535; 2910 *nport = htons((u_int16_t)tmp_nport); 2911 } else if (r->rpool.proxy_port[0]) 2912 *nport = htons(r->rpool.proxy_port[0]); 2913 break; 2914 } 2915 default: 2916 return (NULL); 2917 } 2918 } 2919 2920 return (r); 2921} 2922 2923int 2924#ifdef __FreeBSD__ 2925pf_socket_lookup(int direction, struct pf_pdesc *pd, struct inpcb *inp_arg) 2926#else 2927pf_socket_lookup(int direction, struct pf_pdesc *pd) 2928#endif 2929{ 2930 INIT_VNET_INET(curvnet); 2931 struct pf_addr *saddr, *daddr; 2932 u_int16_t sport, dport; 2933#ifdef __FreeBSD__ 2934 struct inpcbinfo *pi; 2935#else 2936 struct inpcbtable *tb; 2937#endif 2938 struct inpcb *inp; 2939 2940 if (pd == NULL) 2941 return (-1); 2942 pd->lookup.uid = UID_MAX; 2943 pd->lookup.gid = GID_MAX; 2944 pd->lookup.pid = NO_PID; /* XXX: revisit */ 2945#ifdef __FreeBSD__ 2946 if (inp_arg != NULL) { 2947 INP_LOCK_ASSERT(inp_arg); 2948 pd->lookup.uid = inp_arg->inp_cred->cr_uid; 2949 pd->lookup.gid = inp_arg->inp_cred->cr_groups[0]; 2950 return (1); 2951 } 2952#endif 2953 switch (pd->proto) { 2954 case IPPROTO_TCP: 2955 if (pd->hdr.tcp == NULL) 2956 return (-1); 2957 sport = pd->hdr.tcp->th_sport; 2958 dport = pd->hdr.tcp->th_dport; 2959#ifdef __FreeBSD__ 2960 pi = &V_tcbinfo; 2961#else 2962 tb = &tcbtable; 2963#endif 2964 break; 2965 case IPPROTO_UDP: 2966 if (pd->hdr.udp == NULL) 2967 return (-1); 2968 sport = pd->hdr.udp->uh_sport; 2969 dport = pd->hdr.udp->uh_dport; 2970#ifdef __FreeBSD__ 2971 pi = &V_udbinfo; 2972#else 2973 tb = &udbtable; 2974#endif 2975 break; 2976 default: 2977 return (-1); 2978 } 2979 if (direction == PF_IN) { 2980 saddr = pd->src; 2981 daddr = pd->dst; 2982 } else { 2983 u_int16_t p; 2984 2985 p = sport; 2986 sport = dport; 2987 dport = p; 2988 saddr = pd->dst; 2989 daddr = pd->src; 2990 } 2991 switch (pd->af) { 2992#ifdef INET 2993 case AF_INET: 2994#ifdef __FreeBSD__ 2995 INP_INFO_RLOCK(pi); /* XXX LOR */ 2996 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4, 2997 dport, 0, NULL); 2998 if (inp == NULL) { 2999 inp = in_pcblookup_hash(pi, saddr->v4, sport, 3000 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL); 3001 if(inp == NULL) { 3002 INP_INFO_RUNLOCK(pi); 3003 return (-1); 3004 } 3005 } 3006#else 3007 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); 3008 if (inp == NULL) { 3009 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0); 3010 if (inp == NULL) 3011 return (-1); 3012 } 3013#endif 3014 break; 3015#endif /* INET */ 3016#ifdef INET6 3017 case AF_INET6: 3018#ifdef __FreeBSD__ 3019 INP_INFO_RLOCK(pi); 3020 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 3021 &daddr->v6, dport, 0, NULL); 3022 if (inp == NULL) { 3023 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 3024 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL); 3025 if (inp == NULL) { 3026 INP_INFO_RUNLOCK(pi); 3027 return (-1); 3028 } 3029 } 3030#else 3031 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, 3032 dport); 3033 if (inp == NULL) { 3034 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0); 3035 if (inp == NULL) 3036 return (-1); 3037 } 3038#endif 3039 break; 3040#endif /* INET6 */ 3041 3042 default: 3043 return (-1); 3044 } 3045#ifdef __FreeBSD__ 3046 pd->lookup.uid = inp->inp_cred->cr_uid; 3047 pd->lookup.gid = inp->inp_cred->cr_groups[0]; 3048 INP_INFO_RUNLOCK(pi); 3049#else 3050 pd->lookup.uid = inp->inp_socket->so_euid; 3051 pd->lookup.gid = inp->inp_socket->so_egid; 3052 pd->lookup.pid = inp->inp_socket->so_cpid; 3053#endif 3054 return (1); 3055} 3056 3057u_int8_t 3058pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 3059{ 3060 int hlen; 3061 u_int8_t hdr[60]; 3062 u_int8_t *opt, optlen; 3063 u_int8_t wscale = 0; 3064 3065 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 3066 if (hlen <= sizeof(struct tcphdr)) 3067 return (0); 3068 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 3069 return (0); 3070 opt = hdr + sizeof(struct tcphdr); 3071 hlen -= sizeof(struct tcphdr); 3072 while (hlen >= 3) { 3073 switch (*opt) { 3074 case TCPOPT_EOL: 3075 case TCPOPT_NOP: 3076 ++opt; 3077 --hlen; 3078 break; 3079 case TCPOPT_WINDOW: 3080 wscale = opt[2]; 3081 if (wscale > TCP_MAX_WINSHIFT) 3082 wscale = TCP_MAX_WINSHIFT; 3083 wscale |= PF_WSCALE_FLAG; 3084 /* FALLTHROUGH */ 3085 default: 3086 optlen = opt[1]; 3087 if (optlen < 2) 3088 optlen = 2; 3089 hlen -= optlen; 3090 opt += optlen; 3091 break; 3092 } 3093 } 3094 return (wscale); 3095} 3096 3097u_int16_t 3098pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 3099{ 3100 INIT_VNET_INET(curvnet); 3101 int hlen; 3102 u_int8_t hdr[60]; 3103 u_int8_t *opt, optlen; 3104 u_int16_t mss = V_tcp_mssdflt; 3105 3106 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 3107 if (hlen <= sizeof(struct tcphdr)) 3108 return (0); 3109 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 3110 return (0); 3111 opt = hdr + sizeof(struct tcphdr); 3112 hlen -= sizeof(struct tcphdr); 3113 while (hlen >= TCPOLEN_MAXSEG) { 3114 switch (*opt) { 3115 case TCPOPT_EOL: 3116 case TCPOPT_NOP: 3117 ++opt; 3118 --hlen; 3119 break; 3120 case TCPOPT_MAXSEG: 3121 bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2); 3122 NTOHS(mss); 3123 /* FALLTHROUGH */ 3124 default: 3125 optlen = opt[1]; 3126 if (optlen < 2) 3127 optlen = 2; 3128 hlen -= optlen; 3129 opt += optlen; 3130 break; 3131 } 3132 } 3133 return (mss); 3134} 3135 3136u_int16_t 3137pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) 3138{ 3139#ifdef INET 3140 INIT_VNET_INET(curvnet); 3141 struct sockaddr_in *dst; 3142 struct route ro; 3143#endif /* INET */ 3144#ifdef INET6 3145 struct sockaddr_in6 *dst6; 3146 struct route_in6 ro6; 3147#endif /* INET6 */ 3148 struct rtentry *rt = NULL; 3149 int hlen = 0; /* make the compiler happy */ 3150 u_int16_t mss = V_tcp_mssdflt; 3151 3152 switch (af) { 3153#ifdef INET 3154 case AF_INET: 3155 hlen = sizeof(struct ip); 3156 bzero(&ro, sizeof(ro)); 3157 dst = (struct sockaddr_in *)&ro.ro_dst; 3158 dst->sin_family = AF_INET; 3159 dst->sin_len = sizeof(*dst); 3160 dst->sin_addr = addr->v4; 3161#ifdef __FreeBSD__ 3162#ifdef RTF_PRCLONING 3163 rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING)); 3164#else /* !RTF_PRCLONING */ 3165 in_rtalloc_ign(&ro, 0, 0); 3166#endif 3167#else /* ! __FreeBSD__ */ 3168 rtalloc_noclone(&ro, NO_CLONING); 3169#endif 3170 rt = ro.ro_rt; 3171 break; 3172#endif /* INET */ 3173#ifdef INET6 3174 case AF_INET6: 3175 hlen = sizeof(struct ip6_hdr); 3176 bzero(&ro6, sizeof(ro6)); 3177 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst; 3178 dst6->sin6_family = AF_INET6; 3179 dst6->sin6_len = sizeof(*dst6); 3180 dst6->sin6_addr = addr->v6; 3181#ifdef __FreeBSD__ 3182#ifdef RTF_PRCLONING 3183 rtalloc_ign((struct route *)&ro6, 3184 (RTF_CLONING | RTF_PRCLONING)); 3185#else /* !RTF_PRCLONING */ 3186 rtalloc_ign((struct route *)&ro6, 0); 3187#endif 3188#else /* ! __FreeBSD__ */ 3189 rtalloc_noclone((struct route *)&ro6, NO_CLONING); 3190#endif 3191 rt = ro6.ro_rt; 3192 break; 3193#endif /* INET6 */ 3194 } 3195 3196 if (rt && rt->rt_ifp) { 3197 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr); 3198 mss = max(V_tcp_mssdflt, mss); 3199 RTFREE(rt); 3200 } 3201 mss = min(mss, offer); 3202 mss = max(mss, 64); /* sanity - at least max opt space */ 3203 return (mss); 3204} 3205 3206void 3207pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr) 3208{ 3209 struct pf_rule *r = s->rule.ptr; 3210 3211 s->rt_kif = NULL; 3212 if (!r->rt || r->rt == PF_FASTROUTE) 3213 return; 3214 switch (s->af) { 3215#ifdef INET 3216 case AF_INET: 3217 pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, 3218 &s->nat_src_node); 3219 s->rt_kif = r->rpool.cur->kif; 3220 break; 3221#endif /* INET */ 3222#ifdef INET6 3223 case AF_INET6: 3224 pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, 3225 &s->nat_src_node); 3226 s->rt_kif = r->rpool.cur->kif; 3227 break; 3228#endif /* INET6 */ 3229 } 3230} 3231 3232int 3233pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction, 3234 struct pfi_kif *kif, struct mbuf *m, int off, void *h, 3235#ifdef __FreeBSD__ 3236 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3237 struct ifqueue *ifq, struct inpcb *inp) 3238#else 3239 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3240 struct ifqueue *ifq) 3241#endif 3242{ 3243 INIT_VNET_INET(curvnet); 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 = V_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, 0, 0); 5990 else 5991 rtalloc_ign((struct route *)&ro, 0); 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, 0, 0); 6072 else 6073 rtalloc_ign((struct route *)&ro, 0); 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 INIT_VNET_INET(curvnet); 6099 struct mbuf *m0, *m1; 6100 struct route iproute; 6101 struct route *ro = NULL; 6102 struct sockaddr_in *dst; 6103 struct ip *ip; 6104 struct ifnet *ifp = NULL; 6105 struct pf_addr naddr; 6106 struct pf_src_node *sn = NULL; 6107 int error = 0; 6108#ifdef __FreeBSD__ 6109 int sw_csum; 6110#endif 6111#ifdef IPSEC 6112 struct m_tag *mtag; 6113#endif /* IPSEC */ 6114 6115 if (m == NULL || *m == NULL || r == NULL || 6116 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 6117 panic("pf_route: invalid parameters"); 6118 6119 if (pd->pf_mtag->routed++ > 3) { 6120 m0 = *m; 6121 *m = NULL; 6122 goto bad; 6123 } 6124 6125 if (r->rt == PF_DUPTO) { 6126#ifdef __FreeBSD__ 6127 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 6128#else 6129 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 6130#endif 6131 return; 6132 } else { 6133 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 6134 return; 6135 m0 = *m; 6136 } 6137 6138 if (m0->m_len < sizeof(struct ip)) { 6139 DPFPRINTF(PF_DEBUG_URGENT, 6140 ("pf_route: m0->m_len < sizeof(struct ip)\n")); 6141 goto bad; 6142 } 6143 6144 ip = mtod(m0, struct ip *); 6145 6146 ro = &iproute; 6147 bzero((caddr_t)ro, sizeof(*ro)); 6148 dst = satosin(&ro->ro_dst); 6149 dst->sin_family = AF_INET; 6150 dst->sin_len = sizeof(*dst); 6151 dst->sin_addr = ip->ip_dst; 6152 6153 if (r->rt == PF_FASTROUTE) { 6154 in_rtalloc(ro, 0); 6155 if (ro->ro_rt == 0) { 6156 V_ipstat.ips_noroute++; 6157 goto bad; 6158 } 6159 6160 ifp = ro->ro_rt->rt_ifp; 6161 ro->ro_rt->rt_use++; 6162 6163 if (ro->ro_rt->rt_flags & RTF_GATEWAY) 6164 dst = satosin(ro->ro_rt->rt_gateway); 6165 } else { 6166 if (TAILQ_EMPTY(&r->rpool.list)) { 6167 DPFPRINTF(PF_DEBUG_URGENT, 6168 ("pf_route: TAILQ_EMPTY(&r->rpool.list)\n")); 6169 goto bad; 6170 } 6171 if (s == NULL) { 6172 pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src, 6173 &naddr, NULL, &sn); 6174 if (!PF_AZERO(&naddr, AF_INET)) 6175 dst->sin_addr.s_addr = naddr.v4.s_addr; 6176 ifp = r->rpool.cur->kif ? 6177 r->rpool.cur->kif->pfik_ifp : NULL; 6178 } else { 6179 if (!PF_AZERO(&s->rt_addr, AF_INET)) 6180 dst->sin_addr.s_addr = 6181 s->rt_addr.v4.s_addr; 6182 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; 6183 } 6184 } 6185 if (ifp == NULL) 6186 goto bad; 6187 6188 if (oifp != ifp) { 6189#ifdef __FreeBSD__ 6190 PF_UNLOCK(); 6191 if (pf_test(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) { 6192 PF_LOCK(); 6193 goto bad; 6194 } else if (m0 == NULL) { 6195 PF_LOCK(); 6196 goto done; 6197 } 6198 PF_LOCK(); 6199#else 6200 if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS) 6201 goto bad; 6202 else if (m0 == NULL) 6203 goto done; 6204#endif 6205 if (m0->m_len < sizeof(struct ip)) { 6206 DPFPRINTF(PF_DEBUG_URGENT, 6207 ("pf_route: m0->m_len < sizeof(struct ip)\n")); 6208 goto bad; 6209 } 6210 ip = mtod(m0, struct ip *); 6211 } 6212 6213#ifdef __FreeBSD__ 6214 /* Copied from FreeBSD 5.1-CURRENT ip_output. */ 6215 m0->m_pkthdr.csum_flags |= CSUM_IP; 6216 sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist; 6217 if (sw_csum & CSUM_DELAY_DATA) { 6218 /* 6219 * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least) 6220 */ 6221 NTOHS(ip->ip_len); 6222 NTOHS(ip->ip_off); /* XXX: needed? */ 6223 in_delayed_cksum(m0); 6224 HTONS(ip->ip_len); 6225 HTONS(ip->ip_off); 6226 sw_csum &= ~CSUM_DELAY_DATA; 6227 } 6228 m0->m_pkthdr.csum_flags &= ifp->if_hwassist; 6229 6230 if (ntohs(ip->ip_len) <= ifp->if_mtu || 6231 (ifp->if_hwassist & CSUM_FRAGMENT && 6232 ((ip->ip_off & htons(IP_DF)) == 0))) { 6233 /* 6234 * ip->ip_len = htons(ip->ip_len); 6235 * ip->ip_off = htons(ip->ip_off); 6236 */ 6237 ip->ip_sum = 0; 6238 if (sw_csum & CSUM_DELAY_IP) { 6239 /* From KAME */ 6240 if (ip->ip_v == IPVERSION && 6241 (ip->ip_hl << 2) == sizeof(*ip)) { 6242 ip->ip_sum = in_cksum_hdr(ip); 6243 } else { 6244 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 6245 } 6246 } 6247 PF_UNLOCK(); 6248 error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro->ro_rt); 6249 PF_LOCK(); 6250 goto done; 6251 } 6252 6253#else 6254 /* Copied from ip_output. */ 6255#ifdef IPSEC 6256 /* 6257 * If deferred crypto processing is needed, check that the 6258 * interface supports it. 6259 */ 6260 if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL)) 6261 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) { 6262 /* Notify IPsec to do its own crypto. */ 6263 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); 6264 goto bad; 6265 } 6266#endif /* IPSEC */ 6267 6268 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */ 6269 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) { 6270 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) || 6271 ifp->if_bridge != NULL) { 6272 in_delayed_cksum(m0); 6273 m0->m_pkthdr.csum_flags &= ~M_TCPV4_CSUM_OUT; /* Clear */ 6274 } 6275 } else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) { 6276 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) || 6277 ifp->if_bridge != NULL) { 6278 in_delayed_cksum(m0); 6279 m0->m_pkthdr.csum_flags &= ~M_UDPV4_CSUM_OUT; /* Clear */ 6280 } 6281 } 6282 6283 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 6284 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 6285 ifp->if_bridge == NULL) { 6286 m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; 6287 V_ipstat.ips_outhwcsum++; 6288 } else { 6289 ip->ip_sum = 0; 6290 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 6291 } 6292 /* Update relevant hardware checksum stats for TCP/UDP */ 6293 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) 6294 V_tcpstat.tcps_outhwcsum++; 6295 else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) 6296 V_udpstat.udps_outhwcsum++; 6297 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); 6298 goto done; 6299 } 6300#endif 6301 /* 6302 * Too large for interface; fragment if possible. 6303 * Must be able to put at least 8 bytes per fragment. 6304 */ 6305 if (ip->ip_off & htons(IP_DF)) { 6306 V_ipstat.ips_cantfrag++; 6307 if (r->rt != PF_DUPTO) { 6308#ifdef __FreeBSD__ 6309 /* icmp_error() expects host byte ordering */ 6310 NTOHS(ip->ip_len); 6311 NTOHS(ip->ip_off); 6312 PF_UNLOCK(); 6313 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 6314 ifp->if_mtu); 6315 PF_LOCK(); 6316#else 6317 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 6318 ifp->if_mtu); 6319#endif 6320 goto done; 6321 } else 6322 goto bad; 6323 } 6324 6325 m1 = m0; 6326#ifdef __FreeBSD__ 6327 /* 6328 * XXX: is cheaper + less error prone than own function 6329 */ 6330 NTOHS(ip->ip_len); 6331 NTOHS(ip->ip_off); 6332 error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum); 6333#else 6334 error = ip_fragment(m0, ifp, ifp->if_mtu); 6335#endif 6336 if (error) { 6337#ifndef __FreeBSD__ /* ip_fragment does not do m_freem() on FreeBSD */ 6338 m0 = NULL; 6339#endif 6340 goto bad; 6341 } 6342 6343 for (m0 = m1; m0; m0 = m1) { 6344 m1 = m0->m_nextpkt; 6345 m0->m_nextpkt = 0; 6346#ifdef __FreeBSD__ 6347 if (error == 0) { 6348 PF_UNLOCK(); 6349 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 6350 NULL); 6351 PF_LOCK(); 6352 } else 6353#else 6354 if (error == 0) 6355 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 6356 NULL); 6357 else 6358#endif 6359 m_freem(m0); 6360 } 6361 6362 if (error == 0) 6363 V_ipstat.ips_fragmented++; 6364 6365done: 6366 if (r->rt != PF_DUPTO) 6367 *m = NULL; 6368 if (ro == &iproute && ro->ro_rt) 6369 RTFREE(ro->ro_rt); 6370 return; 6371 6372bad: 6373 m_freem(m0); 6374 goto done; 6375} 6376#endif /* INET */ 6377 6378#ifdef INET6 6379void 6380pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 6381 struct pf_state *s, struct pf_pdesc *pd) 6382{ 6383 struct mbuf *m0; 6384 struct route_in6 ip6route; 6385 struct route_in6 *ro; 6386 struct sockaddr_in6 *dst; 6387 struct ip6_hdr *ip6; 6388 struct ifnet *ifp = NULL; 6389 struct pf_addr naddr; 6390 struct pf_src_node *sn = NULL; 6391 int error = 0; 6392 6393 if (m == NULL || *m == NULL || r == NULL || 6394 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 6395 panic("pf_route6: invalid parameters"); 6396 6397 if (pd->pf_mtag->routed++ > 3) { 6398 m0 = *m; 6399 *m = NULL; 6400 goto bad; 6401 } 6402 6403 if (r->rt == PF_DUPTO) { 6404#ifdef __FreeBSD__ 6405 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 6406#else 6407 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 6408#endif 6409 return; 6410 } else { 6411 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 6412 return; 6413 m0 = *m; 6414 } 6415 6416 if (m0->m_len < sizeof(struct ip6_hdr)) { 6417 DPFPRINTF(PF_DEBUG_URGENT, 6418 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n")); 6419 goto bad; 6420 } 6421 ip6 = mtod(m0, struct ip6_hdr *); 6422 6423 ro = &ip6route; 6424 bzero((caddr_t)ro, sizeof(*ro)); 6425 dst = (struct sockaddr_in6 *)&ro->ro_dst; 6426 dst->sin6_family = AF_INET6; 6427 dst->sin6_len = sizeof(*dst); 6428 dst->sin6_addr = ip6->ip6_dst; 6429 6430 /* Cheat. XXX why only in the v6 case??? */ 6431 if (r->rt == PF_FASTROUTE) { 6432#ifdef __FreeBSD__ 6433 m0->m_flags |= M_SKIP_FIREWALL; 6434 PF_UNLOCK(); 6435 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 6436 PF_LOCK(); 6437#else 6438 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 6439 if (mtag == NULL) 6440 goto bad; 6441 m_tag_prepend(m0, mtag); 6442 pd->pf_mtag->flags |= PF_TAG_GENERATED; 6443 ip6_output(m0, NULL, NULL, 0, NULL, NULL); 6444#endif 6445 return; 6446 } 6447 6448 if (TAILQ_EMPTY(&r->rpool.list)) { 6449 DPFPRINTF(PF_DEBUG_URGENT, 6450 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n")); 6451 goto bad; 6452 } 6453 if (s == NULL) { 6454 pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, 6455 &naddr, NULL, &sn); 6456 if (!PF_AZERO(&naddr, AF_INET6)) 6457 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 6458 &naddr, AF_INET6); 6459 ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; 6460 } else { 6461 if (!PF_AZERO(&s->rt_addr, AF_INET6)) 6462 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 6463 &s->rt_addr, AF_INET6); 6464 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; 6465 } 6466 if (ifp == NULL) 6467 goto bad; 6468 6469 if (oifp != ifp) { 6470#ifdef __FreeBSD__ 6471 PF_UNLOCK(); 6472 if (pf_test6(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) { 6473 PF_LOCK(); 6474 goto bad; 6475 } else if (m0 == NULL) { 6476 PF_LOCK(); 6477 goto done; 6478 } 6479 PF_LOCK(); 6480#else 6481 if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS) 6482 goto bad; 6483 else if (m0 == NULL) 6484 goto done; 6485#endif 6486 if (m0->m_len < sizeof(struct ip6_hdr)) { 6487 DPFPRINTF(PF_DEBUG_URGENT, 6488 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n")); 6489 goto bad; 6490 } 6491 ip6 = mtod(m0, struct ip6_hdr *); 6492 } 6493 6494 /* 6495 * If the packet is too large for the outgoing interface, 6496 * send back an icmp6 error. 6497 */ 6498 if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr)) 6499 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); 6500 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { 6501#ifdef __FreeBSD__ 6502 PF_UNLOCK(); 6503#endif 6504 error = nd6_output(ifp, ifp, m0, dst, NULL); 6505#ifdef __FreeBSD__ 6506 PF_LOCK(); 6507#endif 6508 } else { 6509 in6_ifstat_inc(ifp, ifs6_in_toobig); 6510#ifdef __FreeBSD__ 6511 if (r->rt != PF_DUPTO) { 6512 PF_UNLOCK(); 6513 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 6514 PF_LOCK(); 6515 } else 6516#else 6517 if (r->rt != PF_DUPTO) 6518 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 6519 else 6520#endif 6521 goto bad; 6522 } 6523 6524done: 6525 if (r->rt != PF_DUPTO) 6526 *m = NULL; 6527 return; 6528 6529bad: 6530 m_freem(m0); 6531 goto done; 6532} 6533#endif /* INET6 */ 6534 6535 6536#ifdef __FreeBSD__ 6537/* 6538 * FreeBSD supports cksum offloads for the following drivers. 6539 * em(4), fxp(4), ixgb(4), lge(4), ndis(4), nge(4), re(4), 6540 * ti(4), txp(4), xl(4) 6541 * 6542 * CSUM_DATA_VALID | CSUM_PSEUDO_HDR : 6543 * network driver performed cksum including pseudo header, need to verify 6544 * csum_data 6545 * CSUM_DATA_VALID : 6546 * network driver performed cksum, needs to additional pseudo header 6547 * cksum computation with partial csum_data(i.e. lack of H/W support for 6548 * pseudo header, for instance hme(4), sk(4) and possibly gem(4)) 6549 * 6550 * After validating the cksum of packet, set both flag CSUM_DATA_VALID and 6551 * CSUM_PSEUDO_HDR in order to avoid recomputation of the cksum in upper 6552 * TCP/UDP layer. 6553 * Also, set csum_data to 0xffff to force cksum validation. 6554 */ 6555int 6556pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) 6557{ 6558 u_int16_t sum = 0; 6559 int hw_assist = 0; 6560 struct ip *ip; 6561 6562 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 6563 return (1); 6564 if (m->m_pkthdr.len < off + len) 6565 return (1); 6566 6567 switch (p) { 6568 case IPPROTO_TCP: 6569 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 6570 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 6571 sum = m->m_pkthdr.csum_data; 6572 } else { 6573 ip = mtod(m, struct ip *); 6574 sum = in_pseudo(ip->ip_src.s_addr, 6575 ip->ip_dst.s_addr, htonl((u_short)len + 6576 m->m_pkthdr.csum_data + IPPROTO_TCP)); 6577 } 6578 sum ^= 0xffff; 6579 ++hw_assist; 6580 } 6581 break; 6582 case IPPROTO_UDP: 6583 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 6584 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 6585 sum = m->m_pkthdr.csum_data; 6586 } else { 6587 ip = mtod(m, struct ip *); 6588 sum = in_pseudo(ip->ip_src.s_addr, 6589 ip->ip_dst.s_addr, htonl((u_short)len + 6590 m->m_pkthdr.csum_data + IPPROTO_UDP)); 6591 } 6592 sum ^= 0xffff; 6593 ++hw_assist; 6594 } 6595 break; 6596 case IPPROTO_ICMP: 6597#ifdef INET6 6598 case IPPROTO_ICMPV6: 6599#endif /* INET6 */ 6600 break; 6601 default: 6602 return (1); 6603 } 6604 6605 if (!hw_assist) { 6606 switch (af) { 6607 case AF_INET: 6608 if (p == IPPROTO_ICMP) { 6609 if (m->m_len < off) 6610 return (1); 6611 m->m_data += off; 6612 m->m_len -= off; 6613 sum = in_cksum(m, len); 6614 m->m_data -= off; 6615 m->m_len += off; 6616 } else { 6617 if (m->m_len < sizeof(struct ip)) 6618 return (1); 6619 sum = in4_cksum(m, p, off, len); 6620 } 6621 break; 6622#ifdef INET6 6623 case AF_INET6: 6624 if (m->m_len < sizeof(struct ip6_hdr)) 6625 return (1); 6626 sum = in6_cksum(m, p, off, len); 6627 break; 6628#endif /* INET6 */ 6629 default: 6630 return (1); 6631 } 6632 } 6633 if (sum) { 6634 switch (p) { 6635 case IPPROTO_TCP: 6636 { 6637 INIT_VNET_INET(curvnet); 6638 V_tcpstat.tcps_rcvbadsum++; 6639 break; 6640 } 6641 case IPPROTO_UDP: 6642 { 6643 INIT_VNET_INET(curvnet); 6644 V_udpstat.udps_badsum++; 6645 break; 6646 } 6647 case IPPROTO_ICMP: 6648 { 6649 INIT_VNET_INET(curvnet); 6650 V_icmpstat.icps_checksum++; 6651 break; 6652 } 6653#ifdef INET6 6654 case IPPROTO_ICMPV6: 6655 { 6656 INIT_VNET_INET6(curvnet); 6657 V_icmp6stat.icp6s_checksum++; 6658 break; 6659 } 6660#endif /* INET6 */ 6661 } 6662 return (1); 6663 } else { 6664 if (p == IPPROTO_TCP || p == IPPROTO_UDP) { 6665 m->m_pkthdr.csum_flags |= 6666 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); 6667 m->m_pkthdr.csum_data = 0xffff; 6668 } 6669 } 6670 return (0); 6671} 6672#else /* !__FreeBSD__ */ 6673/* 6674 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 6675 * off is the offset where the protocol header starts 6676 * len is the total length of protocol header plus payload 6677 * returns 0 when the checksum is valid, otherwise returns 1. 6678 */ 6679int 6680pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, 6681 sa_family_t af) 6682{ 6683 u_int16_t flag_ok, flag_bad; 6684 u_int16_t sum; 6685 6686 switch (p) { 6687 case IPPROTO_TCP: 6688 flag_ok = M_TCP_CSUM_IN_OK; 6689 flag_bad = M_TCP_CSUM_IN_BAD; 6690 break; 6691 case IPPROTO_UDP: 6692 flag_ok = M_UDP_CSUM_IN_OK; 6693 flag_bad = M_UDP_CSUM_IN_BAD; 6694 break; 6695 case IPPROTO_ICMP: 6696#ifdef INET6 6697 case IPPROTO_ICMPV6: 6698#endif /* INET6 */ 6699 flag_ok = flag_bad = 0; 6700 break; 6701 default: 6702 return (1); 6703 } 6704 if (m->m_pkthdr.csum_flags & flag_ok) 6705 return (0); 6706 if (m->m_pkthdr.csum_flags & flag_bad) 6707 return (1); 6708 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 6709 return (1); 6710 if (m->m_pkthdr.len < off + len) 6711 return (1); 6712 switch (af) { 6713#ifdef INET 6714 case AF_INET: 6715 if (p == IPPROTO_ICMP) { 6716 if (m->m_len < off) 6717 return (1); 6718 m->m_data += off; 6719 m->m_len -= off; 6720 sum = in_cksum(m, len); 6721 m->m_data -= off; 6722 m->m_len += off; 6723 } else { 6724 if (m->m_len < sizeof(struct ip)) 6725 return (1); 6726 sum = in4_cksum(m, p, off, len); 6727 } 6728 break; 6729#endif /* INET */ 6730#ifdef INET6 6731 case AF_INET6: 6732 if (m->m_len < sizeof(struct ip6_hdr)) 6733 return (1); 6734 sum = in6_cksum(m, p, off, len); 6735 break; 6736#endif /* INET6 */ 6737 default: 6738 return (1); 6739 } 6740 if (sum) { 6741 m->m_pkthdr.csum_flags |= flag_bad; 6742 switch (p) { 6743 case IPPROTO_TCP: 6744 V_tcpstat.tcps_rcvbadsum++; 6745 break; 6746 case IPPROTO_UDP: 6747 V_udpstat.udps_badsum++; 6748 break; 6749 case IPPROTO_ICMP: 6750 V_icmpstat.icps_checksum++; 6751 break; 6752#ifdef INET6 6753 case IPPROTO_ICMPV6: 6754 V_icmp6stat.icp6s_checksum++; 6755 break; 6756#endif /* INET6 */ 6757 } 6758 return (1); 6759 } 6760 m->m_pkthdr.csum_flags |= flag_ok; 6761 return (0); 6762} 6763#endif /* __FreeBSD__ */ 6764 6765#ifdef INET 6766int 6767#ifdef __FreeBSD__ 6768pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6769 struct ether_header *eh, struct inpcb *inp) 6770#else 6771pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6772 struct ether_header *eh) 6773#endif 6774{ 6775 struct pfi_kif *kif; 6776 u_short action, reason = 0, log = 0; 6777 struct mbuf *m = *m0; 6778 struct ip *h = NULL; /* make the compiler happy */ 6779 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 6780 struct pf_state *s = NULL; 6781 struct pf_ruleset *ruleset = NULL; 6782 struct pf_pdesc pd; 6783 int off, dirndx, pqid = 0; 6784 6785#ifdef __FreeBSD__ 6786 PF_LOCK(); 6787#endif 6788 if (!pf_status.running) 6789#ifdef __FreeBSD__ 6790 { 6791 PF_UNLOCK(); 6792#endif 6793 return (PF_PASS); 6794#ifdef __FreeBSD__ 6795 } 6796#endif 6797 6798 memset(&pd, 0, sizeof(pd)); 6799 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) { 6800#ifdef __FreeBSD__ 6801 PF_UNLOCK(); 6802#endif 6803 DPFPRINTF(PF_DEBUG_URGENT, 6804 ("pf_test: pf_get_mtag returned NULL\n")); 6805 return (PF_DROP); 6806 } 6807#ifdef __FreeBSD__ 6808 if (m->m_flags & M_SKIP_FIREWALL) { 6809 PF_UNLOCK(); 6810 return (PF_PASS); 6811 } 6812#else 6813 if (pd.pf_mtag->flags & PF_TAG_GENERATED) 6814 return (PF_PASS); 6815#endif 6816 6817#ifdef __FreeBSD__ 6818 /* XXX_IMPORT: later */ 6819#else 6820 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 6821 ifp = ifp->if_carpdev; 6822#endif 6823 6824 kif = (struct pfi_kif *)ifp->if_pf_kif; 6825 if (kif == NULL) { 6826#ifdef __FreeBSD__ 6827 PF_UNLOCK(); 6828#endif 6829 DPFPRINTF(PF_DEBUG_URGENT, 6830 ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname)); 6831 return (PF_DROP); 6832 } 6833 if (kif->pfik_flags & PFI_IFLAG_SKIP) { 6834#ifdef __FreeBSD__ 6835 PF_UNLOCK(); 6836#endif 6837 return (PF_PASS); 6838 } 6839 6840#ifdef __FreeBSD__ 6841 M_ASSERTPKTHDR(m); 6842#else 6843#ifdef DIAGNOSTIC 6844 if ((m->m_flags & M_PKTHDR) == 0) 6845 panic("non-M_PKTHDR is passed to pf_test"); 6846#endif /* DIAGNOSTIC */ 6847#endif /* __FreeBSD__ */ 6848 6849 if (m->m_pkthdr.len < (int)sizeof(*h)) { 6850 action = PF_DROP; 6851 REASON_SET(&reason, PFRES_SHORT); 6852 log = 1; 6853 goto done; 6854 } 6855 6856 /* We do IP header normalization and packet reassembly here */ 6857 if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) { 6858 action = PF_DROP; 6859 goto done; 6860 } 6861 m = *m0; 6862 h = mtod(m, struct ip *); 6863 6864 off = h->ip_hl << 2; 6865 if (off < (int)sizeof(*h)) { 6866 action = PF_DROP; 6867 REASON_SET(&reason, PFRES_SHORT); 6868 log = 1; 6869 goto done; 6870 } 6871 6872 pd.src = (struct pf_addr *)&h->ip_src; 6873 pd.dst = (struct pf_addr *)&h->ip_dst; 6874 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET); 6875 pd.ip_sum = &h->ip_sum; 6876 pd.proto = h->ip_p; 6877 pd.af = AF_INET; 6878 pd.tos = h->ip_tos; 6879 pd.tot_len = ntohs(h->ip_len); 6880 pd.eh = eh; 6881 6882 /* handle fragments that didn't get reassembled by normalization */ 6883 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) { 6884 action = pf_test_fragment(&r, dir, kif, m, h, 6885 &pd, &a, &ruleset); 6886 goto done; 6887 } 6888 6889 switch (h->ip_p) { 6890 6891 case IPPROTO_TCP: { 6892 struct tcphdr th; 6893 6894 pd.hdr.tcp = &th; 6895 if (!pf_pull_hdr(m, off, &th, sizeof(th), 6896 &action, &reason, AF_INET)) { 6897 log = action != PF_PASS; 6898 goto done; 6899 } 6900 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6901 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) { 6902 REASON_SET(&reason, PFRES_PROTCKSUM); 6903 action = PF_DROP; 6904 goto done; 6905 } 6906 pd.p_len = pd.tot_len - off - (th.th_off << 2); 6907 if ((th.th_flags & TH_ACK) && pd.p_len == 0) 6908 pqid = 1; 6909 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 6910 if (action == PF_DROP) 6911 goto done; 6912 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, 6913 &reason); 6914 if (action == PF_PASS) { 6915#if NPFSYNC 6916 pfsync_update_state(s); 6917#endif /* NPFSYNC */ 6918 r = s->rule.ptr; 6919 a = s->anchor.ptr; 6920 log = s->log; 6921 } else if (s == NULL) 6922#ifdef __FreeBSD__ 6923 action = pf_test_tcp(&r, &s, dir, kif, 6924 m, off, h, &pd, &a, &ruleset, NULL, inp); 6925#else 6926 action = pf_test_tcp(&r, &s, dir, kif, 6927 m, off, h, &pd, &a, &ruleset, &ipintrq); 6928#endif 6929 break; 6930 } 6931 6932 case IPPROTO_UDP: { 6933 struct udphdr uh; 6934 6935 pd.hdr.udp = &uh; 6936 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 6937 &action, &reason, AF_INET)) { 6938 log = action != PF_PASS; 6939 goto done; 6940 } 6941 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 6942 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) { 6943 action = PF_DROP; 6944 REASON_SET(&reason, PFRES_PROTCKSUM); 6945 goto done; 6946 } 6947 if (uh.uh_dport == 0 || 6948 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 6949 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 6950 action = PF_DROP; 6951 REASON_SET(&reason, PFRES_SHORT); 6952 goto done; 6953 } 6954 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 6955 if (action == PF_PASS) { 6956#if NPFSYNC 6957 pfsync_update_state(s); 6958#endif /* NPFSYNC */ 6959 r = s->rule.ptr; 6960 a = s->anchor.ptr; 6961 log = s->log; 6962 } else if (s == NULL) 6963#ifdef __FreeBSD__ 6964 action = pf_test_udp(&r, &s, dir, kif, 6965 m, off, h, &pd, &a, &ruleset, NULL, inp); 6966#else 6967 action = pf_test_udp(&r, &s, dir, kif, 6968 m, off, h, &pd, &a, &ruleset, &ipintrq); 6969#endif 6970 break; 6971 } 6972 6973 case IPPROTO_ICMP: { 6974 struct icmp ih; 6975 6976 pd.hdr.icmp = &ih; 6977 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN, 6978 &action, &reason, AF_INET)) { 6979 log = action != PF_PASS; 6980 goto done; 6981 } 6982 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6983 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) { 6984 action = PF_DROP; 6985 REASON_SET(&reason, PFRES_PROTCKSUM); 6986 goto done; 6987 } 6988 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd, 6989 &reason); 6990 if (action == PF_PASS) { 6991#if NPFSYNC 6992 pfsync_update_state(s); 6993#endif /* NPFSYNC */ 6994 r = s->rule.ptr; 6995 a = s->anchor.ptr; 6996 log = s->log; 6997 } else if (s == NULL) 6998#ifdef __FreeBSD__ 6999 action = pf_test_icmp(&r, &s, dir, kif, 7000 m, off, h, &pd, &a, &ruleset, NULL); 7001#else 7002 action = pf_test_icmp(&r, &s, dir, kif, 7003 m, off, h, &pd, &a, &ruleset, &ipintrq); 7004#endif 7005 break; 7006 } 7007 7008 default: 7009 action = pf_test_state_other(&s, dir, kif, &pd); 7010 if (action == PF_PASS) { 7011#if NPFSYNC 7012 pfsync_update_state(s); 7013#endif /* NPFSYNC */ 7014 r = s->rule.ptr; 7015 a = s->anchor.ptr; 7016 log = s->log; 7017 } else if (s == NULL) 7018#ifdef __FreeBSD__ 7019 action = pf_test_other(&r, &s, dir, kif, m, off, h, 7020 &pd, &a, &ruleset, NULL); 7021#else 7022 action = pf_test_other(&r, &s, dir, kif, m, off, h, 7023 &pd, &a, &ruleset, &ipintrq); 7024#endif 7025 break; 7026 } 7027 7028done: 7029 if (action == PF_PASS && h->ip_hl > 5 && 7030 !((s && s->allow_opts) || r->allow_opts)) { 7031 action = PF_DROP; 7032 REASON_SET(&reason, PFRES_IPOPTIONS); 7033 log = 1; 7034 DPFPRINTF(PF_DEBUG_MISC, 7035 ("pf: dropping packet with ip options\n")); 7036 } 7037 7038 if ((s && s->tag) || r->rtableid) 7039 pf_tag_packet(m, pd.pf_mtag, s ? s->tag : 0, r->rtableid); 7040 7041#ifdef ALTQ 7042 if (action == PF_PASS && r->qid) { 7043 if (pqid || (pd.tos & IPTOS_LOWDELAY)) 7044 pd.pf_mtag->qid = r->pqid; 7045 else 7046 pd.pf_mtag->qid = r->qid; 7047 /* add hints for ecn */ 7048 pd.pf_mtag->af = AF_INET; 7049 pd.pf_mtag->hdr = h; 7050 } 7051#endif /* ALTQ */ 7052 7053 /* 7054 * connections redirected to loopback should not match sockets 7055 * bound specifically to loopback due to security implications, 7056 * see tcp_input() and in_pcblookup_listen(). 7057 */ 7058 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 7059 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 7060 (s->nat_rule.ptr->action == PF_RDR || 7061 s->nat_rule.ptr->action == PF_BINAT) && 7062 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 7063 pd.pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST; 7064 7065 if (log) { 7066 struct pf_rule *lr; 7067 7068 if (s != NULL && s->nat_rule.ptr != NULL && 7069 s->nat_rule.ptr->log & PF_LOG_ALL) 7070 lr = s->nat_rule.ptr; 7071 else 7072 lr = r; 7073 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, lr, a, ruleset, 7074 &pd); 7075 } 7076 7077 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7078 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++; 7079 7080 if (action == PF_PASS || r->action == PF_DROP) { 7081 dirndx = (dir == PF_OUT); 7082 r->packets[dirndx]++; 7083 r->bytes[dirndx] += pd.tot_len; 7084 if (a != NULL) { 7085 a->packets[dirndx]++; 7086 a->bytes[dirndx] += pd.tot_len; 7087 } 7088 if (s != NULL) { 7089 if (s->nat_rule.ptr != NULL) { 7090 s->nat_rule.ptr->packets[dirndx]++; 7091 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; 7092 } 7093 if (s->src_node != NULL) { 7094 s->src_node->packets[dirndx]++; 7095 s->src_node->bytes[dirndx] += pd.tot_len; 7096 } 7097 if (s->nat_src_node != NULL) { 7098 s->nat_src_node->packets[dirndx]++; 7099 s->nat_src_node->bytes[dirndx] += pd.tot_len; 7100 } 7101 dirndx = (dir == s->direction) ? 0 : 1; 7102 s->packets[dirndx]++; 7103 s->bytes[dirndx] += pd.tot_len; 7104 } 7105 tr = r; 7106 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7107 if (nr != NULL) { 7108 struct pf_addr *x; 7109 /* 7110 * XXX: we need to make sure that the addresses 7111 * passed to pfr_update_stats() are the same than 7112 * the addresses used during matching (pfr_match) 7113 */ 7114 if (r == &pf_default_rule) { 7115 tr = nr; 7116 x = (s == NULL || s->direction == dir) ? 7117 &pd.baddr : &pd.naddr; 7118 } else 7119 x = (s == NULL || s->direction == dir) ? 7120 &pd.naddr : &pd.baddr; 7121 if (x == &pd.baddr || s == NULL) { 7122 /* we need to change the address */ 7123 if (dir == PF_OUT) 7124 pd.src = x; 7125 else 7126 pd.dst = x; 7127 } 7128 } 7129 if (tr->src.addr.type == PF_ADDR_TABLE) 7130 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL || 7131 s->direction == dir) ? pd.src : pd.dst, pd.af, 7132 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 7133 tr->src.neg); 7134 if (tr->dst.addr.type == PF_ADDR_TABLE) 7135 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL || 7136 s->direction == dir) ? pd.dst : pd.src, pd.af, 7137 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 7138 tr->dst.neg); 7139 } 7140 7141 7142 if (action == PF_SYNPROXY_DROP) { 7143 m_freem(*m0); 7144 *m0 = NULL; 7145 action = PF_PASS; 7146 } else if (r->rt) 7147 /* pf_route can free the mbuf causing *m0 to become NULL */ 7148 pf_route(m0, r, dir, ifp, s, &pd); 7149 7150#ifdef __FreeBSD__ 7151 PF_UNLOCK(); 7152#endif 7153 7154 return (action); 7155} 7156#endif /* INET */ 7157 7158#ifdef INET6 7159int 7160#ifdef __FreeBSD__ 7161pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, 7162 struct ether_header *eh, struct inpcb *inp) 7163#else 7164pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, 7165 struct ether_header *eh) 7166#endif 7167{ 7168 struct pfi_kif *kif; 7169 u_short action, reason = 0, log = 0; 7170 struct mbuf *m = *m0, *n = NULL; 7171 struct ip6_hdr *h; 7172 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 7173 struct pf_state *s = NULL; 7174 struct pf_ruleset *ruleset = NULL; 7175 struct pf_pdesc pd; 7176 int off, terminal = 0, dirndx, rh_cnt = 0; 7177 7178#ifdef __FreeBSD__ 7179 PF_LOCK(); 7180#endif 7181 7182 if (!pf_status.running) 7183#ifdef __FreeBSD__ 7184 { 7185 PF_UNLOCK(); 7186#endif 7187 return (PF_PASS); 7188#ifdef __FreeBSD__ 7189 } 7190#endif 7191 7192 memset(&pd, 0, sizeof(pd)); 7193 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) { 7194#ifdef __FreeBSD__ 7195 PF_UNLOCK(); 7196#endif 7197 DPFPRINTF(PF_DEBUG_URGENT, 7198 ("pf_test6: pf_get_mtag returned NULL\n")); 7199 return (PF_DROP); 7200 } 7201 if (pd.pf_mtag->flags & PF_TAG_GENERATED) 7202 return (PF_PASS); 7203 7204#ifdef __FreeBSD__ 7205 /* XXX_IMPORT: later */ 7206#else 7207 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 7208 ifp = ifp->if_carpdev; 7209#endif 7210 7211 kif = (struct pfi_kif *)ifp->if_pf_kif; 7212 if (kif == NULL) { 7213#ifdef __FreeBSD__ 7214 PF_UNLOCK(); 7215#endif 7216 DPFPRINTF(PF_DEBUG_URGENT, 7217 ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname)); 7218 return (PF_DROP); 7219 } 7220 if (kif->pfik_flags & PFI_IFLAG_SKIP) { 7221#ifdef __FreeBSD__ 7222 PF_UNLOCK(); 7223#endif 7224 return (PF_PASS); 7225 } 7226 7227#ifdef __FreeBSD__ 7228 M_ASSERTPKTHDR(m); 7229#else 7230#ifdef DIAGNOSTIC 7231 if ((m->m_flags & M_PKTHDR) == 0) 7232 panic("non-M_PKTHDR is passed to pf_test6"); 7233#endif /* DIAGNOSTIC */ 7234#endif 7235 7236#ifdef __FreeBSD__ 7237 h = NULL; /* make the compiler happy */ 7238#endif 7239 7240 if (m->m_pkthdr.len < (int)sizeof(*h)) { 7241 action = PF_DROP; 7242 REASON_SET(&reason, PFRES_SHORT); 7243 log = 1; 7244 goto done; 7245 } 7246 7247 /* We do IP header normalization and packet reassembly here */ 7248 if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) { 7249 action = PF_DROP; 7250 goto done; 7251 } 7252 m = *m0; 7253 h = mtod(m, struct ip6_hdr *); 7254 7255#if 1 7256 /* 7257 * we do not support jumbogram yet. if we keep going, zero ip6_plen 7258 * will do something bad, so drop the packet for now. 7259 */ 7260 if (htons(h->ip6_plen) == 0) { 7261 action = PF_DROP; 7262 REASON_SET(&reason, PFRES_NORM); /*XXX*/ 7263 goto done; 7264 } 7265#endif 7266 7267 pd.src = (struct pf_addr *)&h->ip6_src; 7268 pd.dst = (struct pf_addr *)&h->ip6_dst; 7269 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET6); 7270 pd.ip_sum = NULL; 7271 pd.af = AF_INET6; 7272 pd.tos = 0; 7273 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr); 7274 pd.eh = eh; 7275 7276 off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr); 7277 pd.proto = h->ip6_nxt; 7278 do { 7279 switch (pd.proto) { 7280 case IPPROTO_FRAGMENT: 7281 action = pf_test_fragment(&r, dir, kif, m, h, 7282 &pd, &a, &ruleset); 7283 if (action == PF_DROP) 7284 REASON_SET(&reason, PFRES_FRAG); 7285 goto done; 7286 case IPPROTO_ROUTING: { 7287 struct ip6_rthdr rthdr; 7288 7289 if (rh_cnt++) { 7290 DPFPRINTF(PF_DEBUG_MISC, 7291 ("pf: IPv6 more than one rthdr\n")); 7292 action = PF_DROP; 7293 REASON_SET(&reason, PFRES_IPOPTIONS); 7294 log = 1; 7295 goto done; 7296 } 7297 if (!pf_pull_hdr(m, off, &rthdr, sizeof(rthdr), NULL, 7298 &reason, pd.af)) { 7299 DPFPRINTF(PF_DEBUG_MISC, 7300 ("pf: IPv6 short rthdr\n")); 7301 action = PF_DROP; 7302 REASON_SET(&reason, PFRES_SHORT); 7303 log = 1; 7304 goto done; 7305 } 7306 if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) { 7307 DPFPRINTF(PF_DEBUG_MISC, 7308 ("pf: IPv6 rthdr0\n")); 7309 action = PF_DROP; 7310 REASON_SET(&reason, PFRES_IPOPTIONS); 7311 log = 1; 7312 goto done; 7313 } 7314 /* fallthrough */ 7315 } 7316 case IPPROTO_AH: 7317 case IPPROTO_HOPOPTS: 7318 case IPPROTO_DSTOPTS: { 7319 /* get next header and header length */ 7320 struct ip6_ext opt6; 7321 7322 if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6), 7323 NULL, &reason, pd.af)) { 7324 DPFPRINTF(PF_DEBUG_MISC, 7325 ("pf: IPv6 short opt\n")); 7326 action = PF_DROP; 7327 log = 1; 7328 goto done; 7329 } 7330 if (pd.proto == IPPROTO_AH) 7331 off += (opt6.ip6e_len + 2) * 4; 7332 else 7333 off += (opt6.ip6e_len + 1) * 8; 7334 pd.proto = opt6.ip6e_nxt; 7335 /* goto the next header */ 7336 break; 7337 } 7338 default: 7339 terminal++; 7340 break; 7341 } 7342 } while (!terminal); 7343 7344 /* if there's no routing header, use unmodified mbuf for checksumming */ 7345 if (!n) 7346 n = m; 7347 7348 switch (pd.proto) { 7349 7350 case IPPROTO_TCP: { 7351 struct tcphdr th; 7352 7353 pd.hdr.tcp = &th; 7354 if (!pf_pull_hdr(m, off, &th, sizeof(th), 7355 &action, &reason, AF_INET6)) { 7356 log = action != PF_PASS; 7357 goto done; 7358 } 7359 if (dir == PF_IN && pf_check_proto_cksum(n, off, 7360 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7361 IPPROTO_TCP, AF_INET6)) { 7362 action = PF_DROP; 7363 REASON_SET(&reason, PFRES_PROTCKSUM); 7364 goto done; 7365 } 7366 pd.p_len = pd.tot_len - off - (th.th_off << 2); 7367 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 7368 if (action == PF_DROP) 7369 goto done; 7370 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, 7371 &reason); 7372 if (action == PF_PASS) { 7373#if NPFSYNC 7374 pfsync_update_state(s); 7375#endif /* NPFSYNC */ 7376 r = s->rule.ptr; 7377 a = s->anchor.ptr; 7378 log = s->log; 7379 } else if (s == NULL) 7380#ifdef __FreeBSD__ 7381 action = pf_test_tcp(&r, &s, dir, kif, 7382 m, off, h, &pd, &a, &ruleset, NULL, inp); 7383#else 7384 action = pf_test_tcp(&r, &s, dir, kif, 7385 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7386#endif 7387 break; 7388 } 7389 7390 case IPPROTO_UDP: { 7391 struct udphdr uh; 7392 7393 pd.hdr.udp = &uh; 7394 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 7395 &action, &reason, AF_INET6)) { 7396 log = action != PF_PASS; 7397 goto done; 7398 } 7399 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(n, 7400 off, ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7401 IPPROTO_UDP, AF_INET6)) { 7402 action = PF_DROP; 7403 REASON_SET(&reason, PFRES_PROTCKSUM); 7404 goto done; 7405 } 7406 if (uh.uh_dport == 0 || 7407 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 7408 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 7409 action = PF_DROP; 7410 REASON_SET(&reason, PFRES_SHORT); 7411 goto done; 7412 } 7413 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 7414 if (action == PF_PASS) { 7415#if NPFSYNC 7416 pfsync_update_state(s); 7417#endif /* NPFSYNC */ 7418 r = s->rule.ptr; 7419 a = s->anchor.ptr; 7420 log = s->log; 7421 } else if (s == NULL) 7422#ifdef __FreeBSD__ 7423 action = pf_test_udp(&r, &s, dir, kif, 7424 m, off, h, &pd, &a, &ruleset, NULL, inp); 7425#else 7426 action = pf_test_udp(&r, &s, dir, kif, 7427 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7428#endif 7429 break; 7430 } 7431 7432 case IPPROTO_ICMPV6: { 7433 struct icmp6_hdr ih; 7434 7435 pd.hdr.icmp6 = &ih; 7436 if (!pf_pull_hdr(m, off, &ih, sizeof(ih), 7437 &action, &reason, AF_INET6)) { 7438 log = action != PF_PASS; 7439 goto done; 7440 } 7441 if (dir == PF_IN && pf_check_proto_cksum(n, off, 7442 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7443 IPPROTO_ICMPV6, AF_INET6)) { 7444 action = PF_DROP; 7445 REASON_SET(&reason, PFRES_PROTCKSUM); 7446 goto done; 7447 } 7448 action = pf_test_state_icmp(&s, dir, kif, 7449 m, off, h, &pd, &reason); 7450 if (action == PF_PASS) { 7451#if NPFSYNC 7452 pfsync_update_state(s); 7453#endif /* NPFSYNC */ 7454 r = s->rule.ptr; 7455 a = s->anchor.ptr; 7456 log = s->log; 7457 } else if (s == NULL) 7458#ifdef __FreeBSD__ 7459 action = pf_test_icmp(&r, &s, dir, kif, 7460 m, off, h, &pd, &a, &ruleset, NULL); 7461#else 7462 action = pf_test_icmp(&r, &s, dir, kif, 7463 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7464#endif 7465 break; 7466 } 7467 7468 default: 7469 action = pf_test_state_other(&s, dir, kif, &pd); 7470 if (action == PF_PASS) { 7471#if NPFSYNC 7472 pfsync_update_state(s); 7473#endif /* NPFSYNC */ 7474 r = s->rule.ptr; 7475 a = s->anchor.ptr; 7476 log = s->log; 7477 } else if (s == NULL) 7478#ifdef __FreeBSD__ 7479 action = pf_test_other(&r, &s, dir, kif, m, off, h, 7480 &pd, &a, &ruleset, NULL); 7481#else 7482 action = pf_test_other(&r, &s, dir, kif, m, off, h, 7483 &pd, &a, &ruleset, &ip6intrq); 7484#endif 7485 break; 7486 } 7487 7488done: 7489 /* handle dangerous IPv6 extension headers. */ 7490 if (action == PF_PASS && rh_cnt && 7491 !((s && s->allow_opts) || r->allow_opts)) { 7492 action = PF_DROP; 7493 REASON_SET(&reason, PFRES_IPOPTIONS); 7494 log = 1; 7495 DPFPRINTF(PF_DEBUG_MISC, 7496 ("pf: dropping packet with dangerous v6 headers\n")); 7497 } 7498 7499 if ((s && s->tag) || r->rtableid) 7500 pf_tag_packet(m, pd.pf_mtag, s ? s->tag : 0, r->rtableid); 7501 7502#ifdef ALTQ 7503 if (action == PF_PASS && r->qid) { 7504 if (pd.tos & IPTOS_LOWDELAY) 7505 pd.pf_mtag->qid = r->pqid; 7506 else 7507 pd.pf_mtag->qid = r->qid; 7508 /* add hints for ecn */ 7509 pd.pf_mtag->af = AF_INET6; 7510 pd.pf_mtag->hdr = h; 7511 } 7512#endif /* ALTQ */ 7513 7514 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 7515 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 7516 (s->nat_rule.ptr->action == PF_RDR || 7517 s->nat_rule.ptr->action == PF_BINAT) && 7518 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6)) 7519 pd.pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST; 7520 7521 if (log) { 7522 struct pf_rule *lr; 7523 7524 if (s != NULL && s->nat_rule.ptr != NULL && 7525 s->nat_rule.ptr->log & PF_LOG_ALL) 7526 lr = s->nat_rule.ptr; 7527 else 7528 lr = r; 7529 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, lr, a, ruleset, 7530 &pd); 7531 } 7532 7533 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7534 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++; 7535 7536 if (action == PF_PASS || r->action == PF_DROP) { 7537 dirndx = (dir == PF_OUT); 7538 r->packets[dirndx]++; 7539 r->bytes[dirndx] += pd.tot_len; 7540 if (a != NULL) { 7541 a->packets[dirndx]++; 7542 a->bytes[dirndx] += pd.tot_len; 7543 } 7544 if (s != NULL) { 7545 if (s->nat_rule.ptr != NULL) { 7546 s->nat_rule.ptr->packets[dirndx]++; 7547 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; 7548 } 7549 if (s->src_node != NULL) { 7550 s->src_node->packets[dirndx]++; 7551 s->src_node->bytes[dirndx] += pd.tot_len; 7552 } 7553 if (s->nat_src_node != NULL) { 7554 s->nat_src_node->packets[dirndx]++; 7555 s->nat_src_node->bytes[dirndx] += pd.tot_len; 7556 } 7557 dirndx = (dir == s->direction) ? 0 : 1; 7558 s->packets[dirndx]++; 7559 s->bytes[dirndx] += pd.tot_len; 7560 } 7561 tr = r; 7562 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7563 if (nr != NULL) { 7564 struct pf_addr *x; 7565 /* 7566 * XXX: we need to make sure that the addresses 7567 * passed to pfr_update_stats() are the same than 7568 * the addresses used during matching (pfr_match) 7569 */ 7570 if (r == &pf_default_rule) { 7571 tr = nr; 7572 x = (s == NULL || s->direction == dir) ? 7573 &pd.baddr : &pd.naddr; 7574 } else { 7575 x = (s == NULL || s->direction == dir) ? 7576 &pd.naddr : &pd.baddr; 7577 } 7578 if (x == &pd.baddr || s == NULL) { 7579 if (dir == PF_OUT) 7580 pd.src = x; 7581 else 7582 pd.dst = x; 7583 } 7584 } 7585 if (tr->src.addr.type == PF_ADDR_TABLE) 7586 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL || 7587 s->direction == dir) ? pd.src : pd.dst, pd.af, 7588 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 7589 tr->src.neg); 7590 if (tr->dst.addr.type == PF_ADDR_TABLE) 7591 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL || 7592 s->direction == dir) ? pd.dst : pd.src, pd.af, 7593 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 7594 tr->dst.neg); 7595 } 7596 7597 7598 if (action == PF_SYNPROXY_DROP) { 7599 m_freem(*m0); 7600 *m0 = NULL; 7601 action = PF_PASS; 7602 } else if (r->rt) 7603 /* pf_route6 can free the mbuf causing *m0 to become NULL */ 7604 pf_route6(m0, r, dir, ifp, s, &pd); 7605 7606#ifdef __FreeBSD__ 7607 PF_UNLOCK(); 7608#endif 7609 return (action); 7610} 7611#endif /* INET6 */ 7612 7613int 7614pf_check_congestion(struct ifqueue *ifq) 7615{ 7616#ifdef __FreeBSD__ 7617 /* XXX_IMPORT: later */ 7618 return (0); 7619#else 7620 if (ifq->ifq_congestion) 7621 return (1); 7622 else 7623 return (0); 7624#endif 7625} 7626