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