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