pf.c revision 181803
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 181803 2008-08-17 23:27:27Z bz $"); 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 struct mbuf *m; 1763 int len, tlen; 1764#ifdef INET 1765 struct ip *h; 1766#endif /* INET */ 1767#ifdef INET6 1768 struct ip6_hdr *h6; 1769#endif /* INET6 */ 1770 struct tcphdr *th; 1771 char *opt; 1772 struct pf_mtag *pf_mtag; 1773 1774#ifdef __FreeBSD__ 1775 KASSERT( 1776#ifdef INET 1777 af == AF_INET 1778#else 1779 0 1780#endif 1781 || 1782#ifdef INET6 1783 af == AF_INET6 1784#else 1785 0 1786#endif 1787 , ("Unsupported AF %d", af)); 1788 len = 0; 1789 th = NULL; 1790#ifdef INET 1791 h = NULL; 1792#endif 1793#ifdef INET6 1794 h6 = NULL; 1795#endif 1796#endif 1797 1798 /* maximum segment size tcp option */ 1799 tlen = sizeof(struct tcphdr); 1800 if (mss) 1801 tlen += 4; 1802 1803 switch (af) { 1804#ifdef INET 1805 case AF_INET: 1806 len = sizeof(struct ip) + tlen; 1807 break; 1808#endif /* INET */ 1809#ifdef INET6 1810 case AF_INET6: 1811 len = sizeof(struct ip6_hdr) + tlen; 1812 break; 1813#endif /* INET6 */ 1814 } 1815 1816 /* create outgoing mbuf */ 1817 m = m_gethdr(M_DONTWAIT, MT_HEADER); 1818 if (m == NULL) 1819 return; 1820#ifdef __FreeBSD__ 1821#ifdef MAC 1822 if (replyto) 1823 mac_netinet_firewall_reply(replyto, m); 1824 else 1825 mac_netinet_firewall_send(m); 1826#else 1827 (void)replyto; 1828#endif 1829#endif 1830 if ((pf_mtag = pf_get_mtag(m)) == NULL) { 1831 m_freem(m); 1832 return; 1833 } 1834 if (tag) 1835#ifdef __FreeBSD__ 1836 m->m_flags |= M_SKIP_FIREWALL; 1837#else 1838 pf_mtag->flags |= PF_TAG_GENERATED; 1839#endif 1840 1841 pf_mtag->tag = rtag; 1842 1843 if (r != NULL && r->rtableid >= 0) 1844#ifdef __FreeBSD__ 1845 { 1846 M_SETFIB(m, r->rtableid); 1847#endif 1848 pf_mtag->rtableid = r->rtableid; 1849#ifdef __FreeBSD__ 1850 } 1851#endif 1852#ifdef ALTQ 1853 if (r != NULL && r->qid) { 1854 pf_mtag->qid = r->qid; 1855 /* add hints for ecn */ 1856 pf_mtag->af = af; 1857 pf_mtag->hdr = mtod(m, struct ip *); 1858 } 1859#endif /* ALTQ */ 1860 m->m_data += max_linkhdr; 1861 m->m_pkthdr.len = m->m_len = len; 1862 m->m_pkthdr.rcvif = NULL; 1863 bzero(m->m_data, len); 1864 switch (af) { 1865#ifdef INET 1866 case AF_INET: 1867 h = mtod(m, struct ip *); 1868 1869 /* IP header fields included in the TCP checksum */ 1870 h->ip_p = IPPROTO_TCP; 1871 h->ip_len = htons(tlen); 1872 h->ip_src.s_addr = saddr->v4.s_addr; 1873 h->ip_dst.s_addr = daddr->v4.s_addr; 1874 1875 th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip)); 1876 break; 1877#endif /* INET */ 1878#ifdef INET6 1879 case AF_INET6: 1880 h6 = mtod(m, struct ip6_hdr *); 1881 1882 /* IP header fields included in the TCP checksum */ 1883 h6->ip6_nxt = IPPROTO_TCP; 1884 h6->ip6_plen = htons(tlen); 1885 memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr)); 1886 memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr)); 1887 1888 th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr)); 1889 break; 1890#endif /* INET6 */ 1891 } 1892 1893 /* TCP header */ 1894 th->th_sport = sport; 1895 th->th_dport = dport; 1896 th->th_seq = htonl(seq); 1897 th->th_ack = htonl(ack); 1898 th->th_off = tlen >> 2; 1899 th->th_flags = flags; 1900 th->th_win = htons(win); 1901 1902 if (mss) { 1903 opt = (char *)(th + 1); 1904 opt[0] = TCPOPT_MAXSEG; 1905 opt[1] = 4; 1906 HTONS(mss); 1907 bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2); 1908 } 1909 1910 switch (af) { 1911#ifdef INET 1912 case AF_INET: 1913 /* TCP checksum */ 1914 th->th_sum = in_cksum(m, len); 1915 1916 /* Finish the IP header */ 1917 h->ip_v = 4; 1918 h->ip_hl = sizeof(*h) >> 2; 1919 h->ip_tos = IPTOS_LOWDELAY; 1920#ifdef __FreeBSD__ 1921 h->ip_off = V_path_mtu_discovery ? IP_DF : 0; 1922 h->ip_len = len; 1923#else 1924 h->ip_off = htons(ip_mtudisc ? IP_DF : 0); 1925 h->ip_len = htons(len); 1926#endif 1927 h->ip_ttl = ttl ? ttl : V_ip_defttl; 1928 h->ip_sum = 0; 1929 if (eh == NULL) { 1930#ifdef __FreeBSD__ 1931 PF_UNLOCK(); 1932 ip_output(m, (void *)NULL, (void *)NULL, 0, 1933 (void *)NULL, (void *)NULL); 1934 PF_LOCK(); 1935#else /* ! __FreeBSD__ */ 1936 ip_output(m, (void *)NULL, (void *)NULL, 0, 1937 (void *)NULL, (void *)NULL); 1938#endif 1939 } else { 1940 struct route ro; 1941 struct rtentry rt; 1942 struct ether_header *e = (void *)ro.ro_dst.sa_data; 1943 1944 if (ifp == NULL) { 1945 m_freem(m); 1946 return; 1947 } 1948 rt.rt_ifp = ifp; 1949 ro.ro_rt = &rt; 1950 ro.ro_dst.sa_len = sizeof(ro.ro_dst); 1951 ro.ro_dst.sa_family = pseudo_AF_HDRCMPLT; 1952 bcopy(eh->ether_dhost, e->ether_shost, ETHER_ADDR_LEN); 1953 bcopy(eh->ether_shost, e->ether_dhost, ETHER_ADDR_LEN); 1954 e->ether_type = eh->ether_type; 1955#ifdef __FreeBSD__ 1956 PF_UNLOCK(); 1957 /* XXX_IMPORT: later */ 1958 ip_output(m, (void *)NULL, &ro, 0, 1959 (void *)NULL, (void *)NULL); 1960 PF_LOCK(); 1961#else /* ! __FreeBSD__ */ 1962 ip_output(m, (void *)NULL, &ro, IP_ROUTETOETHER, 1963 (void *)NULL, (void *)NULL); 1964#endif 1965 } 1966 break; 1967#endif /* INET */ 1968#ifdef INET6 1969 case AF_INET6: 1970 /* TCP checksum */ 1971 th->th_sum = in6_cksum(m, IPPROTO_TCP, 1972 sizeof(struct ip6_hdr), tlen); 1973 1974 h6->ip6_vfc |= IPV6_VERSION; 1975 h6->ip6_hlim = IPV6_DEFHLIM; 1976 1977#ifdef __FreeBSD__ 1978 PF_UNLOCK(); 1979 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); 1980 PF_LOCK(); 1981#else 1982 ip6_output(m, NULL, NULL, 0, NULL, NULL); 1983#endif 1984 break; 1985#endif /* INET6 */ 1986 } 1987} 1988 1989void 1990pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, 1991 struct pf_rule *r) 1992{ 1993 struct pf_mtag *pf_mtag; 1994 struct mbuf *m0; 1995#ifdef __FreeBSD__ 1996 struct ip *ip; 1997#endif 1998 1999#ifdef __FreeBSD__ 2000 m0 = m_copypacket(m, M_DONTWAIT); 2001 if (m0 == NULL) 2002 return; 2003#else 2004 m0 = m_copy(m, 0, M_COPYALL); 2005#endif 2006 if ((pf_mtag = pf_get_mtag(m0)) == NULL) 2007 return; 2008#ifdef __FreeBSD__ 2009 /* XXX: revisit */ 2010 m0->m_flags |= M_SKIP_FIREWALL; 2011#else 2012 pf_mtag->flags |= PF_TAG_GENERATED; 2013#endif 2014 2015 if (r->rtableid >= 0) 2016#ifdef __FreeBSD__ 2017 { 2018 M_SETFIB(m0, r->rtableid); 2019#endif 2020 pf_mtag->rtableid = r->rtableid; 2021#ifdef __FreeBSD__ 2022 } 2023#endif 2024 2025#ifdef ALTQ 2026 if (r->qid) { 2027 pf_mtag->qid = r->qid; 2028 /* add hints for ecn */ 2029 pf_mtag->af = af; 2030 pf_mtag->hdr = mtod(m0, struct ip *); 2031 } 2032#endif /* ALTQ */ 2033 2034 switch (af) { 2035#ifdef INET 2036 case AF_INET: 2037#ifdef __FreeBSD__ 2038 /* icmp_error() expects host byte ordering */ 2039 ip = mtod(m0, struct ip *); 2040 NTOHS(ip->ip_len); 2041 NTOHS(ip->ip_off); 2042 PF_UNLOCK(); 2043 icmp_error(m0, type, code, 0, 0); 2044 PF_LOCK(); 2045#else 2046 icmp_error(m0, type, code, 0, 0); 2047#endif 2048 break; 2049#endif /* INET */ 2050#ifdef INET6 2051 case AF_INET6: 2052#ifdef __FreeBSD__ 2053 PF_UNLOCK(); 2054#endif 2055 icmp6_error(m0, type, code, 0); 2056#ifdef __FreeBSD__ 2057 PF_LOCK(); 2058#endif 2059 break; 2060#endif /* INET6 */ 2061 } 2062} 2063 2064/* 2065 * Return 1 if the addresses a and b match (with mask m), otherwise return 0. 2066 * If n is 0, they match if they are equal. If n is != 0, they match if they 2067 * are different. 2068 */ 2069int 2070pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m, 2071 struct pf_addr *b, sa_family_t af) 2072{ 2073 int match = 0; 2074 2075 switch (af) { 2076#ifdef INET 2077 case AF_INET: 2078 if ((a->addr32[0] & m->addr32[0]) == 2079 (b->addr32[0] & m->addr32[0])) 2080 match++; 2081 break; 2082#endif /* INET */ 2083#ifdef INET6 2084 case AF_INET6: 2085 if (((a->addr32[0] & m->addr32[0]) == 2086 (b->addr32[0] & m->addr32[0])) && 2087 ((a->addr32[1] & m->addr32[1]) == 2088 (b->addr32[1] & m->addr32[1])) && 2089 ((a->addr32[2] & m->addr32[2]) == 2090 (b->addr32[2] & m->addr32[2])) && 2091 ((a->addr32[3] & m->addr32[3]) == 2092 (b->addr32[3] & m->addr32[3]))) 2093 match++; 2094 break; 2095#endif /* INET6 */ 2096 } 2097 if (match) { 2098 if (n) 2099 return (0); 2100 else 2101 return (1); 2102 } else { 2103 if (n) 2104 return (1); 2105 else 2106 return (0); 2107 } 2108} 2109 2110int 2111pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p) 2112{ 2113 switch (op) { 2114 case PF_OP_IRG: 2115 return ((p > a1) && (p < a2)); 2116 case PF_OP_XRG: 2117 return ((p < a1) || (p > a2)); 2118 case PF_OP_RRG: 2119 return ((p >= a1) && (p <= a2)); 2120 case PF_OP_EQ: 2121 return (p == a1); 2122 case PF_OP_NE: 2123 return (p != a1); 2124 case PF_OP_LT: 2125 return (p < a1); 2126 case PF_OP_LE: 2127 return (p <= a1); 2128 case PF_OP_GT: 2129 return (p > a1); 2130 case PF_OP_GE: 2131 return (p >= a1); 2132 } 2133 return (0); /* never reached */ 2134} 2135 2136int 2137pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p) 2138{ 2139 NTOHS(a1); 2140 NTOHS(a2); 2141 NTOHS(p); 2142 return (pf_match(op, a1, a2, p)); 2143} 2144 2145int 2146pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u) 2147{ 2148 if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 2149 return (0); 2150 return (pf_match(op, a1, a2, u)); 2151} 2152 2153int 2154pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g) 2155{ 2156 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 2157 return (0); 2158 return (pf_match(op, a1, a2, g)); 2159} 2160 2161#ifndef __FreeBSD__ 2162struct pf_mtag * 2163pf_find_mtag(struct mbuf *m) 2164{ 2165 struct m_tag *mtag; 2166 2167 if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) 2168 return (NULL); 2169 2170 return ((struct pf_mtag *)(mtag + 1)); 2171} 2172 2173struct pf_mtag * 2174pf_get_mtag(struct mbuf *m) 2175{ 2176 struct m_tag *mtag; 2177 2178 if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) { 2179 mtag = m_tag_get(PACKET_TAG_PF, sizeof(struct pf_mtag), 2180 M_NOWAIT); 2181 if (mtag == NULL) 2182 return (NULL); 2183 bzero(mtag + 1, sizeof(struct pf_mtag)); 2184 m_tag_prepend(m, mtag); 2185 } 2186 2187 return ((struct pf_mtag *)(mtag + 1)); 2188} 2189#endif 2190 2191int 2192pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_mtag *pf_mtag, 2193 int *tag) 2194{ 2195 if (*tag == -1) 2196 *tag = pf_mtag->tag; 2197 2198 return ((!r->match_tag_not && r->match_tag == *tag) || 2199 (r->match_tag_not && r->match_tag != *tag)); 2200} 2201 2202int 2203pf_tag_packet(struct mbuf *m, struct pf_mtag *pf_mtag, int tag, int rtableid) 2204{ 2205 if (tag <= 0 && rtableid < 0) 2206 return (0); 2207 2208 if (pf_mtag == NULL) 2209 if ((pf_mtag = pf_get_mtag(m)) == NULL) 2210 return (1); 2211 if (tag > 0) 2212 pf_mtag->tag = tag; 2213 if (rtableid >= 0) 2214#ifdef __FreeBSD__ 2215 { 2216 M_SETFIB(m, rtableid); 2217#endif 2218 pf_mtag->rtableid = rtableid; 2219#ifdef __FreeBSD__ 2220 } 2221#endif 2222 2223 return (0); 2224} 2225 2226static void 2227pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n, 2228 struct pf_rule **r, struct pf_rule **a, int *match) 2229{ 2230 struct pf_anchor_stackframe *f; 2231 2232 (*r)->anchor->match = 0; 2233 if (match) 2234 *match = 0; 2235 if (*depth >= sizeof(pf_anchor_stack) / 2236 sizeof(pf_anchor_stack[0])) { 2237 printf("pf_step_into_anchor: stack overflow\n"); 2238 *r = TAILQ_NEXT(*r, entries); 2239 return; 2240 } else if (*depth == 0 && a != NULL) 2241 *a = *r; 2242 f = pf_anchor_stack + (*depth)++; 2243 f->rs = *rs; 2244 f->r = *r; 2245 if ((*r)->anchor_wildcard) { 2246 f->parent = &(*r)->anchor->children; 2247 if ((f->child = RB_MIN(pf_anchor_node, f->parent)) == 2248 NULL) { 2249 *r = NULL; 2250 return; 2251 } 2252 *rs = &f->child->ruleset; 2253 } else { 2254 f->parent = NULL; 2255 f->child = NULL; 2256 *rs = &(*r)->anchor->ruleset; 2257 } 2258 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2259} 2260 2261int 2262pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n, 2263 struct pf_rule **r, struct pf_rule **a, int *match) 2264{ 2265 struct pf_anchor_stackframe *f; 2266 int quick = 0; 2267 2268 do { 2269 if (*depth <= 0) 2270 break; 2271 f = pf_anchor_stack + *depth - 1; 2272 if (f->parent != NULL && f->child != NULL) { 2273 if (f->child->match || 2274 (match != NULL && *match)) { 2275 f->r->anchor->match = 1; 2276 *match = 0; 2277 } 2278 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child); 2279 if (f->child != NULL) { 2280 *rs = &f->child->ruleset; 2281 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2282 if (*r == NULL) 2283 continue; 2284 else 2285 break; 2286 } 2287 } 2288 (*depth)--; 2289 if (*depth == 0 && a != NULL) 2290 *a = NULL; 2291 *rs = f->rs; 2292 if (f->r->anchor->match || (match != NULL && *match)) 2293 quick = f->r->quick; 2294 *r = TAILQ_NEXT(f->r, entries); 2295 } while (*r == NULL); 2296 2297 return (quick); 2298} 2299 2300#ifdef INET6 2301void 2302pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr, 2303 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af) 2304{ 2305 switch (af) { 2306#ifdef INET 2307 case AF_INET: 2308 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) | 2309 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]); 2310 break; 2311#endif /* INET */ 2312 case AF_INET6: 2313 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) | 2314 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]); 2315 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) | 2316 ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]); 2317 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) | 2318 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]); 2319 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) | 2320 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]); 2321 break; 2322 } 2323} 2324 2325void 2326pf_addr_inc(struct pf_addr *addr, sa_family_t af) 2327{ 2328 switch (af) { 2329#ifdef INET 2330 case AF_INET: 2331 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1); 2332 break; 2333#endif /* INET */ 2334 case AF_INET6: 2335 if (addr->addr32[3] == 0xffffffff) { 2336 addr->addr32[3] = 0; 2337 if (addr->addr32[2] == 0xffffffff) { 2338 addr->addr32[2] = 0; 2339 if (addr->addr32[1] == 0xffffffff) { 2340 addr->addr32[1] = 0; 2341 addr->addr32[0] = 2342 htonl(ntohl(addr->addr32[0]) + 1); 2343 } else 2344 addr->addr32[1] = 2345 htonl(ntohl(addr->addr32[1]) + 1); 2346 } else 2347 addr->addr32[2] = 2348 htonl(ntohl(addr->addr32[2]) + 1); 2349 } else 2350 addr->addr32[3] = 2351 htonl(ntohl(addr->addr32[3]) + 1); 2352 break; 2353 } 2354} 2355#endif /* INET6 */ 2356 2357#define mix(a,b,c) \ 2358 do { \ 2359 a -= b; a -= c; a ^= (c >> 13); \ 2360 b -= c; b -= a; b ^= (a << 8); \ 2361 c -= a; c -= b; c ^= (b >> 13); \ 2362 a -= b; a -= c; a ^= (c >> 12); \ 2363 b -= c; b -= a; b ^= (a << 16); \ 2364 c -= a; c -= b; c ^= (b >> 5); \ 2365 a -= b; a -= c; a ^= (c >> 3); \ 2366 b -= c; b -= a; b ^= (a << 10); \ 2367 c -= a; c -= b; c ^= (b >> 15); \ 2368 } while (0) 2369 2370/* 2371 * hash function based on bridge_hash in if_bridge.c 2372 */ 2373void 2374pf_hash(struct pf_addr *inaddr, struct pf_addr *hash, 2375 struct pf_poolhashkey *key, sa_family_t af) 2376{ 2377 u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0]; 2378 2379 switch (af) { 2380#ifdef INET 2381 case AF_INET: 2382 a += inaddr->addr32[0]; 2383 b += key->key32[1]; 2384 mix(a, b, c); 2385 hash->addr32[0] = c + key->key32[2]; 2386 break; 2387#endif /* INET */ 2388#ifdef INET6 2389 case AF_INET6: 2390 a += inaddr->addr32[0]; 2391 b += inaddr->addr32[2]; 2392 mix(a, b, c); 2393 hash->addr32[0] = c; 2394 a += inaddr->addr32[1]; 2395 b += inaddr->addr32[3]; 2396 c += key->key32[1]; 2397 mix(a, b, c); 2398 hash->addr32[1] = c; 2399 a += inaddr->addr32[2]; 2400 b += inaddr->addr32[1]; 2401 c += key->key32[2]; 2402 mix(a, b, c); 2403 hash->addr32[2] = c; 2404 a += inaddr->addr32[3]; 2405 b += inaddr->addr32[0]; 2406 c += key->key32[3]; 2407 mix(a, b, c); 2408 hash->addr32[3] = c; 2409 break; 2410#endif /* INET6 */ 2411 } 2412} 2413 2414int 2415pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr, 2416 struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn) 2417{ 2418 unsigned char hash[16]; 2419 struct pf_pool *rpool = &r->rpool; 2420 struct pf_addr *raddr = &rpool->cur->addr.v.a.addr; 2421 struct pf_addr *rmask = &rpool->cur->addr.v.a.mask; 2422 struct pf_pooladdr *acur = rpool->cur; 2423 struct pf_src_node k; 2424 2425 if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR && 2426 (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { 2427 k.af = af; 2428 PF_ACPY(&k.addr, saddr, af); 2429 if (r->rule_flag & PFRULE_RULESRCTRACK || 2430 r->rpool.opts & PF_POOL_STICKYADDR) 2431 k.rule.ptr = r; 2432 else 2433 k.rule.ptr = NULL; 2434 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++; 2435 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k); 2436 if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) { 2437 PF_ACPY(naddr, &(*sn)->raddr, af); 2438 if (pf_status.debug >= PF_DEBUG_MISC) { 2439 printf("pf_map_addr: src tracking maps "); 2440 pf_print_host(&k.addr, 0, af); 2441 printf(" to "); 2442 pf_print_host(naddr, 0, af); 2443 printf("\n"); 2444 } 2445 return (0); 2446 } 2447 } 2448 2449 if (rpool->cur->addr.type == PF_ADDR_NOROUTE) 2450 return (1); 2451 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 2452 switch (af) { 2453#ifdef INET 2454 case AF_INET: 2455 if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 && 2456 (rpool->opts & PF_POOL_TYPEMASK) != 2457 PF_POOL_ROUNDROBIN) 2458 return (1); 2459 raddr = &rpool->cur->addr.p.dyn->pfid_addr4; 2460 rmask = &rpool->cur->addr.p.dyn->pfid_mask4; 2461 break; 2462#endif /* INET */ 2463#ifdef INET6 2464 case AF_INET6: 2465 if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 && 2466 (rpool->opts & PF_POOL_TYPEMASK) != 2467 PF_POOL_ROUNDROBIN) 2468 return (1); 2469 raddr = &rpool->cur->addr.p.dyn->pfid_addr6; 2470 rmask = &rpool->cur->addr.p.dyn->pfid_mask6; 2471 break; 2472#endif /* INET6 */ 2473 } 2474 } else if (rpool->cur->addr.type == PF_ADDR_TABLE) { 2475 if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN) 2476 return (1); /* unsupported */ 2477 } else { 2478 raddr = &rpool->cur->addr.v.a.addr; 2479 rmask = &rpool->cur->addr.v.a.mask; 2480 } 2481 2482 switch (rpool->opts & PF_POOL_TYPEMASK) { 2483 case PF_POOL_NONE: 2484 PF_ACPY(naddr, raddr, af); 2485 break; 2486 case PF_POOL_BITMASK: 2487 PF_POOLMASK(naddr, raddr, rmask, saddr, af); 2488 break; 2489 case PF_POOL_RANDOM: 2490 if (init_addr != NULL && PF_AZERO(init_addr, af)) { 2491 switch (af) { 2492#ifdef INET 2493 case AF_INET: 2494 rpool->counter.addr32[0] = htonl(arc4random()); 2495 break; 2496#endif /* INET */ 2497#ifdef INET6 2498 case AF_INET6: 2499 if (rmask->addr32[3] != 0xffffffff) 2500 rpool->counter.addr32[3] = 2501 htonl(arc4random()); 2502 else 2503 break; 2504 if (rmask->addr32[2] != 0xffffffff) 2505 rpool->counter.addr32[2] = 2506 htonl(arc4random()); 2507 else 2508 break; 2509 if (rmask->addr32[1] != 0xffffffff) 2510 rpool->counter.addr32[1] = 2511 htonl(arc4random()); 2512 else 2513 break; 2514 if (rmask->addr32[0] != 0xffffffff) 2515 rpool->counter.addr32[0] = 2516 htonl(arc4random()); 2517 break; 2518#endif /* INET6 */ 2519 } 2520 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af); 2521 PF_ACPY(init_addr, naddr, af); 2522 2523 } else { 2524 PF_AINC(&rpool->counter, af); 2525 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af); 2526 } 2527 break; 2528 case PF_POOL_SRCHASH: 2529 pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af); 2530 PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af); 2531 break; 2532 case PF_POOL_ROUNDROBIN: 2533 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 2534 if (!pfr_pool_get(rpool->cur->addr.p.tbl, 2535 &rpool->tblidx, &rpool->counter, 2536 &raddr, &rmask, af)) 2537 goto get_addr; 2538 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 2539 if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 2540 &rpool->tblidx, &rpool->counter, 2541 &raddr, &rmask, af)) 2542 goto get_addr; 2543 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af)) 2544 goto get_addr; 2545 2546 try_next: 2547 if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL) 2548 rpool->cur = TAILQ_FIRST(&rpool->list); 2549 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 2550 rpool->tblidx = -1; 2551 if (pfr_pool_get(rpool->cur->addr.p.tbl, 2552 &rpool->tblidx, &rpool->counter, 2553 &raddr, &rmask, af)) { 2554 /* table contains no address of type 'af' */ 2555 if (rpool->cur != acur) 2556 goto try_next; 2557 return (1); 2558 } 2559 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 2560 rpool->tblidx = -1; 2561 if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 2562 &rpool->tblidx, &rpool->counter, 2563 &raddr, &rmask, af)) { 2564 /* table contains no address of type 'af' */ 2565 if (rpool->cur != acur) 2566 goto try_next; 2567 return (1); 2568 } 2569 } else { 2570 raddr = &rpool->cur->addr.v.a.addr; 2571 rmask = &rpool->cur->addr.v.a.mask; 2572 PF_ACPY(&rpool->counter, raddr, af); 2573 } 2574 2575 get_addr: 2576 PF_ACPY(naddr, &rpool->counter, af); 2577 if (init_addr != NULL && PF_AZERO(init_addr, af)) 2578 PF_ACPY(init_addr, naddr, af); 2579 PF_AINC(&rpool->counter, af); 2580 break; 2581 } 2582 if (*sn != NULL) 2583 PF_ACPY(&(*sn)->raddr, naddr, af); 2584 2585 if (pf_status.debug >= PF_DEBUG_MISC && 2586 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { 2587 printf("pf_map_addr: selected address "); 2588 pf_print_host(naddr, 0, af); 2589 printf("\n"); 2590 } 2591 2592 return (0); 2593} 2594 2595int 2596pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, 2597 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport, 2598 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high, 2599 struct pf_src_node **sn) 2600{ 2601 struct pf_state_cmp key; 2602 struct pf_addr init_addr; 2603 u_int16_t cut; 2604 2605 bzero(&init_addr, sizeof(init_addr)); 2606 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) 2607 return (1); 2608 2609 if (proto == IPPROTO_ICMP) { 2610 low = 1; 2611 high = 65535; 2612 } 2613 2614 do { 2615 key.af = af; 2616 key.proto = proto; 2617 PF_ACPY(&key.ext.addr, daddr, key.af); 2618 PF_ACPY(&key.gwy.addr, naddr, key.af); 2619 key.ext.port = dport; 2620 2621 /* 2622 * port search; start random, step; 2623 * similar 2 portloop in in_pcbbind 2624 */ 2625 if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP || 2626 proto == IPPROTO_ICMP)) { 2627 key.gwy.port = dport; 2628 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) 2629 return (0); 2630 } else if (low == 0 && high == 0) { 2631 key.gwy.port = *nport; 2632 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) 2633 return (0); 2634 } else if (low == high) { 2635 key.gwy.port = htons(low); 2636 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) { 2637 *nport = htons(low); 2638 return (0); 2639 } 2640 } else { 2641 u_int16_t tmp; 2642 2643 if (low > high) { 2644 tmp = low; 2645 low = high; 2646 high = tmp; 2647 } 2648 /* low < high */ 2649 cut = htonl(arc4random()) % (1 + high - low) + low; 2650 /* low <= cut <= high */ 2651 for (tmp = cut; tmp <= high; ++(tmp)) { 2652 key.gwy.port = htons(tmp); 2653 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == 2654 NULL) { 2655 *nport = htons(tmp); 2656 return (0); 2657 } 2658 } 2659 for (tmp = cut - 1; tmp >= low; --(tmp)) { 2660 key.gwy.port = htons(tmp); 2661 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == 2662 NULL) { 2663 *nport = htons(tmp); 2664 return (0); 2665 } 2666 } 2667 } 2668 2669 switch (r->rpool.opts & PF_POOL_TYPEMASK) { 2670 case PF_POOL_RANDOM: 2671 case PF_POOL_ROUNDROBIN: 2672 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) 2673 return (1); 2674 break; 2675 case PF_POOL_NONE: 2676 case PF_POOL_SRCHASH: 2677 case PF_POOL_BITMASK: 2678 default: 2679 return (1); 2680 } 2681 } while (! PF_AEQ(&init_addr, naddr, af) ); 2682 2683 return (1); /* none available */ 2684} 2685 2686struct pf_rule * 2687pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, 2688 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport, 2689 struct pf_addr *daddr, u_int16_t dport, int rs_num) 2690{ 2691 struct pf_rule *r, *rm = NULL; 2692 struct pf_ruleset *ruleset = NULL; 2693 int tag = -1; 2694 int rtableid = -1; 2695 int asd = 0; 2696 2697 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr); 2698 while (r && rm == NULL) { 2699 struct pf_rule_addr *src = NULL, *dst = NULL; 2700 struct pf_addr_wrap *xdst = NULL; 2701 2702 if (r->action == PF_BINAT && direction == PF_IN) { 2703 src = &r->dst; 2704 if (r->rpool.cur != NULL) 2705 xdst = &r->rpool.cur->addr; 2706 } else { 2707 src = &r->src; 2708 dst = &r->dst; 2709 } 2710 2711 r->evaluations++; 2712 if (pfi_kif_match(r->kif, kif) == r->ifnot) 2713 r = r->skip[PF_SKIP_IFP].ptr; 2714 else if (r->direction && r->direction != direction) 2715 r = r->skip[PF_SKIP_DIR].ptr; 2716 else if (r->af && r->af != pd->af) 2717 r = r->skip[PF_SKIP_AF].ptr; 2718 else if (r->proto && r->proto != pd->proto) 2719 r = r->skip[PF_SKIP_PROTO].ptr; 2720 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, 2721 src->neg, kif)) 2722 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR : 2723 PF_SKIP_DST_ADDR].ptr; 2724 else if (src->port_op && !pf_match_port(src->port_op, 2725 src->port[0], src->port[1], sport)) 2726 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT : 2727 PF_SKIP_DST_PORT].ptr; 2728 else if (dst != NULL && 2729 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL)) 2730 r = r->skip[PF_SKIP_DST_ADDR].ptr; 2731 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, 2732 0, NULL)) 2733 r = TAILQ_NEXT(r, entries); 2734 else if (dst != NULL && dst->port_op && 2735 !pf_match_port(dst->port_op, dst->port[0], 2736 dst->port[1], dport)) 2737 r = r->skip[PF_SKIP_DST_PORT].ptr; 2738 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 2739 r = TAILQ_NEXT(r, entries); 2740 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto != 2741 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m, 2742 off, pd->hdr.tcp), r->os_fingerprint))) 2743 r = TAILQ_NEXT(r, entries); 2744 else { 2745 if (r->tag) 2746 tag = r->tag; 2747 if (r->rtableid >= 0) 2748 rtableid = r->rtableid; 2749 if (r->anchor == NULL) { 2750 rm = r; 2751 } else 2752 pf_step_into_anchor(&asd, &ruleset, rs_num, 2753 &r, NULL, NULL); 2754 } 2755 if (r == NULL) 2756 pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r, 2757 NULL, NULL); 2758 } 2759 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) 2760 return (NULL); 2761 if (rm != NULL && (rm->action == PF_NONAT || 2762 rm->action == PF_NORDR || rm->action == PF_NOBINAT)) 2763 return (NULL); 2764 return (rm); 2765} 2766 2767struct pf_rule * 2768pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, 2769 struct pfi_kif *kif, struct pf_src_node **sn, 2770 struct pf_addr *saddr, u_int16_t sport, 2771 struct pf_addr *daddr, u_int16_t dport, 2772 struct pf_addr *naddr, u_int16_t *nport) 2773{ 2774 struct pf_rule *r = NULL; 2775 2776 if (direction == PF_OUT) { 2777 r = pf_match_translation(pd, m, off, direction, kif, saddr, 2778 sport, daddr, dport, PF_RULESET_BINAT); 2779 if (r == NULL) 2780 r = pf_match_translation(pd, m, off, direction, kif, 2781 saddr, sport, daddr, dport, PF_RULESET_NAT); 2782 } else { 2783 r = pf_match_translation(pd, m, off, direction, kif, saddr, 2784 sport, daddr, dport, PF_RULESET_RDR); 2785 if (r == NULL) 2786 r = pf_match_translation(pd, m, off, direction, kif, 2787 saddr, sport, daddr, dport, PF_RULESET_BINAT); 2788 } 2789 2790 if (r != NULL) { 2791 switch (r->action) { 2792 case PF_NONAT: 2793 case PF_NOBINAT: 2794 case PF_NORDR: 2795 return (NULL); 2796 case PF_NAT: 2797 if (pf_get_sport(pd->af, pd->proto, r, saddr, 2798 daddr, dport, naddr, nport, r->rpool.proxy_port[0], 2799 r->rpool.proxy_port[1], sn)) { 2800 DPFPRINTF(PF_DEBUG_MISC, 2801 ("pf: NAT proxy port allocation " 2802 "(%u-%u) failed\n", 2803 r->rpool.proxy_port[0], 2804 r->rpool.proxy_port[1])); 2805 return (NULL); 2806 } 2807 break; 2808 case PF_BINAT: 2809 switch (direction) { 2810 case PF_OUT: 2811 if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){ 2812 switch (pd->af) { 2813#ifdef INET 2814 case AF_INET: 2815 if (r->rpool.cur->addr.p.dyn-> 2816 pfid_acnt4 < 1) 2817 return (NULL); 2818 PF_POOLMASK(naddr, 2819 &r->rpool.cur->addr.p.dyn-> 2820 pfid_addr4, 2821 &r->rpool.cur->addr.p.dyn-> 2822 pfid_mask4, 2823 saddr, AF_INET); 2824 break; 2825#endif /* INET */ 2826#ifdef INET6 2827 case AF_INET6: 2828 if (r->rpool.cur->addr.p.dyn-> 2829 pfid_acnt6 < 1) 2830 return (NULL); 2831 PF_POOLMASK(naddr, 2832 &r->rpool.cur->addr.p.dyn-> 2833 pfid_addr6, 2834 &r->rpool.cur->addr.p.dyn-> 2835 pfid_mask6, 2836 saddr, AF_INET6); 2837 break; 2838#endif /* INET6 */ 2839 } 2840 } else 2841 PF_POOLMASK(naddr, 2842 &r->rpool.cur->addr.v.a.addr, 2843 &r->rpool.cur->addr.v.a.mask, 2844 saddr, pd->af); 2845 break; 2846 case PF_IN: 2847 if (r->src.addr.type == PF_ADDR_DYNIFTL) { 2848 switch (pd->af) { 2849#ifdef INET 2850 case AF_INET: 2851 if (r->src.addr.p.dyn-> 2852 pfid_acnt4 < 1) 2853 return (NULL); 2854 PF_POOLMASK(naddr, 2855 &r->src.addr.p.dyn-> 2856 pfid_addr4, 2857 &r->src.addr.p.dyn-> 2858 pfid_mask4, 2859 daddr, AF_INET); 2860 break; 2861#endif /* INET */ 2862#ifdef INET6 2863 case AF_INET6: 2864 if (r->src.addr.p.dyn-> 2865 pfid_acnt6 < 1) 2866 return (NULL); 2867 PF_POOLMASK(naddr, 2868 &r->src.addr.p.dyn-> 2869 pfid_addr6, 2870 &r->src.addr.p.dyn-> 2871 pfid_mask6, 2872 daddr, AF_INET6); 2873 break; 2874#endif /* INET6 */ 2875 } 2876 } else 2877 PF_POOLMASK(naddr, 2878 &r->src.addr.v.a.addr, 2879 &r->src.addr.v.a.mask, daddr, 2880 pd->af); 2881 break; 2882 } 2883 break; 2884 case PF_RDR: { 2885 if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn)) 2886 return (NULL); 2887 if ((r->rpool.opts & PF_POOL_TYPEMASK) == 2888 PF_POOL_BITMASK) 2889 PF_POOLMASK(naddr, naddr, 2890 &r->rpool.cur->addr.v.a.mask, daddr, 2891 pd->af); 2892 2893 if (r->rpool.proxy_port[1]) { 2894 u_int32_t tmp_nport; 2895 2896 tmp_nport = ((ntohs(dport) - 2897 ntohs(r->dst.port[0])) % 2898 (r->rpool.proxy_port[1] - 2899 r->rpool.proxy_port[0] + 1)) + 2900 r->rpool.proxy_port[0]; 2901 2902 /* wrap around if necessary */ 2903 if (tmp_nport > 65535) 2904 tmp_nport -= 65535; 2905 *nport = htons((u_int16_t)tmp_nport); 2906 } else if (r->rpool.proxy_port[0]) 2907 *nport = htons(r->rpool.proxy_port[0]); 2908 break; 2909 } 2910 default: 2911 return (NULL); 2912 } 2913 } 2914 2915 return (r); 2916} 2917 2918int 2919#ifdef __FreeBSD__ 2920pf_socket_lookup(int direction, struct pf_pdesc *pd, struct inpcb *inp_arg) 2921#else 2922pf_socket_lookup(int direction, struct pf_pdesc *pd) 2923#endif 2924{ 2925 struct pf_addr *saddr, *daddr; 2926 u_int16_t sport, dport; 2927#ifdef __FreeBSD__ 2928 struct inpcbinfo *pi; 2929#else 2930 struct inpcbtable *tb; 2931#endif 2932 struct inpcb *inp; 2933 2934 if (pd == NULL) 2935 return (-1); 2936 pd->lookup.uid = UID_MAX; 2937 pd->lookup.gid = GID_MAX; 2938 pd->lookup.pid = NO_PID; /* XXX: revisit */ 2939#ifdef __FreeBSD__ 2940 if (inp_arg != NULL) { 2941 INP_LOCK_ASSERT(inp_arg); 2942 if (inp_arg->inp_socket) { 2943 pd->lookup.uid = inp_arg->inp_socket->so_cred->cr_uid; 2944 pd->lookup.gid = 2945 inp_arg->inp_socket->so_cred->cr_groups[0]; 2946 return (1); 2947 } else 2948 return (-1); 2949 } 2950#endif 2951 switch (pd->proto) { 2952 case IPPROTO_TCP: 2953 if (pd->hdr.tcp == NULL) 2954 return (-1); 2955 sport = pd->hdr.tcp->th_sport; 2956 dport = pd->hdr.tcp->th_dport; 2957#ifdef __FreeBSD__ 2958 pi = &V_tcbinfo; 2959#else 2960 tb = &tcbtable; 2961#endif 2962 break; 2963 case IPPROTO_UDP: 2964 if (pd->hdr.udp == NULL) 2965 return (-1); 2966 sport = pd->hdr.udp->uh_sport; 2967 dport = pd->hdr.udp->uh_dport; 2968#ifdef __FreeBSD__ 2969 pi = &V_udbinfo; 2970#else 2971 tb = &udbtable; 2972#endif 2973 break; 2974 default: 2975 return (-1); 2976 } 2977 if (direction == PF_IN) { 2978 saddr = pd->src; 2979 daddr = pd->dst; 2980 } else { 2981 u_int16_t p; 2982 2983 p = sport; 2984 sport = dport; 2985 dport = p; 2986 saddr = pd->dst; 2987 daddr = pd->src; 2988 } 2989 switch (pd->af) { 2990#ifdef INET 2991 case AF_INET: 2992#ifdef __FreeBSD__ 2993 INP_INFO_RLOCK(pi); /* XXX LOR */ 2994 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4, 2995 dport, 0, NULL); 2996 if (inp == NULL) { 2997 inp = in_pcblookup_hash(pi, saddr->v4, sport, 2998 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL); 2999 if(inp == NULL) { 3000 INP_INFO_RUNLOCK(pi); 3001 return (-1); 3002 } 3003 } 3004#else 3005 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); 3006 if (inp == NULL) { 3007 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0); 3008 if (inp == NULL) 3009 return (-1); 3010 } 3011#endif 3012 break; 3013#endif /* INET */ 3014#ifdef INET6 3015 case AF_INET6: 3016#ifdef __FreeBSD__ 3017 INP_INFO_RLOCK(pi); 3018 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 3019 &daddr->v6, dport, 0, NULL); 3020 if (inp == NULL) { 3021 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 3022 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL); 3023 if (inp == NULL) { 3024 INP_INFO_RUNLOCK(pi); 3025 return (-1); 3026 } 3027 } 3028#else 3029 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, 3030 dport); 3031 if (inp == NULL) { 3032 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0); 3033 if (inp == NULL) 3034 return (-1); 3035 } 3036#endif 3037 break; 3038#endif /* INET6 */ 3039 3040 default: 3041 return (-1); 3042 } 3043#ifdef __FreeBSD__ 3044 INP_RLOCK(inp); 3045 INP_INFO_RUNLOCK(pi); 3046 if ((inp->inp_socket == NULL) || (inp->inp_socket->so_cred == NULL)) { 3047 INP_RUNLOCK(inp); 3048 return (-1); 3049 } 3050 pd->lookup.uid = inp->inp_socket->so_cred->cr_uid; 3051 pd->lookup.gid = inp->inp_socket->so_cred->cr_groups[0]; 3052 INP_RUNLOCK(inp); 3053#else 3054 pd->lookup.uid = inp->inp_socket->so_euid; 3055 pd->lookup.gid = inp->inp_socket->so_egid; 3056 pd->lookup.pid = inp->inp_socket->so_cpid; 3057#endif 3058 return (1); 3059} 3060 3061u_int8_t 3062pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 3063{ 3064 int hlen; 3065 u_int8_t hdr[60]; 3066 u_int8_t *opt, optlen; 3067 u_int8_t wscale = 0; 3068 3069 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 3070 if (hlen <= sizeof(struct tcphdr)) 3071 return (0); 3072 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 3073 return (0); 3074 opt = hdr + sizeof(struct tcphdr); 3075 hlen -= sizeof(struct tcphdr); 3076 while (hlen >= 3) { 3077 switch (*opt) { 3078 case TCPOPT_EOL: 3079 case TCPOPT_NOP: 3080 ++opt; 3081 --hlen; 3082 break; 3083 case TCPOPT_WINDOW: 3084 wscale = opt[2]; 3085 if (wscale > TCP_MAX_WINSHIFT) 3086 wscale = TCP_MAX_WINSHIFT; 3087 wscale |= PF_WSCALE_FLAG; 3088 /* FALLTHROUGH */ 3089 default: 3090 optlen = opt[1]; 3091 if (optlen < 2) 3092 optlen = 2; 3093 hlen -= optlen; 3094 opt += optlen; 3095 break; 3096 } 3097 } 3098 return (wscale); 3099} 3100 3101u_int16_t 3102pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 3103{ 3104 int hlen; 3105 u_int8_t hdr[60]; 3106 u_int8_t *opt, optlen; 3107 u_int16_t mss = V_tcp_mssdflt; 3108 3109 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 3110 if (hlen <= sizeof(struct tcphdr)) 3111 return (0); 3112 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 3113 return (0); 3114 opt = hdr + sizeof(struct tcphdr); 3115 hlen -= sizeof(struct tcphdr); 3116 while (hlen >= TCPOLEN_MAXSEG) { 3117 switch (*opt) { 3118 case TCPOPT_EOL: 3119 case TCPOPT_NOP: 3120 ++opt; 3121 --hlen; 3122 break; 3123 case TCPOPT_MAXSEG: 3124 bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2); 3125 NTOHS(mss); 3126 /* FALLTHROUGH */ 3127 default: 3128 optlen = opt[1]; 3129 if (optlen < 2) 3130 optlen = 2; 3131 hlen -= optlen; 3132 opt += optlen; 3133 break; 3134 } 3135 } 3136 return (mss); 3137} 3138 3139u_int16_t 3140pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) 3141{ 3142#ifdef INET 3143 struct sockaddr_in *dst; 3144 struct route ro; 3145#endif /* INET */ 3146#ifdef INET6 3147 struct sockaddr_in6 *dst6; 3148 struct route_in6 ro6; 3149#endif /* INET6 */ 3150 struct rtentry *rt = NULL; 3151 int hlen = 0; /* make the compiler happy */ 3152 u_int16_t mss = V_tcp_mssdflt; 3153 3154 switch (af) { 3155#ifdef INET 3156 case AF_INET: 3157 hlen = sizeof(struct ip); 3158 bzero(&ro, sizeof(ro)); 3159 dst = (struct sockaddr_in *)&ro.ro_dst; 3160 dst->sin_family = AF_INET; 3161 dst->sin_len = sizeof(*dst); 3162 dst->sin_addr = addr->v4; 3163#ifdef __FreeBSD__ 3164#ifdef RTF_PRCLONING 3165 rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING)); 3166#else /* !RTF_PRCLONING */ 3167 in_rtalloc_ign(&ro, RTF_CLONING, 0); 3168#endif 3169#else /* ! __FreeBSD__ */ 3170 rtalloc_noclone(&ro, NO_CLONING); 3171#endif 3172 rt = ro.ro_rt; 3173 break; 3174#endif /* INET */ 3175#ifdef INET6 3176 case AF_INET6: 3177 hlen = sizeof(struct ip6_hdr); 3178 bzero(&ro6, sizeof(ro6)); 3179 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst; 3180 dst6->sin6_family = AF_INET6; 3181 dst6->sin6_len = sizeof(*dst6); 3182 dst6->sin6_addr = addr->v6; 3183#ifdef __FreeBSD__ 3184#ifdef RTF_PRCLONING 3185 rtalloc_ign((struct route *)&ro6, 3186 (RTF_CLONING | RTF_PRCLONING)); 3187#else /* !RTF_PRCLONING */ 3188 rtalloc_ign((struct route *)&ro6, RTF_CLONING); 3189#endif 3190#else /* ! __FreeBSD__ */ 3191 rtalloc_noclone((struct route *)&ro6, NO_CLONING); 3192#endif 3193 rt = ro6.ro_rt; 3194 break; 3195#endif /* INET6 */ 3196 } 3197 3198 if (rt && rt->rt_ifp) { 3199 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr); 3200 mss = max(V_tcp_mssdflt, mss); 3201 RTFREE(rt); 3202 } 3203 mss = min(mss, offer); 3204 mss = max(mss, 64); /* sanity - at least max opt space */ 3205 return (mss); 3206} 3207 3208void 3209pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr) 3210{ 3211 struct pf_rule *r = s->rule.ptr; 3212 3213 s->rt_kif = NULL; 3214 if (!r->rt || r->rt == PF_FASTROUTE) 3215 return; 3216 switch (s->af) { 3217#ifdef INET 3218 case AF_INET: 3219 pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, 3220 &s->nat_src_node); 3221 s->rt_kif = r->rpool.cur->kif; 3222 break; 3223#endif /* INET */ 3224#ifdef INET6 3225 case AF_INET6: 3226 pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, 3227 &s->nat_src_node); 3228 s->rt_kif = r->rpool.cur->kif; 3229 break; 3230#endif /* INET6 */ 3231 } 3232} 3233 3234int 3235pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction, 3236 struct pfi_kif *kif, struct mbuf *m, int off, void *h, 3237#ifdef __FreeBSD__ 3238 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3239 struct ifqueue *ifq, struct inpcb *inp) 3240#else 3241 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3242 struct ifqueue *ifq) 3243#endif 3244{ 3245 struct pf_rule *nr = NULL; 3246 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3247 struct tcphdr *th = pd->hdr.tcp; 3248 u_int16_t bport, nport = 0; 3249 sa_family_t af = pd->af; 3250 struct pf_rule *r, *a = NULL; 3251 struct pf_ruleset *ruleset = NULL; 3252 struct pf_src_node *nsn = NULL; 3253 u_short reason; 3254 int rewrite = 0; 3255 int tag = -1, rtableid = -1; 3256 u_int16_t mss = V_tcp_mssdflt; 3257 int asd = 0; 3258 int match = 0; 3259 3260 if (pf_check_congestion(ifq)) { 3261 REASON_SET(&reason, PFRES_CONGEST); 3262 return (PF_DROP); 3263 } 3264 3265#ifdef __FreeBSD__ 3266 if (inp != NULL) 3267 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3268 else if (debug_pfugidhack) { 3269 PF_UNLOCK(); 3270 DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n")); 3271 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3272 PF_LOCK(); 3273 } 3274#endif 3275 3276 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3277 3278 if (direction == PF_OUT) { 3279 bport = nport = th->th_sport; 3280 /* check outgoing packet for BINAT/NAT */ 3281 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 3282 saddr, th->th_sport, daddr, th->th_dport, 3283 &pd->naddr, &nport)) != NULL) { 3284 PF_ACPY(&pd->baddr, saddr, af); 3285 pf_change_ap(saddr, &th->th_sport, pd->ip_sum, 3286 &th->th_sum, &pd->naddr, nport, 0, af); 3287 rewrite++; 3288 if (nr->natpass) 3289 r = NULL; 3290 pd->nat_rule = nr; 3291 } 3292 } else { 3293 bport = nport = th->th_dport; 3294 /* check incoming packet for BINAT/RDR */ 3295 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 3296 saddr, th->th_sport, daddr, th->th_dport, 3297 &pd->naddr, &nport)) != NULL) { 3298 PF_ACPY(&pd->baddr, daddr, af); 3299 pf_change_ap(daddr, &th->th_dport, pd->ip_sum, 3300 &th->th_sum, &pd->naddr, nport, 0, af); 3301 rewrite++; 3302 if (nr->natpass) 3303 r = NULL; 3304 pd->nat_rule = nr; 3305 } 3306 } 3307 3308 while (r != NULL) { 3309 r->evaluations++; 3310 if (pfi_kif_match(r->kif, kif) == r->ifnot) 3311 r = r->skip[PF_SKIP_IFP].ptr; 3312 else if (r->direction && r->direction != direction) 3313 r = r->skip[PF_SKIP_DIR].ptr; 3314 else if (r->af && r->af != af) 3315 r = r->skip[PF_SKIP_AF].ptr; 3316 else if (r->proto && r->proto != IPPROTO_TCP) 3317 r = r->skip[PF_SKIP_PROTO].ptr; 3318 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, 3319 r->src.neg, kif)) 3320 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3321 else if (r->src.port_op && !pf_match_port(r->src.port_op, 3322 r->src.port[0], r->src.port[1], th->th_sport)) 3323 r = r->skip[PF_SKIP_SRC_PORT].ptr; 3324 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, 3325 r->dst.neg, NULL)) 3326 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3327 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 3328 r->dst.port[0], r->dst.port[1], th->th_dport)) 3329 r = r->skip[PF_SKIP_DST_PORT].ptr; 3330 else if (r->tos && !(r->tos == pd->tos)) 3331 r = TAILQ_NEXT(r, entries); 3332 else if (r->rule_flag & PFRULE_FRAGMENT) 3333 r = TAILQ_NEXT(r, entries); 3334 else if ((r->flagset & th->th_flags) != r->flags) 3335 r = TAILQ_NEXT(r, entries); 3336 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done = 3337#ifdef __FreeBSD__ 3338 pf_socket_lookup(direction, pd, inp), 1)) && 3339#else 3340 pf_socket_lookup(direction, pd), 1)) && 3341#endif 3342 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 3343 pd->lookup.uid)) 3344 r = TAILQ_NEXT(r, entries); 3345 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done = 3346#ifdef __FreeBSD__ 3347 pf_socket_lookup(direction, pd, inp), 1)) && 3348#else 3349 pf_socket_lookup(direction, pd), 1)) && 3350#endif 3351 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 3352 pd->lookup.gid)) 3353 r = TAILQ_NEXT(r, entries); 3354 else if (r->prob && r->prob <= arc4random()) 3355 r = TAILQ_NEXT(r, entries); 3356 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 3357 r = TAILQ_NEXT(r, entries); 3358 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match( 3359 pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint)) 3360 r = TAILQ_NEXT(r, entries); 3361 else { 3362 if (r->tag) 3363 tag = r->tag; 3364 if (r->rtableid >= 0) 3365 rtableid = r->rtableid; 3366 if (r->anchor == NULL) { 3367 match = 1; 3368 *rm = r; 3369 *am = a; 3370 *rsm = ruleset; 3371 if ((*rm)->quick) 3372 break; 3373 r = TAILQ_NEXT(r, entries); 3374 } else 3375 pf_step_into_anchor(&asd, &ruleset, 3376 PF_RULESET_FILTER, &r, &a, &match); 3377 } 3378 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 3379 PF_RULESET_FILTER, &r, &a, &match)) 3380 break; 3381 } 3382 r = *rm; 3383 a = *am; 3384 ruleset = *rsm; 3385 3386 REASON_SET(&reason, PFRES_MATCH); 3387 3388 if (r->log || (nr != NULL && nr->natpass && nr->log)) { 3389 if (rewrite) 3390#ifdef __FreeBSD__ 3391 m_copyback(m, off, sizeof(*th), (caddr_t)th); 3392#else 3393 m_copyback(m, off, sizeof(*th), th); 3394#endif 3395 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 3396 a, ruleset, pd); 3397 } 3398 3399 if ((r->action == PF_DROP) && 3400 ((r->rule_flag & PFRULE_RETURNRST) || 3401 (r->rule_flag & PFRULE_RETURNICMP) || 3402 (r->rule_flag & PFRULE_RETURN))) { 3403 /* undo NAT changes, if they have taken place */ 3404 if (nr != NULL) { 3405 if (direction == PF_OUT) { 3406 pf_change_ap(saddr, &th->th_sport, pd->ip_sum, 3407 &th->th_sum, &pd->baddr, bport, 0, af); 3408 rewrite++; 3409 } else { 3410 pf_change_ap(daddr, &th->th_dport, pd->ip_sum, 3411 &th->th_sum, &pd->baddr, bport, 0, af); 3412 rewrite++; 3413 } 3414 } 3415 if (((r->rule_flag & PFRULE_RETURNRST) || 3416 (r->rule_flag & PFRULE_RETURN)) && 3417 !(th->th_flags & TH_RST)) { 3418 u_int32_t ack = ntohl(th->th_seq) + pd->p_len; 3419 3420 if (th->th_flags & TH_SYN) 3421 ack++; 3422 if (th->th_flags & TH_FIN) 3423 ack++; 3424#ifdef __FreeBSD__ 3425 pf_send_tcp(m, r, af, pd->dst, 3426#else 3427 pf_send_tcp(r, af, pd->dst, 3428#endif 3429 pd->src, th->th_dport, th->th_sport, 3430 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0, 3431 r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp); 3432 } else if ((af == AF_INET) && r->return_icmp) 3433 pf_send_icmp(m, r->return_icmp >> 8, 3434 r->return_icmp & 255, af, r); 3435 else if ((af == AF_INET6) && r->return_icmp6) 3436 pf_send_icmp(m, r->return_icmp6 >> 8, 3437 r->return_icmp6 & 255, af, r); 3438 } 3439 3440 if (r->action == PF_DROP) 3441 return (PF_DROP); 3442 3443 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) { 3444 REASON_SET(&reason, PFRES_MEMORY); 3445 return (PF_DROP); 3446 } 3447 3448 if (r->keep_state || nr != NULL || 3449 (pd->flags & PFDESC_TCP_NORM)) { 3450 /* create new state */ 3451 u_int16_t len; 3452 struct pf_state *s = NULL; 3453 struct pf_src_node *sn = NULL; 3454 3455 len = pd->tot_len - off - (th->th_off << 2); 3456 3457 /* check maximums */ 3458 if (r->max_states && (r->states >= r->max_states)) { 3459 pf_status.lcounters[LCNT_STATES]++; 3460 REASON_SET(&reason, PFRES_MAXSTATES); 3461 goto cleanup; 3462 } 3463 /* src node for filter rule */ 3464 if ((r->rule_flag & PFRULE_SRCTRACK || 3465 r->rpool.opts & PF_POOL_STICKYADDR) && 3466 pf_insert_src_node(&sn, r, saddr, af) != 0) { 3467 REASON_SET(&reason, PFRES_SRCLIMIT); 3468 goto cleanup; 3469 } 3470 /* src node for translation rule */ 3471 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 3472 ((direction == PF_OUT && 3473 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 3474 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) { 3475 REASON_SET(&reason, PFRES_SRCLIMIT); 3476 goto cleanup; 3477 } 3478 s = pool_get(&pf_state_pl, PR_NOWAIT); 3479 if (s == NULL) { 3480 REASON_SET(&reason, PFRES_MEMORY); 3481cleanup: 3482 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 3483 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 3484 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3485 pf_status.src_nodes--; 3486 pool_put(&pf_src_tree_pl, sn); 3487 } 3488 if (nsn != sn && nsn != NULL && nsn->states == 0 && 3489 nsn->expire == 0) { 3490 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 3491 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3492 pf_status.src_nodes--; 3493 pool_put(&pf_src_tree_pl, nsn); 3494 } 3495 return (PF_DROP); 3496 } 3497 bzero(s, sizeof(*s)); 3498 s->rule.ptr = r; 3499 s->nat_rule.ptr = nr; 3500 s->anchor.ptr = a; 3501 STATE_INC_COUNTERS(s); 3502 s->allow_opts = r->allow_opts; 3503 s->log = r->log & PF_LOG_ALL; 3504 if (nr != NULL) 3505 s->log |= nr->log & PF_LOG_ALL; 3506 s->proto = IPPROTO_TCP; 3507 s->direction = direction; 3508 s->af = af; 3509 if (direction == PF_OUT) { 3510 PF_ACPY(&s->gwy.addr, saddr, af); 3511 s->gwy.port = th->th_sport; /* sport */ 3512 PF_ACPY(&s->ext.addr, daddr, af); 3513 s->ext.port = th->th_dport; 3514 if (nr != NULL) { 3515 PF_ACPY(&s->lan.addr, &pd->baddr, af); 3516 s->lan.port = bport; 3517 } else { 3518 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 3519 s->lan.port = s->gwy.port; 3520 } 3521 } else { 3522 PF_ACPY(&s->lan.addr, daddr, af); 3523 s->lan.port = th->th_dport; 3524 PF_ACPY(&s->ext.addr, saddr, af); 3525 s->ext.port = th->th_sport; 3526 if (nr != NULL) { 3527 PF_ACPY(&s->gwy.addr, &pd->baddr, af); 3528 s->gwy.port = bport; 3529 } else { 3530 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3531 s->gwy.port = s->lan.port; 3532 } 3533 } 3534 3535 s->src.seqlo = ntohl(th->th_seq); 3536 s->src.seqhi = s->src.seqlo + len + 1; 3537 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 3538 r->keep_state == PF_STATE_MODULATE) { 3539 /* Generate sequence number modulator */ 3540#ifdef __FreeBSD__ 3541 while ((s->src.seqdiff = 3542 pf_new_isn(s) - s->src.seqlo) == 0) 3543 ; 3544#else 3545 while ((s->src.seqdiff = 3546 tcp_rndiss_next() - s->src.seqlo) == 0) 3547 ; 3548#endif 3549 pf_change_a(&th->th_seq, &th->th_sum, 3550 htonl(s->src.seqlo + s->src.seqdiff), 0); 3551 rewrite = 1; 3552 } else 3553 s->src.seqdiff = 0; 3554 if (th->th_flags & TH_SYN) { 3555 s->src.seqhi++; 3556 s->src.wscale = pf_get_wscale(m, off, th->th_off, af); 3557 } 3558 s->src.max_win = MAX(ntohs(th->th_win), 1); 3559 if (s->src.wscale & PF_WSCALE_MASK) { 3560 /* Remove scale factor from initial window */ 3561 int win = s->src.max_win; 3562 win += 1 << (s->src.wscale & PF_WSCALE_MASK); 3563 s->src.max_win = (win - 1) >> 3564 (s->src.wscale & PF_WSCALE_MASK); 3565 } 3566 if (th->th_flags & TH_FIN) 3567 s->src.seqhi++; 3568 s->dst.seqhi = 1; 3569 s->dst.max_win = 1; 3570 s->src.state = TCPS_SYN_SENT; 3571 s->dst.state = TCPS_CLOSED; 3572 s->creation = time_second; 3573 s->expire = time_second; 3574 s->timeout = PFTM_TCP_FIRST_PACKET; 3575 pf_set_rt_ifp(s, saddr); 3576 if (sn != NULL) { 3577 s->src_node = sn; 3578 s->src_node->states++; 3579 } 3580 if (nsn != NULL) { 3581 PF_ACPY(&nsn->raddr, &pd->naddr, af); 3582 s->nat_src_node = nsn; 3583 s->nat_src_node->states++; 3584 } 3585 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m, 3586 off, pd, th, &s->src, &s->dst)) { 3587 REASON_SET(&reason, PFRES_MEMORY); 3588 pf_src_tree_remove_state(s); 3589 STATE_DEC_COUNTERS(s); 3590 pool_put(&pf_state_pl, s); 3591 return (PF_DROP); 3592 } 3593 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub && 3594 pf_normalize_tcp_stateful(m, off, pd, &reason, th, s, 3595 &s->src, &s->dst, &rewrite)) { 3596 /* This really shouldn't happen!!! */ 3597 DPFPRINTF(PF_DEBUG_URGENT, 3598 ("pf_normalize_tcp_stateful failed on first pkt")); 3599 pf_normalize_tcp_cleanup(s); 3600 pf_src_tree_remove_state(s); 3601 STATE_DEC_COUNTERS(s); 3602 pool_put(&pf_state_pl, s); 3603 return (PF_DROP); 3604 } 3605 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { 3606 pf_normalize_tcp_cleanup(s); 3607 REASON_SET(&reason, PFRES_STATEINS); 3608 pf_src_tree_remove_state(s); 3609 STATE_DEC_COUNTERS(s); 3610 pool_put(&pf_state_pl, s); 3611 return (PF_DROP); 3612 } else 3613 *sm = s; 3614 if (tag > 0) { 3615 pf_tag_ref(tag); 3616 s->tag = tag; 3617 } 3618 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 3619 r->keep_state == PF_STATE_SYNPROXY) { 3620 s->src.state = PF_TCPS_PROXY_SRC; 3621 if (nr != NULL) { 3622 if (direction == PF_OUT) { 3623 pf_change_ap(saddr, &th->th_sport, 3624 pd->ip_sum, &th->th_sum, &pd->baddr, 3625 bport, 0, af); 3626 } else { 3627 pf_change_ap(daddr, &th->th_dport, 3628 pd->ip_sum, &th->th_sum, &pd->baddr, 3629 bport, 0, af); 3630 } 3631 } 3632 s->src.seqhi = htonl(arc4random()); 3633 /* Find mss option */ 3634 mss = pf_get_mss(m, off, th->th_off, af); 3635 mss = pf_calc_mss(saddr, af, mss); 3636 mss = pf_calc_mss(daddr, af, mss); 3637 s->src.mss = mss; 3638#ifdef __FreeBSD__ 3639 pf_send_tcp(NULL, r, af, daddr, saddr, th->th_dport, 3640#else 3641 pf_send_tcp(r, af, daddr, saddr, th->th_dport, 3642#endif 3643 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1, 3644 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL); 3645 REASON_SET(&reason, PFRES_SYNPROXY); 3646 return (PF_SYNPROXY_DROP); 3647 } 3648 } 3649 3650 /* copy back packet headers if we performed NAT operations */ 3651 if (rewrite) 3652 m_copyback(m, off, sizeof(*th), (caddr_t)th); 3653 3654 return (PF_PASS); 3655} 3656 3657int 3658pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction, 3659 struct pfi_kif *kif, struct mbuf *m, int off, void *h, 3660#ifdef __FreeBSD__ 3661 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3662 struct ifqueue *ifq, struct inpcb *inp) 3663#else 3664 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3665 struct ifqueue *ifq) 3666#endif 3667{ 3668 struct pf_rule *nr = NULL; 3669 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3670 struct udphdr *uh = pd->hdr.udp; 3671 u_int16_t bport, nport = 0; 3672 sa_family_t af = pd->af; 3673 struct pf_rule *r, *a = NULL; 3674 struct pf_ruleset *ruleset = NULL; 3675 struct pf_src_node *nsn = NULL; 3676 u_short reason; 3677 int rewrite = 0; 3678 int tag = -1, rtableid = -1; 3679 int asd = 0; 3680 int match = 0; 3681 3682 if (pf_check_congestion(ifq)) { 3683 REASON_SET(&reason, PFRES_CONGEST); 3684 return (PF_DROP); 3685 } 3686 3687#ifdef __FreeBSD__ 3688 if (inp != NULL) 3689 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3690 else if (debug_pfugidhack) { 3691 PF_UNLOCK(); 3692 DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n")); 3693 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3694 PF_LOCK(); 3695 } 3696#endif 3697 3698 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3699 3700 if (direction == PF_OUT) { 3701 bport = nport = uh->uh_sport; 3702 /* check outgoing packet for BINAT/NAT */ 3703 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 3704 saddr, uh->uh_sport, daddr, uh->uh_dport, 3705 &pd->naddr, &nport)) != NULL) { 3706 PF_ACPY(&pd->baddr, saddr, af); 3707 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, 3708 &uh->uh_sum, &pd->naddr, nport, 1, af); 3709 rewrite++; 3710 if (nr->natpass) 3711 r = NULL; 3712 pd->nat_rule = nr; 3713 } 3714 } else { 3715 bport = nport = uh->uh_dport; 3716 /* check incoming packet for BINAT/RDR */ 3717 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 3718 saddr, uh->uh_sport, daddr, uh->uh_dport, &pd->naddr, 3719 &nport)) != NULL) { 3720 PF_ACPY(&pd->baddr, daddr, af); 3721 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, 3722 &uh->uh_sum, &pd->naddr, nport, 1, af); 3723 rewrite++; 3724 if (nr->natpass) 3725 r = NULL; 3726 pd->nat_rule = nr; 3727 } 3728 } 3729 3730 while (r != NULL) { 3731 r->evaluations++; 3732 if (pfi_kif_match(r->kif, kif) == r->ifnot) 3733 r = r->skip[PF_SKIP_IFP].ptr; 3734 else if (r->direction && r->direction != direction) 3735 r = r->skip[PF_SKIP_DIR].ptr; 3736 else if (r->af && r->af != af) 3737 r = r->skip[PF_SKIP_AF].ptr; 3738 else if (r->proto && r->proto != IPPROTO_UDP) 3739 r = r->skip[PF_SKIP_PROTO].ptr; 3740 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, 3741 r->src.neg, kif)) 3742 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3743 else if (r->src.port_op && !pf_match_port(r->src.port_op, 3744 r->src.port[0], r->src.port[1], uh->uh_sport)) 3745 r = r->skip[PF_SKIP_SRC_PORT].ptr; 3746 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, 3747 r->dst.neg, NULL)) 3748 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3749 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 3750 r->dst.port[0], r->dst.port[1], uh->uh_dport)) 3751 r = r->skip[PF_SKIP_DST_PORT].ptr; 3752 else if (r->tos && !(r->tos == pd->tos)) 3753 r = TAILQ_NEXT(r, entries); 3754 else if (r->rule_flag & PFRULE_FRAGMENT) 3755 r = TAILQ_NEXT(r, entries); 3756 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done = 3757#ifdef __FreeBSD__ 3758 pf_socket_lookup(direction, pd, inp), 1)) && 3759#else 3760 pf_socket_lookup(direction, pd), 1)) && 3761#endif 3762 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 3763 pd->lookup.uid)) 3764 r = TAILQ_NEXT(r, entries); 3765 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done = 3766#ifdef __FreeBSD__ 3767 pf_socket_lookup(direction, pd, inp), 1)) && 3768#else 3769 pf_socket_lookup(direction, pd), 1)) && 3770#endif 3771 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 3772 pd->lookup.gid)) 3773 r = TAILQ_NEXT(r, entries); 3774 else if (r->prob && r->prob <= arc4random()) 3775 r = TAILQ_NEXT(r, entries); 3776 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 3777 r = TAILQ_NEXT(r, entries); 3778 else if (r->os_fingerprint != PF_OSFP_ANY) 3779 r = TAILQ_NEXT(r, entries); 3780 else { 3781 if (r->tag) 3782 tag = r->tag; 3783 if (r->rtableid >= 0) 3784 rtableid = r->rtableid; 3785 if (r->anchor == NULL) { 3786 match = 1; 3787 *rm = r; 3788 *am = a; 3789 *rsm = ruleset; 3790 if ((*rm)->quick) 3791 break; 3792 r = TAILQ_NEXT(r, entries); 3793 } else 3794 pf_step_into_anchor(&asd, &ruleset, 3795 PF_RULESET_FILTER, &r, &a, &match); 3796 } 3797 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 3798 PF_RULESET_FILTER, &r, &a, &match)) 3799 break; 3800 } 3801 r = *rm; 3802 a = *am; 3803 ruleset = *rsm; 3804 3805 REASON_SET(&reason, PFRES_MATCH); 3806 3807 if (r->log || (nr != NULL && nr->natpass && nr->log)) { 3808 if (rewrite) 3809#ifdef __FreeBSD__ 3810 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 3811#else 3812 m_copyback(m, off, sizeof(*uh), uh); 3813#endif 3814 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 3815 a, ruleset, pd); 3816 } 3817 3818 if ((r->action == PF_DROP) && 3819 ((r->rule_flag & PFRULE_RETURNICMP) || 3820 (r->rule_flag & PFRULE_RETURN))) { 3821 /* undo NAT changes, if they have taken place */ 3822 if (nr != NULL) { 3823 if (direction == PF_OUT) { 3824 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, 3825 &uh->uh_sum, &pd->baddr, bport, 1, af); 3826 rewrite++; 3827 } else { 3828 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, 3829 &uh->uh_sum, &pd->baddr, bport, 1, af); 3830 rewrite++; 3831 } 3832 } 3833 if ((af == AF_INET) && r->return_icmp) 3834 pf_send_icmp(m, r->return_icmp >> 8, 3835 r->return_icmp & 255, af, r); 3836 else if ((af == AF_INET6) && r->return_icmp6) 3837 pf_send_icmp(m, r->return_icmp6 >> 8, 3838 r->return_icmp6 & 255, af, r); 3839 } 3840 3841 if (r->action == PF_DROP) 3842 return (PF_DROP); 3843 3844 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) { 3845 REASON_SET(&reason, PFRES_MEMORY); 3846 return (PF_DROP); 3847 } 3848 3849 if (r->keep_state || nr != NULL) { 3850 /* create new state */ 3851 struct pf_state *s = NULL; 3852 struct pf_src_node *sn = NULL; 3853 3854 /* check maximums */ 3855 if (r->max_states && (r->states >= r->max_states)) { 3856 pf_status.lcounters[LCNT_STATES]++; 3857 REASON_SET(&reason, PFRES_MAXSTATES); 3858 goto cleanup; 3859 } 3860 /* src node for filter rule */ 3861 if ((r->rule_flag & PFRULE_SRCTRACK || 3862 r->rpool.opts & PF_POOL_STICKYADDR) && 3863 pf_insert_src_node(&sn, r, saddr, af) != 0) { 3864 REASON_SET(&reason, PFRES_SRCLIMIT); 3865 goto cleanup; 3866 } 3867 /* src node for translation rule */ 3868 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 3869 ((direction == PF_OUT && 3870 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 3871 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) { 3872 REASON_SET(&reason, PFRES_SRCLIMIT); 3873 goto cleanup; 3874 } 3875 s = pool_get(&pf_state_pl, PR_NOWAIT); 3876 if (s == NULL) { 3877 REASON_SET(&reason, PFRES_MEMORY); 3878cleanup: 3879 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 3880 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 3881 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3882 pf_status.src_nodes--; 3883 pool_put(&pf_src_tree_pl, sn); 3884 } 3885 if (nsn != sn && nsn != NULL && nsn->states == 0 && 3886 nsn->expire == 0) { 3887 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 3888 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3889 pf_status.src_nodes--; 3890 pool_put(&pf_src_tree_pl, nsn); 3891 } 3892 return (PF_DROP); 3893 } 3894 bzero(s, sizeof(*s)); 3895 s->rule.ptr = r; 3896 s->nat_rule.ptr = nr; 3897 s->anchor.ptr = a; 3898 STATE_INC_COUNTERS(s); 3899 s->allow_opts = r->allow_opts; 3900 s->log = r->log & PF_LOG_ALL; 3901 if (nr != NULL) 3902 s->log |= nr->log & PF_LOG_ALL; 3903 s->proto = IPPROTO_UDP; 3904 s->direction = direction; 3905 s->af = af; 3906 if (direction == PF_OUT) { 3907 PF_ACPY(&s->gwy.addr, saddr, af); 3908 s->gwy.port = uh->uh_sport; 3909 PF_ACPY(&s->ext.addr, daddr, af); 3910 s->ext.port = uh->uh_dport; 3911 if (nr != NULL) { 3912 PF_ACPY(&s->lan.addr, &pd->baddr, af); 3913 s->lan.port = bport; 3914 } else { 3915 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 3916 s->lan.port = s->gwy.port; 3917 } 3918 } else { 3919 PF_ACPY(&s->lan.addr, daddr, af); 3920 s->lan.port = uh->uh_dport; 3921 PF_ACPY(&s->ext.addr, saddr, af); 3922 s->ext.port = uh->uh_sport; 3923 if (nr != NULL) { 3924 PF_ACPY(&s->gwy.addr, &pd->baddr, af); 3925 s->gwy.port = bport; 3926 } else { 3927 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3928 s->gwy.port = s->lan.port; 3929 } 3930 } 3931 s->src.state = PFUDPS_SINGLE; 3932 s->dst.state = PFUDPS_NO_TRAFFIC; 3933 s->creation = time_second; 3934 s->expire = time_second; 3935 s->timeout = PFTM_UDP_FIRST_PACKET; 3936 pf_set_rt_ifp(s, saddr); 3937 if (sn != NULL) { 3938 s->src_node = sn; 3939 s->src_node->states++; 3940 } 3941 if (nsn != NULL) { 3942 PF_ACPY(&nsn->raddr, &pd->naddr, af); 3943 s->nat_src_node = nsn; 3944 s->nat_src_node->states++; 3945 } 3946 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { 3947 REASON_SET(&reason, PFRES_STATEINS); 3948 pf_src_tree_remove_state(s); 3949 STATE_DEC_COUNTERS(s); 3950 pool_put(&pf_state_pl, s); 3951 return (PF_DROP); 3952 } else 3953 *sm = s; 3954 if (tag > 0) { 3955 pf_tag_ref(tag); 3956 s->tag = tag; 3957 } 3958 } 3959 3960 /* copy back packet headers if we performed NAT operations */ 3961 if (rewrite) 3962 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 3963 3964 return (PF_PASS); 3965} 3966 3967int 3968pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction, 3969 struct pfi_kif *kif, struct mbuf *m, int off, void *h, 3970 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3971 struct ifqueue *ifq) 3972{ 3973 struct pf_rule *nr = NULL; 3974 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3975 struct pf_rule *r, *a = NULL; 3976 struct pf_ruleset *ruleset = NULL; 3977 struct pf_src_node *nsn = NULL; 3978 u_short reason; 3979 u_int16_t icmpid = 0, bport, nport = 0; 3980 sa_family_t af = pd->af; 3981 u_int8_t icmptype = 0; /* make the compiler happy */ 3982 u_int8_t icmpcode = 0; /* make the compiler happy */ 3983 int state_icmp = 0; 3984 int tag = -1, rtableid = -1; 3985#ifdef INET6 3986 int rewrite = 0; 3987#endif /* INET6 */ 3988 int asd = 0; 3989 int match = 0; 3990 3991 if (pf_check_congestion(ifq)) { 3992 REASON_SET(&reason, PFRES_CONGEST); 3993 return (PF_DROP); 3994 } 3995 3996 switch (pd->proto) { 3997#ifdef INET 3998 case IPPROTO_ICMP: 3999 icmptype = pd->hdr.icmp->icmp_type; 4000 icmpcode = pd->hdr.icmp->icmp_code; 4001 icmpid = pd->hdr.icmp->icmp_id; 4002 4003 if (icmptype == ICMP_UNREACH || 4004 icmptype == ICMP_SOURCEQUENCH || 4005 icmptype == ICMP_REDIRECT || 4006 icmptype == ICMP_TIMXCEED || 4007 icmptype == ICMP_PARAMPROB) 4008 state_icmp++; 4009 break; 4010#endif /* INET */ 4011#ifdef INET6 4012 case IPPROTO_ICMPV6: 4013 icmptype = pd->hdr.icmp6->icmp6_type; 4014 icmpcode = pd->hdr.icmp6->icmp6_code; 4015 icmpid = pd->hdr.icmp6->icmp6_id; 4016 4017 if (icmptype == ICMP6_DST_UNREACH || 4018 icmptype == ICMP6_PACKET_TOO_BIG || 4019 icmptype == ICMP6_TIME_EXCEEDED || 4020 icmptype == ICMP6_PARAM_PROB) 4021 state_icmp++; 4022 break; 4023#endif /* INET6 */ 4024 } 4025 4026 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 4027 4028 if (direction == PF_OUT) { 4029 bport = nport = icmpid; 4030 /* check outgoing packet for BINAT/NAT */ 4031 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 4032 saddr, icmpid, daddr, icmpid, &pd->naddr, &nport)) != 4033 NULL) { 4034 PF_ACPY(&pd->baddr, saddr, af); 4035 switch (af) { 4036#ifdef INET 4037 case AF_INET: 4038 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, 4039 pd->naddr.v4.s_addr, 0); 4040 pd->hdr.icmp->icmp_cksum = pf_cksum_fixup( 4041 pd->hdr.icmp->icmp_cksum, icmpid, nport, 0); 4042 pd->hdr.icmp->icmp_id = nport; 4043 m_copyback(m, off, ICMP_MINLEN, 4044 (caddr_t)pd->hdr.icmp); 4045 break; 4046#endif /* INET */ 4047#ifdef INET6 4048 case AF_INET6: 4049 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum, 4050 &pd->naddr, 0); 4051 rewrite++; 4052 break; 4053#endif /* INET6 */ 4054 } 4055 if (nr->natpass) 4056 r = NULL; 4057 pd->nat_rule = nr; 4058 } 4059 } else { 4060 bport = nport = icmpid; 4061 /* check incoming packet for BINAT/RDR */ 4062 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 4063 saddr, icmpid, daddr, icmpid, &pd->naddr, &nport)) != 4064 NULL) { 4065 PF_ACPY(&pd->baddr, daddr, af); 4066 switch (af) { 4067#ifdef INET 4068 case AF_INET: 4069 pf_change_a(&daddr->v4.s_addr, 4070 pd->ip_sum, pd->naddr.v4.s_addr, 0); 4071 break; 4072#endif /* INET */ 4073#ifdef INET6 4074 case AF_INET6: 4075 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, 4076 &pd->naddr, 0); 4077 rewrite++; 4078 break; 4079#endif /* INET6 */ 4080 } 4081 if (nr->natpass) 4082 r = NULL; 4083 pd->nat_rule = nr; 4084 } 4085 } 4086 4087 while (r != NULL) { 4088 r->evaluations++; 4089 if (pfi_kif_match(r->kif, kif) == r->ifnot) 4090 r = r->skip[PF_SKIP_IFP].ptr; 4091 else if (r->direction && r->direction != direction) 4092 r = r->skip[PF_SKIP_DIR].ptr; 4093 else if (r->af && r->af != af) 4094 r = r->skip[PF_SKIP_AF].ptr; 4095 else if (r->proto && r->proto != pd->proto) 4096 r = r->skip[PF_SKIP_PROTO].ptr; 4097 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, 4098 r->src.neg, kif)) 4099 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 4100 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, 4101 r->dst.neg, NULL)) 4102 r = r->skip[PF_SKIP_DST_ADDR].ptr; 4103 else if (r->type && r->type != icmptype + 1) 4104 r = TAILQ_NEXT(r, entries); 4105 else if (r->code && r->code != icmpcode + 1) 4106 r = TAILQ_NEXT(r, entries); 4107 else if (r->tos && !(r->tos == pd->tos)) 4108 r = TAILQ_NEXT(r, entries); 4109 else if (r->rule_flag & PFRULE_FRAGMENT) 4110 r = TAILQ_NEXT(r, entries); 4111 else if (r->prob && r->prob <= arc4random()) 4112 r = TAILQ_NEXT(r, entries); 4113 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 4114 r = TAILQ_NEXT(r, entries); 4115 else if (r->os_fingerprint != PF_OSFP_ANY) 4116 r = TAILQ_NEXT(r, entries); 4117 else { 4118 if (r->tag) 4119 tag = r->tag; 4120 if (r->rtableid >= 0) 4121 rtableid = r->rtableid; 4122 if (r->anchor == NULL) { 4123 match = 1; 4124 *rm = r; 4125 *am = a; 4126 *rsm = ruleset; 4127 if ((*rm)->quick) 4128 break; 4129 r = TAILQ_NEXT(r, entries); 4130 } else 4131 pf_step_into_anchor(&asd, &ruleset, 4132 PF_RULESET_FILTER, &r, &a, &match); 4133 } 4134 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 4135 PF_RULESET_FILTER, &r, &a, &match)) 4136 break; 4137 } 4138 r = *rm; 4139 a = *am; 4140 ruleset = *rsm; 4141 4142 REASON_SET(&reason, PFRES_MATCH); 4143 4144 if (r->log || (nr != NULL && nr->natpass && nr->log)) { 4145#ifdef INET6 4146 if (rewrite) 4147 m_copyback(m, off, sizeof(struct icmp6_hdr), 4148 (caddr_t)pd->hdr.icmp6); 4149#endif /* INET6 */ 4150 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 4151 a, ruleset, pd); 4152 } 4153 4154 if (r->action != PF_PASS) 4155 return (PF_DROP); 4156 4157 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) { 4158 REASON_SET(&reason, PFRES_MEMORY); 4159 return (PF_DROP); 4160 } 4161 4162 if (!state_icmp && (r->keep_state || nr != NULL)) { 4163 /* create new state */ 4164 struct pf_state *s = NULL; 4165 struct pf_src_node *sn = NULL; 4166 4167 /* check maximums */ 4168 if (r->max_states && (r->states >= r->max_states)) { 4169 pf_status.lcounters[LCNT_STATES]++; 4170 REASON_SET(&reason, PFRES_MAXSTATES); 4171 goto cleanup; 4172 } 4173 /* src node for filter rule */ 4174 if ((r->rule_flag & PFRULE_SRCTRACK || 4175 r->rpool.opts & PF_POOL_STICKYADDR) && 4176 pf_insert_src_node(&sn, r, saddr, af) != 0) { 4177 REASON_SET(&reason, PFRES_SRCLIMIT); 4178 goto cleanup; 4179 } 4180 /* src node for translation rule */ 4181 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 4182 ((direction == PF_OUT && 4183 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 4184 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) { 4185 REASON_SET(&reason, PFRES_SRCLIMIT); 4186 goto cleanup; 4187 } 4188 s = pool_get(&pf_state_pl, PR_NOWAIT); 4189 if (s == NULL) { 4190 REASON_SET(&reason, PFRES_MEMORY); 4191cleanup: 4192 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 4193 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 4194 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4195 pf_status.src_nodes--; 4196 pool_put(&pf_src_tree_pl, sn); 4197 } 4198 if (nsn != sn && nsn != NULL && nsn->states == 0 && 4199 nsn->expire == 0) { 4200 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 4201 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4202 pf_status.src_nodes--; 4203 pool_put(&pf_src_tree_pl, nsn); 4204 } 4205 return (PF_DROP); 4206 } 4207 bzero(s, sizeof(*s)); 4208 s->rule.ptr = r; 4209 s->nat_rule.ptr = nr; 4210 s->anchor.ptr = a; 4211 STATE_INC_COUNTERS(s); 4212 s->allow_opts = r->allow_opts; 4213 s->log = r->log & PF_LOG_ALL; 4214 if (nr != NULL) 4215 s->log |= nr->log & PF_LOG_ALL; 4216 s->proto = pd->proto; 4217 s->direction = direction; 4218 s->af = af; 4219 if (direction == PF_OUT) { 4220 PF_ACPY(&s->gwy.addr, saddr, af); 4221 s->gwy.port = nport; 4222 PF_ACPY(&s->ext.addr, daddr, af); 4223 s->ext.port = 0; 4224 if (nr != NULL) { 4225 PF_ACPY(&s->lan.addr, &pd->baddr, af); 4226 s->lan.port = bport; 4227 } else { 4228 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 4229 s->lan.port = s->gwy.port; 4230 } 4231 } else { 4232 PF_ACPY(&s->lan.addr, daddr, af); 4233 s->lan.port = nport; 4234 PF_ACPY(&s->ext.addr, saddr, af); 4235 s->ext.port = 0; 4236 if (nr != NULL) { 4237 PF_ACPY(&s->gwy.addr, &pd->baddr, af); 4238 s->gwy.port = bport; 4239 } else { 4240 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 4241 s->gwy.port = s->lan.port; 4242 } 4243 } 4244 s->creation = time_second; 4245 s->expire = time_second; 4246 s->timeout = PFTM_ICMP_FIRST_PACKET; 4247 pf_set_rt_ifp(s, saddr); 4248 if (sn != NULL) { 4249 s->src_node = sn; 4250 s->src_node->states++; 4251 } 4252 if (nsn != NULL) { 4253 PF_ACPY(&nsn->raddr, &pd->naddr, af); 4254 s->nat_src_node = nsn; 4255 s->nat_src_node->states++; 4256 } 4257 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { 4258 REASON_SET(&reason, PFRES_STATEINS); 4259 pf_src_tree_remove_state(s); 4260 STATE_DEC_COUNTERS(s); 4261 pool_put(&pf_state_pl, s); 4262 return (PF_DROP); 4263 } else 4264 *sm = s; 4265 if (tag > 0) { 4266 pf_tag_ref(tag); 4267 s->tag = tag; 4268 } 4269 } 4270 4271#ifdef INET6 4272 /* copy back packet headers if we performed IPv6 NAT operations */ 4273 if (rewrite) 4274 m_copyback(m, off, sizeof(struct icmp6_hdr), 4275 (caddr_t)pd->hdr.icmp6); 4276#endif /* INET6 */ 4277 4278 return (PF_PASS); 4279} 4280 4281int 4282pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction, 4283 struct pfi_kif *kif, struct mbuf *m, int off, void *h, struct pf_pdesc *pd, 4284 struct pf_rule **am, struct pf_ruleset **rsm, struct ifqueue *ifq) 4285{ 4286 struct pf_rule *nr = NULL; 4287 struct pf_rule *r, *a = NULL; 4288 struct pf_ruleset *ruleset = NULL; 4289 struct pf_src_node *nsn = NULL; 4290 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 4291 sa_family_t af = pd->af; 4292 u_short reason; 4293 int tag = -1, rtableid = -1; 4294 int asd = 0; 4295 int match = 0; 4296 4297 if (pf_check_congestion(ifq)) { 4298 REASON_SET(&reason, PFRES_CONGEST); 4299 return (PF_DROP); 4300 } 4301 4302 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 4303 4304 if (direction == PF_OUT) { 4305 /* check outgoing packet for BINAT/NAT */ 4306 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 4307 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { 4308 PF_ACPY(&pd->baddr, saddr, af); 4309 switch (af) { 4310#ifdef INET 4311 case AF_INET: 4312 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, 4313 pd->naddr.v4.s_addr, 0); 4314 break; 4315#endif /* INET */ 4316#ifdef INET6 4317 case AF_INET6: 4318 PF_ACPY(saddr, &pd->naddr, af); 4319 break; 4320#endif /* INET6 */ 4321 } 4322 if (nr->natpass) 4323 r = NULL; 4324 pd->nat_rule = nr; 4325 } 4326 } else { 4327 /* check incoming packet for BINAT/RDR */ 4328 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 4329 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { 4330 PF_ACPY(&pd->baddr, daddr, af); 4331 switch (af) { 4332#ifdef INET 4333 case AF_INET: 4334 pf_change_a(&daddr->v4.s_addr, 4335 pd->ip_sum, pd->naddr.v4.s_addr, 0); 4336 break; 4337#endif /* INET */ 4338#ifdef INET6 4339 case AF_INET6: 4340 PF_ACPY(daddr, &pd->naddr, af); 4341 break; 4342#endif /* INET6 */ 4343 } 4344 if (nr->natpass) 4345 r = NULL; 4346 pd->nat_rule = nr; 4347 } 4348 } 4349 4350 while (r != NULL) { 4351 r->evaluations++; 4352 if (pfi_kif_match(r->kif, kif) == r->ifnot) 4353 r = r->skip[PF_SKIP_IFP].ptr; 4354 else if (r->direction && r->direction != direction) 4355 r = r->skip[PF_SKIP_DIR].ptr; 4356 else if (r->af && r->af != af) 4357 r = r->skip[PF_SKIP_AF].ptr; 4358 else if (r->proto && r->proto != pd->proto) 4359 r = r->skip[PF_SKIP_PROTO].ptr; 4360 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, 4361 r->src.neg, kif)) 4362 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 4363 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, 4364 r->dst.neg, NULL)) 4365 r = r->skip[PF_SKIP_DST_ADDR].ptr; 4366 else if (r->tos && !(r->tos == pd->tos)) 4367 r = TAILQ_NEXT(r, entries); 4368 else if (r->rule_flag & PFRULE_FRAGMENT) 4369 r = TAILQ_NEXT(r, entries); 4370 else if (r->prob && r->prob <= arc4random()) 4371 r = TAILQ_NEXT(r, entries); 4372 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 4373 r = TAILQ_NEXT(r, entries); 4374 else if (r->os_fingerprint != PF_OSFP_ANY) 4375 r = TAILQ_NEXT(r, entries); 4376 else { 4377 if (r->tag) 4378 tag = r->tag; 4379 if (r->rtableid >= 0) 4380 rtableid = r->rtableid; 4381 if (r->anchor == NULL) { 4382 match = 1; 4383 *rm = r; 4384 *am = a; 4385 *rsm = ruleset; 4386 if ((*rm)->quick) 4387 break; 4388 r = TAILQ_NEXT(r, entries); 4389 } else 4390 pf_step_into_anchor(&asd, &ruleset, 4391 PF_RULESET_FILTER, &r, &a, &match); 4392 } 4393 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 4394 PF_RULESET_FILTER, &r, &a, &match)) 4395 break; 4396 } 4397 r = *rm; 4398 a = *am; 4399 ruleset = *rsm; 4400 4401 REASON_SET(&reason, PFRES_MATCH); 4402 4403 if (r->log || (nr != NULL && nr->natpass && nr->log)) 4404 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 4405 a, ruleset, pd); 4406 4407 if ((r->action == PF_DROP) && 4408 ((r->rule_flag & PFRULE_RETURNICMP) || 4409 (r->rule_flag & PFRULE_RETURN))) { 4410 struct pf_addr *a = NULL; 4411 4412 if (nr != NULL) { 4413 if (direction == PF_OUT) 4414 a = saddr; 4415 else 4416 a = daddr; 4417 } 4418 if (a != NULL) { 4419 switch (af) { 4420#ifdef INET 4421 case AF_INET: 4422 pf_change_a(&a->v4.s_addr, pd->ip_sum, 4423 pd->baddr.v4.s_addr, 0); 4424 break; 4425#endif /* INET */ 4426#ifdef INET6 4427 case AF_INET6: 4428 PF_ACPY(a, &pd->baddr, af); 4429 break; 4430#endif /* INET6 */ 4431 } 4432 } 4433 if ((af == AF_INET) && r->return_icmp) 4434 pf_send_icmp(m, r->return_icmp >> 8, 4435 r->return_icmp & 255, af, r); 4436 else if ((af == AF_INET6) && r->return_icmp6) 4437 pf_send_icmp(m, r->return_icmp6 >> 8, 4438 r->return_icmp6 & 255, af, r); 4439 } 4440 4441 if (r->action != PF_PASS) 4442 return (PF_DROP); 4443 4444 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) { 4445 REASON_SET(&reason, PFRES_MEMORY); 4446 return (PF_DROP); 4447 } 4448 4449 if (r->keep_state || nr != NULL) { 4450 /* create new state */ 4451 struct pf_state *s = NULL; 4452 struct pf_src_node *sn = NULL; 4453 4454 /* check maximums */ 4455 if (r->max_states && (r->states >= r->max_states)) { 4456 pf_status.lcounters[LCNT_STATES]++; 4457 REASON_SET(&reason, PFRES_MAXSTATES); 4458 goto cleanup; 4459 } 4460 /* src node for filter rule */ 4461 if ((r->rule_flag & PFRULE_SRCTRACK || 4462 r->rpool.opts & PF_POOL_STICKYADDR) && 4463 pf_insert_src_node(&sn, r, saddr, af) != 0) { 4464 REASON_SET(&reason, PFRES_SRCLIMIT); 4465 goto cleanup; 4466 } 4467 /* src node for translation rule */ 4468 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 4469 ((direction == PF_OUT && 4470 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 4471 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) { 4472 REASON_SET(&reason, PFRES_SRCLIMIT); 4473 goto cleanup; 4474 } 4475 s = pool_get(&pf_state_pl, PR_NOWAIT); 4476 if (s == NULL) { 4477 REASON_SET(&reason, PFRES_MEMORY); 4478cleanup: 4479 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 4480 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 4481 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4482 pf_status.src_nodes--; 4483 pool_put(&pf_src_tree_pl, sn); 4484 } 4485 if (nsn != sn && nsn != NULL && nsn->states == 0 && 4486 nsn->expire == 0) { 4487 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 4488 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4489 pf_status.src_nodes--; 4490 pool_put(&pf_src_tree_pl, nsn); 4491 } 4492 return (PF_DROP); 4493 } 4494 bzero(s, sizeof(*s)); 4495 s->rule.ptr = r; 4496 s->nat_rule.ptr = nr; 4497 s->anchor.ptr = a; 4498 STATE_INC_COUNTERS(s); 4499 s->allow_opts = r->allow_opts; 4500 s->log = r->log & PF_LOG_ALL; 4501 if (nr != NULL) 4502 s->log |= nr->log & PF_LOG_ALL; 4503 s->proto = pd->proto; 4504 s->direction = direction; 4505 s->af = af; 4506 if (direction == PF_OUT) { 4507 PF_ACPY(&s->gwy.addr, saddr, af); 4508 PF_ACPY(&s->ext.addr, daddr, af); 4509 if (nr != NULL) 4510 PF_ACPY(&s->lan.addr, &pd->baddr, af); 4511 else 4512 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 4513 } else { 4514 PF_ACPY(&s->lan.addr, daddr, af); 4515 PF_ACPY(&s->ext.addr, saddr, af); 4516 if (nr != NULL) 4517 PF_ACPY(&s->gwy.addr, &pd->baddr, af); 4518 else 4519 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 4520 } 4521 s->src.state = PFOTHERS_SINGLE; 4522 s->dst.state = PFOTHERS_NO_TRAFFIC; 4523 s->creation = time_second; 4524 s->expire = time_second; 4525 s->timeout = PFTM_OTHER_FIRST_PACKET; 4526 pf_set_rt_ifp(s, saddr); 4527 if (sn != NULL) { 4528 s->src_node = sn; 4529 s->src_node->states++; 4530 } 4531 if (nsn != NULL) { 4532 PF_ACPY(&nsn->raddr, &pd->naddr, af); 4533 s->nat_src_node = nsn; 4534 s->nat_src_node->states++; 4535 } 4536 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { 4537 REASON_SET(&reason, PFRES_STATEINS); 4538 pf_src_tree_remove_state(s); 4539 STATE_DEC_COUNTERS(s); 4540 pool_put(&pf_state_pl, s); 4541 return (PF_DROP); 4542 } else 4543 *sm = s; 4544 if (tag > 0) { 4545 pf_tag_ref(tag); 4546 s->tag = tag; 4547 } 4548 } 4549 4550 return (PF_PASS); 4551} 4552 4553int 4554pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, 4555 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, 4556 struct pf_ruleset **rsm) 4557{ 4558 struct pf_rule *r, *a = NULL; 4559 struct pf_ruleset *ruleset = NULL; 4560 sa_family_t af = pd->af; 4561 u_short reason; 4562 int tag = -1; 4563 int asd = 0; 4564 int match = 0; 4565 4566 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 4567 while (r != NULL) { 4568 r->evaluations++; 4569 if (pfi_kif_match(r->kif, kif) == r->ifnot) 4570 r = r->skip[PF_SKIP_IFP].ptr; 4571 else if (r->direction && r->direction != direction) 4572 r = r->skip[PF_SKIP_DIR].ptr; 4573 else if (r->af && r->af != af) 4574 r = r->skip[PF_SKIP_AF].ptr; 4575 else if (r->proto && r->proto != pd->proto) 4576 r = r->skip[PF_SKIP_PROTO].ptr; 4577 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, 4578 r->src.neg, kif)) 4579 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 4580 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, 4581 r->dst.neg, NULL)) 4582 r = r->skip[PF_SKIP_DST_ADDR].ptr; 4583 else if (r->tos && !(r->tos == pd->tos)) 4584 r = TAILQ_NEXT(r, entries); 4585 else if (r->os_fingerprint != PF_OSFP_ANY) 4586 r = TAILQ_NEXT(r, entries); 4587 else if (pd->proto == IPPROTO_UDP && 4588 (r->src.port_op || r->dst.port_op)) 4589 r = TAILQ_NEXT(r, entries); 4590 else if (pd->proto == IPPROTO_TCP && 4591 (r->src.port_op || r->dst.port_op || r->flagset)) 4592 r = TAILQ_NEXT(r, entries); 4593 else if ((pd->proto == IPPROTO_ICMP || 4594 pd->proto == IPPROTO_ICMPV6) && 4595 (r->type || r->code)) 4596 r = TAILQ_NEXT(r, entries); 4597 else if (r->prob && r->prob <= arc4random()) 4598 r = TAILQ_NEXT(r, entries); 4599 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag)) 4600 r = TAILQ_NEXT(r, entries); 4601 else { 4602 if (r->anchor == NULL) { 4603 match = 1; 4604 *rm = r; 4605 *am = a; 4606 *rsm = ruleset; 4607 if ((*rm)->quick) 4608 break; 4609 r = TAILQ_NEXT(r, entries); 4610 } else 4611 pf_step_into_anchor(&asd, &ruleset, 4612 PF_RULESET_FILTER, &r, &a, &match); 4613 } 4614 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 4615 PF_RULESET_FILTER, &r, &a, &match)) 4616 break; 4617 } 4618 r = *rm; 4619 a = *am; 4620 ruleset = *rsm; 4621 4622 REASON_SET(&reason, PFRES_MATCH); 4623 4624 if (r->log) 4625 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset, 4626 pd); 4627 4628 if (r->action != PF_PASS) 4629 return (PF_DROP); 4630 4631 if (pf_tag_packet(m, pd->pf_mtag, tag, -1)) { 4632 REASON_SET(&reason, PFRES_MEMORY); 4633 return (PF_DROP); 4634 } 4635 4636 return (PF_PASS); 4637} 4638 4639int 4640pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, 4641 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, 4642 u_short *reason) 4643{ 4644 struct pf_state_cmp key; 4645 struct tcphdr *th = pd->hdr.tcp; 4646 u_int16_t win = ntohs(th->th_win); 4647 u_int32_t ack, end, seq, orig_seq; 4648 u_int8_t sws, dws; 4649 int ackskew; 4650 int copyback = 0; 4651 struct pf_state_peer *src, *dst; 4652 4653 key.af = pd->af; 4654 key.proto = IPPROTO_TCP; 4655 if (direction == PF_IN) { 4656 PF_ACPY(&key.ext.addr, pd->src, key.af); 4657 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 4658 key.ext.port = th->th_sport; 4659 key.gwy.port = th->th_dport; 4660 } else { 4661 PF_ACPY(&key.lan.addr, pd->src, key.af); 4662 PF_ACPY(&key.ext.addr, pd->dst, key.af); 4663 key.lan.port = th->th_sport; 4664 key.ext.port = th->th_dport; 4665 } 4666 4667 STATE_LOOKUP(); 4668 4669 if (direction == (*state)->direction) { 4670 src = &(*state)->src; 4671 dst = &(*state)->dst; 4672 } else { 4673 src = &(*state)->dst; 4674 dst = &(*state)->src; 4675 } 4676 4677 if ((*state)->src.state == PF_TCPS_PROXY_SRC) { 4678 if (direction != (*state)->direction) { 4679 REASON_SET(reason, PFRES_SYNPROXY); 4680 return (PF_SYNPROXY_DROP); 4681 } 4682 if (th->th_flags & TH_SYN) { 4683 if (ntohl(th->th_seq) != (*state)->src.seqlo) { 4684 REASON_SET(reason, PFRES_SYNPROXY); 4685 return (PF_DROP); 4686 } 4687#ifdef __FreeBSD__ 4688 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst, 4689#else 4690 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4691#endif 4692 pd->src, th->th_dport, th->th_sport, 4693 (*state)->src.seqhi, ntohl(th->th_seq) + 1, 4694 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1, 4695 0, NULL, NULL); 4696 REASON_SET(reason, PFRES_SYNPROXY); 4697 return (PF_SYNPROXY_DROP); 4698 } else if (!(th->th_flags & TH_ACK) || 4699 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 4700 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) { 4701 REASON_SET(reason, PFRES_SYNPROXY); 4702 return (PF_DROP); 4703 } else if ((*state)->src_node != NULL && 4704 pf_src_connlimit(state)) { 4705 REASON_SET(reason, PFRES_SRCLIMIT); 4706 return (PF_DROP); 4707 } else 4708 (*state)->src.state = PF_TCPS_PROXY_DST; 4709 } 4710 if ((*state)->src.state == PF_TCPS_PROXY_DST) { 4711 struct pf_state_host *src, *dst; 4712 4713 if (direction == PF_OUT) { 4714 src = &(*state)->gwy; 4715 dst = &(*state)->ext; 4716 } else { 4717 src = &(*state)->ext; 4718 dst = &(*state)->lan; 4719 } 4720 if (direction == (*state)->direction) { 4721 if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) || 4722 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 4723 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) { 4724 REASON_SET(reason, PFRES_SYNPROXY); 4725 return (PF_DROP); 4726 } 4727 (*state)->src.max_win = MAX(ntohs(th->th_win), 1); 4728 if ((*state)->dst.seqhi == 1) 4729 (*state)->dst.seqhi = htonl(arc4random()); 4730#ifdef __FreeBSD__ 4731 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4732 &src->addr, 4733#else 4734 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 4735#endif 4736 &dst->addr, src->port, dst->port, 4737 (*state)->dst.seqhi, 0, TH_SYN, 0, 4738 (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL); 4739 REASON_SET(reason, PFRES_SYNPROXY); 4740 return (PF_SYNPROXY_DROP); 4741 } else if (((th->th_flags & (TH_SYN|TH_ACK)) != 4742 (TH_SYN|TH_ACK)) || 4743 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) { 4744 REASON_SET(reason, PFRES_SYNPROXY); 4745 return (PF_DROP); 4746 } else { 4747 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1); 4748 (*state)->dst.seqlo = ntohl(th->th_seq); 4749#ifdef __FreeBSD__ 4750 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst, 4751#else 4752 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4753#endif 4754 pd->src, th->th_dport, th->th_sport, 4755 ntohl(th->th_ack), ntohl(th->th_seq) + 1, 4756 TH_ACK, (*state)->src.max_win, 0, 0, 0, 4757 (*state)->tag, NULL, NULL); 4758#ifdef __FreeBSD__ 4759 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4760 &src->addr, 4761#else 4762 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 4763#endif 4764 &dst->addr, src->port, dst->port, 4765 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1, 4766 TH_ACK, (*state)->dst.max_win, 0, 0, 1, 4767 0, NULL, NULL); 4768 (*state)->src.seqdiff = (*state)->dst.seqhi - 4769 (*state)->src.seqlo; 4770 (*state)->dst.seqdiff = (*state)->src.seqhi - 4771 (*state)->dst.seqlo; 4772 (*state)->src.seqhi = (*state)->src.seqlo + 4773 (*state)->dst.max_win; 4774 (*state)->dst.seqhi = (*state)->dst.seqlo + 4775 (*state)->src.max_win; 4776 (*state)->src.wscale = (*state)->dst.wscale = 0; 4777 (*state)->src.state = (*state)->dst.state = 4778 TCPS_ESTABLISHED; 4779 REASON_SET(reason, PFRES_SYNPROXY); 4780 return (PF_SYNPROXY_DROP); 4781 } 4782 } 4783 4784 if (((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) && 4785 dst->state >= TCPS_FIN_WAIT_2 && 4786 src->state >= TCPS_FIN_WAIT_2) { 4787 if (pf_status.debug >= PF_DEBUG_MISC) { 4788 printf("pf: state reuse "); 4789 pf_print_state(*state); 4790 pf_print_flags(th->th_flags); 4791 printf("\n"); 4792 } 4793 /* XXX make sure it's the same direction ?? */ 4794 (*state)->src.state = (*state)->dst.state = TCPS_CLOSED; 4795 pf_unlink_state(*state); 4796 *state = NULL; 4797 return (PF_DROP); 4798 } 4799 4800 if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) { 4801 sws = src->wscale & PF_WSCALE_MASK; 4802 dws = dst->wscale & PF_WSCALE_MASK; 4803 } else 4804 sws = dws = 0; 4805 4806 /* 4807 * Sequence tracking algorithm from Guido van Rooij's paper: 4808 * http://www.madison-gurkha.com/publications/tcp_filtering/ 4809 * tcp_filtering.ps 4810 */ 4811 4812 orig_seq = seq = ntohl(th->th_seq); 4813 if (src->seqlo == 0) { 4814 /* First packet from this end. Set its state */ 4815 4816 if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) && 4817 src->scrub == NULL) { 4818 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) { 4819 REASON_SET(reason, PFRES_MEMORY); 4820 return (PF_DROP); 4821 } 4822 } 4823 4824 /* Deferred generation of sequence number modulator */ 4825 if (dst->seqdiff && !src->seqdiff) { 4826#ifdef __FreeBSD__ 4827 while ((src->seqdiff = pf_new_isn(*state) - seq) == 0) 4828 ; 4829#else 4830 while ((src->seqdiff = tcp_rndiss_next() - seq) == 0) 4831 ; 4832#endif 4833 ack = ntohl(th->th_ack) - dst->seqdiff; 4834 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4835 src->seqdiff), 0); 4836 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4837 copyback = 1; 4838 } else { 4839 ack = ntohl(th->th_ack); 4840 } 4841 4842 end = seq + pd->p_len; 4843 if (th->th_flags & TH_SYN) { 4844 end++; 4845 if (dst->wscale & PF_WSCALE_FLAG) { 4846 src->wscale = pf_get_wscale(m, off, th->th_off, 4847 pd->af); 4848 if (src->wscale & PF_WSCALE_FLAG) { 4849 /* Remove scale factor from initial 4850 * window */ 4851 sws = src->wscale & PF_WSCALE_MASK; 4852 win = ((u_int32_t)win + (1 << sws) - 1) 4853 >> sws; 4854 dws = dst->wscale & PF_WSCALE_MASK; 4855 } else { 4856 /* fixup other window */ 4857 dst->max_win <<= dst->wscale & 4858 PF_WSCALE_MASK; 4859 /* in case of a retrans SYN|ACK */ 4860 dst->wscale = 0; 4861 } 4862 } 4863 } 4864 if (th->th_flags & TH_FIN) 4865 end++; 4866 4867 src->seqlo = seq; 4868 if (src->state < TCPS_SYN_SENT) 4869 src->state = TCPS_SYN_SENT; 4870 4871 /* 4872 * May need to slide the window (seqhi may have been set by 4873 * the crappy stack check or if we picked up the connection 4874 * after establishment) 4875 */ 4876 if (src->seqhi == 1 || 4877 SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi)) 4878 src->seqhi = end + MAX(1, dst->max_win << dws); 4879 if (win > src->max_win) 4880 src->max_win = win; 4881 4882 } else { 4883 ack = ntohl(th->th_ack) - dst->seqdiff; 4884 if (src->seqdiff) { 4885 /* Modulate sequence numbers */ 4886 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4887 src->seqdiff), 0); 4888 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4889 copyback = 1; 4890 } 4891 end = seq + pd->p_len; 4892 if (th->th_flags & TH_SYN) 4893 end++; 4894 if (th->th_flags & TH_FIN) 4895 end++; 4896 } 4897 4898 if ((th->th_flags & TH_ACK) == 0) { 4899 /* Let it pass through the ack skew check */ 4900 ack = dst->seqlo; 4901 } else if ((ack == 0 && 4902 (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) || 4903 /* broken tcp stacks do not set ack */ 4904 (dst->state < TCPS_SYN_SENT)) { 4905 /* 4906 * Many stacks (ours included) will set the ACK number in an 4907 * FIN|ACK if the SYN times out -- no sequence to ACK. 4908 */ 4909 ack = dst->seqlo; 4910 } 4911 4912 if (seq == end) { 4913 /* Ease sequencing restrictions on no data packets */ 4914 seq = src->seqlo; 4915 end = seq; 4916 } 4917 4918 ackskew = dst->seqlo - ack; 4919 4920 4921 /* 4922 * Need to demodulate the sequence numbers in any TCP SACK options 4923 * (Selective ACK). We could optionally validate the SACK values 4924 * against the current ACK window, either forwards or backwards, but 4925 * I'm not confident that SACK has been implemented properly 4926 * everywhere. It wouldn't surprise me if several stacks accidently 4927 * SACK too far backwards of previously ACKed data. There really aren't 4928 * any security implications of bad SACKing unless the target stack 4929 * doesn't validate the option length correctly. Someone trying to 4930 * spoof into a TCP connection won't bother blindly sending SACK 4931 * options anyway. 4932 */ 4933 if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) { 4934 if (pf_modulate_sack(m, off, pd, th, dst)) 4935 copyback = 1; 4936 } 4937 4938 4939#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */ 4940 if (SEQ_GEQ(src->seqhi, end) && 4941 /* Last octet inside other's window space */ 4942 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) && 4943 /* Retrans: not more than one window back */ 4944 (ackskew >= -MAXACKWINDOW) && 4945 /* Acking not more than one reassembled fragment backwards */ 4946 (ackskew <= (MAXACKWINDOW << sws)) && 4947 /* Acking not more than one window forward */ 4948 ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo || 4949 (orig_seq == src->seqlo + 1) || (pd->flags & PFDESC_IP_REAS) == 0)) { 4950 /* Require an exact/+1 sequence match on resets when possible */ 4951 4952 if (dst->scrub || src->scrub) { 4953 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 4954 *state, src, dst, ©back)) 4955 return (PF_DROP); 4956 } 4957 4958 /* update max window */ 4959 if (src->max_win < win) 4960 src->max_win = win; 4961 /* synchronize sequencing */ 4962 if (SEQ_GT(end, src->seqlo)) 4963 src->seqlo = end; 4964 /* slide the window of what the other end can send */ 4965 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) 4966 dst->seqhi = ack + MAX((win << sws), 1); 4967 4968 4969 /* update states */ 4970 if (th->th_flags & TH_SYN) 4971 if (src->state < TCPS_SYN_SENT) 4972 src->state = TCPS_SYN_SENT; 4973 if (th->th_flags & TH_FIN) 4974 if (src->state < TCPS_CLOSING) 4975 src->state = TCPS_CLOSING; 4976 if (th->th_flags & TH_ACK) { 4977 if (dst->state == TCPS_SYN_SENT) { 4978 dst->state = TCPS_ESTABLISHED; 4979 if (src->state == TCPS_ESTABLISHED && 4980 (*state)->src_node != NULL && 4981 pf_src_connlimit(state)) { 4982 REASON_SET(reason, PFRES_SRCLIMIT); 4983 return (PF_DROP); 4984 } 4985 } else if (dst->state == TCPS_CLOSING) 4986 dst->state = TCPS_FIN_WAIT_2; 4987 } 4988 if (th->th_flags & TH_RST) 4989 src->state = dst->state = TCPS_TIME_WAIT; 4990 4991 /* update expire time */ 4992 (*state)->expire = time_second; 4993 if (src->state >= TCPS_FIN_WAIT_2 && 4994 dst->state >= TCPS_FIN_WAIT_2) 4995 (*state)->timeout = PFTM_TCP_CLOSED; 4996 else if (src->state >= TCPS_CLOSING && 4997 dst->state >= TCPS_CLOSING) 4998 (*state)->timeout = PFTM_TCP_FIN_WAIT; 4999 else if (src->state < TCPS_ESTABLISHED || 5000 dst->state < TCPS_ESTABLISHED) 5001 (*state)->timeout = PFTM_TCP_OPENING; 5002 else if (src->state >= TCPS_CLOSING || 5003 dst->state >= TCPS_CLOSING) 5004 (*state)->timeout = PFTM_TCP_CLOSING; 5005 else 5006 (*state)->timeout = PFTM_TCP_ESTABLISHED; 5007 5008 /* Fall through to PASS packet */ 5009 5010 } else if ((dst->state < TCPS_SYN_SENT || 5011 dst->state >= TCPS_FIN_WAIT_2 || 5012 src->state >= TCPS_FIN_WAIT_2) && 5013 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) && 5014 /* Within a window forward of the originating packet */ 5015 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) { 5016 /* Within a window backward of the originating packet */ 5017 5018 /* 5019 * This currently handles three situations: 5020 * 1) Stupid stacks will shotgun SYNs before their peer 5021 * replies. 5022 * 2) When PF catches an already established stream (the 5023 * firewall rebooted, the state table was flushed, routes 5024 * changed...) 5025 * 3) Packets get funky immediately after the connection 5026 * closes (this should catch Solaris spurious ACK|FINs 5027 * that web servers like to spew after a close) 5028 * 5029 * This must be a little more careful than the above code 5030 * since packet floods will also be caught here. We don't 5031 * update the TTL here to mitigate the damage of a packet 5032 * flood and so the same code can handle awkward establishment 5033 * and a loosened connection close. 5034 * In the establishment case, a correct peer response will 5035 * validate the connection, go through the normal state code 5036 * and keep updating the state TTL. 5037 */ 5038 5039 if (pf_status.debug >= PF_DEBUG_MISC) { 5040 printf("pf: loose state match: "); 5041 pf_print_state(*state); 5042 pf_print_flags(th->th_flags); 5043 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d " 5044 "pkts=%llu:%llu\n", seq, orig_seq, ack, pd->p_len, 5045#ifdef __FreeBSD__ 5046 ackskew, (unsigned long long)(*state)->packets[0], 5047 (unsigned long long)(*state)->packets[1]); 5048#else 5049 ackskew, (*state)->packets[0], 5050 (*state)->packets[1]); 5051#endif 5052 } 5053 5054 if (dst->scrub || src->scrub) { 5055 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 5056 *state, src, dst, ©back)) 5057 return (PF_DROP); 5058 } 5059 5060 /* update max window */ 5061 if (src->max_win < win) 5062 src->max_win = win; 5063 /* synchronize sequencing */ 5064 if (SEQ_GT(end, src->seqlo)) 5065 src->seqlo = end; 5066 /* slide the window of what the other end can send */ 5067 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) 5068 dst->seqhi = ack + MAX((win << sws), 1); 5069 5070 /* 5071 * Cannot set dst->seqhi here since this could be a shotgunned 5072 * SYN and not an already established connection. 5073 */ 5074 5075 if (th->th_flags & TH_FIN) 5076 if (src->state < TCPS_CLOSING) 5077 src->state = TCPS_CLOSING; 5078 if (th->th_flags & TH_RST) 5079 src->state = dst->state = TCPS_TIME_WAIT; 5080 5081 /* Fall through to PASS packet */ 5082 5083 } else { 5084 if ((*state)->dst.state == TCPS_SYN_SENT && 5085 (*state)->src.state == TCPS_SYN_SENT) { 5086 /* Send RST for state mismatches during handshake */ 5087 if (!(th->th_flags & TH_RST)) 5088#ifdef __FreeBSD__ 5089 pf_send_tcp(m, (*state)->rule.ptr, pd->af, 5090#else 5091 pf_send_tcp((*state)->rule.ptr, pd->af, 5092#endif 5093 pd->dst, pd->src, th->th_dport, 5094 th->th_sport, ntohl(th->th_ack), 0, 5095 TH_RST, 0, 0, 5096 (*state)->rule.ptr->return_ttl, 1, 0, 5097 pd->eh, kif->pfik_ifp); 5098 src->seqlo = 0; 5099 src->seqhi = 1; 5100 src->max_win = 1; 5101 } else if (pf_status.debug >= PF_DEBUG_MISC) { 5102 printf("pf: BAD state: "); 5103 pf_print_state(*state); 5104 pf_print_flags(th->th_flags); 5105 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d " 5106 "pkts=%llu:%llu dir=%s,%s\n", 5107 seq, orig_seq, ack, pd->p_len, ackskew, 5108#ifdef __FreeBSD__ 5109 (unsigned long long)(*state)->packets[0], 5110 (unsigned long long)(*state)->packets[1], 5111#else 5112 (*state)->packets[0], (*state)->packets[1], 5113#endif 5114 direction == PF_IN ? "in" : "out", 5115 direction == (*state)->direction ? "fwd" : "rev"); 5116 printf("pf: State failure on: %c %c %c %c | %c %c\n", 5117 SEQ_GEQ(src->seqhi, end) ? ' ' : '1', 5118 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ? 5119 ' ': '2', 5120 (ackskew >= -MAXACKWINDOW) ? ' ' : '3', 5121 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4', 5122 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5', 5123 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6'); 5124 } 5125 REASON_SET(reason, PFRES_BADSTATE); 5126 return (PF_DROP); 5127 } 5128 5129 /* Any packets which have gotten here are to be passed */ 5130 5131 /* translate source/destination address, if necessary */ 5132 if (STATE_TRANSLATE(*state)) { 5133 if (direction == PF_OUT) 5134 pf_change_ap(pd->src, &th->th_sport, pd->ip_sum, 5135 &th->th_sum, &(*state)->gwy.addr, 5136 (*state)->gwy.port, 0, pd->af); 5137 else 5138 pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, 5139 &th->th_sum, &(*state)->lan.addr, 5140 (*state)->lan.port, 0, pd->af); 5141 m_copyback(m, off, sizeof(*th), (caddr_t)th); 5142 } else if (copyback) { 5143 /* Copyback sequence modulation or stateful scrub changes */ 5144 m_copyback(m, off, sizeof(*th), (caddr_t)th); 5145 } 5146 5147 return (PF_PASS); 5148} 5149 5150int 5151pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, 5152 struct mbuf *m, int off, void *h, struct pf_pdesc *pd) 5153{ 5154 struct pf_state_peer *src, *dst; 5155 struct pf_state_cmp key; 5156 struct udphdr *uh = pd->hdr.udp; 5157 5158 key.af = pd->af; 5159 key.proto = IPPROTO_UDP; 5160 if (direction == PF_IN) { 5161 PF_ACPY(&key.ext.addr, pd->src, key.af); 5162 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 5163 key.ext.port = uh->uh_sport; 5164 key.gwy.port = uh->uh_dport; 5165 } else { 5166 PF_ACPY(&key.lan.addr, pd->src, key.af); 5167 PF_ACPY(&key.ext.addr, pd->dst, key.af); 5168 key.lan.port = uh->uh_sport; 5169 key.ext.port = uh->uh_dport; 5170 } 5171 5172 STATE_LOOKUP(); 5173 5174 if (direction == (*state)->direction) { 5175 src = &(*state)->src; 5176 dst = &(*state)->dst; 5177 } else { 5178 src = &(*state)->dst; 5179 dst = &(*state)->src; 5180 } 5181 5182 /* update states */ 5183 if (src->state < PFUDPS_SINGLE) 5184 src->state = PFUDPS_SINGLE; 5185 if (dst->state == PFUDPS_SINGLE) 5186 dst->state = PFUDPS_MULTIPLE; 5187 5188 /* update expire time */ 5189 (*state)->expire = time_second; 5190 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE) 5191 (*state)->timeout = PFTM_UDP_MULTIPLE; 5192 else 5193 (*state)->timeout = PFTM_UDP_SINGLE; 5194 5195 /* translate source/destination address, if necessary */ 5196 if (STATE_TRANSLATE(*state)) { 5197 if (direction == PF_OUT) 5198 pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum, 5199 &uh->uh_sum, &(*state)->gwy.addr, 5200 (*state)->gwy.port, 1, pd->af); 5201 else 5202 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, 5203 &uh->uh_sum, &(*state)->lan.addr, 5204 (*state)->lan.port, 1, pd->af); 5205 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 5206 } 5207 5208 return (PF_PASS); 5209} 5210 5211int 5212pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, 5213 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason) 5214{ 5215 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 5216 u_int16_t icmpid = 0; /* make the compiler happy */ 5217 u_int16_t *icmpsum = NULL; /* make the compiler happy */ 5218 u_int8_t icmptype = 0; /* make the compiler happy */ 5219 int state_icmp = 0; 5220 struct pf_state_cmp key; 5221 5222 switch (pd->proto) { 5223#ifdef INET 5224 case IPPROTO_ICMP: 5225 icmptype = pd->hdr.icmp->icmp_type; 5226 icmpid = pd->hdr.icmp->icmp_id; 5227 icmpsum = &pd->hdr.icmp->icmp_cksum; 5228 5229 if (icmptype == ICMP_UNREACH || 5230 icmptype == ICMP_SOURCEQUENCH || 5231 icmptype == ICMP_REDIRECT || 5232 icmptype == ICMP_TIMXCEED || 5233 icmptype == ICMP_PARAMPROB) 5234 state_icmp++; 5235 break; 5236#endif /* INET */ 5237#ifdef INET6 5238 case IPPROTO_ICMPV6: 5239 icmptype = pd->hdr.icmp6->icmp6_type; 5240 icmpid = pd->hdr.icmp6->icmp6_id; 5241 icmpsum = &pd->hdr.icmp6->icmp6_cksum; 5242 5243 if (icmptype == ICMP6_DST_UNREACH || 5244 icmptype == ICMP6_PACKET_TOO_BIG || 5245 icmptype == ICMP6_TIME_EXCEEDED || 5246 icmptype == ICMP6_PARAM_PROB) 5247 state_icmp++; 5248 break; 5249#endif /* INET6 */ 5250 } 5251 5252 if (!state_icmp) { 5253 5254 /* 5255 * ICMP query/reply message not related to a TCP/UDP packet. 5256 * Search for an ICMP state. 5257 */ 5258 key.af = pd->af; 5259 key.proto = pd->proto; 5260 if (direction == PF_IN) { 5261 PF_ACPY(&key.ext.addr, pd->src, key.af); 5262 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 5263 key.ext.port = 0; 5264 key.gwy.port = icmpid; 5265 } else { 5266 PF_ACPY(&key.lan.addr, pd->src, key.af); 5267 PF_ACPY(&key.ext.addr, pd->dst, key.af); 5268 key.lan.port = icmpid; 5269 key.ext.port = 0; 5270 } 5271 5272 STATE_LOOKUP(); 5273 5274 (*state)->expire = time_second; 5275 (*state)->timeout = PFTM_ICMP_ERROR_REPLY; 5276 5277 /* translate source/destination address, if necessary */ 5278 if (STATE_TRANSLATE(*state)) { 5279 if (direction == PF_OUT) { 5280 switch (pd->af) { 5281#ifdef INET 5282 case AF_INET: 5283 pf_change_a(&saddr->v4.s_addr, 5284 pd->ip_sum, 5285 (*state)->gwy.addr.v4.s_addr, 0); 5286 pd->hdr.icmp->icmp_cksum = 5287 pf_cksum_fixup( 5288 pd->hdr.icmp->icmp_cksum, icmpid, 5289 (*state)->gwy.port, 0); 5290 pd->hdr.icmp->icmp_id = 5291 (*state)->gwy.port; 5292 m_copyback(m, off, ICMP_MINLEN, 5293 (caddr_t)pd->hdr.icmp); 5294 break; 5295#endif /* INET */ 5296#ifdef INET6 5297 case AF_INET6: 5298 pf_change_a6(saddr, 5299 &pd->hdr.icmp6->icmp6_cksum, 5300 &(*state)->gwy.addr, 0); 5301 m_copyback(m, off, 5302 sizeof(struct icmp6_hdr), 5303 (caddr_t)pd->hdr.icmp6); 5304 break; 5305#endif /* INET6 */ 5306 } 5307 } else { 5308 switch (pd->af) { 5309#ifdef INET 5310 case AF_INET: 5311 pf_change_a(&daddr->v4.s_addr, 5312 pd->ip_sum, 5313 (*state)->lan.addr.v4.s_addr, 0); 5314 pd->hdr.icmp->icmp_cksum = 5315 pf_cksum_fixup( 5316 pd->hdr.icmp->icmp_cksum, icmpid, 5317 (*state)->lan.port, 0); 5318 pd->hdr.icmp->icmp_id = 5319 (*state)->lan.port; 5320 m_copyback(m, off, ICMP_MINLEN, 5321 (caddr_t)pd->hdr.icmp); 5322 break; 5323#endif /* INET */ 5324#ifdef INET6 5325 case AF_INET6: 5326 pf_change_a6(daddr, 5327 &pd->hdr.icmp6->icmp6_cksum, 5328 &(*state)->lan.addr, 0); 5329 m_copyback(m, off, 5330 sizeof(struct icmp6_hdr), 5331 (caddr_t)pd->hdr.icmp6); 5332 break; 5333#endif /* INET6 */ 5334 } 5335 } 5336 } 5337 5338 return (PF_PASS); 5339 5340 } else { 5341 /* 5342 * ICMP error message in response to a TCP/UDP packet. 5343 * Extract the inner TCP/UDP header and search for that state. 5344 */ 5345 5346 struct pf_pdesc pd2; 5347#ifdef INET 5348 struct ip h2; 5349#endif /* INET */ 5350#ifdef INET6 5351 struct ip6_hdr h2_6; 5352 int terminal = 0; 5353#endif /* INET6 */ 5354 int ipoff2 = 0; /* make the compiler happy */ 5355 int off2 = 0; /* make the compiler happy */ 5356 5357 pd2.af = pd->af; 5358 switch (pd->af) { 5359#ifdef INET 5360 case AF_INET: 5361 /* offset of h2 in mbuf chain */ 5362 ipoff2 = off + ICMP_MINLEN; 5363 5364 if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2), 5365 NULL, reason, pd2.af)) { 5366 DPFPRINTF(PF_DEBUG_MISC, 5367 ("pf: ICMP error message too short " 5368 "(ip)\n")); 5369 return (PF_DROP); 5370 } 5371 /* 5372 * ICMP error messages don't refer to non-first 5373 * fragments 5374 */ 5375 if (h2.ip_off & htons(IP_OFFMASK)) { 5376 REASON_SET(reason, PFRES_FRAG); 5377 return (PF_DROP); 5378 } 5379 5380 /* offset of protocol header that follows h2 */ 5381 off2 = ipoff2 + (h2.ip_hl << 2); 5382 5383 pd2.proto = h2.ip_p; 5384 pd2.src = (struct pf_addr *)&h2.ip_src; 5385 pd2.dst = (struct pf_addr *)&h2.ip_dst; 5386 pd2.ip_sum = &h2.ip_sum; 5387 break; 5388#endif /* INET */ 5389#ifdef INET6 5390 case AF_INET6: 5391 ipoff2 = off + sizeof(struct icmp6_hdr); 5392 5393 if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6), 5394 NULL, reason, pd2.af)) { 5395 DPFPRINTF(PF_DEBUG_MISC, 5396 ("pf: ICMP error message too short " 5397 "(ip6)\n")); 5398 return (PF_DROP); 5399 } 5400 pd2.proto = h2_6.ip6_nxt; 5401 pd2.src = (struct pf_addr *)&h2_6.ip6_src; 5402 pd2.dst = (struct pf_addr *)&h2_6.ip6_dst; 5403 pd2.ip_sum = NULL; 5404 off2 = ipoff2 + sizeof(h2_6); 5405 do { 5406 switch (pd2.proto) { 5407 case IPPROTO_FRAGMENT: 5408 /* 5409 * ICMPv6 error messages for 5410 * non-first fragments 5411 */ 5412 REASON_SET(reason, PFRES_FRAG); 5413 return (PF_DROP); 5414 case IPPROTO_AH: 5415 case IPPROTO_HOPOPTS: 5416 case IPPROTO_ROUTING: 5417 case IPPROTO_DSTOPTS: { 5418 /* get next header and header length */ 5419 struct ip6_ext opt6; 5420 5421 if (!pf_pull_hdr(m, off2, &opt6, 5422 sizeof(opt6), NULL, reason, 5423 pd2.af)) { 5424 DPFPRINTF(PF_DEBUG_MISC, 5425 ("pf: ICMPv6 short opt\n")); 5426 return (PF_DROP); 5427 } 5428 if (pd2.proto == IPPROTO_AH) 5429 off2 += (opt6.ip6e_len + 2) * 4; 5430 else 5431 off2 += (opt6.ip6e_len + 1) * 8; 5432 pd2.proto = opt6.ip6e_nxt; 5433 /* goto the next header */ 5434 break; 5435 } 5436 default: 5437 terminal++; 5438 break; 5439 } 5440 } while (!terminal); 5441 break; 5442#endif /* INET6 */ 5443#ifdef __FreeBSD__ 5444 default: 5445 panic("AF not supported: %d", pd->af); 5446#endif 5447 } 5448 5449 switch (pd2.proto) { 5450 case IPPROTO_TCP: { 5451 struct tcphdr th; 5452 u_int32_t seq; 5453 struct pf_state_peer *src, *dst; 5454 u_int8_t dws; 5455 int copyback = 0; 5456 5457 /* 5458 * Only the first 8 bytes of the TCP header can be 5459 * expected. Don't access any TCP header fields after 5460 * th_seq, an ackskew test is not possible. 5461 */ 5462 if (!pf_pull_hdr(m, off2, &th, 8, NULL, reason, 5463 pd2.af)) { 5464 DPFPRINTF(PF_DEBUG_MISC, 5465 ("pf: ICMP error message too short " 5466 "(tcp)\n")); 5467 return (PF_DROP); 5468 } 5469 5470 key.af = pd2.af; 5471 key.proto = IPPROTO_TCP; 5472 if (direction == PF_IN) { 5473 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 5474 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 5475 key.ext.port = th.th_dport; 5476 key.gwy.port = th.th_sport; 5477 } else { 5478 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 5479 PF_ACPY(&key.ext.addr, pd2.src, key.af); 5480 key.lan.port = th.th_dport; 5481 key.ext.port = th.th_sport; 5482 } 5483 5484 STATE_LOOKUP(); 5485 5486 if (direction == (*state)->direction) { 5487 src = &(*state)->dst; 5488 dst = &(*state)->src; 5489 } else { 5490 src = &(*state)->src; 5491 dst = &(*state)->dst; 5492 } 5493 5494 if (src->wscale && dst->wscale) 5495 dws = dst->wscale & PF_WSCALE_MASK; 5496 else 5497 dws = 0; 5498 5499 /* Demodulate sequence number */ 5500 seq = ntohl(th.th_seq) - src->seqdiff; 5501 if (src->seqdiff) { 5502 pf_change_a(&th.th_seq, icmpsum, 5503 htonl(seq), 0); 5504 copyback = 1; 5505 } 5506 5507 if (!SEQ_GEQ(src->seqhi, seq) || 5508 !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws))) { 5509 if (pf_status.debug >= PF_DEBUG_MISC) { 5510 printf("pf: BAD ICMP %d:%d ", 5511 icmptype, pd->hdr.icmp->icmp_code); 5512 pf_print_host(pd->src, 0, pd->af); 5513 printf(" -> "); 5514 pf_print_host(pd->dst, 0, pd->af); 5515 printf(" state: "); 5516 pf_print_state(*state); 5517 printf(" seq=%u\n", seq); 5518 } 5519 REASON_SET(reason, PFRES_BADSTATE); 5520 return (PF_DROP); 5521 } 5522 5523 if (STATE_TRANSLATE(*state)) { 5524 if (direction == PF_IN) { 5525 pf_change_icmp(pd2.src, &th.th_sport, 5526 daddr, &(*state)->lan.addr, 5527 (*state)->lan.port, NULL, 5528 pd2.ip_sum, icmpsum, 5529 pd->ip_sum, 0, pd2.af); 5530 } else { 5531 pf_change_icmp(pd2.dst, &th.th_dport, 5532 saddr, &(*state)->gwy.addr, 5533 (*state)->gwy.port, NULL, 5534 pd2.ip_sum, icmpsum, 5535 pd->ip_sum, 0, pd2.af); 5536 } 5537 copyback = 1; 5538 } 5539 5540 if (copyback) { 5541 switch (pd2.af) { 5542#ifdef INET 5543 case AF_INET: 5544 m_copyback(m, off, ICMP_MINLEN, 5545 (caddr_t)pd->hdr.icmp); 5546 m_copyback(m, ipoff2, sizeof(h2), 5547 (caddr_t)&h2); 5548 break; 5549#endif /* INET */ 5550#ifdef INET6 5551 case AF_INET6: 5552 m_copyback(m, off, 5553 sizeof(struct icmp6_hdr), 5554 (caddr_t)pd->hdr.icmp6); 5555 m_copyback(m, ipoff2, sizeof(h2_6), 5556 (caddr_t)&h2_6); 5557 break; 5558#endif /* INET6 */ 5559 } 5560 m_copyback(m, off2, 8, (caddr_t)&th); 5561 } 5562 5563 return (PF_PASS); 5564 break; 5565 } 5566 case IPPROTO_UDP: { 5567 struct udphdr uh; 5568 5569 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh), 5570 NULL, reason, pd2.af)) { 5571 DPFPRINTF(PF_DEBUG_MISC, 5572 ("pf: ICMP error message too short " 5573 "(udp)\n")); 5574 return (PF_DROP); 5575 } 5576 5577 key.af = pd2.af; 5578 key.proto = IPPROTO_UDP; 5579 if (direction == PF_IN) { 5580 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 5581 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 5582 key.ext.port = uh.uh_dport; 5583 key.gwy.port = uh.uh_sport; 5584 } else { 5585 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 5586 PF_ACPY(&key.ext.addr, pd2.src, key.af); 5587 key.lan.port = uh.uh_dport; 5588 key.ext.port = uh.uh_sport; 5589 } 5590 5591 STATE_LOOKUP(); 5592 5593 if (STATE_TRANSLATE(*state)) { 5594 if (direction == PF_IN) { 5595 pf_change_icmp(pd2.src, &uh.uh_sport, 5596 daddr, &(*state)->lan.addr, 5597 (*state)->lan.port, &uh.uh_sum, 5598 pd2.ip_sum, icmpsum, 5599 pd->ip_sum, 1, pd2.af); 5600 } else { 5601 pf_change_icmp(pd2.dst, &uh.uh_dport, 5602 saddr, &(*state)->gwy.addr, 5603 (*state)->gwy.port, &uh.uh_sum, 5604 pd2.ip_sum, icmpsum, 5605 pd->ip_sum, 1, pd2.af); 5606 } 5607 switch (pd2.af) { 5608#ifdef INET 5609 case AF_INET: 5610 m_copyback(m, off, ICMP_MINLEN, 5611 (caddr_t)pd->hdr.icmp); 5612 m_copyback(m, ipoff2, sizeof(h2), 5613 (caddr_t)&h2); 5614 break; 5615#endif /* INET */ 5616#ifdef INET6 5617 case AF_INET6: 5618 m_copyback(m, off, 5619 sizeof(struct icmp6_hdr), 5620 (caddr_t)pd->hdr.icmp6); 5621 m_copyback(m, ipoff2, sizeof(h2_6), 5622 (caddr_t)&h2_6); 5623 break; 5624#endif /* INET6 */ 5625 } 5626 m_copyback(m, off2, sizeof(uh), 5627 (caddr_t)&uh); 5628 } 5629 5630 return (PF_PASS); 5631 break; 5632 } 5633#ifdef INET 5634 case IPPROTO_ICMP: { 5635 struct icmp iih; 5636 5637 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN, 5638 NULL, reason, pd2.af)) { 5639 DPFPRINTF(PF_DEBUG_MISC, 5640 ("pf: ICMP error message too short i" 5641 "(icmp)\n")); 5642 return (PF_DROP); 5643 } 5644 5645 key.af = pd2.af; 5646 key.proto = IPPROTO_ICMP; 5647 if (direction == PF_IN) { 5648 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 5649 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 5650 key.ext.port = 0; 5651 key.gwy.port = iih.icmp_id; 5652 } else { 5653 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 5654 PF_ACPY(&key.ext.addr, pd2.src, key.af); 5655 key.lan.port = iih.icmp_id; 5656 key.ext.port = 0; 5657 } 5658 5659 STATE_LOOKUP(); 5660 5661 if (STATE_TRANSLATE(*state)) { 5662 if (direction == PF_IN) { 5663 pf_change_icmp(pd2.src, &iih.icmp_id, 5664 daddr, &(*state)->lan.addr, 5665 (*state)->lan.port, NULL, 5666 pd2.ip_sum, icmpsum, 5667 pd->ip_sum, 0, AF_INET); 5668 } else { 5669 pf_change_icmp(pd2.dst, &iih.icmp_id, 5670 saddr, &(*state)->gwy.addr, 5671 (*state)->gwy.port, NULL, 5672 pd2.ip_sum, icmpsum, 5673 pd->ip_sum, 0, AF_INET); 5674 } 5675 m_copyback(m, off, ICMP_MINLEN, 5676 (caddr_t)pd->hdr.icmp); 5677 m_copyback(m, ipoff2, sizeof(h2), 5678 (caddr_t)&h2); 5679 m_copyback(m, off2, ICMP_MINLEN, 5680 (caddr_t)&iih); 5681 } 5682 5683 return (PF_PASS); 5684 break; 5685 } 5686#endif /* INET */ 5687#ifdef INET6 5688 case IPPROTO_ICMPV6: { 5689 struct icmp6_hdr iih; 5690 5691 if (!pf_pull_hdr(m, off2, &iih, 5692 sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) { 5693 DPFPRINTF(PF_DEBUG_MISC, 5694 ("pf: ICMP error message too short " 5695 "(icmp6)\n")); 5696 return (PF_DROP); 5697 } 5698 5699 key.af = pd2.af; 5700 key.proto = IPPROTO_ICMPV6; 5701 if (direction == PF_IN) { 5702 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 5703 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 5704 key.ext.port = 0; 5705 key.gwy.port = iih.icmp6_id; 5706 } else { 5707 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 5708 PF_ACPY(&key.ext.addr, pd2.src, key.af); 5709 key.lan.port = iih.icmp6_id; 5710 key.ext.port = 0; 5711 } 5712 5713 STATE_LOOKUP(); 5714 5715 if (STATE_TRANSLATE(*state)) { 5716 if (direction == PF_IN) { 5717 pf_change_icmp(pd2.src, &iih.icmp6_id, 5718 daddr, &(*state)->lan.addr, 5719 (*state)->lan.port, NULL, 5720 pd2.ip_sum, icmpsum, 5721 pd->ip_sum, 0, AF_INET6); 5722 } else { 5723 pf_change_icmp(pd2.dst, &iih.icmp6_id, 5724 saddr, &(*state)->gwy.addr, 5725 (*state)->gwy.port, NULL, 5726 pd2.ip_sum, icmpsum, 5727 pd->ip_sum, 0, AF_INET6); 5728 } 5729 m_copyback(m, off, sizeof(struct icmp6_hdr), 5730 (caddr_t)pd->hdr.icmp6); 5731 m_copyback(m, ipoff2, sizeof(h2_6), 5732 (caddr_t)&h2_6); 5733 m_copyback(m, off2, sizeof(struct icmp6_hdr), 5734 (caddr_t)&iih); 5735 } 5736 5737 return (PF_PASS); 5738 break; 5739 } 5740#endif /* INET6 */ 5741 default: { 5742 key.af = pd2.af; 5743 key.proto = pd2.proto; 5744 if (direction == PF_IN) { 5745 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 5746 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 5747 key.ext.port = 0; 5748 key.gwy.port = 0; 5749 } else { 5750 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 5751 PF_ACPY(&key.ext.addr, pd2.src, key.af); 5752 key.lan.port = 0; 5753 key.ext.port = 0; 5754 } 5755 5756 STATE_LOOKUP(); 5757 5758 if (STATE_TRANSLATE(*state)) { 5759 if (direction == PF_IN) { 5760 pf_change_icmp(pd2.src, NULL, 5761 daddr, &(*state)->lan.addr, 5762 0, NULL, 5763 pd2.ip_sum, icmpsum, 5764 pd->ip_sum, 0, pd2.af); 5765 } else { 5766 pf_change_icmp(pd2.dst, NULL, 5767 saddr, &(*state)->gwy.addr, 5768 0, NULL, 5769 pd2.ip_sum, icmpsum, 5770 pd->ip_sum, 0, pd2.af); 5771 } 5772 switch (pd2.af) { 5773#ifdef INET 5774 case AF_INET: 5775 m_copyback(m, off, ICMP_MINLEN, 5776 (caddr_t)pd->hdr.icmp); 5777 m_copyback(m, ipoff2, sizeof(h2), 5778 (caddr_t)&h2); 5779 break; 5780#endif /* INET */ 5781#ifdef INET6 5782 case AF_INET6: 5783 m_copyback(m, off, 5784 sizeof(struct icmp6_hdr), 5785 (caddr_t)pd->hdr.icmp6); 5786 m_copyback(m, ipoff2, sizeof(h2_6), 5787 (caddr_t)&h2_6); 5788 break; 5789#endif /* INET6 */ 5790 } 5791 } 5792 5793 return (PF_PASS); 5794 break; 5795 } 5796 } 5797 } 5798} 5799 5800int 5801pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, 5802 struct pf_pdesc *pd) 5803{ 5804 struct pf_state_peer *src, *dst; 5805 struct pf_state_cmp key; 5806 5807 key.af = pd->af; 5808 key.proto = pd->proto; 5809 if (direction == PF_IN) { 5810 PF_ACPY(&key.ext.addr, pd->src, key.af); 5811 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 5812 key.ext.port = 0; 5813 key.gwy.port = 0; 5814 } else { 5815 PF_ACPY(&key.lan.addr, pd->src, key.af); 5816 PF_ACPY(&key.ext.addr, pd->dst, key.af); 5817 key.lan.port = 0; 5818 key.ext.port = 0; 5819 } 5820 5821 STATE_LOOKUP(); 5822 5823 if (direction == (*state)->direction) { 5824 src = &(*state)->src; 5825 dst = &(*state)->dst; 5826 } else { 5827 src = &(*state)->dst; 5828 dst = &(*state)->src; 5829 } 5830 5831 /* update states */ 5832 if (src->state < PFOTHERS_SINGLE) 5833 src->state = PFOTHERS_SINGLE; 5834 if (dst->state == PFOTHERS_SINGLE) 5835 dst->state = PFOTHERS_MULTIPLE; 5836 5837 /* update expire time */ 5838 (*state)->expire = time_second; 5839 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE) 5840 (*state)->timeout = PFTM_OTHER_MULTIPLE; 5841 else 5842 (*state)->timeout = PFTM_OTHER_SINGLE; 5843 5844 /* translate source/destination address, if necessary */ 5845 if (STATE_TRANSLATE(*state)) { 5846 if (direction == PF_OUT) 5847 switch (pd->af) { 5848#ifdef INET 5849 case AF_INET: 5850 pf_change_a(&pd->src->v4.s_addr, 5851 pd->ip_sum, (*state)->gwy.addr.v4.s_addr, 5852 0); 5853 break; 5854#endif /* INET */ 5855#ifdef INET6 5856 case AF_INET6: 5857 PF_ACPY(pd->src, &(*state)->gwy.addr, pd->af); 5858 break; 5859#endif /* INET6 */ 5860 } 5861 else 5862 switch (pd->af) { 5863#ifdef INET 5864 case AF_INET: 5865 pf_change_a(&pd->dst->v4.s_addr, 5866 pd->ip_sum, (*state)->lan.addr.v4.s_addr, 5867 0); 5868 break; 5869#endif /* INET */ 5870#ifdef INET6 5871 case AF_INET6: 5872 PF_ACPY(pd->dst, &(*state)->lan.addr, pd->af); 5873 break; 5874#endif /* INET6 */ 5875 } 5876 } 5877 5878 return (PF_PASS); 5879} 5880 5881/* 5882 * ipoff and off are measured from the start of the mbuf chain. 5883 * h must be at "ipoff" on the mbuf chain. 5884 */ 5885void * 5886pf_pull_hdr(struct mbuf *m, int off, void *p, int len, 5887 u_short *actionp, u_short *reasonp, sa_family_t af) 5888{ 5889 switch (af) { 5890#ifdef INET 5891 case AF_INET: { 5892 struct ip *h = mtod(m, struct ip *); 5893 u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3; 5894 5895 if (fragoff) { 5896 if (fragoff >= len) 5897 ACTION_SET(actionp, PF_PASS); 5898 else { 5899 ACTION_SET(actionp, PF_DROP); 5900 REASON_SET(reasonp, PFRES_FRAG); 5901 } 5902 return (NULL); 5903 } 5904 if (m->m_pkthdr.len < off + len || 5905 ntohs(h->ip_len) < off + len) { 5906 ACTION_SET(actionp, PF_DROP); 5907 REASON_SET(reasonp, PFRES_SHORT); 5908 return (NULL); 5909 } 5910 break; 5911 } 5912#endif /* INET */ 5913#ifdef INET6 5914 case AF_INET6: { 5915 struct ip6_hdr *h = mtod(m, struct ip6_hdr *); 5916 5917 if (m->m_pkthdr.len < off + len || 5918 (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) < 5919 (unsigned)(off + len)) { 5920 ACTION_SET(actionp, PF_DROP); 5921 REASON_SET(reasonp, PFRES_SHORT); 5922 return (NULL); 5923 } 5924 break; 5925 } 5926#endif /* INET6 */ 5927 } 5928 m_copydata(m, off, len, p); 5929 return (p); 5930} 5931 5932int 5933pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif) 5934{ 5935 struct sockaddr_in *dst; 5936 int ret = 1; 5937 int check_mpath; 5938#ifndef __FreeBSD__ 5939 extern int ipmultipath; 5940#endif 5941#ifdef INET6 5942#ifndef __FreeBSD__ 5943 extern int ip6_multipath; 5944#endif 5945 struct sockaddr_in6 *dst6; 5946 struct route_in6 ro; 5947#else 5948 struct route ro; 5949#endif 5950 struct radix_node *rn; 5951 struct rtentry *rt; 5952 struct ifnet *ifp; 5953 5954 check_mpath = 0; 5955 bzero(&ro, sizeof(ro)); 5956 switch (af) { 5957 case AF_INET: 5958 dst = satosin(&ro.ro_dst); 5959 dst->sin_family = AF_INET; 5960 dst->sin_len = sizeof(*dst); 5961 dst->sin_addr = addr->v4; 5962#ifndef __FreeBSD__ /* MULTIPATH_ROUTING */ 5963 if (ipmultipath) 5964 check_mpath = 1; 5965#endif 5966 break; 5967#ifdef INET6 5968 case AF_INET6: 5969 dst6 = (struct sockaddr_in6 *)&ro.ro_dst; 5970 dst6->sin6_family = AF_INET6; 5971 dst6->sin6_len = sizeof(*dst6); 5972 dst6->sin6_addr = addr->v6; 5973#ifndef __FreeBSD__ /* MULTIPATH_ROUTING */ 5974 if (ip6_multipath) 5975 check_mpath = 1; 5976#endif 5977 break; 5978#endif /* INET6 */ 5979 default: 5980 return (0); 5981 } 5982 5983 /* Skip checks for ipsec interfaces */ 5984 if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC) 5985 goto out; 5986 5987#ifdef __FreeBSD__ 5988/* XXX MRT not always INET */ /* stick with table 0 though */ 5989 if (af == AF_INET) 5990 in_rtalloc_ign((struct route *)&ro, RTF_CLONING, 0); 5991 else 5992 rtalloc_ign((struct route *)&ro, RTF_CLONING); 5993#else /* ! __FreeBSD__ */ 5994 rtalloc_noclone((struct route *)&ro, NO_CLONING); 5995#endif 5996 5997 if (ro.ro_rt != NULL) { 5998 /* No interface given, this is a no-route check */ 5999 if (kif == NULL) 6000 goto out; 6001 6002 if (kif->pfik_ifp == NULL) { 6003 ret = 0; 6004 goto out; 6005 } 6006 6007 /* Perform uRPF check if passed input interface */ 6008 ret = 0; 6009 rn = (struct radix_node *)ro.ro_rt; 6010 do { 6011 rt = (struct rtentry *)rn; 6012#ifndef __FreeBSD__ /* CARPDEV */ 6013 if (rt->rt_ifp->if_type == IFT_CARP) 6014 ifp = rt->rt_ifp->if_carpdev; 6015 else 6016#endif 6017 ifp = rt->rt_ifp; 6018 6019 if (kif->pfik_ifp == ifp) 6020 ret = 1; 6021#ifdef __FreeBSD__ /* MULTIPATH_ROUTING */ 6022 rn = NULL; 6023#else 6024 rn = rn_mpath_next(rn); 6025#endif 6026 } while (check_mpath == 1 && rn != NULL && ret == 0); 6027 } else 6028 ret = 0; 6029out: 6030 if (ro.ro_rt != NULL) 6031 RTFREE(ro.ro_rt); 6032 return (ret); 6033} 6034 6035int 6036pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw) 6037{ 6038 struct sockaddr_in *dst; 6039#ifdef INET6 6040 struct sockaddr_in6 *dst6; 6041 struct route_in6 ro; 6042#else 6043 struct route ro; 6044#endif 6045 int ret = 0; 6046 6047 bzero(&ro, sizeof(ro)); 6048 switch (af) { 6049 case AF_INET: 6050 dst = satosin(&ro.ro_dst); 6051 dst->sin_family = AF_INET; 6052 dst->sin_len = sizeof(*dst); 6053 dst->sin_addr = addr->v4; 6054 break; 6055#ifdef INET6 6056 case AF_INET6: 6057 dst6 = (struct sockaddr_in6 *)&ro.ro_dst; 6058 dst6->sin6_family = AF_INET6; 6059 dst6->sin6_len = sizeof(*dst6); 6060 dst6->sin6_addr = addr->v6; 6061 break; 6062#endif /* INET6 */ 6063 default: 6064 return (0); 6065 } 6066 6067#ifdef __FreeBSD__ 6068# ifdef RTF_PRCLONING 6069 rtalloc_ign((struct route *)&ro, (RTF_CLONING|RTF_PRCLONING)); 6070# else /* !RTF_PRCLONING */ 6071 if (af == AF_INET) 6072 in_rtalloc_ign((struct route *)&ro, RTF_CLONING, 0); 6073 else 6074 rtalloc_ign((struct route *)&ro, RTF_CLONING); 6075# endif 6076#else /* ! __FreeBSD__ */ 6077 rtalloc_noclone((struct route *)&ro, NO_CLONING); 6078#endif 6079 6080 if (ro.ro_rt != NULL) { 6081#ifdef __FreeBSD__ 6082 /* XXX_IMPORT: later */ 6083#else 6084 if (ro.ro_rt->rt_labelid == aw->v.rtlabel) 6085 ret = 1; 6086#endif 6087 RTFREE(ro.ro_rt); 6088 } 6089 6090 return (ret); 6091} 6092 6093#ifdef INET 6094 6095void 6096pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 6097 struct pf_state *s, struct pf_pdesc *pd) 6098{ 6099 struct mbuf *m0, *m1; 6100 struct route iproute; 6101 struct route *ro = NULL; 6102 struct sockaddr_in *dst; 6103 struct ip *ip; 6104 struct ifnet *ifp = NULL; 6105 struct pf_addr naddr; 6106 struct pf_src_node *sn = NULL; 6107 int error = 0; 6108#ifdef __FreeBSD__ 6109 int sw_csum; 6110#endif 6111#ifdef IPSEC 6112 struct m_tag *mtag; 6113#endif /* IPSEC */ 6114 6115 if (m == NULL || *m == NULL || r == NULL || 6116 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 6117 panic("pf_route: invalid parameters"); 6118 6119 if (pd->pf_mtag->routed++ > 3) { 6120 m0 = *m; 6121 *m = NULL; 6122 goto bad; 6123 } 6124 6125 if (r->rt == PF_DUPTO) { 6126#ifdef __FreeBSD__ 6127 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 6128#else 6129 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 6130#endif 6131 return; 6132 } else { 6133 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 6134 return; 6135 m0 = *m; 6136 } 6137 6138 if (m0->m_len < sizeof(struct ip)) { 6139 DPFPRINTF(PF_DEBUG_URGENT, 6140 ("pf_route: m0->m_len < sizeof(struct ip)\n")); 6141 goto bad; 6142 } 6143 6144 ip = mtod(m0, struct ip *); 6145 6146 ro = &iproute; 6147 bzero((caddr_t)ro, sizeof(*ro)); 6148 dst = satosin(&ro->ro_dst); 6149 dst->sin_family = AF_INET; 6150 dst->sin_len = sizeof(*dst); 6151 dst->sin_addr = ip->ip_dst; 6152 6153 if (r->rt == PF_FASTROUTE) { 6154 in_rtalloc(ro, 0); 6155 if (ro->ro_rt == 0) { 6156 V_ipstat.ips_noroute++; 6157 goto bad; 6158 } 6159 6160 ifp = ro->ro_rt->rt_ifp; 6161 ro->ro_rt->rt_use++; 6162 6163 if (ro->ro_rt->rt_flags & RTF_GATEWAY) 6164 dst = satosin(ro->ro_rt->rt_gateway); 6165 } else { 6166 if (TAILQ_EMPTY(&r->rpool.list)) { 6167 DPFPRINTF(PF_DEBUG_URGENT, 6168 ("pf_route: TAILQ_EMPTY(&r->rpool.list)\n")); 6169 goto bad; 6170 } 6171 if (s == NULL) { 6172 pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src, 6173 &naddr, NULL, &sn); 6174 if (!PF_AZERO(&naddr, AF_INET)) 6175 dst->sin_addr.s_addr = naddr.v4.s_addr; 6176 ifp = r->rpool.cur->kif ? 6177 r->rpool.cur->kif->pfik_ifp : NULL; 6178 } else { 6179 if (!PF_AZERO(&s->rt_addr, AF_INET)) 6180 dst->sin_addr.s_addr = 6181 s->rt_addr.v4.s_addr; 6182 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; 6183 } 6184 } 6185 if (ifp == NULL) 6186 goto bad; 6187 6188 if (oifp != ifp) { 6189#ifdef __FreeBSD__ 6190 PF_UNLOCK(); 6191 if (pf_test(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) { 6192 PF_LOCK(); 6193 goto bad; 6194 } else if (m0 == NULL) { 6195 PF_LOCK(); 6196 goto done; 6197 } 6198 PF_LOCK(); 6199#else 6200 if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS) 6201 goto bad; 6202 else if (m0 == NULL) 6203 goto done; 6204#endif 6205 if (m0->m_len < sizeof(struct ip)) { 6206 DPFPRINTF(PF_DEBUG_URGENT, 6207 ("pf_route: m0->m_len < sizeof(struct ip)\n")); 6208 goto bad; 6209 } 6210 ip = mtod(m0, struct ip *); 6211 } 6212 6213#ifdef __FreeBSD__ 6214 /* Copied from FreeBSD 5.1-CURRENT ip_output. */ 6215 m0->m_pkthdr.csum_flags |= CSUM_IP; 6216 sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist; 6217 if (sw_csum & CSUM_DELAY_DATA) { 6218 /* 6219 * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least) 6220 */ 6221 NTOHS(ip->ip_len); 6222 NTOHS(ip->ip_off); /* XXX: needed? */ 6223 in_delayed_cksum(m0); 6224 HTONS(ip->ip_len); 6225 HTONS(ip->ip_off); 6226 sw_csum &= ~CSUM_DELAY_DATA; 6227 } 6228 m0->m_pkthdr.csum_flags &= ifp->if_hwassist; 6229 6230 if (ntohs(ip->ip_len) <= ifp->if_mtu || 6231 (ifp->if_hwassist & CSUM_FRAGMENT && 6232 ((ip->ip_off & htons(IP_DF)) == 0))) { 6233 /* 6234 * ip->ip_len = htons(ip->ip_len); 6235 * ip->ip_off = htons(ip->ip_off); 6236 */ 6237 ip->ip_sum = 0; 6238 if (sw_csum & CSUM_DELAY_IP) { 6239 /* From KAME */ 6240 if (ip->ip_v == IPVERSION && 6241 (ip->ip_hl << 2) == sizeof(*ip)) { 6242 ip->ip_sum = in_cksum_hdr(ip); 6243 } else { 6244 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 6245 } 6246 } 6247 PF_UNLOCK(); 6248 error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro->ro_rt); 6249 PF_LOCK(); 6250 goto done; 6251 } 6252 6253#else 6254 /* Copied from ip_output. */ 6255#ifdef IPSEC 6256 /* 6257 * If deferred crypto processing is needed, check that the 6258 * interface supports it. 6259 */ 6260 if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL)) 6261 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) { 6262 /* Notify IPsec to do its own crypto. */ 6263 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); 6264 goto bad; 6265 } 6266#endif /* IPSEC */ 6267 6268 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */ 6269 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) { 6270 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) || 6271 ifp->if_bridge != NULL) { 6272 in_delayed_cksum(m0); 6273 m0->m_pkthdr.csum_flags &= ~M_TCPV4_CSUM_OUT; /* Clear */ 6274 } 6275 } else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) { 6276 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) || 6277 ifp->if_bridge != NULL) { 6278 in_delayed_cksum(m0); 6279 m0->m_pkthdr.csum_flags &= ~M_UDPV4_CSUM_OUT; /* Clear */ 6280 } 6281 } 6282 6283 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 6284 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 6285 ifp->if_bridge == NULL) { 6286 m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; 6287 V_ipstat.ips_outhwcsum++; 6288 } else { 6289 ip->ip_sum = 0; 6290 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 6291 } 6292 /* Update relevant hardware checksum stats for TCP/UDP */ 6293 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) 6294 V_tcpstat.tcps_outhwcsum++; 6295 else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) 6296 V_udpstat.udps_outhwcsum++; 6297 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); 6298 goto done; 6299 } 6300#endif 6301 /* 6302 * Too large for interface; fragment if possible. 6303 * Must be able to put at least 8 bytes per fragment. 6304 */ 6305 if (ip->ip_off & htons(IP_DF)) { 6306 V_ipstat.ips_cantfrag++; 6307 if (r->rt != PF_DUPTO) { 6308#ifdef __FreeBSD__ 6309 /* icmp_error() expects host byte ordering */ 6310 NTOHS(ip->ip_len); 6311 NTOHS(ip->ip_off); 6312 PF_UNLOCK(); 6313 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 6314 ifp->if_mtu); 6315 PF_LOCK(); 6316#else 6317 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 6318 ifp->if_mtu); 6319#endif 6320 goto done; 6321 } else 6322 goto bad; 6323 } 6324 6325 m1 = m0; 6326#ifdef __FreeBSD__ 6327 /* 6328 * XXX: is cheaper + less error prone than own function 6329 */ 6330 NTOHS(ip->ip_len); 6331 NTOHS(ip->ip_off); 6332 error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum); 6333#else 6334 error = ip_fragment(m0, ifp, ifp->if_mtu); 6335#endif 6336 if (error) { 6337#ifndef __FreeBSD__ /* ip_fragment does not do m_freem() on FreeBSD */ 6338 m0 = NULL; 6339#endif 6340 goto bad; 6341 } 6342 6343 for (m0 = m1; m0; m0 = m1) { 6344 m1 = m0->m_nextpkt; 6345 m0->m_nextpkt = 0; 6346#ifdef __FreeBSD__ 6347 if (error == 0) { 6348 PF_UNLOCK(); 6349 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 6350 NULL); 6351 PF_LOCK(); 6352 } else 6353#else 6354 if (error == 0) 6355 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 6356 NULL); 6357 else 6358#endif 6359 m_freem(m0); 6360 } 6361 6362 if (error == 0) 6363 V_ipstat.ips_fragmented++; 6364 6365done: 6366 if (r->rt != PF_DUPTO) 6367 *m = NULL; 6368 if (ro == &iproute && ro->ro_rt) 6369 RTFREE(ro->ro_rt); 6370 return; 6371 6372bad: 6373 m_freem(m0); 6374 goto done; 6375} 6376#endif /* INET */ 6377 6378#ifdef INET6 6379void 6380pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 6381 struct pf_state *s, struct pf_pdesc *pd) 6382{ 6383 struct mbuf *m0; 6384 struct route_in6 ip6route; 6385 struct route_in6 *ro; 6386 struct sockaddr_in6 *dst; 6387 struct ip6_hdr *ip6; 6388 struct ifnet *ifp = NULL; 6389 struct pf_addr naddr; 6390 struct pf_src_node *sn = NULL; 6391 int error = 0; 6392 6393 if (m == NULL || *m == NULL || r == NULL || 6394 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 6395 panic("pf_route6: invalid parameters"); 6396 6397 if (pd->pf_mtag->routed++ > 3) { 6398 m0 = *m; 6399 *m = NULL; 6400 goto bad; 6401 } 6402 6403 if (r->rt == PF_DUPTO) { 6404#ifdef __FreeBSD__ 6405 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 6406#else 6407 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 6408#endif 6409 return; 6410 } else { 6411 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 6412 return; 6413 m0 = *m; 6414 } 6415 6416 if (m0->m_len < sizeof(struct ip6_hdr)) { 6417 DPFPRINTF(PF_DEBUG_URGENT, 6418 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n")); 6419 goto bad; 6420 } 6421 ip6 = mtod(m0, struct ip6_hdr *); 6422 6423 ro = &ip6route; 6424 bzero((caddr_t)ro, sizeof(*ro)); 6425 dst = (struct sockaddr_in6 *)&ro->ro_dst; 6426 dst->sin6_family = AF_INET6; 6427 dst->sin6_len = sizeof(*dst); 6428 dst->sin6_addr = ip6->ip6_dst; 6429 6430 /* Cheat. XXX why only in the v6 case??? */ 6431 if (r->rt == PF_FASTROUTE) { 6432#ifdef __FreeBSD__ 6433 m0->m_flags |= M_SKIP_FIREWALL; 6434 PF_UNLOCK(); 6435 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 6436 PF_LOCK(); 6437#else 6438 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 6439 if (mtag == NULL) 6440 goto bad; 6441 m_tag_prepend(m0, mtag); 6442 pd->pf_mtag->flags |= PF_TAG_GENERATED; 6443 ip6_output(m0, NULL, NULL, 0, NULL, NULL); 6444#endif 6445 return; 6446 } 6447 6448 if (TAILQ_EMPTY(&r->rpool.list)) { 6449 DPFPRINTF(PF_DEBUG_URGENT, 6450 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n")); 6451 goto bad; 6452 } 6453 if (s == NULL) { 6454 pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, 6455 &naddr, NULL, &sn); 6456 if (!PF_AZERO(&naddr, AF_INET6)) 6457 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 6458 &naddr, AF_INET6); 6459 ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; 6460 } else { 6461 if (!PF_AZERO(&s->rt_addr, AF_INET6)) 6462 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 6463 &s->rt_addr, AF_INET6); 6464 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; 6465 } 6466 if (ifp == NULL) 6467 goto bad; 6468 6469 if (oifp != ifp) { 6470#ifdef __FreeBSD__ 6471 PF_UNLOCK(); 6472 if (pf_test6(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) { 6473 PF_LOCK(); 6474 goto bad; 6475 } else if (m0 == NULL) { 6476 PF_LOCK(); 6477 goto done; 6478 } 6479 PF_LOCK(); 6480#else 6481 if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS) 6482 goto bad; 6483 else if (m0 == NULL) 6484 goto done; 6485#endif 6486 if (m0->m_len < sizeof(struct ip6_hdr)) { 6487 DPFPRINTF(PF_DEBUG_URGENT, 6488 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n")); 6489 goto bad; 6490 } 6491 ip6 = mtod(m0, struct ip6_hdr *); 6492 } 6493 6494 /* 6495 * If the packet is too large for the outgoing interface, 6496 * send back an icmp6 error. 6497 */ 6498 if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr)) 6499 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); 6500 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { 6501#ifdef __FreeBSD__ 6502 PF_UNLOCK(); 6503#endif 6504 error = nd6_output(ifp, ifp, m0, dst, NULL); 6505#ifdef __FreeBSD__ 6506 PF_LOCK(); 6507#endif 6508 } else { 6509 in6_ifstat_inc(ifp, ifs6_in_toobig); 6510#ifdef __FreeBSD__ 6511 if (r->rt != PF_DUPTO) { 6512 PF_UNLOCK(); 6513 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 6514 PF_LOCK(); 6515 } else 6516#else 6517 if (r->rt != PF_DUPTO) 6518 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 6519 else 6520#endif 6521 goto bad; 6522 } 6523 6524done: 6525 if (r->rt != PF_DUPTO) 6526 *m = NULL; 6527 return; 6528 6529bad: 6530 m_freem(m0); 6531 goto done; 6532} 6533#endif /* INET6 */ 6534 6535 6536#ifdef __FreeBSD__ 6537/* 6538 * FreeBSD supports cksum offloads for the following drivers. 6539 * em(4), fxp(4), ixgb(4), lge(4), ndis(4), nge(4), re(4), 6540 * ti(4), txp(4), xl(4) 6541 * 6542 * CSUM_DATA_VALID | CSUM_PSEUDO_HDR : 6543 * network driver performed cksum including pseudo header, need to verify 6544 * csum_data 6545 * CSUM_DATA_VALID : 6546 * network driver performed cksum, needs to additional pseudo header 6547 * cksum computation with partial csum_data(i.e. lack of H/W support for 6548 * pseudo header, for instance hme(4), sk(4) and possibly gem(4)) 6549 * 6550 * After validating the cksum of packet, set both flag CSUM_DATA_VALID and 6551 * CSUM_PSEUDO_HDR in order to avoid recomputation of the cksum in upper 6552 * TCP/UDP layer. 6553 * Also, set csum_data to 0xffff to force cksum validation. 6554 */ 6555int 6556pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) 6557{ 6558 u_int16_t sum = 0; 6559 int hw_assist = 0; 6560 struct ip *ip; 6561 6562 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 6563 return (1); 6564 if (m->m_pkthdr.len < off + len) 6565 return (1); 6566 6567 switch (p) { 6568 case IPPROTO_TCP: 6569 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 6570 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 6571 sum = m->m_pkthdr.csum_data; 6572 } else { 6573 ip = mtod(m, struct ip *); 6574 sum = in_pseudo(ip->ip_src.s_addr, 6575 ip->ip_dst.s_addr, htonl((u_short)len + 6576 m->m_pkthdr.csum_data + IPPROTO_TCP)); 6577 } 6578 sum ^= 0xffff; 6579 ++hw_assist; 6580 } 6581 break; 6582 case IPPROTO_UDP: 6583 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 6584 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 6585 sum = m->m_pkthdr.csum_data; 6586 } else { 6587 ip = mtod(m, struct ip *); 6588 sum = in_pseudo(ip->ip_src.s_addr, 6589 ip->ip_dst.s_addr, htonl((u_short)len + 6590 m->m_pkthdr.csum_data + IPPROTO_UDP)); 6591 } 6592 sum ^= 0xffff; 6593 ++hw_assist; 6594 } 6595 break; 6596 case IPPROTO_ICMP: 6597#ifdef INET6 6598 case IPPROTO_ICMPV6: 6599#endif /* INET6 */ 6600 break; 6601 default: 6602 return (1); 6603 } 6604 6605 if (!hw_assist) { 6606 switch (af) { 6607 case AF_INET: 6608 if (p == IPPROTO_ICMP) { 6609 if (m->m_len < off) 6610 return (1); 6611 m->m_data += off; 6612 m->m_len -= off; 6613 sum = in_cksum(m, len); 6614 m->m_data -= off; 6615 m->m_len += off; 6616 } else { 6617 if (m->m_len < sizeof(struct ip)) 6618 return (1); 6619 sum = in4_cksum(m, p, off, len); 6620 } 6621 break; 6622#ifdef INET6 6623 case AF_INET6: 6624 if (m->m_len < sizeof(struct ip6_hdr)) 6625 return (1); 6626 sum = in6_cksum(m, p, off, len); 6627 break; 6628#endif /* INET6 */ 6629 default: 6630 return (1); 6631 } 6632 } 6633 if (sum) { 6634 switch (p) { 6635 case IPPROTO_TCP: 6636 V_tcpstat.tcps_rcvbadsum++; 6637 break; 6638 case IPPROTO_UDP: 6639 V_udpstat.udps_badsum++; 6640 break; 6641 case IPPROTO_ICMP: 6642 V_icmpstat.icps_checksum++; 6643 break; 6644#ifdef INET6 6645 case IPPROTO_ICMPV6: 6646 V_icmp6stat.icp6s_checksum++; 6647 break; 6648#endif /* INET6 */ 6649 } 6650 return (1); 6651 } else { 6652 if (p == IPPROTO_TCP || p == IPPROTO_UDP) { 6653 m->m_pkthdr.csum_flags |= 6654 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); 6655 m->m_pkthdr.csum_data = 0xffff; 6656 } 6657 } 6658 return (0); 6659} 6660#else /* !__FreeBSD__ */ 6661/* 6662 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 6663 * off is the offset where the protocol header starts 6664 * len is the total length of protocol header plus payload 6665 * returns 0 when the checksum is valid, otherwise returns 1. 6666 */ 6667int 6668pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, 6669 sa_family_t af) 6670{ 6671 u_int16_t flag_ok, flag_bad; 6672 u_int16_t sum; 6673 6674 switch (p) { 6675 case IPPROTO_TCP: 6676 flag_ok = M_TCP_CSUM_IN_OK; 6677 flag_bad = M_TCP_CSUM_IN_BAD; 6678 break; 6679 case IPPROTO_UDP: 6680 flag_ok = M_UDP_CSUM_IN_OK; 6681 flag_bad = M_UDP_CSUM_IN_BAD; 6682 break; 6683 case IPPROTO_ICMP: 6684#ifdef INET6 6685 case IPPROTO_ICMPV6: 6686#endif /* INET6 */ 6687 flag_ok = flag_bad = 0; 6688 break; 6689 default: 6690 return (1); 6691 } 6692 if (m->m_pkthdr.csum_flags & flag_ok) 6693 return (0); 6694 if (m->m_pkthdr.csum_flags & flag_bad) 6695 return (1); 6696 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 6697 return (1); 6698 if (m->m_pkthdr.len < off + len) 6699 return (1); 6700 switch (af) { 6701#ifdef INET 6702 case AF_INET: 6703 if (p == IPPROTO_ICMP) { 6704 if (m->m_len < off) 6705 return (1); 6706 m->m_data += off; 6707 m->m_len -= off; 6708 sum = in_cksum(m, len); 6709 m->m_data -= off; 6710 m->m_len += off; 6711 } else { 6712 if (m->m_len < sizeof(struct ip)) 6713 return (1); 6714 sum = in4_cksum(m, p, off, len); 6715 } 6716 break; 6717#endif /* INET */ 6718#ifdef INET6 6719 case AF_INET6: 6720 if (m->m_len < sizeof(struct ip6_hdr)) 6721 return (1); 6722 sum = in6_cksum(m, p, off, len); 6723 break; 6724#endif /* INET6 */ 6725 default: 6726 return (1); 6727 } 6728 if (sum) { 6729 m->m_pkthdr.csum_flags |= flag_bad; 6730 switch (p) { 6731 case IPPROTO_TCP: 6732 V_tcpstat.tcps_rcvbadsum++; 6733 break; 6734 case IPPROTO_UDP: 6735 V_udpstat.udps_badsum++; 6736 break; 6737 case IPPROTO_ICMP: 6738 V_icmpstat.icps_checksum++; 6739 break; 6740#ifdef INET6 6741 case IPPROTO_ICMPV6: 6742 V_icmp6stat.icp6s_checksum++; 6743 break; 6744#endif /* INET6 */ 6745 } 6746 return (1); 6747 } 6748 m->m_pkthdr.csum_flags |= flag_ok; 6749 return (0); 6750} 6751#endif /* __FreeBSD__ */ 6752 6753#ifdef INET 6754int 6755#ifdef __FreeBSD__ 6756pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6757 struct ether_header *eh, struct inpcb *inp) 6758#else 6759pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6760 struct ether_header *eh) 6761#endif 6762{ 6763 struct pfi_kif *kif; 6764 u_short action, reason = 0, log = 0; 6765 struct mbuf *m = *m0; 6766 struct ip *h = NULL; /* make the compiler happy */ 6767 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 6768 struct pf_state *s = NULL; 6769 struct pf_ruleset *ruleset = NULL; 6770 struct pf_pdesc pd; 6771 int off, dirndx, pqid = 0; 6772 6773#ifdef __FreeBSD__ 6774 PF_LOCK(); 6775#endif 6776 if (!pf_status.running) 6777#ifdef __FreeBSD__ 6778 { 6779 PF_UNLOCK(); 6780#endif 6781 return (PF_PASS); 6782#ifdef __FreeBSD__ 6783 } 6784#endif 6785 6786 memset(&pd, 0, sizeof(pd)); 6787 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) { 6788#ifdef __FreeBSD__ 6789 PF_UNLOCK(); 6790#endif 6791 DPFPRINTF(PF_DEBUG_URGENT, 6792 ("pf_test: pf_get_mtag returned NULL\n")); 6793 return (PF_DROP); 6794 } 6795#ifdef __FreeBSD__ 6796 if (m->m_flags & M_SKIP_FIREWALL) { 6797 PF_UNLOCK(); 6798 return (PF_PASS); 6799 } 6800#else 6801 if (pd.pf_mtag->flags & PF_TAG_GENERATED) 6802 return (PF_PASS); 6803#endif 6804 6805#ifdef __FreeBSD__ 6806 /* XXX_IMPORT: later */ 6807#else 6808 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 6809 ifp = ifp->if_carpdev; 6810#endif 6811 6812 kif = (struct pfi_kif *)ifp->if_pf_kif; 6813 if (kif == NULL) { 6814#ifdef __FreeBSD__ 6815 PF_UNLOCK(); 6816#endif 6817 DPFPRINTF(PF_DEBUG_URGENT, 6818 ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname)); 6819 return (PF_DROP); 6820 } 6821 if (kif->pfik_flags & PFI_IFLAG_SKIP) { 6822#ifdef __FreeBSD__ 6823 PF_UNLOCK(); 6824#endif 6825 return (PF_PASS); 6826 } 6827 6828#ifdef __FreeBSD__ 6829 M_ASSERTPKTHDR(m); 6830#else 6831#ifdef DIAGNOSTIC 6832 if ((m->m_flags & M_PKTHDR) == 0) 6833 panic("non-M_PKTHDR is passed to pf_test"); 6834#endif /* DIAGNOSTIC */ 6835#endif /* __FreeBSD__ */ 6836 6837 if (m->m_pkthdr.len < (int)sizeof(*h)) { 6838 action = PF_DROP; 6839 REASON_SET(&reason, PFRES_SHORT); 6840 log = 1; 6841 goto done; 6842 } 6843 6844 /* We do IP header normalization and packet reassembly here */ 6845 if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) { 6846 action = PF_DROP; 6847 goto done; 6848 } 6849 m = *m0; 6850 h = mtod(m, struct ip *); 6851 6852 off = h->ip_hl << 2; 6853 if (off < (int)sizeof(*h)) { 6854 action = PF_DROP; 6855 REASON_SET(&reason, PFRES_SHORT); 6856 log = 1; 6857 goto done; 6858 } 6859 6860 pd.src = (struct pf_addr *)&h->ip_src; 6861 pd.dst = (struct pf_addr *)&h->ip_dst; 6862 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET); 6863 pd.ip_sum = &h->ip_sum; 6864 pd.proto = h->ip_p; 6865 pd.af = AF_INET; 6866 pd.tos = h->ip_tos; 6867 pd.tot_len = ntohs(h->ip_len); 6868 pd.eh = eh; 6869 6870 /* handle fragments that didn't get reassembled by normalization */ 6871 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) { 6872 action = pf_test_fragment(&r, dir, kif, m, h, 6873 &pd, &a, &ruleset); 6874 goto done; 6875 } 6876 6877 switch (h->ip_p) { 6878 6879 case IPPROTO_TCP: { 6880 struct tcphdr th; 6881 6882 pd.hdr.tcp = &th; 6883 if (!pf_pull_hdr(m, off, &th, sizeof(th), 6884 &action, &reason, AF_INET)) { 6885 log = action != PF_PASS; 6886 goto done; 6887 } 6888 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6889 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) { 6890 REASON_SET(&reason, PFRES_PROTCKSUM); 6891 action = PF_DROP; 6892 goto done; 6893 } 6894 pd.p_len = pd.tot_len - off - (th.th_off << 2); 6895 if ((th.th_flags & TH_ACK) && pd.p_len == 0) 6896 pqid = 1; 6897 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 6898 if (action == PF_DROP) 6899 goto done; 6900 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, 6901 &reason); 6902 if (action == PF_PASS) { 6903#if NPFSYNC 6904 pfsync_update_state(s); 6905#endif /* NPFSYNC */ 6906 r = s->rule.ptr; 6907 a = s->anchor.ptr; 6908 log = s->log; 6909 } else if (s == NULL) 6910#ifdef __FreeBSD__ 6911 action = pf_test_tcp(&r, &s, dir, kif, 6912 m, off, h, &pd, &a, &ruleset, NULL, inp); 6913#else 6914 action = pf_test_tcp(&r, &s, dir, kif, 6915 m, off, h, &pd, &a, &ruleset, &ipintrq); 6916#endif 6917 break; 6918 } 6919 6920 case IPPROTO_UDP: { 6921 struct udphdr uh; 6922 6923 pd.hdr.udp = &uh; 6924 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 6925 &action, &reason, AF_INET)) { 6926 log = action != PF_PASS; 6927 goto done; 6928 } 6929 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 6930 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) { 6931 action = PF_DROP; 6932 REASON_SET(&reason, PFRES_PROTCKSUM); 6933 goto done; 6934 } 6935 if (uh.uh_dport == 0 || 6936 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 6937 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 6938 action = PF_DROP; 6939 REASON_SET(&reason, PFRES_SHORT); 6940 goto done; 6941 } 6942 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 6943 if (action == PF_PASS) { 6944#if NPFSYNC 6945 pfsync_update_state(s); 6946#endif /* NPFSYNC */ 6947 r = s->rule.ptr; 6948 a = s->anchor.ptr; 6949 log = s->log; 6950 } else if (s == NULL) 6951#ifdef __FreeBSD__ 6952 action = pf_test_udp(&r, &s, dir, kif, 6953 m, off, h, &pd, &a, &ruleset, NULL, inp); 6954#else 6955 action = pf_test_udp(&r, &s, dir, kif, 6956 m, off, h, &pd, &a, &ruleset, &ipintrq); 6957#endif 6958 break; 6959 } 6960 6961 case IPPROTO_ICMP: { 6962 struct icmp ih; 6963 6964 pd.hdr.icmp = &ih; 6965 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN, 6966 &action, &reason, AF_INET)) { 6967 log = action != PF_PASS; 6968 goto done; 6969 } 6970 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6971 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) { 6972 action = PF_DROP; 6973 REASON_SET(&reason, PFRES_PROTCKSUM); 6974 goto done; 6975 } 6976 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd, 6977 &reason); 6978 if (action == PF_PASS) { 6979#if NPFSYNC 6980 pfsync_update_state(s); 6981#endif /* NPFSYNC */ 6982 r = s->rule.ptr; 6983 a = s->anchor.ptr; 6984 log = s->log; 6985 } else if (s == NULL) 6986#ifdef __FreeBSD__ 6987 action = pf_test_icmp(&r, &s, dir, kif, 6988 m, off, h, &pd, &a, &ruleset, NULL); 6989#else 6990 action = pf_test_icmp(&r, &s, dir, kif, 6991 m, off, h, &pd, &a, &ruleset, &ipintrq); 6992#endif 6993 break; 6994 } 6995 6996 default: 6997 action = pf_test_state_other(&s, dir, kif, &pd); 6998 if (action == PF_PASS) { 6999#if NPFSYNC 7000 pfsync_update_state(s); 7001#endif /* NPFSYNC */ 7002 r = s->rule.ptr; 7003 a = s->anchor.ptr; 7004 log = s->log; 7005 } else if (s == NULL) 7006#ifdef __FreeBSD__ 7007 action = pf_test_other(&r, &s, dir, kif, m, off, h, 7008 &pd, &a, &ruleset, NULL); 7009#else 7010 action = pf_test_other(&r, &s, dir, kif, m, off, h, 7011 &pd, &a, &ruleset, &ipintrq); 7012#endif 7013 break; 7014 } 7015 7016done: 7017 if (action == PF_PASS && h->ip_hl > 5 && 7018 !((s && s->allow_opts) || r->allow_opts)) { 7019 action = PF_DROP; 7020 REASON_SET(&reason, PFRES_IPOPTIONS); 7021 log = 1; 7022 DPFPRINTF(PF_DEBUG_MISC, 7023 ("pf: dropping packet with ip options\n")); 7024 } 7025 7026 if ((s && s->tag) || r->rtableid) 7027 pf_tag_packet(m, pd.pf_mtag, s ? s->tag : 0, r->rtableid); 7028 7029#ifdef ALTQ 7030 if (action == PF_PASS && r->qid) { 7031 if (pqid || (pd.tos & IPTOS_LOWDELAY)) 7032 pd.pf_mtag->qid = r->pqid; 7033 else 7034 pd.pf_mtag->qid = r->qid; 7035 /* add hints for ecn */ 7036 pd.pf_mtag->af = AF_INET; 7037 pd.pf_mtag->hdr = h; 7038 } 7039#endif /* ALTQ */ 7040 7041 /* 7042 * connections redirected to loopback should not match sockets 7043 * bound specifically to loopback due to security implications, 7044 * see tcp_input() and in_pcblookup_listen(). 7045 */ 7046 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 7047 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 7048 (s->nat_rule.ptr->action == PF_RDR || 7049 s->nat_rule.ptr->action == PF_BINAT) && 7050 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 7051 pd.pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST; 7052 7053 if (log) { 7054 struct pf_rule *lr; 7055 7056 if (s != NULL && s->nat_rule.ptr != NULL && 7057 s->nat_rule.ptr->log & PF_LOG_ALL) 7058 lr = s->nat_rule.ptr; 7059 else 7060 lr = r; 7061 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, lr, a, ruleset, 7062 &pd); 7063 } 7064 7065 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7066 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++; 7067 7068 if (action == PF_PASS || r->action == PF_DROP) { 7069 dirndx = (dir == PF_OUT); 7070 r->packets[dirndx]++; 7071 r->bytes[dirndx] += pd.tot_len; 7072 if (a != NULL) { 7073 a->packets[dirndx]++; 7074 a->bytes[dirndx] += pd.tot_len; 7075 } 7076 if (s != NULL) { 7077 if (s->nat_rule.ptr != NULL) { 7078 s->nat_rule.ptr->packets[dirndx]++; 7079 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; 7080 } 7081 if (s->src_node != NULL) { 7082 s->src_node->packets[dirndx]++; 7083 s->src_node->bytes[dirndx] += pd.tot_len; 7084 } 7085 if (s->nat_src_node != NULL) { 7086 s->nat_src_node->packets[dirndx]++; 7087 s->nat_src_node->bytes[dirndx] += pd.tot_len; 7088 } 7089 dirndx = (dir == s->direction) ? 0 : 1; 7090 s->packets[dirndx]++; 7091 s->bytes[dirndx] += pd.tot_len; 7092 } 7093 tr = r; 7094 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7095 if (nr != NULL) { 7096 struct pf_addr *x; 7097 /* 7098 * XXX: we need to make sure that the addresses 7099 * passed to pfr_update_stats() are the same than 7100 * the addresses used during matching (pfr_match) 7101 */ 7102 if (r == &pf_default_rule) { 7103 tr = nr; 7104 x = (s == NULL || s->direction == dir) ? 7105 &pd.baddr : &pd.naddr; 7106 } else 7107 x = (s == NULL || s->direction == dir) ? 7108 &pd.naddr : &pd.baddr; 7109 if (x == &pd.baddr || s == NULL) { 7110 /* we need to change the address */ 7111 if (dir == PF_OUT) 7112 pd.src = x; 7113 else 7114 pd.dst = x; 7115 } 7116 } 7117 if (tr->src.addr.type == PF_ADDR_TABLE) 7118 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL || 7119 s->direction == dir) ? pd.src : pd.dst, pd.af, 7120 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 7121 tr->src.neg); 7122 if (tr->dst.addr.type == PF_ADDR_TABLE) 7123 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL || 7124 s->direction == dir) ? pd.dst : pd.src, pd.af, 7125 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 7126 tr->dst.neg); 7127 } 7128 7129 7130 if (action == PF_SYNPROXY_DROP) { 7131 m_freem(*m0); 7132 *m0 = NULL; 7133 action = PF_PASS; 7134 } else if (r->rt) 7135 /* pf_route can free the mbuf causing *m0 to become NULL */ 7136 pf_route(m0, r, dir, ifp, s, &pd); 7137 7138#ifdef __FreeBSD__ 7139 PF_UNLOCK(); 7140#endif 7141 7142 return (action); 7143} 7144#endif /* INET */ 7145 7146#ifdef INET6 7147int 7148#ifdef __FreeBSD__ 7149pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, 7150 struct ether_header *eh, struct inpcb *inp) 7151#else 7152pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, 7153 struct ether_header *eh) 7154#endif 7155{ 7156 struct pfi_kif *kif; 7157 u_short action, reason = 0, log = 0; 7158 struct mbuf *m = *m0, *n = NULL; 7159 struct ip6_hdr *h; 7160 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 7161 struct pf_state *s = NULL; 7162 struct pf_ruleset *ruleset = NULL; 7163 struct pf_pdesc pd; 7164 int off, terminal = 0, dirndx, rh_cnt = 0; 7165 7166#ifdef __FreeBSD__ 7167 PF_LOCK(); 7168#endif 7169 7170 if (!pf_status.running) 7171#ifdef __FreeBSD__ 7172 { 7173 PF_UNLOCK(); 7174#endif 7175 return (PF_PASS); 7176#ifdef __FreeBSD__ 7177 } 7178#endif 7179 7180 memset(&pd, 0, sizeof(pd)); 7181 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) { 7182#ifdef __FreeBSD__ 7183 PF_UNLOCK(); 7184#endif 7185 DPFPRINTF(PF_DEBUG_URGENT, 7186 ("pf_test6: pf_get_mtag returned NULL\n")); 7187 return (PF_DROP); 7188 } 7189 if (pd.pf_mtag->flags & PF_TAG_GENERATED) 7190 return (PF_PASS); 7191 7192#ifdef __FreeBSD__ 7193 /* XXX_IMPORT: later */ 7194#else 7195 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 7196 ifp = ifp->if_carpdev; 7197#endif 7198 7199 kif = (struct pfi_kif *)ifp->if_pf_kif; 7200 if (kif == NULL) { 7201#ifdef __FreeBSD__ 7202 PF_UNLOCK(); 7203#endif 7204 DPFPRINTF(PF_DEBUG_URGENT, 7205 ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname)); 7206 return (PF_DROP); 7207 } 7208 if (kif->pfik_flags & PFI_IFLAG_SKIP) { 7209#ifdef __FreeBSD__ 7210 PF_UNLOCK(); 7211#endif 7212 return (PF_PASS); 7213 } 7214 7215#ifdef __FreeBSD__ 7216 M_ASSERTPKTHDR(m); 7217#else 7218#ifdef DIAGNOSTIC 7219 if ((m->m_flags & M_PKTHDR) == 0) 7220 panic("non-M_PKTHDR is passed to pf_test6"); 7221#endif /* DIAGNOSTIC */ 7222#endif 7223 7224#ifdef __FreeBSD__ 7225 h = NULL; /* make the compiler happy */ 7226#endif 7227 7228 if (m->m_pkthdr.len < (int)sizeof(*h)) { 7229 action = PF_DROP; 7230 REASON_SET(&reason, PFRES_SHORT); 7231 log = 1; 7232 goto done; 7233 } 7234 7235 /* We do IP header normalization and packet reassembly here */ 7236 if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) { 7237 action = PF_DROP; 7238 goto done; 7239 } 7240 m = *m0; 7241 h = mtod(m, struct ip6_hdr *); 7242 7243#if 1 7244 /* 7245 * we do not support jumbogram yet. if we keep going, zero ip6_plen 7246 * will do something bad, so drop the packet for now. 7247 */ 7248 if (htons(h->ip6_plen) == 0) { 7249 action = PF_DROP; 7250 REASON_SET(&reason, PFRES_NORM); /*XXX*/ 7251 goto done; 7252 } 7253#endif 7254 7255 pd.src = (struct pf_addr *)&h->ip6_src; 7256 pd.dst = (struct pf_addr *)&h->ip6_dst; 7257 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET6); 7258 pd.ip_sum = NULL; 7259 pd.af = AF_INET6; 7260 pd.tos = 0; 7261 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr); 7262 pd.eh = eh; 7263 7264 off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr); 7265 pd.proto = h->ip6_nxt; 7266 do { 7267 switch (pd.proto) { 7268 case IPPROTO_FRAGMENT: 7269 action = pf_test_fragment(&r, dir, kif, m, h, 7270 &pd, &a, &ruleset); 7271 if (action == PF_DROP) 7272 REASON_SET(&reason, PFRES_FRAG); 7273 goto done; 7274 case IPPROTO_ROUTING: { 7275 struct ip6_rthdr rthdr; 7276 7277 if (rh_cnt++) { 7278 DPFPRINTF(PF_DEBUG_MISC, 7279 ("pf: IPv6 more than one rthdr\n")); 7280 action = PF_DROP; 7281 REASON_SET(&reason, PFRES_IPOPTIONS); 7282 log = 1; 7283 goto done; 7284 } 7285 if (!pf_pull_hdr(m, off, &rthdr, sizeof(rthdr), NULL, 7286 &reason, pd.af)) { 7287 DPFPRINTF(PF_DEBUG_MISC, 7288 ("pf: IPv6 short rthdr\n")); 7289 action = PF_DROP; 7290 REASON_SET(&reason, PFRES_SHORT); 7291 log = 1; 7292 goto done; 7293 } 7294 if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) { 7295 DPFPRINTF(PF_DEBUG_MISC, 7296 ("pf: IPv6 rthdr0\n")); 7297 action = PF_DROP; 7298 REASON_SET(&reason, PFRES_IPOPTIONS); 7299 log = 1; 7300 goto done; 7301 } 7302 /* fallthrough */ 7303 } 7304 case IPPROTO_AH: 7305 case IPPROTO_HOPOPTS: 7306 case IPPROTO_DSTOPTS: { 7307 /* get next header and header length */ 7308 struct ip6_ext opt6; 7309 7310 if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6), 7311 NULL, &reason, pd.af)) { 7312 DPFPRINTF(PF_DEBUG_MISC, 7313 ("pf: IPv6 short opt\n")); 7314 action = PF_DROP; 7315 log = 1; 7316 goto done; 7317 } 7318 if (pd.proto == IPPROTO_AH) 7319 off += (opt6.ip6e_len + 2) * 4; 7320 else 7321 off += (opt6.ip6e_len + 1) * 8; 7322 pd.proto = opt6.ip6e_nxt; 7323 /* goto the next header */ 7324 break; 7325 } 7326 default: 7327 terminal++; 7328 break; 7329 } 7330 } while (!terminal); 7331 7332 /* if there's no routing header, use unmodified mbuf for checksumming */ 7333 if (!n) 7334 n = m; 7335 7336 switch (pd.proto) { 7337 7338 case IPPROTO_TCP: { 7339 struct tcphdr th; 7340 7341 pd.hdr.tcp = &th; 7342 if (!pf_pull_hdr(m, off, &th, sizeof(th), 7343 &action, &reason, AF_INET6)) { 7344 log = action != PF_PASS; 7345 goto done; 7346 } 7347 if (dir == PF_IN && pf_check_proto_cksum(n, off, 7348 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7349 IPPROTO_TCP, AF_INET6)) { 7350 action = PF_DROP; 7351 REASON_SET(&reason, PFRES_PROTCKSUM); 7352 goto done; 7353 } 7354 pd.p_len = pd.tot_len - off - (th.th_off << 2); 7355 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 7356 if (action == PF_DROP) 7357 goto done; 7358 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, 7359 &reason); 7360 if (action == PF_PASS) { 7361#if NPFSYNC 7362 pfsync_update_state(s); 7363#endif /* NPFSYNC */ 7364 r = s->rule.ptr; 7365 a = s->anchor.ptr; 7366 log = s->log; 7367 } else if (s == NULL) 7368#ifdef __FreeBSD__ 7369 action = pf_test_tcp(&r, &s, dir, kif, 7370 m, off, h, &pd, &a, &ruleset, NULL, inp); 7371#else 7372 action = pf_test_tcp(&r, &s, dir, kif, 7373 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7374#endif 7375 break; 7376 } 7377 7378 case IPPROTO_UDP: { 7379 struct udphdr uh; 7380 7381 pd.hdr.udp = &uh; 7382 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 7383 &action, &reason, AF_INET6)) { 7384 log = action != PF_PASS; 7385 goto done; 7386 } 7387 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(n, 7388 off, ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7389 IPPROTO_UDP, AF_INET6)) { 7390 action = PF_DROP; 7391 REASON_SET(&reason, PFRES_PROTCKSUM); 7392 goto done; 7393 } 7394 if (uh.uh_dport == 0 || 7395 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 7396 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 7397 action = PF_DROP; 7398 REASON_SET(&reason, PFRES_SHORT); 7399 goto done; 7400 } 7401 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 7402 if (action == PF_PASS) { 7403#if NPFSYNC 7404 pfsync_update_state(s); 7405#endif /* NPFSYNC */ 7406 r = s->rule.ptr; 7407 a = s->anchor.ptr; 7408 log = s->log; 7409 } else if (s == NULL) 7410#ifdef __FreeBSD__ 7411 action = pf_test_udp(&r, &s, dir, kif, 7412 m, off, h, &pd, &a, &ruleset, NULL, inp); 7413#else 7414 action = pf_test_udp(&r, &s, dir, kif, 7415 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7416#endif 7417 break; 7418 } 7419 7420 case IPPROTO_ICMPV6: { 7421 struct icmp6_hdr ih; 7422 7423 pd.hdr.icmp6 = &ih; 7424 if (!pf_pull_hdr(m, off, &ih, sizeof(ih), 7425 &action, &reason, AF_INET6)) { 7426 log = action != PF_PASS; 7427 goto done; 7428 } 7429 if (dir == PF_IN && pf_check_proto_cksum(n, off, 7430 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), 7431 IPPROTO_ICMPV6, AF_INET6)) { 7432 action = PF_DROP; 7433 REASON_SET(&reason, PFRES_PROTCKSUM); 7434 goto done; 7435 } 7436 action = pf_test_state_icmp(&s, dir, kif, 7437 m, off, h, &pd, &reason); 7438 if (action == PF_PASS) { 7439#if NPFSYNC 7440 pfsync_update_state(s); 7441#endif /* NPFSYNC */ 7442 r = s->rule.ptr; 7443 a = s->anchor.ptr; 7444 log = s->log; 7445 } else if (s == NULL) 7446#ifdef __FreeBSD__ 7447 action = pf_test_icmp(&r, &s, dir, kif, 7448 m, off, h, &pd, &a, &ruleset, NULL); 7449#else 7450 action = pf_test_icmp(&r, &s, dir, kif, 7451 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7452#endif 7453 break; 7454 } 7455 7456 default: 7457 action = pf_test_state_other(&s, dir, kif, &pd); 7458 if (action == PF_PASS) { 7459#if NPFSYNC 7460 pfsync_update_state(s); 7461#endif /* NPFSYNC */ 7462 r = s->rule.ptr; 7463 a = s->anchor.ptr; 7464 log = s->log; 7465 } else if (s == NULL) 7466#ifdef __FreeBSD__ 7467 action = pf_test_other(&r, &s, dir, kif, m, off, h, 7468 &pd, &a, &ruleset, NULL); 7469#else 7470 action = pf_test_other(&r, &s, dir, kif, m, off, h, 7471 &pd, &a, &ruleset, &ip6intrq); 7472#endif 7473 break; 7474 } 7475 7476done: 7477 /* handle dangerous IPv6 extension headers. */ 7478 if (action == PF_PASS && rh_cnt && 7479 !((s && s->allow_opts) || r->allow_opts)) { 7480 action = PF_DROP; 7481 REASON_SET(&reason, PFRES_IPOPTIONS); 7482 log = 1; 7483 DPFPRINTF(PF_DEBUG_MISC, 7484 ("pf: dropping packet with dangerous v6 headers\n")); 7485 } 7486 7487 if ((s && s->tag) || r->rtableid) 7488 pf_tag_packet(m, pd.pf_mtag, s ? s->tag : 0, r->rtableid); 7489 7490#ifdef ALTQ 7491 if (action == PF_PASS && r->qid) { 7492 if (pd.tos & IPTOS_LOWDELAY) 7493 pd.pf_mtag->qid = r->pqid; 7494 else 7495 pd.pf_mtag->qid = r->qid; 7496 /* add hints for ecn */ 7497 pd.pf_mtag->af = AF_INET6; 7498 pd.pf_mtag->hdr = h; 7499 } 7500#endif /* ALTQ */ 7501 7502 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 7503 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 7504 (s->nat_rule.ptr->action == PF_RDR || 7505 s->nat_rule.ptr->action == PF_BINAT) && 7506 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6)) 7507 pd.pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST; 7508 7509 if (log) { 7510 struct pf_rule *lr; 7511 7512 if (s != NULL && s->nat_rule.ptr != NULL && 7513 s->nat_rule.ptr->log & PF_LOG_ALL) 7514 lr = s->nat_rule.ptr; 7515 else 7516 lr = r; 7517 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, lr, a, ruleset, 7518 &pd); 7519 } 7520 7521 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7522 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++; 7523 7524 if (action == PF_PASS || r->action == PF_DROP) { 7525 dirndx = (dir == PF_OUT); 7526 r->packets[dirndx]++; 7527 r->bytes[dirndx] += pd.tot_len; 7528 if (a != NULL) { 7529 a->packets[dirndx]++; 7530 a->bytes[dirndx] += pd.tot_len; 7531 } 7532 if (s != NULL) { 7533 if (s->nat_rule.ptr != NULL) { 7534 s->nat_rule.ptr->packets[dirndx]++; 7535 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; 7536 } 7537 if (s->src_node != NULL) { 7538 s->src_node->packets[dirndx]++; 7539 s->src_node->bytes[dirndx] += pd.tot_len; 7540 } 7541 if (s->nat_src_node != NULL) { 7542 s->nat_src_node->packets[dirndx]++; 7543 s->nat_src_node->bytes[dirndx] += pd.tot_len; 7544 } 7545 dirndx = (dir == s->direction) ? 0 : 1; 7546 s->packets[dirndx]++; 7547 s->bytes[dirndx] += pd.tot_len; 7548 } 7549 tr = r; 7550 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7551 if (nr != NULL) { 7552 struct pf_addr *x; 7553 /* 7554 * XXX: we need to make sure that the addresses 7555 * passed to pfr_update_stats() are the same than 7556 * the addresses used during matching (pfr_match) 7557 */ 7558 if (r == &pf_default_rule) { 7559 tr = nr; 7560 x = (s == NULL || s->direction == dir) ? 7561 &pd.baddr : &pd.naddr; 7562 } else { 7563 x = (s == NULL || s->direction == dir) ? 7564 &pd.naddr : &pd.baddr; 7565 } 7566 if (x == &pd.baddr || s == NULL) { 7567 if (dir == PF_OUT) 7568 pd.src = x; 7569 else 7570 pd.dst = x; 7571 } 7572 } 7573 if (tr->src.addr.type == PF_ADDR_TABLE) 7574 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL || 7575 s->direction == dir) ? pd.src : pd.dst, pd.af, 7576 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 7577 tr->src.neg); 7578 if (tr->dst.addr.type == PF_ADDR_TABLE) 7579 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL || 7580 s->direction == dir) ? pd.dst : pd.src, pd.af, 7581 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 7582 tr->dst.neg); 7583 } 7584 7585 7586 if (action == PF_SYNPROXY_DROP) { 7587 m_freem(*m0); 7588 *m0 = NULL; 7589 action = PF_PASS; 7590 } else if (r->rt) 7591 /* pf_route6 can free the mbuf causing *m0 to become NULL */ 7592 pf_route6(m0, r, dir, ifp, s, &pd); 7593 7594#ifdef __FreeBSD__ 7595 PF_UNLOCK(); 7596#endif 7597 return (action); 7598} 7599#endif /* INET6 */ 7600 7601int 7602pf_check_congestion(struct ifqueue *ifq) 7603{ 7604#ifdef __FreeBSD__ 7605 /* XXX_IMPORT: later */ 7606 return (0); 7607#else 7608 if (ifq->ifq_congestion) 7609 return (1); 7610 else 7611 return (0); 7612#endif 7613} 7614