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