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