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