pf.c revision 135920
1/* $FreeBSD: head/sys/contrib/pf/net/pf.c 135920 2004-09-29 04:54:33Z mlaier $ */ 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 PF_AINC(&rpool->counter, af); 2091 break; 2092 } 2093 if (*sn != NULL) 2094 PF_ACPY(&(*sn)->raddr, naddr, af); 2095 2096 if (pf_status.debug >= PF_DEBUG_MISC && 2097 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { 2098 printf("pf_map_addr: selected address "); 2099 pf_print_host(naddr, 0, af); 2100 printf("\n"); 2101 } 2102 2103 return (0); 2104} 2105 2106int 2107pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, 2108 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport, 2109 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high, 2110 struct pf_src_node **sn) 2111{ 2112 struct pf_state key; 2113 struct pf_addr init_addr; 2114 u_int16_t cut; 2115 2116 bzero(&init_addr, sizeof(init_addr)); 2117 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) 2118 return (1); 2119 2120 do { 2121 key.af = af; 2122 key.proto = proto; 2123 PF_ACPY(&key.ext.addr, daddr, key.af); 2124 PF_ACPY(&key.gwy.addr, naddr, key.af); 2125 key.ext.port = dport; 2126 2127 /* 2128 * port search; start random, step; 2129 * similar 2 portloop in in_pcbbind 2130 */ 2131 if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP)) { 2132 key.gwy.port = 0; 2133 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) 2134 return (0); 2135 } else if (low == 0 && high == 0) { 2136 key.gwy.port = *nport; 2137 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) 2138 return (0); 2139 } else if (low == high) { 2140 key.gwy.port = htons(low); 2141 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) { 2142 *nport = htons(low); 2143 return (0); 2144 } 2145 } else { 2146 u_int16_t tmp; 2147 2148 if (low > high) { 2149 tmp = low; 2150 low = high; 2151 high = tmp; 2152 } 2153 /* low < high */ 2154 cut = arc4random() % (1 + high - low) + low; 2155 /* low <= cut <= high */ 2156 for (tmp = cut; tmp <= high; ++(tmp)) { 2157 key.gwy.port = htons(tmp); 2158 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == 2159 NULL) { 2160 *nport = htons(tmp); 2161 return (0); 2162 } 2163 } 2164 for (tmp = cut - 1; tmp >= low; --(tmp)) { 2165 key.gwy.port = htons(tmp); 2166 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == 2167 NULL) { 2168 *nport = htons(tmp); 2169 return (0); 2170 } 2171 } 2172 } 2173 2174 switch (r->rpool.opts & PF_POOL_TYPEMASK) { 2175 case PF_POOL_RANDOM: 2176 case PF_POOL_ROUNDROBIN: 2177 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) 2178 return (1); 2179 break; 2180 case PF_POOL_NONE: 2181 case PF_POOL_SRCHASH: 2182 case PF_POOL_BITMASK: 2183 default: 2184 return (1); 2185 } 2186 } while (! PF_AEQ(&init_addr, naddr, af) ); 2187 2188 return (1); /* none available */ 2189} 2190 2191struct pf_rule * 2192pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, 2193 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport, 2194 struct pf_addr *daddr, u_int16_t dport, int rs_num) 2195{ 2196 struct pf_rule *r, *rm = NULL, *anchorrule = NULL; 2197 struct pf_ruleset *ruleset = NULL; 2198 2199 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr); 2200 while (r && rm == NULL) { 2201 struct pf_rule_addr *src = NULL, *dst = NULL; 2202 struct pf_addr_wrap *xdst = NULL; 2203 2204 if (r->action == PF_BINAT && direction == PF_IN) { 2205 src = &r->dst; 2206 if (r->rpool.cur != NULL) 2207 xdst = &r->rpool.cur->addr; 2208 } else { 2209 src = &r->src; 2210 dst = &r->dst; 2211 } 2212 2213 r->evaluations++; 2214 if (r->kif != NULL && 2215 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) 2216 r = r->skip[PF_SKIP_IFP].ptr; 2217 else if (r->direction && r->direction != direction) 2218 r = r->skip[PF_SKIP_DIR].ptr; 2219 else if (r->af && r->af != pd->af) 2220 r = r->skip[PF_SKIP_AF].ptr; 2221 else if (r->proto && r->proto != pd->proto) 2222 r = r->skip[PF_SKIP_PROTO].ptr; 2223 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, src->not)) 2224 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR : 2225 PF_SKIP_DST_ADDR].ptr; 2226 else if (src->port_op && !pf_match_port(src->port_op, 2227 src->port[0], src->port[1], sport)) 2228 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT : 2229 PF_SKIP_DST_PORT].ptr; 2230 else if (dst != NULL && 2231 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->not)) 2232 r = r->skip[PF_SKIP_DST_ADDR].ptr; 2233 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, 0)) 2234 r = TAILQ_NEXT(r, entries); 2235 else if (dst != NULL && dst->port_op && 2236 !pf_match_port(dst->port_op, dst->port[0], 2237 dst->port[1], dport)) 2238 r = r->skip[PF_SKIP_DST_PORT].ptr; 2239 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto != 2240 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m, 2241 off, pd->hdr.tcp), r->os_fingerprint))) 2242 r = TAILQ_NEXT(r, entries); 2243 else if (r->anchorname[0] && r->anchor == NULL) 2244 r = TAILQ_NEXT(r, entries); 2245 else if (r->anchor == NULL) 2246 rm = r; 2247 else 2248 PF_STEP_INTO_ANCHOR(r, anchorrule, ruleset, rs_num); 2249 if (r == NULL && anchorrule != NULL) 2250 PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset, 2251 rs_num); 2252 } 2253 if (rm != NULL && (rm->action == PF_NONAT || 2254 rm->action == PF_NORDR || rm->action == PF_NOBINAT)) 2255 return (NULL); 2256 return (rm); 2257} 2258 2259struct pf_rule * 2260pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, 2261 struct pfi_kif *kif, struct pf_src_node **sn, 2262 struct pf_addr *saddr, u_int16_t sport, 2263 struct pf_addr *daddr, u_int16_t dport, 2264 struct pf_addr *naddr, u_int16_t *nport) 2265{ 2266 struct pf_rule *r = NULL; 2267 2268 if (direction == PF_OUT) { 2269 r = pf_match_translation(pd, m, off, direction, kif, saddr, 2270 sport, daddr, dport, PF_RULESET_BINAT); 2271 if (r == NULL) 2272 r = pf_match_translation(pd, m, off, direction, kif, 2273 saddr, sport, daddr, dport, PF_RULESET_NAT); 2274 } else { 2275 r = pf_match_translation(pd, m, off, direction, kif, saddr, 2276 sport, daddr, dport, PF_RULESET_RDR); 2277 if (r == NULL) 2278 r = pf_match_translation(pd, m, off, direction, kif, 2279 saddr, sport, daddr, dport, PF_RULESET_BINAT); 2280 } 2281 2282 if (r != NULL) { 2283 switch (r->action) { 2284 case PF_NONAT: 2285 case PF_NOBINAT: 2286 case PF_NORDR: 2287 return (NULL); 2288 case PF_NAT: 2289 if (pf_get_sport(pd->af, pd->proto, r, saddr, 2290 daddr, dport, naddr, nport, r->rpool.proxy_port[0], 2291 r->rpool.proxy_port[1], sn)) { 2292 DPFPRINTF(PF_DEBUG_MISC, 2293 ("pf: NAT proxy port allocation " 2294 "(%u-%u) failed\n", 2295 r->rpool.proxy_port[0], 2296 r->rpool.proxy_port[1])); 2297 return (NULL); 2298 } 2299 break; 2300 case PF_BINAT: 2301 switch (direction) { 2302 case PF_OUT: 2303 if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){ 2304 if (pd->af == AF_INET) { 2305 if (r->rpool.cur->addr.p.dyn-> 2306 pfid_acnt4 < 1) 2307 return (NULL); 2308 PF_POOLMASK(naddr, 2309 &r->rpool.cur->addr.p.dyn-> 2310 pfid_addr4, 2311 &r->rpool.cur->addr.p.dyn-> 2312 pfid_mask4, 2313 saddr, AF_INET); 2314 } else { 2315 if (r->rpool.cur->addr.p.dyn-> 2316 pfid_acnt6 < 1) 2317 return (NULL); 2318 PF_POOLMASK(naddr, 2319 &r->rpool.cur->addr.p.dyn-> 2320 pfid_addr6, 2321 &r->rpool.cur->addr.p.dyn-> 2322 pfid_mask6, 2323 saddr, AF_INET6); 2324 } 2325 } else 2326 PF_POOLMASK(naddr, 2327 &r->rpool.cur->addr.v.a.addr, 2328 &r->rpool.cur->addr.v.a.mask, 2329 saddr, pd->af); 2330 break; 2331 case PF_IN: 2332 if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){ 2333 if (pd->af == AF_INET) { 2334 if (r->src.addr.p.dyn-> 2335 pfid_acnt4 < 1) 2336 return (NULL); 2337 PF_POOLMASK(naddr, 2338 &r->src.addr.p.dyn-> 2339 pfid_addr4, 2340 &r->src.addr.p.dyn-> 2341 pfid_mask4, 2342 daddr, AF_INET); 2343 } else { 2344 if (r->src.addr.p.dyn-> 2345 pfid_acnt6 < 1) 2346 return (NULL); 2347 PF_POOLMASK(naddr, 2348 &r->src.addr.p.dyn-> 2349 pfid_addr6, 2350 &r->src.addr.p.dyn-> 2351 pfid_mask6, 2352 daddr, AF_INET6); 2353 } 2354 } else 2355 PF_POOLMASK(naddr, 2356 &r->src.addr.v.a.addr, 2357 &r->src.addr.v.a.mask, daddr, 2358 pd->af); 2359 break; 2360 } 2361 break; 2362 case PF_RDR: { 2363 if (pf_map_addr(r->af, r, saddr, naddr, NULL, sn)) 2364 return (NULL); 2365 2366 if (r->rpool.proxy_port[1]) { 2367 u_int32_t tmp_nport; 2368 2369 tmp_nport = ((ntohs(dport) - 2370 ntohs(r->dst.port[0])) % 2371 (r->rpool.proxy_port[1] - 2372 r->rpool.proxy_port[0] + 1)) + 2373 r->rpool.proxy_port[0]; 2374 2375 /* wrap around if necessary */ 2376 if (tmp_nport > 65535) 2377 tmp_nport -= 65535; 2378 *nport = htons((u_int16_t)tmp_nport); 2379 } else if (r->rpool.proxy_port[0]) 2380 *nport = htons(r->rpool.proxy_port[0]); 2381 break; 2382 } 2383 default: 2384 return (NULL); 2385 } 2386 } 2387 2388 return (r); 2389} 2390 2391int 2392#ifdef __FreeBSD__ 2393pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd, 2394 struct inpcb *inp_arg) 2395#else 2396pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd) 2397#endif 2398{ 2399 struct pf_addr *saddr, *daddr; 2400 u_int16_t sport, dport; 2401#ifdef __FreeBSD__ 2402 struct inpcbinfo *pi; 2403#else 2404 struct inpcbtable *tb; 2405#endif 2406 struct inpcb *inp; 2407 2408 *uid = UID_MAX; 2409 *gid = GID_MAX; 2410#ifdef __FreeBSD__ 2411 if (inp_arg != NULL) { 2412 INP_LOCK_ASSERT(inp_arg); 2413 if (inp_arg->inp_socket) { 2414 *uid = inp_arg->inp_socket->so_cred->cr_uid; 2415 *gid = inp_arg->inp_socket->so_cred->cr_groups[0]; 2416 return (1); 2417 } else 2418 return (0); 2419 } 2420#endif 2421 switch (pd->proto) { 2422 case IPPROTO_TCP: 2423 sport = pd->hdr.tcp->th_sport; 2424 dport = pd->hdr.tcp->th_dport; 2425#ifdef __FreeBSD__ 2426 pi = &tcbinfo; 2427#else 2428 tb = &tcbtable; 2429#endif 2430 break; 2431 case IPPROTO_UDP: 2432 sport = pd->hdr.udp->uh_sport; 2433 dport = pd->hdr.udp->uh_dport; 2434#ifdef __FreeBSD__ 2435 pi = &udbinfo; 2436#else 2437 tb = &udbtable; 2438#endif 2439 break; 2440 default: 2441 return (0); 2442 } 2443 if (direction == PF_IN) { 2444 saddr = pd->src; 2445 daddr = pd->dst; 2446 } else { 2447 u_int16_t p; 2448 2449 p = sport; 2450 sport = dport; 2451 dport = p; 2452 saddr = pd->dst; 2453 daddr = pd->src; 2454 } 2455 switch (pd->af) { 2456 case AF_INET: 2457#ifdef __FreeBSD__ 2458 INP_INFO_RLOCK(pi); /* XXX LOR */ 2459 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4, 2460 dport, 0, NULL); 2461 if (inp == NULL) { 2462 inp = in_pcblookup_hash(pi, saddr->v4, sport, 2463 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL); 2464 if(inp == NULL) { 2465 INP_INFO_RUNLOCK(pi); 2466 return (0); 2467 } 2468 } 2469#else 2470 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); 2471 if (inp == NULL) { 2472 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0); 2473 if (inp == NULL) 2474 return (0); 2475 } 2476#endif 2477 break; 2478#ifdef INET6 2479 case AF_INET6: 2480#ifdef __FreeBSD__ 2481 INP_INFO_RLOCK(pi); 2482 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 2483 &daddr->v6, dport, 0, NULL); 2484 if (inp == NULL) { 2485 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 2486 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL); 2487 if (inp == NULL) { 2488 INP_INFO_RUNLOCK(pi); 2489 return (0); 2490 } 2491 } 2492#else 2493 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, 2494 dport); 2495 if (inp == NULL) { 2496 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0); 2497 if (inp == NULL) 2498 return (0); 2499 } 2500#endif 2501 break; 2502#endif /* INET6 */ 2503 2504 default: 2505 return (0); 2506 } 2507#ifdef __FreeBSD__ 2508 INP_LOCK(inp); 2509 *uid = inp->inp_socket->so_cred->cr_uid; 2510 *gid = inp->inp_socket->so_cred->cr_groups[0]; 2511 INP_UNLOCK(inp); 2512 INP_INFO_RUNLOCK(pi); 2513#else 2514 *uid = inp->inp_socket->so_euid; 2515 *gid = inp->inp_socket->so_egid; 2516#endif 2517 return (1); 2518} 2519 2520u_int8_t 2521pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 2522{ 2523 int hlen; 2524 u_int8_t hdr[60]; 2525 u_int8_t *opt, optlen; 2526 u_int8_t wscale = 0; 2527 2528 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 2529 if (hlen <= sizeof(struct tcphdr)) 2530 return (0); 2531 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 2532 return (0); 2533 opt = hdr + sizeof(struct tcphdr); 2534 hlen -= sizeof(struct tcphdr); 2535 while (hlen >= 3) { 2536 switch (*opt) { 2537 case TCPOPT_EOL: 2538 case TCPOPT_NOP: 2539 ++opt; 2540 --hlen; 2541 break; 2542 case TCPOPT_WINDOW: 2543 wscale = opt[2]; 2544 if (wscale > TCP_MAX_WINSHIFT) 2545 wscale = TCP_MAX_WINSHIFT; 2546 wscale |= PF_WSCALE_FLAG; 2547 /* FALLTHROUGH */ 2548 default: 2549 optlen = opt[1]; 2550 if (optlen < 2) 2551 optlen = 2; 2552 hlen -= optlen; 2553 opt += optlen; 2554 break; 2555 } 2556 } 2557 return (wscale); 2558} 2559 2560u_int16_t 2561pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 2562{ 2563 int hlen; 2564 u_int8_t hdr[60]; 2565 u_int8_t *opt, optlen; 2566 u_int16_t mss = tcp_mssdflt; 2567 2568 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 2569 if (hlen <= sizeof(struct tcphdr)) 2570 return (0); 2571 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 2572 return (0); 2573 opt = hdr + sizeof(struct tcphdr); 2574 hlen -= sizeof(struct tcphdr); 2575 while (hlen >= TCPOLEN_MAXSEG) { 2576 switch (*opt) { 2577 case TCPOPT_EOL: 2578 case TCPOPT_NOP: 2579 ++opt; 2580 --hlen; 2581 break; 2582 case TCPOPT_MAXSEG: 2583 bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2); 2584 /* FALLTHROUGH */ 2585 default: 2586 optlen = opt[1]; 2587 if (optlen < 2) 2588 optlen = 2; 2589 hlen -= optlen; 2590 opt += optlen; 2591 break; 2592 } 2593 } 2594 return (mss); 2595} 2596 2597u_int16_t 2598pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) 2599{ 2600#ifdef INET 2601 struct sockaddr_in *dst; 2602 struct route ro; 2603#endif /* INET */ 2604#ifdef INET6 2605 struct sockaddr_in6 *dst6; 2606 struct route_in6 ro6; 2607#endif /* INET6 */ 2608 struct rtentry *rt = NULL; 2609 int hlen = 0; /* make the compiler happy */ 2610 u_int16_t mss = tcp_mssdflt; 2611 2612 switch (af) { 2613#ifdef INET 2614 case AF_INET: 2615 hlen = sizeof(struct ip); 2616 bzero(&ro, sizeof(ro)); 2617 dst = (struct sockaddr_in *)&ro.ro_dst; 2618 dst->sin_family = AF_INET; 2619 dst->sin_len = sizeof(*dst); 2620 dst->sin_addr = addr->v4; 2621#ifdef __FreeBSD__ 2622#ifdef RTF_PRCLONING 2623 rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING)); 2624#else /* !RTF_PRCLONING */ 2625 rtalloc_ign(&ro, RTF_CLONING); 2626#endif 2627#else /* ! __FreeBSD__ */ 2628 rtalloc_noclone(&ro, NO_CLONING); 2629#endif 2630 rt = ro.ro_rt; 2631 break; 2632#endif /* INET */ 2633#ifdef INET6 2634 case AF_INET6: 2635 hlen = sizeof(struct ip6_hdr); 2636 bzero(&ro6, sizeof(ro6)); 2637 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst; 2638 dst6->sin6_family = AF_INET6; 2639 dst6->sin6_len = sizeof(*dst6); 2640 dst6->sin6_addr = addr->v6; 2641#ifdef __FreeBSD__ 2642#ifdef RTF_PRCLONING 2643 rtalloc_ign((struct route *)&ro6, 2644 (RTF_CLONING | RTF_PRCLONING)); 2645#else /* !RTF_PRCLONING */ 2646 rtalloc_ign((struct route *)&ro6, RTF_CLONING); 2647#endif 2648#else /* ! __FreeBSD__ */ 2649 rtalloc_noclone((struct route *)&ro6, NO_CLONING); 2650#endif 2651 rt = ro6.ro_rt; 2652 break; 2653#endif /* INET6 */ 2654 } 2655 2656 if (rt && rt->rt_ifp) { 2657 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr); 2658 mss = max(tcp_mssdflt, mss); 2659 RTFREE(rt); 2660 } 2661 mss = min(mss, offer); 2662 mss = max(mss, 64); /* sanity - at least max opt space */ 2663 return (mss); 2664} 2665 2666void 2667pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr) 2668{ 2669 struct pf_rule *r = s->rule.ptr; 2670 2671 s->rt_kif = NULL; 2672 if (!r->rt || r->rt == PF_FASTROUTE) 2673 return; 2674 switch (s->af) { 2675#ifdef INET 2676 case AF_INET: 2677 pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, 2678 &s->nat_src_node); 2679 s->rt_kif = r->rpool.cur->kif; 2680 break; 2681#endif /* INET */ 2682#ifdef INET6 2683 case AF_INET6: 2684 pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, 2685 &s->nat_src_node); 2686 s->rt_kif = r->rpool.cur->kif; 2687 break; 2688#endif /* INET6 */ 2689 } 2690} 2691 2692int 2693pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction, 2694 struct pfi_kif *kif, struct mbuf *m, int off, void *h, 2695#ifdef __FreeBSD__ 2696 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 2697 struct inpcb *inp) 2698#else 2699 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) 2700#endif 2701{ 2702 struct pf_rule *nr = NULL; 2703 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 2704 struct tcphdr *th = pd->hdr.tcp; 2705 u_int16_t bport, nport = 0; 2706 sa_family_t af = pd->af; 2707 int lookup = -1; 2708 uid_t uid; 2709 gid_t gid; 2710 struct pf_rule *r, *a = NULL; 2711 struct pf_ruleset *ruleset = NULL; 2712 struct pf_src_node *nsn = NULL; 2713 u_short reason; 2714 int rewrite = 0; 2715 struct pf_tag *pftag = NULL; 2716 int tag = -1; 2717 u_int16_t mss = tcp_mssdflt; 2718 2719 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 2720 2721 if (direction == PF_OUT) { 2722 bport = nport = th->th_sport; 2723 /* check outgoing packet for BINAT/NAT */ 2724 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 2725 saddr, th->th_sport, daddr, th->th_dport, 2726 &pd->naddr, &nport)) != NULL) { 2727 PF_ACPY(&pd->baddr, saddr, af); 2728 pf_change_ap(saddr, &th->th_sport, pd->ip_sum, 2729 &th->th_sum, &pd->naddr, nport, 0, af); 2730 rewrite++; 2731 if (nr->natpass) 2732 r = NULL; 2733 pd->nat_rule = nr; 2734 } 2735 } else { 2736 bport = nport = th->th_dport; 2737 /* check incoming packet for BINAT/RDR */ 2738 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 2739 saddr, th->th_sport, daddr, th->th_dport, 2740 &pd->naddr, &nport)) != NULL) { 2741 PF_ACPY(&pd->baddr, daddr, af); 2742 pf_change_ap(daddr, &th->th_dport, pd->ip_sum, 2743 &th->th_sum, &pd->naddr, nport, 0, af); 2744 rewrite++; 2745 if (nr->natpass) 2746 r = NULL; 2747 pd->nat_rule = nr; 2748 } 2749 } 2750 2751 while (r != NULL) { 2752 r->evaluations++; 2753 if (r->kif != NULL && 2754 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) 2755 r = r->skip[PF_SKIP_IFP].ptr; 2756 else if (r->direction && r->direction != direction) 2757 r = r->skip[PF_SKIP_DIR].ptr; 2758 else if (r->af && r->af != af) 2759 r = r->skip[PF_SKIP_AF].ptr; 2760 else if (r->proto && r->proto != IPPROTO_TCP) 2761 r = r->skip[PF_SKIP_PROTO].ptr; 2762 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) 2763 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 2764 else if (r->src.port_op && !pf_match_port(r->src.port_op, 2765 r->src.port[0], r->src.port[1], th->th_sport)) 2766 r = r->skip[PF_SKIP_SRC_PORT].ptr; 2767 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) 2768 r = r->skip[PF_SKIP_DST_ADDR].ptr; 2769 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 2770 r->dst.port[0], r->dst.port[1], th->th_dport)) 2771 r = r->skip[PF_SKIP_DST_PORT].ptr; 2772 else if (r->tos && !(r->tos & pd->tos)) 2773 r = TAILQ_NEXT(r, entries); 2774 else if (r->rule_flag & PFRULE_FRAGMENT) 2775 r = TAILQ_NEXT(r, entries); 2776 else if ((r->flagset & th->th_flags) != r->flags) 2777 r = TAILQ_NEXT(r, entries); 2778 else if (r->uid.op && (lookup != -1 || (lookup = 2779#ifdef __FreeBSD__ 2780 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) && 2781#else 2782 pf_socket_lookup(&uid, &gid, direction, pd), 1)) && 2783#endif 2784 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 2785 uid)) 2786 r = TAILQ_NEXT(r, entries); 2787 else if (r->gid.op && (lookup != -1 || (lookup = 2788#ifdef __FreeBSD__ 2789 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) && 2790#else 2791 pf_socket_lookup(&uid, &gid, direction, pd), 1)) && 2792#endif 2793 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 2794 gid)) 2795 r = TAILQ_NEXT(r, entries); 2796 else if (r->match_tag && !pf_match_tag(m, r, nr, pftag, &tag)) 2797 r = TAILQ_NEXT(r, entries); 2798 else if (r->anchorname[0] && r->anchor == NULL) 2799 r = TAILQ_NEXT(r, entries); 2800 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match( 2801 pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint)) 2802 r = TAILQ_NEXT(r, entries); 2803 else { 2804 if (r->tag) 2805 tag = r->tag; 2806 if (r->anchor == NULL) { 2807 *rm = r; 2808 *am = a; 2809 *rsm = ruleset; 2810 if ((*rm)->quick) 2811 break; 2812 r = TAILQ_NEXT(r, entries); 2813 } else 2814 PF_STEP_INTO_ANCHOR(r, a, ruleset, 2815 PF_RULESET_FILTER); 2816 } 2817 if (r == NULL && a != NULL) 2818 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 2819 PF_RULESET_FILTER); 2820 } 2821 r = *rm; 2822 a = *am; 2823 ruleset = *rsm; 2824 2825 REASON_SET(&reason, PFRES_MATCH); 2826 2827 if (r->log) { 2828 if (rewrite) 2829 m_copyback(m, off, sizeof(*th), (caddr_t)th); 2830 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); 2831 } 2832 2833 if ((r->action == PF_DROP) && 2834 ((r->rule_flag & PFRULE_RETURNRST) || 2835 (r->rule_flag & PFRULE_RETURNICMP) || 2836 (r->rule_flag & PFRULE_RETURN))) { 2837 /* undo NAT changes, if they have taken place */ 2838 if (nr != NULL) { 2839 if (direction == PF_OUT) { 2840 pf_change_ap(saddr, &th->th_sport, pd->ip_sum, 2841 &th->th_sum, &pd->baddr, bport, 0, af); 2842 rewrite++; 2843 } else { 2844 pf_change_ap(daddr, &th->th_dport, pd->ip_sum, 2845 &th->th_sum, &pd->baddr, bport, 0, af); 2846 rewrite++; 2847 } 2848 } 2849 if (((r->rule_flag & PFRULE_RETURNRST) || 2850 (r->rule_flag & PFRULE_RETURN)) && 2851 !(th->th_flags & TH_RST)) { 2852 u_int32_t ack = ntohl(th->th_seq) + pd->p_len; 2853 2854 if (th->th_flags & TH_SYN) 2855 ack++; 2856 if (th->th_flags & TH_FIN) 2857 ack++; 2858 pf_send_tcp(r, af, pd->dst, 2859 pd->src, th->th_dport, th->th_sport, 2860 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0, 2861 r->return_ttl); 2862 } else if ((af == AF_INET) && r->return_icmp) 2863 pf_send_icmp(m, r->return_icmp >> 8, 2864 r->return_icmp & 255, af, r); 2865 else if ((af == AF_INET6) && r->return_icmp6) 2866 pf_send_icmp(m, r->return_icmp6 >> 8, 2867 r->return_icmp6 & 255, af, r); 2868 } 2869 2870 if (r->action == PF_DROP) 2871 return (PF_DROP); 2872 2873 if (pf_tag_packet(m, pftag, tag)) { 2874 REASON_SET(&reason, PFRES_MEMORY); 2875 return (PF_DROP); 2876 } 2877 2878 if (r->keep_state || nr != NULL || 2879 (pd->flags & PFDESC_TCP_NORM)) { 2880 /* create new state */ 2881 u_int16_t len; 2882 struct pf_state *s = NULL; 2883 struct pf_src_node *sn = NULL; 2884 2885 len = pd->tot_len - off - (th->th_off << 2); 2886 2887 /* check maximums */ 2888 if (r->max_states && (r->states >= r->max_states)) 2889 goto cleanup; 2890 /* src node for flter rule */ 2891 if ((r->rule_flag & PFRULE_SRCTRACK || 2892 r->rpool.opts & PF_POOL_STICKYADDR) && 2893 pf_insert_src_node(&sn, r, saddr, af) != 0) 2894 goto cleanup; 2895 /* src node for translation rule */ 2896 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 2897 ((direction == PF_OUT && 2898 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 2899 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) 2900 goto cleanup; 2901 s = pool_get(&pf_state_pl, PR_NOWAIT); 2902 if (s == NULL) { 2903cleanup: 2904 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 2905 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 2906 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 2907 pf_status.src_nodes--; 2908 pool_put(&pf_src_tree_pl, sn); 2909 } 2910 if (nsn != sn && nsn != NULL && nsn->states == 0 && 2911 nsn->expire == 0) { 2912 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 2913 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 2914 pf_status.src_nodes--; 2915 pool_put(&pf_src_tree_pl, nsn); 2916 } 2917 REASON_SET(&reason, PFRES_MEMORY); 2918 return (PF_DROP); 2919 } 2920 bzero(s, sizeof(*s)); 2921 r->states++; 2922 if (a != NULL) 2923 a->states++; 2924 s->rule.ptr = r; 2925 s->nat_rule.ptr = nr; 2926 if (s->nat_rule.ptr != NULL) 2927 s->nat_rule.ptr->states++; 2928 s->anchor.ptr = a; 2929 s->allow_opts = r->allow_opts; 2930 s->log = r->log & 2; 2931 s->proto = IPPROTO_TCP; 2932 s->direction = direction; 2933 s->af = af; 2934 if (direction == PF_OUT) { 2935 PF_ACPY(&s->gwy.addr, saddr, af); 2936 s->gwy.port = th->th_sport; /* sport */ 2937 PF_ACPY(&s->ext.addr, daddr, af); 2938 s->ext.port = th->th_dport; 2939 if (nr != NULL) { 2940 PF_ACPY(&s->lan.addr, &pd->baddr, af); 2941 s->lan.port = bport; 2942 } else { 2943 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 2944 s->lan.port = s->gwy.port; 2945 } 2946 } else { 2947 PF_ACPY(&s->lan.addr, daddr, af); 2948 s->lan.port = th->th_dport; 2949 PF_ACPY(&s->ext.addr, saddr, af); 2950 s->ext.port = th->th_sport; 2951 if (nr != NULL) { 2952 PF_ACPY(&s->gwy.addr, &pd->baddr, af); 2953 s->gwy.port = bport; 2954 } else { 2955 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 2956 s->gwy.port = s->lan.port; 2957 } 2958 } 2959 2960 s->src.seqlo = ntohl(th->th_seq); 2961 s->src.seqhi = s->src.seqlo + len + 1; 2962 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 2963 r->keep_state == PF_STATE_MODULATE) { 2964 /* Generate sequence number modulator */ 2965 while ((s->src.seqdiff = arc4random()) == 0) 2966 ; 2967 pf_change_a(&th->th_seq, &th->th_sum, 2968 htonl(s->src.seqlo + s->src.seqdiff), 0); 2969 rewrite = 1; 2970 } else 2971 s->src.seqdiff = 0; 2972 if (th->th_flags & TH_SYN) { 2973 s->src.seqhi++; 2974 s->src.wscale = pf_get_wscale(m, off, th->th_off, af); 2975 } 2976 s->src.max_win = MAX(ntohs(th->th_win), 1); 2977 if (s->src.wscale & PF_WSCALE_MASK) { 2978 /* Remove scale factor from initial window */ 2979 int win = s->src.max_win; 2980 win += 1 << (s->src.wscale & PF_WSCALE_MASK); 2981 s->src.max_win = (win - 1) >> 2982 (s->src.wscale & PF_WSCALE_MASK); 2983 } 2984 if (th->th_flags & TH_FIN) 2985 s->src.seqhi++; 2986 s->dst.seqhi = 1; 2987 s->dst.max_win = 1; 2988 s->src.state = TCPS_SYN_SENT; 2989 s->dst.state = TCPS_CLOSED; 2990#ifdef __FreeBSD__ 2991 s->creation = time_second; 2992 s->expire = time_second; 2993#else 2994 s->creation = time.tv_sec; 2995 s->expire = time.tv_sec; 2996#endif 2997 s->timeout = PFTM_TCP_FIRST_PACKET; 2998 pf_set_rt_ifp(s, saddr); 2999 if (sn != NULL) { 3000 s->src_node = sn; 3001 s->src_node->states++; 3002 } 3003 if (nsn != NULL) { 3004 PF_ACPY(&nsn->raddr, &pd->naddr, af); 3005 s->nat_src_node = nsn; 3006 s->nat_src_node->states++; 3007 } 3008 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m, 3009 off, pd, th, &s->src, &s->dst)) { 3010 REASON_SET(&reason, PFRES_MEMORY); 3011 pf_src_tree_remove_state(s); 3012 pool_put(&pf_state_pl, s); 3013 return (PF_DROP); 3014 } 3015 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub && 3016 pf_normalize_tcp_stateful(m, off, pd, &reason, th, &s->src, 3017 &s->dst, &rewrite)) { 3018 pf_normalize_tcp_cleanup(s); 3019 pf_src_tree_remove_state(s); 3020 pool_put(&pf_state_pl, s); 3021 return (PF_DROP); 3022 } 3023 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { 3024 pf_normalize_tcp_cleanup(s); 3025 REASON_SET(&reason, PFRES_MEMORY); 3026 pf_src_tree_remove_state(s); 3027 pool_put(&pf_state_pl, s); 3028 return (PF_DROP); 3029 } else 3030 *sm = s; 3031 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 3032 r->keep_state == PF_STATE_SYNPROXY) { 3033 s->src.state = PF_TCPS_PROXY_SRC; 3034 if (nr != NULL) { 3035 if (direction == PF_OUT) { 3036 pf_change_ap(saddr, &th->th_sport, 3037 pd->ip_sum, &th->th_sum, &pd->baddr, 3038 bport, 0, af); 3039 } else { 3040 pf_change_ap(daddr, &th->th_dport, 3041 pd->ip_sum, &th->th_sum, &pd->baddr, 3042 bport, 0, af); 3043 } 3044 } 3045 s->src.seqhi = arc4random(); 3046 /* Find mss option */ 3047 mss = pf_get_mss(m, off, th->th_off, af); 3048 mss = pf_calc_mss(saddr, af, mss); 3049 mss = pf_calc_mss(daddr, af, mss); 3050 s->src.mss = mss; 3051 pf_send_tcp(r, af, daddr, saddr, th->th_dport, 3052 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1, 3053 TH_SYN|TH_ACK, 0, s->src.mss, 0); 3054 return (PF_SYNPROXY_DROP); 3055 } 3056 } 3057 3058 /* copy back packet headers if we performed NAT operations */ 3059 if (rewrite) 3060 m_copyback(m, off, sizeof(*th), (caddr_t)th); 3061 3062 return (PF_PASS); 3063} 3064 3065int 3066pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction, 3067 struct pfi_kif *kif, struct mbuf *m, int off, void *h, 3068#ifdef __FreeBSD__ 3069 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3070 struct inpcb *inp) 3071#else 3072 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) 3073#endif 3074{ 3075 struct pf_rule *nr = NULL; 3076 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3077 struct udphdr *uh = pd->hdr.udp; 3078 u_int16_t bport, nport = 0; 3079 sa_family_t af = pd->af; 3080 int lookup = -1; 3081 uid_t uid; 3082 gid_t gid; 3083 struct pf_rule *r, *a = NULL; 3084 struct pf_ruleset *ruleset = NULL; 3085 struct pf_src_node *nsn = NULL; 3086 u_short reason; 3087 int rewrite = 0; 3088 struct pf_tag *pftag = NULL; 3089 int tag = -1; 3090 3091 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3092 3093 if (direction == PF_OUT) { 3094 bport = nport = uh->uh_sport; 3095 /* check outgoing packet for BINAT/NAT */ 3096 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 3097 saddr, uh->uh_sport, daddr, uh->uh_dport, 3098 &pd->naddr, &nport)) != NULL) { 3099 PF_ACPY(&pd->baddr, saddr, af); 3100 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, 3101 &uh->uh_sum, &pd->naddr, nport, 1, af); 3102 rewrite++; 3103 if (nr->natpass) 3104 r = NULL; 3105 pd->nat_rule = nr; 3106 } 3107 } else { 3108 bport = nport = uh->uh_dport; 3109 /* check incoming packet for BINAT/RDR */ 3110 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 3111 saddr, uh->uh_sport, daddr, uh->uh_dport, &pd->naddr, 3112 &nport)) != NULL) { 3113 PF_ACPY(&pd->baddr, daddr, af); 3114 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, 3115 &uh->uh_sum, &pd->naddr, nport, 1, af); 3116 rewrite++; 3117 if (nr->natpass) 3118 r = NULL; 3119 pd->nat_rule = nr; 3120 } 3121 } 3122 3123 while (r != NULL) { 3124 r->evaluations++; 3125 if (r->kif != NULL && 3126 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) 3127 r = r->skip[PF_SKIP_IFP].ptr; 3128 else if (r->direction && r->direction != direction) 3129 r = r->skip[PF_SKIP_DIR].ptr; 3130 else if (r->af && r->af != af) 3131 r = r->skip[PF_SKIP_AF].ptr; 3132 else if (r->proto && r->proto != IPPROTO_UDP) 3133 r = r->skip[PF_SKIP_PROTO].ptr; 3134 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) 3135 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3136 else if (r->src.port_op && !pf_match_port(r->src.port_op, 3137 r->src.port[0], r->src.port[1], uh->uh_sport)) 3138 r = r->skip[PF_SKIP_SRC_PORT].ptr; 3139 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) 3140 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3141 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 3142 r->dst.port[0], r->dst.port[1], uh->uh_dport)) 3143 r = r->skip[PF_SKIP_DST_PORT].ptr; 3144 else if (r->tos && !(r->tos & pd->tos)) 3145 r = TAILQ_NEXT(r, entries); 3146 else if (r->rule_flag & PFRULE_FRAGMENT) 3147 r = TAILQ_NEXT(r, entries); 3148 else if (r->uid.op && (lookup != -1 || (lookup = 3149#ifdef __FreeBSD__ 3150 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) && 3151#else 3152 pf_socket_lookup(&uid, &gid, direction, pd), 1)) && 3153#endif 3154 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 3155 uid)) 3156 r = TAILQ_NEXT(r, entries); 3157 else if (r->gid.op && (lookup != -1 || (lookup = 3158#ifdef __FreeBSD__ 3159 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) && 3160#else 3161 pf_socket_lookup(&uid, &gid, direction, pd), 1)) && 3162#endif 3163 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 3164 gid)) 3165 r = TAILQ_NEXT(r, entries); 3166 else if (r->match_tag && !pf_match_tag(m, r, nr, pftag, &tag)) 3167 r = TAILQ_NEXT(r, entries); 3168 else if (r->anchorname[0] && r->anchor == NULL) 3169 r = TAILQ_NEXT(r, entries); 3170 else if (r->os_fingerprint != PF_OSFP_ANY) 3171 r = TAILQ_NEXT(r, entries); 3172 else { 3173 if (r->tag) 3174 tag = r->tag; 3175 if (r->anchor == NULL) { 3176 *rm = r; 3177 *am = a; 3178 *rsm = ruleset; 3179 if ((*rm)->quick) 3180 break; 3181 r = TAILQ_NEXT(r, entries); 3182 } else 3183 PF_STEP_INTO_ANCHOR(r, a, ruleset, 3184 PF_RULESET_FILTER); 3185 } 3186 if (r == NULL && a != NULL) 3187 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3188 PF_RULESET_FILTER); 3189 } 3190 r = *rm; 3191 a = *am; 3192 ruleset = *rsm; 3193 3194 REASON_SET(&reason, PFRES_MATCH); 3195 3196 if (r->log) { 3197 if (rewrite) 3198 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 3199 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); 3200 } 3201 3202 if ((r->action == PF_DROP) && 3203 ((r->rule_flag & PFRULE_RETURNICMP) || 3204 (r->rule_flag & PFRULE_RETURN))) { 3205 /* undo NAT changes, if they have taken place */ 3206 if (nr != NULL) { 3207 if (direction == PF_OUT) { 3208 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, 3209 &uh->uh_sum, &pd->baddr, bport, 1, af); 3210 rewrite++; 3211 } else { 3212 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, 3213 &uh->uh_sum, &pd->baddr, bport, 1, af); 3214 rewrite++; 3215 } 3216 } 3217 if ((af == AF_INET) && r->return_icmp) 3218 pf_send_icmp(m, r->return_icmp >> 8, 3219 r->return_icmp & 255, af, r); 3220 else if ((af == AF_INET6) && r->return_icmp6) 3221 pf_send_icmp(m, r->return_icmp6 >> 8, 3222 r->return_icmp6 & 255, af, r); 3223 } 3224 3225 if (r->action == PF_DROP) 3226 return (PF_DROP); 3227 3228 if (pf_tag_packet(m, pftag, tag)) { 3229 REASON_SET(&reason, PFRES_MEMORY); 3230 return (PF_DROP); 3231 } 3232 3233 if (r->keep_state || nr != NULL) { 3234 /* create new state */ 3235 struct pf_state *s = NULL; 3236 struct pf_src_node *sn = NULL; 3237 3238 /* check maximums */ 3239 if (r->max_states && (r->states >= r->max_states)) 3240 goto cleanup; 3241 /* src node for flter rule */ 3242 if ((r->rule_flag & PFRULE_SRCTRACK || 3243 r->rpool.opts & PF_POOL_STICKYADDR) && 3244 pf_insert_src_node(&sn, r, saddr, af) != 0) 3245 goto cleanup; 3246 /* src node for translation rule */ 3247 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 3248 ((direction == PF_OUT && 3249 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 3250 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) 3251 goto cleanup; 3252 s = pool_get(&pf_state_pl, PR_NOWAIT); 3253 if (s == NULL) { 3254cleanup: 3255 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 3256 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 3257 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3258 pf_status.src_nodes--; 3259 pool_put(&pf_src_tree_pl, sn); 3260 } 3261 if (nsn != sn && nsn != NULL && nsn->states == 0 && 3262 nsn->expire == 0) { 3263 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 3264 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3265 pf_status.src_nodes--; 3266 pool_put(&pf_src_tree_pl, nsn); 3267 } 3268 REASON_SET(&reason, PFRES_MEMORY); 3269 return (PF_DROP); 3270 } 3271 bzero(s, sizeof(*s)); 3272 r->states++; 3273 if (a != NULL) 3274 a->states++; 3275 s->rule.ptr = r; 3276 s->nat_rule.ptr = nr; 3277 if (s->nat_rule.ptr != NULL) 3278 s->nat_rule.ptr->states++; 3279 s->anchor.ptr = a; 3280 s->allow_opts = r->allow_opts; 3281 s->log = r->log & 2; 3282 s->proto = IPPROTO_UDP; 3283 s->direction = direction; 3284 s->af = af; 3285 if (direction == PF_OUT) { 3286 PF_ACPY(&s->gwy.addr, saddr, af); 3287 s->gwy.port = uh->uh_sport; 3288 PF_ACPY(&s->ext.addr, daddr, af); 3289 s->ext.port = uh->uh_dport; 3290 if (nr != NULL) { 3291 PF_ACPY(&s->lan.addr, &pd->baddr, af); 3292 s->lan.port = bport; 3293 } else { 3294 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 3295 s->lan.port = s->gwy.port; 3296 } 3297 } else { 3298 PF_ACPY(&s->lan.addr, daddr, af); 3299 s->lan.port = uh->uh_dport; 3300 PF_ACPY(&s->ext.addr, saddr, af); 3301 s->ext.port = uh->uh_sport; 3302 if (nr != NULL) { 3303 PF_ACPY(&s->gwy.addr, &pd->baddr, af); 3304 s->gwy.port = bport; 3305 } else { 3306 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3307 s->gwy.port = s->lan.port; 3308 } 3309 } 3310 s->src.state = PFUDPS_SINGLE; 3311 s->dst.state = PFUDPS_NO_TRAFFIC; 3312#ifdef __FreeBSD__ 3313 s->creation = time_second; 3314 s->expire = time_second; 3315#else 3316 s->creation = time.tv_sec; 3317 s->expire = time.tv_sec; 3318#endif 3319 s->timeout = PFTM_UDP_FIRST_PACKET; 3320 pf_set_rt_ifp(s, saddr); 3321 if (sn != NULL) { 3322 s->src_node = sn; 3323 s->src_node->states++; 3324 } 3325 if (nsn != NULL) { 3326 PF_ACPY(&nsn->raddr, &pd->naddr, af); 3327 s->nat_src_node = nsn; 3328 s->nat_src_node->states++; 3329 } 3330 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { 3331 REASON_SET(&reason, PFRES_MEMORY); 3332 pf_src_tree_remove_state(s); 3333 pool_put(&pf_state_pl, s); 3334 return (PF_DROP); 3335 } else 3336 *sm = s; 3337 } 3338 3339 /* copy back packet headers if we performed NAT operations */ 3340 if (rewrite) 3341 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 3342 3343 return (PF_PASS); 3344} 3345 3346int 3347pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction, 3348 struct pfi_kif *kif, struct mbuf *m, int off, void *h, 3349 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) 3350{ 3351 struct pf_rule *nr = NULL; 3352 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3353 struct pf_rule *r, *a = NULL; 3354 struct pf_ruleset *ruleset = NULL; 3355 struct pf_src_node *nsn = NULL; 3356 u_short reason; 3357 u_int16_t icmpid = 0; /* make the compiler happy */ 3358 sa_family_t af = pd->af; 3359 u_int8_t icmptype = 0; /* make the compiler happy */ 3360 u_int8_t icmpcode = 0; /* make the compiler happy */ 3361 int state_icmp = 0; 3362 struct pf_tag *pftag = NULL; 3363 int tag = -1; 3364#ifdef INET6 3365 int rewrite = 0; 3366#endif /* INET6 */ 3367 3368 switch (pd->proto) { 3369#ifdef INET 3370 case IPPROTO_ICMP: 3371 icmptype = pd->hdr.icmp->icmp_type; 3372 icmpcode = pd->hdr.icmp->icmp_code; 3373 icmpid = pd->hdr.icmp->icmp_id; 3374 3375 if (icmptype == ICMP_UNREACH || 3376 icmptype == ICMP_SOURCEQUENCH || 3377 icmptype == ICMP_REDIRECT || 3378 icmptype == ICMP_TIMXCEED || 3379 icmptype == ICMP_PARAMPROB) 3380 state_icmp++; 3381 break; 3382#endif /* INET */ 3383#ifdef INET6 3384 case IPPROTO_ICMPV6: 3385 icmptype = pd->hdr.icmp6->icmp6_type; 3386 icmpcode = pd->hdr.icmp6->icmp6_code; 3387 icmpid = pd->hdr.icmp6->icmp6_id; 3388 3389 if (icmptype == ICMP6_DST_UNREACH || 3390 icmptype == ICMP6_PACKET_TOO_BIG || 3391 icmptype == ICMP6_TIME_EXCEEDED || 3392 icmptype == ICMP6_PARAM_PROB) 3393 state_icmp++; 3394 break; 3395#endif /* INET6 */ 3396 } 3397 3398 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3399 3400 if (direction == PF_OUT) { 3401 /* check outgoing packet for BINAT/NAT */ 3402 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 3403 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { 3404 PF_ACPY(&pd->baddr, saddr, af); 3405 switch (af) { 3406#ifdef INET 3407 case AF_INET: 3408 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, 3409 pd->naddr.v4.s_addr, 0); 3410 break; 3411#endif /* INET */ 3412#ifdef INET6 3413 case AF_INET6: 3414 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum, 3415 &pd->naddr, 0); 3416 rewrite++; 3417 break; 3418#endif /* INET6 */ 3419 } 3420 if (nr->natpass) 3421 r = NULL; 3422 pd->nat_rule = nr; 3423 } 3424 } else { 3425 /* check incoming packet for BINAT/RDR */ 3426 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 3427 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { 3428 PF_ACPY(&pd->baddr, daddr, af); 3429 switch (af) { 3430#ifdef INET 3431 case AF_INET: 3432 pf_change_a(&daddr->v4.s_addr, 3433 pd->ip_sum, pd->naddr.v4.s_addr, 0); 3434 break; 3435#endif /* INET */ 3436#ifdef INET6 3437 case AF_INET6: 3438 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, 3439 &pd->naddr, 0); 3440 rewrite++; 3441 break; 3442#endif /* INET6 */ 3443 } 3444 if (nr->natpass) 3445 r = NULL; 3446 pd->nat_rule = nr; 3447 } 3448 } 3449 3450 while (r != NULL) { 3451 r->evaluations++; 3452 if (r->kif != NULL && 3453 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) 3454 r = r->skip[PF_SKIP_IFP].ptr; 3455 else if (r->direction && r->direction != direction) 3456 r = r->skip[PF_SKIP_DIR].ptr; 3457 else if (r->af && r->af != af) 3458 r = r->skip[PF_SKIP_AF].ptr; 3459 else if (r->proto && r->proto != pd->proto) 3460 r = r->skip[PF_SKIP_PROTO].ptr; 3461 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) 3462 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3463 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) 3464 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3465 else if (r->type && r->type != icmptype + 1) 3466 r = TAILQ_NEXT(r, entries); 3467 else if (r->code && r->code != icmpcode + 1) 3468 r = TAILQ_NEXT(r, entries); 3469 else if (r->tos && !(r->tos & pd->tos)) 3470 r = TAILQ_NEXT(r, entries); 3471 else if (r->rule_flag & PFRULE_FRAGMENT) 3472 r = TAILQ_NEXT(r, entries); 3473 else if (r->match_tag && !pf_match_tag(m, r, nr, pftag, &tag)) 3474 r = TAILQ_NEXT(r, entries); 3475 else if (r->anchorname[0] && r->anchor == NULL) 3476 r = TAILQ_NEXT(r, entries); 3477 else if (r->os_fingerprint != PF_OSFP_ANY) 3478 r = TAILQ_NEXT(r, entries); 3479 else { 3480 if (r->tag) 3481 tag = r->tag; 3482 if (r->anchor == NULL) { 3483 *rm = r; 3484 *am = a; 3485 *rsm = ruleset; 3486 if ((*rm)->quick) 3487 break; 3488 r = TAILQ_NEXT(r, entries); 3489 } else 3490 PF_STEP_INTO_ANCHOR(r, a, ruleset, 3491 PF_RULESET_FILTER); 3492 } 3493 if (r == NULL && a != NULL) 3494 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3495 PF_RULESET_FILTER); 3496 } 3497 r = *rm; 3498 a = *am; 3499 ruleset = *rsm; 3500 3501 REASON_SET(&reason, PFRES_MATCH); 3502 3503 if (r->log) { 3504#ifdef INET6 3505 if (rewrite) 3506 m_copyback(m, off, sizeof(struct icmp6_hdr), 3507 (caddr_t)pd->hdr.icmp6); 3508#endif /* INET6 */ 3509 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); 3510 } 3511 3512 if (r->action != PF_PASS) 3513 return (PF_DROP); 3514 3515 if (pf_tag_packet(m, pftag, tag)) { 3516 REASON_SET(&reason, PFRES_MEMORY); 3517 return (PF_DROP); 3518 } 3519 3520 if (!state_icmp && (r->keep_state || nr != NULL)) { 3521 /* create new state */ 3522 struct pf_state *s = NULL; 3523 struct pf_src_node *sn = NULL; 3524 3525 /* check maximums */ 3526 if (r->max_states && (r->states >= r->max_states)) 3527 goto cleanup; 3528 /* src node for flter rule */ 3529 if ((r->rule_flag & PFRULE_SRCTRACK || 3530 r->rpool.opts & PF_POOL_STICKYADDR) && 3531 pf_insert_src_node(&sn, r, saddr, af) != 0) 3532 goto cleanup; 3533 /* src node for translation rule */ 3534 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 3535 ((direction == PF_OUT && 3536 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 3537 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) 3538 goto cleanup; 3539 s = pool_get(&pf_state_pl, PR_NOWAIT); 3540 if (s == NULL) { 3541cleanup: 3542 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 3543 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 3544 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3545 pf_status.src_nodes--; 3546 pool_put(&pf_src_tree_pl, sn); 3547 } 3548 if (nsn != sn && nsn != NULL && nsn->states == 0 && 3549 nsn->expire == 0) { 3550 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 3551 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3552 pf_status.src_nodes--; 3553 pool_put(&pf_src_tree_pl, nsn); 3554 } 3555 REASON_SET(&reason, PFRES_MEMORY); 3556 return (PF_DROP); 3557 } 3558 bzero(s, sizeof(*s)); 3559 r->states++; 3560 if (a != NULL) 3561 a->states++; 3562 s->rule.ptr = r; 3563 s->nat_rule.ptr = nr; 3564 if (s->nat_rule.ptr != NULL) 3565 s->nat_rule.ptr->states++; 3566 s->anchor.ptr = a; 3567 s->allow_opts = r->allow_opts; 3568 s->log = r->log & 2; 3569 s->proto = pd->proto; 3570 s->direction = direction; 3571 s->af = af; 3572 if (direction == PF_OUT) { 3573 PF_ACPY(&s->gwy.addr, saddr, af); 3574 s->gwy.port = icmpid; 3575 PF_ACPY(&s->ext.addr, daddr, af); 3576 s->ext.port = icmpid; 3577 if (nr != NULL) 3578 PF_ACPY(&s->lan.addr, &pd->baddr, af); 3579 else 3580 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 3581 s->lan.port = icmpid; 3582 } else { 3583 PF_ACPY(&s->lan.addr, daddr, af); 3584 s->lan.port = icmpid; 3585 PF_ACPY(&s->ext.addr, saddr, af); 3586 s->ext.port = icmpid; 3587 if (nr != NULL) 3588 PF_ACPY(&s->gwy.addr, &pd->baddr, af); 3589 else 3590 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3591 s->gwy.port = icmpid; 3592 } 3593#ifdef __FreeBSD__ 3594 s->creation = time_second; 3595 s->expire = time_second; 3596#else 3597 s->creation = time.tv_sec; 3598 s->expire = time.tv_sec; 3599#endif 3600 s->timeout = PFTM_ICMP_FIRST_PACKET; 3601 pf_set_rt_ifp(s, saddr); 3602 if (sn != NULL) { 3603 s->src_node = sn; 3604 s->src_node->states++; 3605 } 3606 if (nsn != NULL) { 3607 PF_ACPY(&nsn->raddr, &pd->naddr, af); 3608 s->nat_src_node = nsn; 3609 s->nat_src_node->states++; 3610 } 3611 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { 3612 REASON_SET(&reason, PFRES_MEMORY); 3613 pf_src_tree_remove_state(s); 3614 pool_put(&pf_state_pl, s); 3615 return (PF_DROP); 3616 } else 3617 *sm = s; 3618 } 3619 3620#ifdef INET6 3621 /* copy back packet headers if we performed IPv6 NAT operations */ 3622 if (rewrite) 3623 m_copyback(m, off, sizeof(struct icmp6_hdr), 3624 (caddr_t)pd->hdr.icmp6); 3625#endif /* INET6 */ 3626 3627 return (PF_PASS); 3628} 3629 3630int 3631pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction, 3632 struct pfi_kif *kif, struct mbuf *m, int off, void *h, struct pf_pdesc *pd, 3633 struct pf_rule **am, struct pf_ruleset **rsm) 3634{ 3635 struct pf_rule *nr = NULL; 3636 struct pf_rule *r, *a = NULL; 3637 struct pf_ruleset *ruleset = NULL; 3638 struct pf_src_node *nsn = NULL; 3639 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3640 sa_family_t af = pd->af; 3641 u_short reason; 3642 struct pf_tag *pftag = NULL; 3643 int tag = -1; 3644 3645 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3646 3647 if (direction == PF_OUT) { 3648 /* check outgoing packet for BINAT/NAT */ 3649 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 3650 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { 3651 PF_ACPY(&pd->baddr, saddr, af); 3652 switch (af) { 3653#ifdef INET 3654 case AF_INET: 3655 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, 3656 pd->naddr.v4.s_addr, 0); 3657 break; 3658#endif /* INET */ 3659#ifdef INET6 3660 case AF_INET6: 3661 PF_ACPY(saddr, &pd->naddr, af); 3662 break; 3663#endif /* INET6 */ 3664 } 3665 if (nr->natpass) 3666 r = NULL; 3667 pd->nat_rule = nr; 3668 } 3669 } else { 3670 /* check incoming packet for BINAT/RDR */ 3671 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 3672 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { 3673 PF_ACPY(&pd->baddr, daddr, af); 3674 switch (af) { 3675#ifdef INET 3676 case AF_INET: 3677 pf_change_a(&daddr->v4.s_addr, 3678 pd->ip_sum, pd->naddr.v4.s_addr, 0); 3679 break; 3680#endif /* INET */ 3681#ifdef INET6 3682 case AF_INET6: 3683 PF_ACPY(daddr, &pd->naddr, af); 3684 break; 3685#endif /* INET6 */ 3686 } 3687 if (nr->natpass) 3688 r = NULL; 3689 pd->nat_rule = nr; 3690 } 3691 } 3692 3693 while (r != NULL) { 3694 r->evaluations++; 3695 if (r->kif != NULL && 3696 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) 3697 r = r->skip[PF_SKIP_IFP].ptr; 3698 else if (r->direction && r->direction != direction) 3699 r = r->skip[PF_SKIP_DIR].ptr; 3700 else if (r->af && r->af != af) 3701 r = r->skip[PF_SKIP_AF].ptr; 3702 else if (r->proto && r->proto != pd->proto) 3703 r = r->skip[PF_SKIP_PROTO].ptr; 3704 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not)) 3705 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3706 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not)) 3707 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3708 else if (r->tos && !(r->tos & pd->tos)) 3709 r = TAILQ_NEXT(r, entries); 3710 else if (r->rule_flag & PFRULE_FRAGMENT) 3711 r = TAILQ_NEXT(r, entries); 3712 else if (r->match_tag && !pf_match_tag(m, r, nr, pftag, &tag)) 3713 r = TAILQ_NEXT(r, entries); 3714 else if (r->anchorname[0] && r->anchor == NULL) 3715 r = TAILQ_NEXT(r, entries); 3716 else if (r->os_fingerprint != PF_OSFP_ANY) 3717 r = TAILQ_NEXT(r, entries); 3718 else { 3719 if (r->tag) 3720 tag = r->tag; 3721 if (r->anchor == NULL) { 3722 *rm = r; 3723 *am = a; 3724 *rsm = ruleset; 3725 if ((*rm)->quick) 3726 break; 3727 r = TAILQ_NEXT(r, entries); 3728 } else 3729 PF_STEP_INTO_ANCHOR(r, a, ruleset, 3730 PF_RULESET_FILTER); 3731 } 3732 if (r == NULL && a != NULL) 3733 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3734 PF_RULESET_FILTER); 3735 } 3736 r = *rm; 3737 a = *am; 3738 ruleset = *rsm; 3739 3740 REASON_SET(&reason, PFRES_MATCH); 3741 3742 if (r->log) 3743 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); 3744 3745 if ((r->action == PF_DROP) && 3746 ((r->rule_flag & PFRULE_RETURNICMP) || 3747 (r->rule_flag & PFRULE_RETURN))) { 3748 struct pf_addr *a = NULL; 3749 3750 if (nr != NULL) { 3751 if (direction == PF_OUT) 3752 a = saddr; 3753 else 3754 a = daddr; 3755 } 3756 if (a != NULL) { 3757 switch (af) { 3758#ifdef INET 3759 case AF_INET: 3760 pf_change_a(&a->v4.s_addr, pd->ip_sum, 3761 pd->baddr.v4.s_addr, 0); 3762 break; 3763#endif /* INET */ 3764#ifdef INET6 3765 case AF_INET6: 3766 PF_ACPY(a, &pd->baddr, af); 3767 break; 3768#endif /* INET6 */ 3769 } 3770 } 3771 if ((af == AF_INET) && r->return_icmp) 3772 pf_send_icmp(m, r->return_icmp >> 8, 3773 r->return_icmp & 255, af, r); 3774 else if ((af == AF_INET6) && r->return_icmp6) 3775 pf_send_icmp(m, r->return_icmp6 >> 8, 3776 r->return_icmp6 & 255, af, r); 3777 } 3778 3779 if (r->action != PF_PASS) 3780 return (PF_DROP); 3781 3782 if (pf_tag_packet(m, pftag, tag)) { 3783 REASON_SET(&reason, PFRES_MEMORY); 3784 return (PF_DROP); 3785 } 3786 3787 if (r->keep_state || nr != NULL) { 3788 /* create new state */ 3789 struct pf_state *s = NULL; 3790 struct pf_src_node *sn = NULL; 3791 3792 /* check maximums */ 3793 if (r->max_states && (r->states >= r->max_states)) 3794 goto cleanup; 3795 /* src node for flter rule */ 3796 if ((r->rule_flag & PFRULE_SRCTRACK || 3797 r->rpool.opts & PF_POOL_STICKYADDR) && 3798 pf_insert_src_node(&sn, r, saddr, af) != 0) 3799 goto cleanup; 3800 /* src node for translation rule */ 3801 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 3802 ((direction == PF_OUT && 3803 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 3804 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) 3805 goto cleanup; 3806 s = pool_get(&pf_state_pl, PR_NOWAIT); 3807 if (s == NULL) { 3808cleanup: 3809 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 3810 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 3811 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3812 pf_status.src_nodes--; 3813 pool_put(&pf_src_tree_pl, sn); 3814 } 3815 if (nsn != sn && nsn != NULL && nsn->states == 0 && 3816 nsn->expire == 0) { 3817 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 3818 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3819 pf_status.src_nodes--; 3820 pool_put(&pf_src_tree_pl, nsn); 3821 } 3822 REASON_SET(&reason, PFRES_MEMORY); 3823 return (PF_DROP); 3824 } 3825 bzero(s, sizeof(*s)); 3826 r->states++; 3827 if (a != NULL) 3828 a->states++; 3829 s->rule.ptr = r; 3830 s->nat_rule.ptr = nr; 3831 if (s->nat_rule.ptr != NULL) 3832 s->nat_rule.ptr->states++; 3833 s->anchor.ptr = a; 3834 s->allow_opts = r->allow_opts; 3835 s->log = r->log & 2; 3836 s->proto = pd->proto; 3837 s->direction = direction; 3838 s->af = af; 3839 if (direction == PF_OUT) { 3840 PF_ACPY(&s->gwy.addr, saddr, af); 3841 PF_ACPY(&s->ext.addr, daddr, af); 3842 if (nr != NULL) 3843 PF_ACPY(&s->lan.addr, &pd->baddr, af); 3844 else 3845 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 3846 } else { 3847 PF_ACPY(&s->lan.addr, daddr, af); 3848 PF_ACPY(&s->ext.addr, saddr, af); 3849 if (nr != NULL) 3850 PF_ACPY(&s->gwy.addr, &pd->baddr, af); 3851 else 3852 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3853 } 3854 s->src.state = PFOTHERS_SINGLE; 3855 s->dst.state = PFOTHERS_NO_TRAFFIC; 3856#ifdef __FreeBSD__ 3857 s->creation = time_second; 3858 s->expire = time_second; 3859#else 3860 s->creation = time.tv_sec; 3861 s->expire = time.tv_sec; 3862#endif 3863 s->timeout = PFTM_OTHER_FIRST_PACKET; 3864 pf_set_rt_ifp(s, saddr); 3865 if (sn != NULL) { 3866 s->src_node = sn; 3867 s->src_node->states++; 3868 } 3869 if (nsn != NULL) { 3870 PF_ACPY(&nsn->raddr, &pd->naddr, af); 3871 s->nat_src_node = nsn; 3872 s->nat_src_node->states++; 3873 } 3874 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { 3875 REASON_SET(&reason, PFRES_MEMORY); 3876 pf_src_tree_remove_state(s); 3877 pool_put(&pf_state_pl, s); 3878 return (PF_DROP); 3879 } else 3880 *sm = s; 3881 } 3882 3883 return (PF_PASS); 3884} 3885 3886int 3887pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, 3888 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, 3889 struct pf_ruleset **rsm) 3890{ 3891 struct pf_rule *r, *a = NULL; 3892 struct pf_ruleset *ruleset = NULL; 3893 sa_family_t af = pd->af; 3894 u_short reason; 3895 struct pf_tag *pftag = NULL; 3896 int tag = -1; 3897 3898 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3899 while (r != NULL) { 3900 r->evaluations++; 3901 if (r->kif != NULL && 3902 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) 3903 r = r->skip[PF_SKIP_IFP].ptr; 3904 else if (r->direction && r->direction != direction) 3905 r = r->skip[PF_SKIP_DIR].ptr; 3906 else if (r->af && r->af != af) 3907 r = r->skip[PF_SKIP_AF].ptr; 3908 else if (r->proto && r->proto != pd->proto) 3909 r = r->skip[PF_SKIP_PROTO].ptr; 3910 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not)) 3911 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3912 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not)) 3913 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3914 else if (r->tos && !(r->tos & pd->tos)) 3915 r = TAILQ_NEXT(r, entries); 3916 else if (r->src.port_op || r->dst.port_op || 3917 r->flagset || r->type || r->code || 3918 r->os_fingerprint != PF_OSFP_ANY) 3919 r = TAILQ_NEXT(r, entries); 3920 else if (r->match_tag && !pf_match_tag(m, r, NULL, pftag, &tag)) 3921 r = TAILQ_NEXT(r, entries); 3922 else if (r->anchorname[0] && r->anchor == NULL) 3923 r = TAILQ_NEXT(r, entries); 3924 else { 3925 if (r->anchor == NULL) { 3926 *rm = r; 3927 *am = a; 3928 *rsm = ruleset; 3929 if ((*rm)->quick) 3930 break; 3931 r = TAILQ_NEXT(r, entries); 3932 } else 3933 PF_STEP_INTO_ANCHOR(r, a, ruleset, 3934 PF_RULESET_FILTER); 3935 } 3936 if (r == NULL && a != NULL) 3937 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3938 PF_RULESET_FILTER); 3939 } 3940 r = *rm; 3941 a = *am; 3942 ruleset = *rsm; 3943 3944 REASON_SET(&reason, PFRES_MATCH); 3945 3946 if (r->log) 3947 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); 3948 3949 if (r->action != PF_PASS) 3950 return (PF_DROP); 3951 3952 if (pf_tag_packet(m, pftag, tag)) { 3953 REASON_SET(&reason, PFRES_MEMORY); 3954 return (PF_DROP); 3955 } 3956 3957 return (PF_PASS); 3958} 3959 3960int 3961pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, 3962 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, 3963 u_short *reason) 3964{ 3965 struct pf_state key; 3966 struct tcphdr *th = pd->hdr.tcp; 3967 u_int16_t win = ntohs(th->th_win); 3968 u_int32_t ack, end, seq; 3969 u_int8_t sws, dws; 3970 int ackskew; 3971 int copyback = 0; 3972 struct pf_state_peer *src, *dst; 3973 3974 key.af = pd->af; 3975 key.proto = IPPROTO_TCP; 3976 if (direction == PF_IN) { 3977 PF_ACPY(&key.ext.addr, pd->src, key.af); 3978 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 3979 key.ext.port = th->th_sport; 3980 key.gwy.port = th->th_dport; 3981 } else { 3982 PF_ACPY(&key.lan.addr, pd->src, key.af); 3983 PF_ACPY(&key.ext.addr, pd->dst, key.af); 3984 key.lan.port = th->th_sport; 3985 key.ext.port = th->th_dport; 3986 } 3987 3988 STATE_LOOKUP(); 3989 3990 if (direction == (*state)->direction) { 3991 src = &(*state)->src; 3992 dst = &(*state)->dst; 3993 } else { 3994 src = &(*state)->dst; 3995 dst = &(*state)->src; 3996 } 3997 3998 if ((*state)->src.state == PF_TCPS_PROXY_SRC) { 3999 if (direction != (*state)->direction) 4000 return (PF_SYNPROXY_DROP); 4001 if (th->th_flags & TH_SYN) { 4002 if (ntohl(th->th_seq) != (*state)->src.seqlo) 4003 return (PF_DROP); 4004 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4005 pd->src, th->th_dport, th->th_sport, 4006 (*state)->src.seqhi, ntohl(th->th_seq) + 1, 4007 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0); 4008 return (PF_SYNPROXY_DROP); 4009 } else if (!(th->th_flags & TH_ACK) || 4010 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 4011 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) 4012 return (PF_DROP); 4013 else 4014 (*state)->src.state = PF_TCPS_PROXY_DST; 4015 } 4016 if ((*state)->src.state == PF_TCPS_PROXY_DST) { 4017 struct pf_state_host *src, *dst; 4018 4019 if (direction == PF_OUT) { 4020 src = &(*state)->gwy; 4021 dst = &(*state)->ext; 4022 } else { 4023 src = &(*state)->ext; 4024 dst = &(*state)->lan; 4025 } 4026 if (direction == (*state)->direction) { 4027 if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) || 4028 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 4029 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) 4030 return (PF_DROP); 4031 (*state)->src.max_win = MAX(ntohs(th->th_win), 1); 4032 if ((*state)->dst.seqhi == 1) 4033 (*state)->dst.seqhi = arc4random(); 4034 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 4035 &dst->addr, src->port, dst->port, 4036 (*state)->dst.seqhi, 0, TH_SYN, 0, 4037 (*state)->src.mss, 0); 4038 return (PF_SYNPROXY_DROP); 4039 } else if (((th->th_flags & (TH_SYN|TH_ACK)) != 4040 (TH_SYN|TH_ACK)) || 4041 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) 4042 return (PF_DROP); 4043 else { 4044 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1); 4045 (*state)->dst.seqlo = ntohl(th->th_seq); 4046 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4047 pd->src, th->th_dport, th->th_sport, 4048 ntohl(th->th_ack), ntohl(th->th_seq) + 1, 4049 TH_ACK, (*state)->src.max_win, 0, 0); 4050 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 4051 &dst->addr, src->port, dst->port, 4052 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1, 4053 TH_ACK, (*state)->dst.max_win, 0, 0); 4054 (*state)->src.seqdiff = (*state)->dst.seqhi - 4055 (*state)->src.seqlo; 4056 (*state)->dst.seqdiff = (*state)->src.seqhi - 4057 (*state)->dst.seqlo; 4058 (*state)->src.seqhi = (*state)->src.seqlo + 4059 (*state)->src.max_win; 4060 (*state)->dst.seqhi = (*state)->dst.seqlo + 4061 (*state)->dst.max_win; 4062 (*state)->src.wscale = (*state)->dst.wscale = 0; 4063 (*state)->src.state = (*state)->dst.state = 4064 TCPS_ESTABLISHED; 4065 return (PF_SYNPROXY_DROP); 4066 } 4067 } 4068 4069 if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) { 4070 sws = src->wscale & PF_WSCALE_MASK; 4071 dws = dst->wscale & PF_WSCALE_MASK; 4072 } else 4073 sws = dws = 0; 4074 4075 /* 4076 * Sequence tracking algorithm from Guido van Rooij's paper: 4077 * http://www.madison-gurkha.com/publications/tcp_filtering/ 4078 * tcp_filtering.ps 4079 */ 4080 4081 seq = ntohl(th->th_seq); 4082 if (src->seqlo == 0) { 4083 /* First packet from this end. Set its state */ 4084 4085 if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) && 4086 src->scrub == NULL) { 4087 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) { 4088 REASON_SET(reason, PFRES_MEMORY); 4089 return (PF_DROP); 4090 } 4091 } 4092 4093 /* Deferred generation of sequence number modulator */ 4094 if (dst->seqdiff && !src->seqdiff) { 4095 while ((src->seqdiff = arc4random()) == 0) 4096 ; 4097 ack = ntohl(th->th_ack) - dst->seqdiff; 4098 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4099 src->seqdiff), 0); 4100 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4101 copyback = 1; 4102 } else { 4103 ack = ntohl(th->th_ack); 4104 } 4105 4106 end = seq + pd->p_len; 4107 if (th->th_flags & TH_SYN) { 4108 end++; 4109 if (dst->wscale & PF_WSCALE_FLAG) { 4110 src->wscale = pf_get_wscale(m, off, th->th_off, 4111 pd->af); 4112 if (src->wscale & PF_WSCALE_FLAG) { 4113 /* Remove scale factor from initial 4114 * window */ 4115 sws = src->wscale & PF_WSCALE_MASK; 4116 win = ((u_int32_t)win + (1 << sws) - 1) 4117 >> sws; 4118 dws = dst->wscale & PF_WSCALE_MASK; 4119 } else { 4120 /* fixup other window */ 4121 dst->max_win <<= dst->wscale & 4122 PF_WSCALE_MASK; 4123 /* in case of a retrans SYN|ACK */ 4124 dst->wscale = 0; 4125 } 4126 } 4127 } 4128 if (th->th_flags & TH_FIN) 4129 end++; 4130 4131 src->seqlo = seq; 4132 if (src->state < TCPS_SYN_SENT) 4133 src->state = TCPS_SYN_SENT; 4134 4135 /* 4136 * May need to slide the window (seqhi may have been set by 4137 * the crappy stack check or if we picked up the connection 4138 * after establishment) 4139 */ 4140 if (src->seqhi == 1 || 4141 SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi)) 4142 src->seqhi = end + MAX(1, dst->max_win << dws); 4143 if (win > src->max_win) 4144 src->max_win = win; 4145 4146 } else { 4147 ack = ntohl(th->th_ack) - dst->seqdiff; 4148 if (src->seqdiff) { 4149 /* Modulate sequence numbers */ 4150 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4151 src->seqdiff), 0); 4152 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4153 copyback = 1; 4154 } 4155 end = seq + pd->p_len; 4156 if (th->th_flags & TH_SYN) 4157 end++; 4158 if (th->th_flags & TH_FIN) 4159 end++; 4160 } 4161 4162 if ((th->th_flags & TH_ACK) == 0) { 4163 /* Let it pass through the ack skew check */ 4164 ack = dst->seqlo; 4165 } else if ((ack == 0 && 4166 (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) || 4167 /* broken tcp stacks do not set ack */ 4168 (dst->state < TCPS_SYN_SENT)) { 4169 /* 4170 * Many stacks (ours included) will set the ACK number in an 4171 * FIN|ACK if the SYN times out -- no sequence to ACK. 4172 */ 4173 ack = dst->seqlo; 4174 } 4175 4176 if (seq == end) { 4177 /* Ease sequencing restrictions on no data packets */ 4178 seq = src->seqlo; 4179 end = seq; 4180 } 4181 4182 ackskew = dst->seqlo - ack; 4183 4184#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */ 4185 if (SEQ_GEQ(src->seqhi, end) && 4186 /* Last octet inside other's window space */ 4187 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) && 4188 /* Retrans: not more than one window back */ 4189 (ackskew >= -MAXACKWINDOW) && 4190 /* Acking not more than one reassembled fragment backwards */ 4191 (ackskew <= (MAXACKWINDOW << sws))) { 4192 /* Acking not more than one window forward */ 4193 4194 /* update max window */ 4195 if (src->max_win < win) 4196 src->max_win = win; 4197 /* synchronize sequencing */ 4198 if (SEQ_GT(end, src->seqlo)) 4199 src->seqlo = end; 4200 /* slide the window of what the other end can send */ 4201 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) 4202 dst->seqhi = ack + MAX((win << sws), 1); 4203 4204 4205 /* update states */ 4206 if (th->th_flags & TH_SYN) 4207 if (src->state < TCPS_SYN_SENT) 4208 src->state = TCPS_SYN_SENT; 4209 if (th->th_flags & TH_FIN) 4210 if (src->state < TCPS_CLOSING) 4211 src->state = TCPS_CLOSING; 4212 if (th->th_flags & TH_ACK) { 4213 if (dst->state == TCPS_SYN_SENT) 4214 dst->state = TCPS_ESTABLISHED; 4215 else if (dst->state == TCPS_CLOSING) 4216 dst->state = TCPS_FIN_WAIT_2; 4217 } 4218 if (th->th_flags & TH_RST) 4219 src->state = dst->state = TCPS_TIME_WAIT; 4220 4221 /* update expire time */ 4222#ifdef __FreeBSD__ 4223 (*state)->expire = time_second; 4224#else 4225 (*state)->expire = time.tv_sec; 4226#endif 4227 if (src->state >= TCPS_FIN_WAIT_2 && 4228 dst->state >= TCPS_FIN_WAIT_2) 4229 (*state)->timeout = PFTM_TCP_CLOSED; 4230 else if (src->state >= TCPS_FIN_WAIT_2 || 4231 dst->state >= TCPS_FIN_WAIT_2) 4232 (*state)->timeout = PFTM_TCP_FIN_WAIT; 4233 else if (src->state < TCPS_ESTABLISHED || 4234 dst->state < TCPS_ESTABLISHED) 4235 (*state)->timeout = PFTM_TCP_OPENING; 4236 else if (src->state >= TCPS_CLOSING || 4237 dst->state >= TCPS_CLOSING) 4238 (*state)->timeout = PFTM_TCP_CLOSING; 4239 else 4240 (*state)->timeout = PFTM_TCP_ESTABLISHED; 4241 4242 /* Fall through to PASS packet */ 4243 4244 } else if ((dst->state < TCPS_SYN_SENT || 4245 dst->state >= TCPS_FIN_WAIT_2 || 4246 src->state >= TCPS_FIN_WAIT_2) && 4247 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) && 4248 /* Within a window forward of the originating packet */ 4249 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) { 4250 /* Within a window backward of the originating packet */ 4251 4252 /* 4253 * This currently handles three situations: 4254 * 1) Stupid stacks will shotgun SYNs before their peer 4255 * replies. 4256 * 2) When PF catches an already established stream (the 4257 * firewall rebooted, the state table was flushed, routes 4258 * changed...) 4259 * 3) Packets get funky immediately after the connection 4260 * closes (this should catch Solaris spurious ACK|FINs 4261 * that web servers like to spew after a close) 4262 * 4263 * This must be a little more careful than the above code 4264 * since packet floods will also be caught here. We don't 4265 * update the TTL here to mitigate the damage of a packet 4266 * flood and so the same code can handle awkward establishment 4267 * and a loosened connection close. 4268 * In the establishment case, a correct peer response will 4269 * validate the connection, go through the normal state code 4270 * and keep updating the state TTL. 4271 */ 4272 4273 if (pf_status.debug >= PF_DEBUG_MISC) { 4274 printf("pf: loose state match: "); 4275 pf_print_state(*state); 4276 pf_print_flags(th->th_flags); 4277 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d\n", 4278 seq, ack, pd->p_len, ackskew, 4279 (*state)->packets[0], (*state)->packets[1]); 4280 } 4281 4282 /* update max window */ 4283 if (src->max_win < win) 4284 src->max_win = win; 4285 /* synchronize sequencing */ 4286 if (SEQ_GT(end, src->seqlo)) 4287 src->seqlo = end; 4288 /* slide the window of what the other end can send */ 4289 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) 4290 dst->seqhi = ack + MAX((win << sws), 1); 4291 4292 /* 4293 * Cannot set dst->seqhi here since this could be a shotgunned 4294 * SYN and not an already established connection. 4295 */ 4296 4297 if (th->th_flags & TH_FIN) 4298 if (src->state < TCPS_CLOSING) 4299 src->state = TCPS_CLOSING; 4300 if (th->th_flags & TH_RST) 4301 src->state = dst->state = TCPS_TIME_WAIT; 4302 4303 /* Fall through to PASS packet */ 4304 4305 } else { 4306 if ((*state)->dst.state == TCPS_SYN_SENT && 4307 (*state)->src.state == TCPS_SYN_SENT) { 4308 /* Send RST for state mismatches during handshake */ 4309 if (!(th->th_flags & TH_RST)) { 4310 u_int32_t ack = ntohl(th->th_seq) + pd->p_len; 4311 4312 if (th->th_flags & TH_SYN) 4313 ack++; 4314 if (th->th_flags & TH_FIN) 4315 ack++; 4316 pf_send_tcp((*state)->rule.ptr, pd->af, 4317 pd->dst, pd->src, th->th_dport, 4318 th->th_sport, ntohl(th->th_ack), ack, 4319 TH_RST|TH_ACK, 0, 0, 4320 (*state)->rule.ptr->return_ttl); 4321 } 4322 src->seqlo = 0; 4323 src->seqhi = 1; 4324 src->max_win = 1; 4325 } else if (pf_status.debug >= PF_DEBUG_MISC) { 4326 printf("pf: BAD state: "); 4327 pf_print_state(*state); 4328 pf_print_flags(th->th_flags); 4329 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d " 4330 "dir=%s,%s\n", seq, ack, pd->p_len, ackskew, 4331 (*state)->packets[0], (*state)->packets[1], 4332 direction == PF_IN ? "in" : "out", 4333 direction == (*state)->direction ? "fwd" : "rev"); 4334 printf("pf: State failure on: %c %c %c %c | %c %c\n", 4335 SEQ_GEQ(src->seqhi, end) ? ' ' : '1', 4336 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ? 4337 ' ': '2', 4338 (ackskew >= -MAXACKWINDOW) ? ' ' : '3', 4339 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4', 4340 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5', 4341 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6'); 4342 } 4343 return (PF_DROP); 4344 } 4345 4346 if (dst->scrub || src->scrub) { 4347 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 4348 src, dst, ©back)) 4349 return (PF_DROP); 4350 } 4351 4352 /* Any packets which have gotten here are to be passed */ 4353 4354 /* translate source/destination address, if necessary */ 4355 if (STATE_TRANSLATE(*state)) { 4356 if (direction == PF_OUT) 4357 pf_change_ap(pd->src, &th->th_sport, pd->ip_sum, 4358 &th->th_sum, &(*state)->gwy.addr, 4359 (*state)->gwy.port, 0, pd->af); 4360 else 4361 pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, 4362 &th->th_sum, &(*state)->lan.addr, 4363 (*state)->lan.port, 0, pd->af); 4364 m_copyback(m, off, sizeof(*th), (caddr_t)th); 4365 } else if (copyback) { 4366 /* Copyback sequence modulation or stateful scrub changes */ 4367 m_copyback(m, off, sizeof(*th), (caddr_t)th); 4368 } 4369 4370 return (PF_PASS); 4371} 4372 4373int 4374pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, 4375 struct mbuf *m, int off, void *h, struct pf_pdesc *pd) 4376{ 4377 struct pf_state_peer *src, *dst; 4378 struct pf_state key; 4379 struct udphdr *uh = pd->hdr.udp; 4380 4381 key.af = pd->af; 4382 key.proto = IPPROTO_UDP; 4383 if (direction == PF_IN) { 4384 PF_ACPY(&key.ext.addr, pd->src, key.af); 4385 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 4386 key.ext.port = uh->uh_sport; 4387 key.gwy.port = uh->uh_dport; 4388 } else { 4389 PF_ACPY(&key.lan.addr, pd->src, key.af); 4390 PF_ACPY(&key.ext.addr, pd->dst, key.af); 4391 key.lan.port = uh->uh_sport; 4392 key.ext.port = uh->uh_dport; 4393 } 4394 4395 STATE_LOOKUP(); 4396 4397 if (direction == (*state)->direction) { 4398 src = &(*state)->src; 4399 dst = &(*state)->dst; 4400 } else { 4401 src = &(*state)->dst; 4402 dst = &(*state)->src; 4403 } 4404 4405 /* update states */ 4406 if (src->state < PFUDPS_SINGLE) 4407 src->state = PFUDPS_SINGLE; 4408 if (dst->state == PFUDPS_SINGLE) 4409 dst->state = PFUDPS_MULTIPLE; 4410 4411 /* update expire time */ 4412#ifdef __FreeBSD__ 4413 (*state)->expire = time_second; 4414#else 4415 (*state)->expire = time.tv_sec; 4416#endif 4417 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE) 4418 (*state)->timeout = PFTM_UDP_MULTIPLE; 4419 else 4420 (*state)->timeout = PFTM_UDP_SINGLE; 4421 4422 /* translate source/destination address, if necessary */ 4423 if (STATE_TRANSLATE(*state)) { 4424 if (direction == PF_OUT) 4425 pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum, 4426 &uh->uh_sum, &(*state)->gwy.addr, 4427 (*state)->gwy.port, 1, pd->af); 4428 else 4429 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, 4430 &uh->uh_sum, &(*state)->lan.addr, 4431 (*state)->lan.port, 1, pd->af); 4432 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 4433 } 4434 4435 return (PF_PASS); 4436} 4437 4438int 4439pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, 4440 struct mbuf *m, int off, void *h, struct pf_pdesc *pd) 4441{ 4442 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 4443 u_int16_t icmpid = 0; /* make the compiler happy */ 4444 u_int16_t *icmpsum = NULL; /* make the compiler happy */ 4445 u_int8_t icmptype = 0; /* make the compiler happy */ 4446 int state_icmp = 0; 4447 4448 switch (pd->proto) { 4449#ifdef INET 4450 case IPPROTO_ICMP: 4451 icmptype = pd->hdr.icmp->icmp_type; 4452 icmpid = pd->hdr.icmp->icmp_id; 4453 icmpsum = &pd->hdr.icmp->icmp_cksum; 4454 4455 if (icmptype == ICMP_UNREACH || 4456 icmptype == ICMP_SOURCEQUENCH || 4457 icmptype == ICMP_REDIRECT || 4458 icmptype == ICMP_TIMXCEED || 4459 icmptype == ICMP_PARAMPROB) 4460 state_icmp++; 4461 break; 4462#endif /* INET */ 4463#ifdef INET6 4464 case IPPROTO_ICMPV6: 4465 icmptype = pd->hdr.icmp6->icmp6_type; 4466 icmpid = pd->hdr.icmp6->icmp6_id; 4467 icmpsum = &pd->hdr.icmp6->icmp6_cksum; 4468 4469 if (icmptype == ICMP6_DST_UNREACH || 4470 icmptype == ICMP6_PACKET_TOO_BIG || 4471 icmptype == ICMP6_TIME_EXCEEDED || 4472 icmptype == ICMP6_PARAM_PROB) 4473 state_icmp++; 4474 break; 4475#endif /* INET6 */ 4476 } 4477 4478 if (!state_icmp) { 4479 4480 /* 4481 * ICMP query/reply message not related to a TCP/UDP packet. 4482 * Search for an ICMP state. 4483 */ 4484 struct pf_state key; 4485 4486 key.af = pd->af; 4487 key.proto = pd->proto; 4488 if (direction == PF_IN) { 4489 PF_ACPY(&key.ext.addr, pd->src, key.af); 4490 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 4491 key.ext.port = icmpid; 4492 key.gwy.port = icmpid; 4493 } else { 4494 PF_ACPY(&key.lan.addr, pd->src, key.af); 4495 PF_ACPY(&key.ext.addr, pd->dst, key.af); 4496 key.lan.port = icmpid; 4497 key.ext.port = icmpid; 4498 } 4499 4500 STATE_LOOKUP(); 4501 4502#ifdef __FreeBSD__ 4503 (*state)->expire = time_second; 4504#else 4505 (*state)->expire = time.tv_sec; 4506#endif 4507 (*state)->timeout = PFTM_ICMP_ERROR_REPLY; 4508 4509 /* translate source/destination address, if necessary */ 4510 if (PF_ANEQ(&(*state)->lan.addr, &(*state)->gwy.addr, pd->af)) { 4511 if (direction == PF_OUT) { 4512 switch (pd->af) { 4513#ifdef INET 4514 case AF_INET: 4515 pf_change_a(&saddr->v4.s_addr, 4516 pd->ip_sum, 4517 (*state)->gwy.addr.v4.s_addr, 0); 4518 break; 4519#endif /* INET */ 4520#ifdef INET6 4521 case AF_INET6: 4522 pf_change_a6(saddr, 4523 &pd->hdr.icmp6->icmp6_cksum, 4524 &(*state)->gwy.addr, 0); 4525 m_copyback(m, off, 4526 sizeof(struct icmp6_hdr), 4527 (caddr_t)pd->hdr.icmp6); 4528 break; 4529#endif /* INET6 */ 4530 } 4531 } else { 4532 switch (pd->af) { 4533#ifdef INET 4534 case AF_INET: 4535 pf_change_a(&daddr->v4.s_addr, 4536 pd->ip_sum, 4537 (*state)->lan.addr.v4.s_addr, 0); 4538 break; 4539#endif /* INET */ 4540#ifdef INET6 4541 case AF_INET6: 4542 pf_change_a6(daddr, 4543 &pd->hdr.icmp6->icmp6_cksum, 4544 &(*state)->lan.addr, 0); 4545 m_copyback(m, off, 4546 sizeof(struct icmp6_hdr), 4547 (caddr_t)pd->hdr.icmp6); 4548 break; 4549#endif /* INET6 */ 4550 } 4551 } 4552 } 4553 4554 return (PF_PASS); 4555 4556 } else { 4557 /* 4558 * ICMP error message in response to a TCP/UDP packet. 4559 * Extract the inner TCP/UDP header and search for that state. 4560 */ 4561 4562 struct pf_pdesc pd2; 4563#ifdef INET 4564 struct ip h2; 4565#endif /* INET */ 4566#ifdef INET6 4567 struct ip6_hdr h2_6; 4568 int terminal = 0; 4569#endif /* INET6 */ 4570 int ipoff2 = 0; /* make the compiler happy */ 4571 int off2 = 0; /* make the compiler happy */ 4572 4573 pd2.af = pd->af; 4574 switch (pd->af) { 4575#ifdef INET 4576 case AF_INET: 4577 /* offset of h2 in mbuf chain */ 4578 ipoff2 = off + ICMP_MINLEN; 4579 4580 if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2), 4581 NULL, NULL, pd2.af)) { 4582 DPFPRINTF(PF_DEBUG_MISC, 4583 ("pf: ICMP error message too short " 4584 "(ip)\n")); 4585 return (PF_DROP); 4586 } 4587 /* 4588 * ICMP error messages don't refer to non-first 4589 * fragments 4590 */ 4591 if (h2.ip_off & htons(IP_OFFMASK)) 4592 return (PF_DROP); 4593 4594 /* offset of protocol header that follows h2 */ 4595 off2 = ipoff2 + (h2.ip_hl << 2); 4596 4597 pd2.proto = h2.ip_p; 4598 pd2.src = (struct pf_addr *)&h2.ip_src; 4599 pd2.dst = (struct pf_addr *)&h2.ip_dst; 4600 pd2.ip_sum = &h2.ip_sum; 4601 break; 4602#endif /* INET */ 4603#ifdef INET6 4604 case AF_INET6: 4605 ipoff2 = off + sizeof(struct icmp6_hdr); 4606 4607 if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6), 4608 NULL, NULL, pd2.af)) { 4609 DPFPRINTF(PF_DEBUG_MISC, 4610 ("pf: ICMP error message too short " 4611 "(ip6)\n")); 4612 return (PF_DROP); 4613 } 4614 pd2.proto = h2_6.ip6_nxt; 4615 pd2.src = (struct pf_addr *)&h2_6.ip6_src; 4616 pd2.dst = (struct pf_addr *)&h2_6.ip6_dst; 4617 pd2.ip_sum = NULL; 4618 off2 = ipoff2 + sizeof(h2_6); 4619 do { 4620 switch (pd2.proto) { 4621 case IPPROTO_FRAGMENT: 4622 /* 4623 * ICMPv6 error messages for 4624 * non-first fragments 4625 */ 4626 return (PF_DROP); 4627 case IPPROTO_AH: 4628 case IPPROTO_HOPOPTS: 4629 case IPPROTO_ROUTING: 4630 case IPPROTO_DSTOPTS: { 4631 /* get next header and header length */ 4632 struct ip6_ext opt6; 4633 4634 if (!pf_pull_hdr(m, off2, &opt6, 4635 sizeof(opt6), NULL, NULL, pd2.af)) { 4636 DPFPRINTF(PF_DEBUG_MISC, 4637 ("pf: ICMPv6 short opt\n")); 4638 return (PF_DROP); 4639 } 4640 if (pd2.proto == IPPROTO_AH) 4641 off2 += (opt6.ip6e_len + 2) * 4; 4642 else 4643 off2 += (opt6.ip6e_len + 1) * 8; 4644 pd2.proto = opt6.ip6e_nxt; 4645 /* goto the next header */ 4646 break; 4647 } 4648 default: 4649 terminal++; 4650 break; 4651 } 4652 } while (!terminal); 4653 break; 4654#endif /* INET6 */ 4655 } 4656 4657 switch (pd2.proto) { 4658 case IPPROTO_TCP: { 4659 struct tcphdr th; 4660 u_int32_t seq; 4661 struct pf_state key; 4662 struct pf_state_peer *src, *dst; 4663 u_int8_t dws; 4664 int copyback = 0; 4665 4666 /* 4667 * Only the first 8 bytes of the TCP header can be 4668 * expected. Don't access any TCP header fields after 4669 * th_seq, an ackskew test is not possible. 4670 */ 4671 if (!pf_pull_hdr(m, off2, &th, 8, NULL, NULL, pd2.af)) { 4672 DPFPRINTF(PF_DEBUG_MISC, 4673 ("pf: ICMP error message too short " 4674 "(tcp)\n")); 4675 return (PF_DROP); 4676 } 4677 4678 key.af = pd2.af; 4679 key.proto = IPPROTO_TCP; 4680 if (direction == PF_IN) { 4681 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 4682 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 4683 key.ext.port = th.th_dport; 4684 key.gwy.port = th.th_sport; 4685 } else { 4686 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 4687 PF_ACPY(&key.ext.addr, pd2.src, key.af); 4688 key.lan.port = th.th_dport; 4689 key.ext.port = th.th_sport; 4690 } 4691 4692 STATE_LOOKUP(); 4693 4694 if (direction == (*state)->direction) { 4695 src = &(*state)->dst; 4696 dst = &(*state)->src; 4697 } else { 4698 src = &(*state)->src; 4699 dst = &(*state)->dst; 4700 } 4701 4702 if (src->wscale && dst->wscale && 4703 !(th.th_flags & TH_SYN)) 4704 dws = dst->wscale & PF_WSCALE_MASK; 4705 else 4706 dws = 0; 4707 4708 /* Demodulate sequence number */ 4709 seq = ntohl(th.th_seq) - src->seqdiff; 4710 if (src->seqdiff) { 4711 pf_change_a(&th.th_seq, icmpsum, 4712 htonl(seq), 0); 4713 copyback = 1; 4714 } 4715 4716 if (!SEQ_GEQ(src->seqhi, seq) || 4717 !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws))) { 4718 if (pf_status.debug >= PF_DEBUG_MISC) { 4719 printf("pf: BAD ICMP %d:%d ", 4720 icmptype, pd->hdr.icmp->icmp_code); 4721 pf_print_host(pd->src, 0, pd->af); 4722 printf(" -> "); 4723 pf_print_host(pd->dst, 0, pd->af); 4724 printf(" state: "); 4725 pf_print_state(*state); 4726 printf(" seq=%u\n", seq); 4727 } 4728 return (PF_DROP); 4729 } 4730 4731 if (STATE_TRANSLATE(*state)) { 4732 if (direction == PF_IN) { 4733 pf_change_icmp(pd2.src, &th.th_sport, 4734 daddr, &(*state)->lan.addr, 4735 (*state)->lan.port, NULL, 4736 pd2.ip_sum, icmpsum, 4737 pd->ip_sum, 0, pd2.af); 4738 } else { 4739 pf_change_icmp(pd2.dst, &th.th_dport, 4740 saddr, &(*state)->gwy.addr, 4741 (*state)->gwy.port, NULL, 4742 pd2.ip_sum, icmpsum, 4743 pd->ip_sum, 0, pd2.af); 4744 } 4745 copyback = 1; 4746 } 4747 4748 if (copyback) { 4749 switch (pd2.af) { 4750#ifdef INET 4751 case AF_INET: 4752 m_copyback(m, off, ICMP_MINLEN, 4753 (caddr_t)pd->hdr.icmp); 4754 m_copyback(m, ipoff2, sizeof(h2), 4755 (caddr_t)&h2); 4756 break; 4757#endif /* INET */ 4758#ifdef INET6 4759 case AF_INET6: 4760 m_copyback(m, off, 4761 sizeof(struct icmp6_hdr), 4762 (caddr_t)pd->hdr.icmp6); 4763 m_copyback(m, ipoff2, sizeof(h2_6), 4764 (caddr_t)&h2_6); 4765 break; 4766#endif /* INET6 */ 4767 } 4768 m_copyback(m, off2, 8, (caddr_t)&th); 4769 } 4770 4771 return (PF_PASS); 4772 break; 4773 } 4774 case IPPROTO_UDP: { 4775 struct udphdr uh; 4776 struct pf_state key; 4777 4778 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh), 4779 NULL, NULL, pd2.af)) { 4780 DPFPRINTF(PF_DEBUG_MISC, 4781 ("pf: ICMP error message too short " 4782 "(udp)\n")); 4783 return (PF_DROP); 4784 } 4785 4786 key.af = pd2.af; 4787 key.proto = IPPROTO_UDP; 4788 if (direction == PF_IN) { 4789 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 4790 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 4791 key.ext.port = uh.uh_dport; 4792 key.gwy.port = uh.uh_sport; 4793 } else { 4794 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 4795 PF_ACPY(&key.ext.addr, pd2.src, key.af); 4796 key.lan.port = uh.uh_dport; 4797 key.ext.port = uh.uh_sport; 4798 } 4799 4800 STATE_LOOKUP(); 4801 4802 if (STATE_TRANSLATE(*state)) { 4803 if (direction == PF_IN) { 4804 pf_change_icmp(pd2.src, &uh.uh_sport, 4805 daddr, &(*state)->lan.addr, 4806 (*state)->lan.port, &uh.uh_sum, 4807 pd2.ip_sum, icmpsum, 4808 pd->ip_sum, 1, pd2.af); 4809 } else { 4810 pf_change_icmp(pd2.dst, &uh.uh_dport, 4811 saddr, &(*state)->gwy.addr, 4812 (*state)->gwy.port, &uh.uh_sum, 4813 pd2.ip_sum, icmpsum, 4814 pd->ip_sum, 1, pd2.af); 4815 } 4816 switch (pd2.af) { 4817#ifdef INET 4818 case AF_INET: 4819 m_copyback(m, off, ICMP_MINLEN, 4820 (caddr_t)pd->hdr.icmp); 4821 m_copyback(m, ipoff2, sizeof(h2), 4822 (caddr_t)&h2); 4823 break; 4824#endif /* INET */ 4825#ifdef INET6 4826 case AF_INET6: 4827 m_copyback(m, off, 4828 sizeof(struct icmp6_hdr), 4829 (caddr_t)pd->hdr.icmp6); 4830 m_copyback(m, ipoff2, sizeof(h2_6), 4831 (caddr_t)&h2_6); 4832 break; 4833#endif /* INET6 */ 4834 } 4835 m_copyback(m, off2, sizeof(uh), 4836 (caddr_t)&uh); 4837 } 4838 4839 return (PF_PASS); 4840 break; 4841 } 4842#ifdef INET 4843 case IPPROTO_ICMP: { 4844 struct icmp iih; 4845 struct pf_state key; 4846 4847 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN, 4848 NULL, NULL, pd2.af)) { 4849 DPFPRINTF(PF_DEBUG_MISC, 4850 ("pf: ICMP error message too short i" 4851 "(icmp)\n")); 4852 return (PF_DROP); 4853 } 4854 4855 key.af = pd2.af; 4856 key.proto = IPPROTO_ICMP; 4857 if (direction == PF_IN) { 4858 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 4859 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 4860 key.ext.port = iih.icmp_id; 4861 key.gwy.port = iih.icmp_id; 4862 } else { 4863 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 4864 PF_ACPY(&key.ext.addr, pd2.src, key.af); 4865 key.lan.port = iih.icmp_id; 4866 key.ext.port = iih.icmp_id; 4867 } 4868 4869 STATE_LOOKUP(); 4870 4871 if (STATE_TRANSLATE(*state)) { 4872 if (direction == PF_IN) { 4873 pf_change_icmp(pd2.src, &iih.icmp_id, 4874 daddr, &(*state)->lan.addr, 4875 (*state)->lan.port, NULL, 4876 pd2.ip_sum, icmpsum, 4877 pd->ip_sum, 0, AF_INET); 4878 } else { 4879 pf_change_icmp(pd2.dst, &iih.icmp_id, 4880 saddr, &(*state)->gwy.addr, 4881 (*state)->gwy.port, NULL, 4882 pd2.ip_sum, icmpsum, 4883 pd->ip_sum, 0, AF_INET); 4884 } 4885 m_copyback(m, off, ICMP_MINLEN, 4886 (caddr_t)pd->hdr.icmp); 4887 m_copyback(m, ipoff2, sizeof(h2), 4888 (caddr_t)&h2); 4889 m_copyback(m, off2, ICMP_MINLEN, 4890 (caddr_t)&iih); 4891 } 4892 4893 return (PF_PASS); 4894 break; 4895 } 4896#endif /* INET */ 4897#ifdef INET6 4898 case IPPROTO_ICMPV6: { 4899 struct icmp6_hdr iih; 4900 struct pf_state key; 4901 4902 if (!pf_pull_hdr(m, off2, &iih, 4903 sizeof(struct icmp6_hdr), NULL, NULL, pd2.af)) { 4904 DPFPRINTF(PF_DEBUG_MISC, 4905 ("pf: ICMP error message too short " 4906 "(icmp6)\n")); 4907 return (PF_DROP); 4908 } 4909 4910 key.af = pd2.af; 4911 key.proto = IPPROTO_ICMPV6; 4912 if (direction == PF_IN) { 4913 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 4914 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 4915 key.ext.port = iih.icmp6_id; 4916 key.gwy.port = iih.icmp6_id; 4917 } else { 4918 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 4919 PF_ACPY(&key.ext.addr, pd2.src, key.af); 4920 key.lan.port = iih.icmp6_id; 4921 key.ext.port = iih.icmp6_id; 4922 } 4923 4924 STATE_LOOKUP(); 4925 4926 if (STATE_TRANSLATE(*state)) { 4927 if (direction == PF_IN) { 4928 pf_change_icmp(pd2.src, &iih.icmp6_id, 4929 daddr, &(*state)->lan.addr, 4930 (*state)->lan.port, NULL, 4931 pd2.ip_sum, icmpsum, 4932 pd->ip_sum, 0, AF_INET6); 4933 } else { 4934 pf_change_icmp(pd2.dst, &iih.icmp6_id, 4935 saddr, &(*state)->gwy.addr, 4936 (*state)->gwy.port, NULL, 4937 pd2.ip_sum, icmpsum, 4938 pd->ip_sum, 0, AF_INET6); 4939 } 4940 m_copyback(m, off, sizeof(struct icmp6_hdr), 4941 (caddr_t)pd->hdr.icmp6); 4942 m_copyback(m, ipoff2, sizeof(h2_6), 4943 (caddr_t)&h2_6); 4944 m_copyback(m, off2, sizeof(struct icmp6_hdr), 4945 (caddr_t)&iih); 4946 } 4947 4948 return (PF_PASS); 4949 break; 4950 } 4951#endif /* INET6 */ 4952 default: { 4953 struct pf_state key; 4954 4955 key.af = pd2.af; 4956 key.proto = pd2.proto; 4957 if (direction == PF_IN) { 4958 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 4959 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 4960 key.ext.port = 0; 4961 key.gwy.port = 0; 4962 } else { 4963 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 4964 PF_ACPY(&key.ext.addr, pd2.src, key.af); 4965 key.lan.port = 0; 4966 key.ext.port = 0; 4967 } 4968 4969 STATE_LOOKUP(); 4970 4971 if (STATE_TRANSLATE(*state)) { 4972 if (direction == PF_IN) { 4973 pf_change_icmp(pd2.src, NULL, 4974 daddr, &(*state)->lan.addr, 4975 0, NULL, 4976 pd2.ip_sum, icmpsum, 4977 pd->ip_sum, 0, pd2.af); 4978 } else { 4979 pf_change_icmp(pd2.dst, NULL, 4980 saddr, &(*state)->gwy.addr, 4981 0, NULL, 4982 pd2.ip_sum, icmpsum, 4983 pd->ip_sum, 0, pd2.af); 4984 } 4985 switch (pd2.af) { 4986#ifdef INET 4987 case AF_INET: 4988 m_copyback(m, off, ICMP_MINLEN, 4989 (caddr_t)pd->hdr.icmp); 4990 m_copyback(m, ipoff2, sizeof(h2), 4991 (caddr_t)&h2); 4992 break; 4993#endif /* INET */ 4994#ifdef INET6 4995 case AF_INET6: 4996 m_copyback(m, off, 4997 sizeof(struct icmp6_hdr), 4998 (caddr_t)pd->hdr.icmp6); 4999 m_copyback(m, ipoff2, sizeof(h2_6), 5000 (caddr_t)&h2_6); 5001 break; 5002#endif /* INET6 */ 5003 } 5004 } 5005 5006 return (PF_PASS); 5007 break; 5008 } 5009 } 5010 } 5011} 5012 5013int 5014pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, 5015 struct pf_pdesc *pd) 5016{ 5017 struct pf_state_peer *src, *dst; 5018 struct pf_state key; 5019 5020 key.af = pd->af; 5021 key.proto = pd->proto; 5022 if (direction == PF_IN) { 5023 PF_ACPY(&key.ext.addr, pd->src, key.af); 5024 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 5025 key.ext.port = 0; 5026 key.gwy.port = 0; 5027 } else { 5028 PF_ACPY(&key.lan.addr, pd->src, key.af); 5029 PF_ACPY(&key.ext.addr, pd->dst, key.af); 5030 key.lan.port = 0; 5031 key.ext.port = 0; 5032 } 5033 5034 STATE_LOOKUP(); 5035 5036 if (direction == (*state)->direction) { 5037 src = &(*state)->src; 5038 dst = &(*state)->dst; 5039 } else { 5040 src = &(*state)->dst; 5041 dst = &(*state)->src; 5042 } 5043 5044 /* update states */ 5045 if (src->state < PFOTHERS_SINGLE) 5046 src->state = PFOTHERS_SINGLE; 5047 if (dst->state == PFOTHERS_SINGLE) 5048 dst->state = PFOTHERS_MULTIPLE; 5049 5050 /* update expire time */ 5051#ifdef __FreeBSD__ 5052 (*state)->expire = time_second; 5053#else 5054 (*state)->expire = time.tv_sec; 5055#endif 5056 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE) 5057 (*state)->timeout = PFTM_OTHER_MULTIPLE; 5058 else 5059 (*state)->timeout = PFTM_OTHER_SINGLE; 5060 5061 /* translate source/destination address, if necessary */ 5062 if (STATE_TRANSLATE(*state)) { 5063 if (direction == PF_OUT) 5064 switch (pd->af) { 5065#ifdef INET 5066 case AF_INET: 5067 pf_change_a(&pd->src->v4.s_addr, 5068 pd->ip_sum, (*state)->gwy.addr.v4.s_addr, 5069 0); 5070 break; 5071#endif /* INET */ 5072#ifdef INET6 5073 case AF_INET6: 5074 PF_ACPY(pd->src, &(*state)->gwy.addr, pd->af); 5075 break; 5076#endif /* INET6 */ 5077 } 5078 else 5079 switch (pd->af) { 5080#ifdef INET 5081 case AF_INET: 5082 pf_change_a(&pd->dst->v4.s_addr, 5083 pd->ip_sum, (*state)->lan.addr.v4.s_addr, 5084 0); 5085 break; 5086#endif /* INET */ 5087#ifdef INET6 5088 case AF_INET6: 5089 PF_ACPY(pd->dst, &(*state)->lan.addr, pd->af); 5090 break; 5091#endif /* INET6 */ 5092 } 5093 } 5094 5095 return (PF_PASS); 5096} 5097 5098/* 5099 * ipoff and off are measured from the start of the mbuf chain. 5100 * h must be at "ipoff" on the mbuf chain. 5101 */ 5102void * 5103pf_pull_hdr(struct mbuf *m, int off, void *p, int len, 5104 u_short *actionp, u_short *reasonp, sa_family_t af) 5105{ 5106 switch (af) { 5107#ifdef INET 5108 case AF_INET: { 5109 struct ip *h = mtod(m, struct ip *); 5110 u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3; 5111 5112 if (fragoff) { 5113 if (fragoff >= len) 5114 ACTION_SET(actionp, PF_PASS); 5115 else { 5116 ACTION_SET(actionp, PF_DROP); 5117 REASON_SET(reasonp, PFRES_FRAG); 5118 } 5119 return (NULL); 5120 } 5121 if (m->m_pkthdr.len < off + len || 5122 ntohs(h->ip_len) < off + len) { 5123 ACTION_SET(actionp, PF_DROP); 5124 REASON_SET(reasonp, PFRES_SHORT); 5125 return (NULL); 5126 } 5127 break; 5128 } 5129#endif /* INET */ 5130#ifdef INET6 5131 case AF_INET6: { 5132 struct ip6_hdr *h = mtod(m, struct ip6_hdr *); 5133 5134 if (m->m_pkthdr.len < off + len || 5135 (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) < 5136 (unsigned)(off + len)) { 5137 ACTION_SET(actionp, PF_DROP); 5138 REASON_SET(reasonp, PFRES_SHORT); 5139 return (NULL); 5140 } 5141 break; 5142 } 5143#endif /* INET6 */ 5144 } 5145 m_copydata(m, off, len, p); 5146 return (p); 5147} 5148 5149int 5150pf_routable(struct pf_addr *addr, sa_family_t af) 5151{ 5152 struct sockaddr_in *dst; 5153 struct route ro; 5154 int ret = 0; 5155 5156 bzero(&ro, sizeof(ro)); 5157 dst = satosin(&ro.ro_dst); 5158 dst->sin_family = af; 5159 dst->sin_len = sizeof(*dst); 5160 dst->sin_addr = addr->v4; 5161#ifdef __FreeBSD__ 5162#ifdef RTF_PRCLONING 5163 rtalloc_ign(&ro, (RTF_CLONING|RTF_PRCLONING)); 5164#else /* !RTF_PRCLONING */ 5165 rtalloc_ign(&ro, RTF_CLONING); 5166#endif 5167#else /* ! __FreeBSD__ */ 5168 rtalloc_noclone(&ro, NO_CLONING); 5169#endif 5170 5171 if (ro.ro_rt != NULL) { 5172 ret = 1; 5173 RTFREE(ro.ro_rt); 5174 } 5175 5176 return (ret); 5177} 5178 5179#ifdef INET 5180 5181void 5182pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 5183 struct pf_state *s) 5184{ 5185 struct mbuf *m0, *m1; 5186 struct m_tag *mtag; 5187 struct route iproute; 5188 struct route *ro = NULL; /* XXX: was uninitialized */ 5189 struct sockaddr_in *dst; 5190 struct ip *ip; 5191 struct ifnet *ifp = NULL; 5192 struct pf_addr naddr; 5193 struct pf_src_node *sn = NULL; 5194 int error = 0; 5195#ifdef __FreeBSD__ 5196 int sw_csum; 5197#endif 5198 5199 if (m == NULL || *m == NULL || r == NULL || 5200 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 5201 panic("pf_route: invalid parameters"); 5202 5203 if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) { 5204 if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) == 5205 NULL) { 5206 m0 = *m; 5207 *m = NULL; 5208 goto bad; 5209 } 5210 *(char *)(mtag + 1) = 1; 5211 m_tag_prepend(*m, mtag); 5212 } else { 5213 if (*(char *)(mtag + 1) > 3) { 5214 m0 = *m; 5215 *m = NULL; 5216 goto bad; 5217 } 5218 (*(char *)(mtag + 1))++; 5219 } 5220 5221 if (r->rt == PF_DUPTO) { 5222#ifdef __FreeBSD__ 5223 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 5224#else 5225 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 5226#endif 5227 return; 5228#ifdef __FreeBSD__ 5229 if ((mtag = m_tag_copy(mtag, M_DONTWAIT)) == NULL) 5230#else 5231 if ((mtag = m_tag_copy(mtag)) == NULL) 5232#endif 5233 goto bad; 5234 m_tag_prepend(m0, mtag); 5235 } else { 5236 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 5237 return; 5238 m0 = *m; 5239 } 5240 5241 if (m0->m_len < sizeof(struct ip)) 5242 panic("pf_route: m0->m_len < sizeof(struct ip)"); 5243 ip = mtod(m0, struct ip *); 5244 5245 ro = &iproute; 5246 bzero((caddr_t)ro, sizeof(*ro)); 5247 dst = satosin(&ro->ro_dst); 5248 dst->sin_family = AF_INET; 5249 dst->sin_len = sizeof(*dst); 5250 dst->sin_addr = ip->ip_dst; 5251 5252 if (r->rt == PF_FASTROUTE) { 5253 rtalloc(ro); 5254 if (ro->ro_rt == 0) { 5255 ipstat.ips_noroute++; 5256 goto bad; 5257 } 5258 5259 ifp = ro->ro_rt->rt_ifp; 5260 ro->ro_rt->rt_use++; 5261 5262 if (ro->ro_rt->rt_flags & RTF_GATEWAY) 5263 dst = satosin(ro->ro_rt->rt_gateway); 5264 } else { 5265 if (TAILQ_EMPTY(&r->rpool.list)) 5266 panic("pf_route: TAILQ_EMPTY(&r->rpool.list)"); 5267 if (s == NULL) { 5268 pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src, 5269 &naddr, NULL, &sn); 5270 if (!PF_AZERO(&naddr, AF_INET)) 5271 dst->sin_addr.s_addr = naddr.v4.s_addr; 5272 ifp = r->rpool.cur->kif ? 5273 r->rpool.cur->kif->pfik_ifp : NULL; 5274 } else { 5275 if (!PF_AZERO(&s->rt_addr, AF_INET)) 5276 dst->sin_addr.s_addr = 5277 s->rt_addr.v4.s_addr; 5278 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; 5279 } 5280 } 5281 if (ifp == NULL) 5282 goto bad; 5283 5284 if (oifp != ifp) { 5285#ifdef __FreeBSD__ 5286 PF_UNLOCK(); 5287 if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS) { 5288 PF_LOCK(); 5289 goto bad; 5290 } else if (m0 == NULL) { 5291 PF_LOCK(); 5292 goto done; 5293 } 5294 PF_LOCK(); 5295#else 5296 if (pf_test(PF_OUT, ifp, &m0) != PF_PASS) 5297 goto bad; 5298 else if (m0 == NULL) 5299 goto done; 5300#endif 5301 if (m0->m_len < sizeof(struct ip)) 5302 panic("pf_route: m0->m_len < sizeof(struct ip)"); 5303 ip = mtod(m0, struct ip *); 5304 } 5305 5306#ifdef __FreeBSD__ 5307 /* Copied from FreeBSD 5.1-CURRENT ip_output. */ 5308 m0->m_pkthdr.csum_flags |= CSUM_IP; 5309 sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist; 5310 if (sw_csum & CSUM_DELAY_DATA) { 5311 /* 5312 * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least) 5313 */ 5314 NTOHS(ip->ip_len); 5315 NTOHS(ip->ip_off); /* XXX: needed? */ 5316 in_delayed_cksum(m0); 5317 HTONS(ip->ip_len); 5318 HTONS(ip->ip_off); 5319 sw_csum &= ~CSUM_DELAY_DATA; 5320 } 5321 m0->m_pkthdr.csum_flags &= ifp->if_hwassist; 5322 5323 if (ntohs(ip->ip_len) <= ifp->if_mtu || 5324 (ifp->if_hwassist & CSUM_FRAGMENT && 5325 ((ip->ip_off & htons(IP_DF)) == 0))) { 5326 /* 5327 * ip->ip_len = htons(ip->ip_len); 5328 * ip->ip_off = htons(ip->ip_off); 5329 */ 5330 ip->ip_sum = 0; 5331 if (sw_csum & CSUM_DELAY_IP) { 5332 /* From KAME */ 5333 if (ip->ip_v == IPVERSION && 5334 (ip->ip_hl << 2) == sizeof(*ip)) { 5335 ip->ip_sum = in_cksum_hdr(ip); 5336 } else { 5337 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 5338 } 5339 } 5340 PF_UNLOCK(); 5341 error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro->ro_rt); 5342 PF_LOCK(); 5343 goto done; 5344 } 5345 5346#else 5347 /* Copied from ip_output. */ 5348#ifdef IPSEC 5349 /* 5350 * If deferred crypto processing is needed, check that the 5351 * interface supports it. 5352 */ 5353 if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL)) 5354 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) { 5355 /* Notify IPsec to do its own crypto. */ 5356 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); 5357 goto bad; 5358 } 5359#endif /* IPSEC */ 5360 5361 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */ 5362 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) { 5363 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) || 5364 ifp->if_bridge != NULL) { 5365 in_delayed_cksum(m0); 5366 m0->m_pkthdr.csum &= ~M_TCPV4_CSUM_OUT; /* Clear */ 5367 } 5368 } else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) { 5369 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) || 5370 ifp->if_bridge != NULL) { 5371 in_delayed_cksum(m0); 5372 m0->m_pkthdr.csum &= ~M_UDPV4_CSUM_OUT; /* Clear */ 5373 } 5374 } 5375 5376 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 5377 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 5378 ifp->if_bridge == NULL) { 5379 m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT; 5380 ipstat.ips_outhwcsum++; 5381 } else { 5382 ip->ip_sum = 0; 5383 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 5384 } 5385 /* Update relevant hardware checksum stats for TCP/UDP */ 5386 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) 5387 tcpstat.tcps_outhwcsum++; 5388 else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) 5389 udpstat.udps_outhwcsum++; 5390 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); 5391 goto done; 5392 } 5393#endif 5394 /* 5395 * Too large for interface; fragment if possible. 5396 * Must be able to put at least 8 bytes per fragment. 5397 */ 5398 if (ip->ip_off & htons(IP_DF)) { 5399 ipstat.ips_cantfrag++; 5400 if (r->rt != PF_DUPTO) { 5401#ifdef __FreeBSD__ 5402 /* icmp_error() expects host byte ordering */ 5403 NTOHS(ip->ip_len); 5404 NTOHS(ip->ip_off); 5405 PF_UNLOCK(); 5406#endif 5407 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 5408 ifp); 5409#ifdef __FreeBSD__ 5410 PF_LOCK(); 5411#endif 5412 goto done; 5413 } else 5414 goto bad; 5415 } 5416 5417 m1 = m0; 5418#ifdef __FreeBSD__ 5419 /* 5420 * XXX: is cheaper + less error prone than own function 5421 */ 5422 NTOHS(ip->ip_len); 5423 NTOHS(ip->ip_off); 5424 error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum); 5425#else 5426 error = ip_fragment(m0, ifp, ifp->if_mtu); 5427#endif 5428 if (error) { 5429#ifndef __FreeBSD__ /* ip_fragment does not do m_freem() on FreeBSD */ 5430 m0 = NULL; 5431#endif 5432 goto bad; 5433 } 5434 5435 for (m0 = m1; m0; m0 = m1) { 5436 m1 = m0->m_nextpkt; 5437 m0->m_nextpkt = 0; 5438#ifdef __FreeBSD__ 5439 if (error == 0) { 5440 PF_UNLOCK(); 5441 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 5442 NULL); 5443 PF_LOCK(); 5444 } else 5445#else 5446 if (error == 0) 5447 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 5448 NULL); 5449 else 5450#endif 5451 m_freem(m0); 5452 } 5453 5454 if (error == 0) 5455 ipstat.ips_fragmented++; 5456 5457done: 5458 if (r->rt != PF_DUPTO) 5459 *m = NULL; 5460 if (ro == &iproute && ro->ro_rt) 5461 RTFREE(ro->ro_rt); 5462 return; 5463 5464bad: 5465 m_freem(m0); 5466 goto done; 5467} 5468#endif /* INET */ 5469 5470#ifdef INET6 5471void 5472pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 5473 struct pf_state *s) 5474{ 5475 struct mbuf *m0; 5476 struct m_tag *mtag; 5477 struct route_in6 ip6route; 5478 struct route_in6 *ro; 5479 struct sockaddr_in6 *dst; 5480 struct ip6_hdr *ip6; 5481 struct ifnet *ifp = NULL; 5482 struct pf_addr naddr; 5483 struct pf_src_node *sn = NULL; 5484 int error = 0; 5485 5486 if (m == NULL || *m == NULL || r == NULL || 5487 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 5488 panic("pf_route6: invalid parameters"); 5489 5490 if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) { 5491 if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) == 5492 NULL) { 5493 m0 = *m; 5494 *m = NULL; 5495 goto bad; 5496 } 5497 *(char *)(mtag + 1) = 1; 5498 m_tag_prepend(*m, mtag); 5499 } else { 5500 if (*(char *)(mtag + 1) > 3) { 5501 m0 = *m; 5502 *m = NULL; 5503 goto bad; 5504 } 5505 (*(char *)(mtag + 1))++; 5506 } 5507 5508 if (r->rt == PF_DUPTO) { 5509#ifdef __FreeBSD__ 5510 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 5511#else 5512 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 5513#endif 5514 return; 5515#ifdef __FreeBSD__ 5516 if ((mtag = m_tag_copy(mtag, M_DONTWAIT)) == NULL) 5517#else 5518 if ((mtag = m_tag_copy(mtag)) == NULL) 5519#endif 5520 goto bad; 5521 m_tag_prepend(m0, mtag); 5522 } else { 5523 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 5524 return; 5525 m0 = *m; 5526 } 5527 5528 if (m0->m_len < sizeof(struct ip6_hdr)) 5529 panic("pf_route6: m0->m_len < sizeof(struct ip6_hdr)"); 5530 ip6 = mtod(m0, struct ip6_hdr *); 5531 5532 ro = &ip6route; 5533 bzero((caddr_t)ro, sizeof(*ro)); 5534 dst = (struct sockaddr_in6 *)&ro->ro_dst; 5535 dst->sin6_family = AF_INET6; 5536 dst->sin6_len = sizeof(*dst); 5537 dst->sin6_addr = ip6->ip6_dst; 5538 5539 /* Cheat. */ 5540 if (r->rt == PF_FASTROUTE) { 5541#ifdef __FreeBSD__ 5542 m0->m_flags |= M_SKIP_FIREWALL; 5543 PF_UNLOCK(); 5544 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 5545 PF_LOCK(); 5546#else 5547 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 5548 if (mtag == NULL) 5549 goto bad; 5550 m_tag_prepend(m0, mtag); 5551 ip6_output(m0, NULL, NULL, 0, NULL, NULL); 5552#endif 5553 return; 5554 } 5555 5556 if (TAILQ_EMPTY(&r->rpool.list)) 5557 panic("pf_route6: TAILQ_EMPTY(&r->rpool.list)"); 5558 if (s == NULL) { 5559 pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, 5560 &naddr, NULL, &sn); 5561 if (!PF_AZERO(&naddr, AF_INET6)) 5562 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 5563 &naddr, AF_INET6); 5564 ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; 5565 } else { 5566 if (!PF_AZERO(&s->rt_addr, AF_INET6)) 5567 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 5568 &s->rt_addr, AF_INET6); 5569 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; 5570 } 5571 if (ifp == NULL) 5572 goto bad; 5573 5574 if (oifp != ifp) { 5575#ifdef __FreeBSD__ 5576 PF_UNLOCK(); 5577 if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS) { 5578 PF_LOCK(); 5579 goto bad; 5580 } else if (m0 == NULL) { 5581 PF_LOCK(); 5582 goto done; 5583 } 5584 PF_LOCK(); 5585#else 5586 if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS) 5587 goto bad; 5588 else if (m0 == NULL) 5589 goto done; 5590#endif 5591 if (m0->m_len < sizeof(struct ip6_hdr)) 5592 panic("pf_route6: m0->m_len < sizeof(struct ip6_hdr)"); 5593 ip6 = mtod(m0, struct ip6_hdr *); 5594 } 5595 5596 /* 5597 * If the packet is too large for the outgoing interface, 5598 * send back an icmp6 error. 5599 */ 5600 if (IN6_IS_ADDR_LINKLOCAL(&dst->sin6_addr)) 5601 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); 5602 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { 5603#ifdef __FreeBSD__ 5604 PF_UNLOCK(); 5605#endif 5606 error = nd6_output(ifp, ifp, m0, dst, NULL); 5607#ifdef __FreeBSD__ 5608 PF_LOCK(); 5609#endif 5610 } else { 5611 in6_ifstat_inc(ifp, ifs6_in_toobig); 5612#ifdef __FreeBSD__ 5613 if (r->rt != PF_DUPTO) { 5614 PF_UNLOCK(); 5615 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 5616 PF_LOCK(); 5617 } else 5618#else 5619 if (r->rt != PF_DUPTO) 5620 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 5621 else 5622#endif 5623 goto bad; 5624 } 5625 5626done: 5627 if (r->rt != PF_DUPTO) 5628 *m = NULL; 5629 return; 5630 5631bad: 5632 m_freem(m0); 5633 goto done; 5634} 5635#endif /* INET6 */ 5636 5637 5638#ifdef __FreeBSD__ 5639/* 5640 * FreeBSD supports cksum offloads for the following drivers. 5641 * em(4), fxp(4), gx(4), ixgb(4), lge(4), ndis(4), nge(4), re(4), 5642 * ti(4), txp(4), xl(4) 5643 * 5644 * CSUM_DATA_VALID | CSUM_PSEUDO_HDR : 5645 * network driver performed cksum including pseudo header, need to verify 5646 * csum_data 5647 * CSUM_DATA_VALID : 5648 * network driver performed cksum, needs to additional pseudo header 5649 * cksum computation with partial csum_data(i.e. lack of H/W support for 5650 * pseudo header, for instance hme(4), sk(4) and possibly gem(4)) 5651 * 5652 * After validating the cksum of packet, set both flag CSUM_DATA_VALID and 5653 * CSUM_PSEUDO_HDR in order to avoid recomputation of the cksum in upper 5654 * TCP/UDP layer. 5655 * Also, set csum_data to 0xffff to force cksum validation. 5656 */ 5657int 5658pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) 5659{ 5660 u_int16_t sum = 0; 5661 int hw_assist = 0; 5662 struct ip *ip; 5663 5664 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 5665 return (1); 5666 if (m->m_pkthdr.len < off + len) 5667 return (1); 5668 5669 switch (p) { 5670 case IPPROTO_TCP: 5671 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 5672 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 5673 sum = m->m_pkthdr.csum_data; 5674 } else { 5675 ip = mtod(m, struct ip *); 5676 sum = in_pseudo(ip->ip_src.s_addr, 5677 ip->ip_dst.s_addr, htonl((u_short)len + 5678 m->m_pkthdr.csum_data + IPPROTO_TCP)); 5679 } 5680 sum ^= 0xffff; 5681 ++hw_assist; 5682 } 5683 break; 5684 case IPPROTO_UDP: 5685 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 5686 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 5687 sum = m->m_pkthdr.csum_data; 5688 } else { 5689 ip = mtod(m, struct ip *); 5690 sum = in_pseudo(ip->ip_src.s_addr, 5691 ip->ip_dst.s_addr, htonl((u_short)len + 5692 m->m_pkthdr.csum_data + IPPROTO_UDP)); 5693 } 5694 sum ^= 0xffff; 5695 ++hw_assist; 5696 } 5697 break; 5698 case IPPROTO_ICMP: 5699#ifdef INET6 5700 case IPPROTO_ICMPV6: 5701#endif /* INET6 */ 5702 break; 5703 default: 5704 return (1); 5705 } 5706 5707 if (!hw_assist) { 5708 switch (af) { 5709 case AF_INET: 5710 if (p == IPPROTO_ICMP) { 5711 if (m->m_len < off) 5712 return (1); 5713 m->m_data += off; 5714 m->m_len -= off; 5715 sum = in_cksum(m, len); 5716 m->m_data -= off; 5717 m->m_len += off; 5718 } else { 5719 if (m->m_len < sizeof(struct ip)) 5720 return (1); 5721 sum = in4_cksum(m, p, off, len); 5722 } 5723 break; 5724#ifdef INET6 5725 case AF_INET6: 5726 if (m->m_len < sizeof(struct ip6_hdr)) 5727 return (1); 5728 sum = in6_cksum(m, p, off, len); 5729 break; 5730#endif /* INET6 */ 5731 default: 5732 return (1); 5733 } 5734 } 5735 if (sum) { 5736 switch (p) { 5737 case IPPROTO_TCP: 5738 tcpstat.tcps_rcvbadsum++; 5739 break; 5740 case IPPROTO_UDP: 5741 udpstat.udps_badsum++; 5742 break; 5743 case IPPROTO_ICMP: 5744 icmpstat.icps_checksum++; 5745 break; 5746#ifdef INET6 5747 case IPPROTO_ICMPV6: 5748 icmp6stat.icp6s_checksum++; 5749 break; 5750#endif /* INET6 */ 5751 } 5752 return (1); 5753 } else { 5754 if (p == IPPROTO_TCP || p == IPPROTO_UDP) { 5755 m->m_pkthdr.csum_flags |= 5756 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); 5757 m->m_pkthdr.csum_data = 0xffff; 5758 } 5759 } 5760 return (0); 5761} 5762#else 5763/* 5764 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 5765 * off is the offset where the protocol header starts 5766 * len is the total length of protocol header plus payload 5767 * returns 0 when the checksum is valid, otherwise returns 1. 5768 */ 5769int 5770pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, 5771 sa_family_t af) 5772{ 5773 u_int16_t flag_ok, flag_bad; 5774 u_int16_t sum; 5775 5776 switch (p) { 5777 case IPPROTO_TCP: 5778 flag_ok = M_TCP_CSUM_IN_OK; 5779 flag_bad = M_TCP_CSUM_IN_BAD; 5780 break; 5781 case IPPROTO_UDP: 5782 flag_ok = M_UDP_CSUM_IN_OK; 5783 flag_bad = M_UDP_CSUM_IN_BAD; 5784 break; 5785 case IPPROTO_ICMP: 5786#ifdef INET6 5787 case IPPROTO_ICMPV6: 5788#endif /* INET6 */ 5789 flag_ok = flag_bad = 0; 5790 break; 5791 default: 5792 return (1); 5793 } 5794 if (m->m_pkthdr.csum & flag_ok) 5795 return (0); 5796 if (m->m_pkthdr.csum & flag_bad) 5797 return (1); 5798 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 5799 return (1); 5800 if (m->m_pkthdr.len < off + len) 5801 return (1); 5802 switch (af) { 5803 case AF_INET: 5804 if (p == IPPROTO_ICMP) { 5805 if (m->m_len < off) 5806 return (1); 5807 m->m_data += off; 5808 m->m_len -= off; 5809 sum = in_cksum(m, len); 5810 m->m_data -= off; 5811 m->m_len += off; 5812 } else { 5813 if (m->m_len < sizeof(struct ip)) 5814 return (1); 5815 sum = in4_cksum(m, p, off, len); 5816 } 5817 break; 5818#ifdef INET6 5819 case AF_INET6: 5820 if (m->m_len < sizeof(struct ip6_hdr)) 5821 return (1); 5822 sum = in6_cksum(m, p, off, len); 5823 break; 5824#endif /* INET6 */ 5825 default: 5826 return (1); 5827 } 5828 if (sum) { 5829 m->m_pkthdr.csum |= flag_bad; 5830 switch (p) { 5831 case IPPROTO_TCP: 5832 tcpstat.tcps_rcvbadsum++; 5833 break; 5834 case IPPROTO_UDP: 5835 udpstat.udps_badsum++; 5836 break; 5837 case IPPROTO_ICMP: 5838 icmpstat.icps_checksum++; 5839 break; 5840#ifdef INET6 5841 case IPPROTO_ICMPV6: 5842 icmp6stat.icp6s_checksum++; 5843 break; 5844#endif /* INET6 */ 5845 } 5846 return (1); 5847 } 5848 m->m_pkthdr.csum |= flag_ok; 5849 return (0); 5850} 5851#endif 5852 5853static int 5854pf_add_mbuf_tag(struct mbuf *m, u_int tag) 5855{ 5856 struct m_tag *mtag; 5857 5858 if (m_tag_find(m, tag, NULL) != NULL) 5859 return (0); 5860 mtag = m_tag_get(tag, 0, M_NOWAIT); 5861 if (mtag == NULL) 5862 return (1); 5863 m_tag_prepend(m, mtag); 5864 return (0); 5865} 5866 5867#ifdef INET 5868int 5869#ifdef __FreeBSD__ 5870pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) 5871#else 5872pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) 5873#endif 5874{ 5875 struct pfi_kif *kif; 5876 u_short action, reason = 0, log = 0; 5877 struct mbuf *m = *m0; 5878 struct ip *h = NULL; /* make the compiler happy */ 5879 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 5880 struct pf_state *s = NULL; 5881 struct pf_ruleset *ruleset = NULL; 5882 struct pf_pdesc pd; 5883 int off, dirndx, pqid = 0; 5884 5885#ifdef __FreeBSD__ 5886 PF_LOCK(); 5887#endif 5888 if (!pf_status.running || 5889#ifdef __FreeBSD__ 5890 (m->m_flags & M_SKIP_FIREWALL)) { 5891 PF_UNLOCK(); 5892#else 5893 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) { 5894#endif 5895 return (PF_PASS); 5896 } 5897 5898 kif = pfi_index2kif[ifp->if_index]; 5899 if (kif == NULL) { 5900#ifdef __FreeBSD__ 5901 PF_UNLOCK(); 5902#endif 5903 return (PF_DROP); 5904 } 5905 5906#ifdef __FreeBSD__ 5907 M_ASSERTPKTHDR(m); 5908#else 5909#ifdef DIAGNOSTIC 5910 if ((m->m_flags & M_PKTHDR) == 0) 5911 panic("non-M_PKTHDR is passed to pf_test"); 5912#endif 5913#endif 5914 5915 memset(&pd, 0, sizeof(pd)); 5916 if (m->m_pkthdr.len < (int)sizeof(*h)) { 5917 action = PF_DROP; 5918 REASON_SET(&reason, PFRES_SHORT); 5919 log = 1; 5920 goto done; 5921 } 5922 5923 /* We do IP header normalization and packet reassembly here */ 5924 if (pf_normalize_ip(m0, dir, kif, &reason) != PF_PASS) { 5925 action = PF_DROP; 5926 goto done; 5927 } 5928 m = *m0; 5929 h = mtod(m, struct ip *); 5930 5931 off = h->ip_hl << 2; 5932 if (off < (int)sizeof(*h)) { 5933 action = PF_DROP; 5934 REASON_SET(&reason, PFRES_SHORT); 5935 log = 1; 5936 goto done; 5937 } 5938 5939 pd.src = (struct pf_addr *)&h->ip_src; 5940 pd.dst = (struct pf_addr *)&h->ip_dst; 5941 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET); 5942 pd.ip_sum = &h->ip_sum; 5943 pd.proto = h->ip_p; 5944 pd.af = AF_INET; 5945 pd.tos = h->ip_tos; 5946 pd.tot_len = ntohs(h->ip_len); 5947 5948 /* handle fragments that didn't get reassembled by normalization */ 5949 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) { 5950 action = pf_test_fragment(&r, dir, kif, m, h, 5951 &pd, &a, &ruleset); 5952 goto done; 5953 } 5954 5955 switch (h->ip_p) { 5956 5957 case IPPROTO_TCP: { 5958 struct tcphdr th; 5959 5960 pd.hdr.tcp = &th; 5961 if (!pf_pull_hdr(m, off, &th, sizeof(th), 5962 &action, &reason, AF_INET)) { 5963 log = action != PF_PASS; 5964 goto done; 5965 } 5966 if (dir == PF_IN && pf_check_proto_cksum(m, off, 5967 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) { 5968 action = PF_DROP; 5969 goto done; 5970 } 5971 pd.p_len = pd.tot_len - off - (th.th_off << 2); 5972 if ((th.th_flags & TH_ACK) && pd.p_len == 0) 5973 pqid = 1; 5974 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 5975 if (action == PF_DROP) 5976 goto done; 5977 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, 5978 &reason); 5979 if (action == PF_PASS) { 5980#if NPFSYNC 5981 pfsync_update_state(s); 5982#endif 5983 r = s->rule.ptr; 5984 a = s->anchor.ptr; 5985 log = s->log; 5986 } else if (s == NULL) 5987#ifdef __FreeBSD__ 5988 action = pf_test_tcp(&r, &s, dir, kif, 5989 m, off, h, &pd, &a, &ruleset, inp); 5990#else 5991 action = pf_test_tcp(&r, &s, dir, kif, 5992 m, off, h, &pd, &a, &ruleset); 5993#endif 5994 break; 5995 } 5996 5997 case IPPROTO_UDP: { 5998 struct udphdr uh; 5999 6000 pd.hdr.udp = &uh; 6001 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 6002 &action, &reason, AF_INET)) { 6003 log = action != PF_PASS; 6004 goto done; 6005 } 6006 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 6007 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) { 6008 action = PF_DROP; 6009 goto done; 6010 } 6011 if (uh.uh_dport == 0 || 6012 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 6013 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 6014 action = PF_DROP; 6015 goto done; 6016 } 6017 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 6018 if (action == PF_PASS) { 6019#if NPFSYNC 6020 pfsync_update_state(s); 6021#endif 6022 r = s->rule.ptr; 6023 a = s->anchor.ptr; 6024 log = s->log; 6025 } else if (s == NULL) 6026#ifdef __FreeBSD__ 6027 action = pf_test_udp(&r, &s, dir, kif, 6028 m, off, h, &pd, &a, &ruleset, inp); 6029#else 6030 action = pf_test_udp(&r, &s, dir, kif, 6031 m, off, h, &pd, &a, &ruleset); 6032#endif 6033 break; 6034 } 6035 6036 case IPPROTO_ICMP: { 6037 struct icmp ih; 6038 6039 pd.hdr.icmp = &ih; 6040 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN, 6041 &action, &reason, AF_INET)) { 6042 log = action != PF_PASS; 6043 goto done; 6044 } 6045 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6046 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) { 6047 action = PF_DROP; 6048 goto done; 6049 } 6050 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd); 6051 if (action == PF_PASS) { 6052#if NPFSYNC 6053 pfsync_update_state(s); 6054#endif 6055 r = s->rule.ptr; 6056 a = s->anchor.ptr; 6057 log = s->log; 6058 } else if (s == NULL) 6059 action = pf_test_icmp(&r, &s, dir, kif, 6060 m, off, h, &pd, &a, &ruleset); 6061 break; 6062 } 6063 6064 default: 6065 action = pf_test_state_other(&s, dir, kif, &pd); 6066 if (action == PF_PASS) { 6067#if NPFSYNC 6068 pfsync_update_state(s); 6069#endif 6070 r = s->rule.ptr; 6071 a = s->anchor.ptr; 6072 log = s->log; 6073 } else if (s == NULL) 6074 action = pf_test_other(&r, &s, dir, kif, m, off, h, 6075 &pd, &a, &ruleset); 6076 break; 6077 } 6078 6079done: 6080 if (action == PF_PASS && h->ip_hl > 5 && 6081 !((s && s->allow_opts) || r->allow_opts)) { 6082 action = PF_DROP; 6083 REASON_SET(&reason, PFRES_SHORT); 6084 log = 1; 6085 DPFPRINTF(PF_DEBUG_MISC, 6086 ("pf: dropping packet with ip options\n")); 6087 } 6088 6089#ifdef ALTQ 6090 if (action == PF_PASS && r->qid) { 6091 struct m_tag *mtag; 6092 struct altq_tag *atag; 6093 6094 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); 6095 if (mtag != NULL) { 6096 atag = (struct altq_tag *)(mtag + 1); 6097 if (pqid || pd.tos == IPTOS_LOWDELAY) 6098 atag->qid = r->pqid; 6099 else 6100 atag->qid = r->qid; 6101 /* add hints for ecn */ 6102 atag->af = AF_INET; 6103 atag->hdr = h; 6104 m_tag_prepend(m, mtag); 6105 } 6106 } 6107#endif 6108 6109 /* 6110 * connections redirected to loopback should not match sockets 6111 * bound specifically to loopback due to security implications, 6112 * see tcp_input() and in_pcblookup_listen(). 6113 */ 6114 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 6115 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 6116 (s->nat_rule.ptr->action == PF_RDR || 6117 s->nat_rule.ptr->action == PF_BINAT) && 6118 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET && 6119 pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) { 6120 action = PF_DROP; 6121 REASON_SET(&reason, PFRES_MEMORY); 6122 } 6123 6124 if (log) 6125 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, a, ruleset); 6126 6127 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 6128 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++; 6129 6130 if (action == PF_PASS || r->action == PF_DROP) { 6131 r->packets++; 6132 r->bytes += pd.tot_len; 6133 if (a != NULL) { 6134 a->packets++; 6135 a->bytes += pd.tot_len; 6136 } 6137 if (s != NULL) { 6138 dirndx = (dir == s->direction) ? 0 : 1; 6139 s->packets[dirndx]++; 6140 s->bytes[dirndx] += pd.tot_len; 6141 if (s->nat_rule.ptr != NULL) { 6142 s->nat_rule.ptr->packets++; 6143 s->nat_rule.ptr->bytes += pd.tot_len; 6144 } 6145 if (s->src_node != NULL) { 6146 s->src_node->packets++; 6147 s->src_node->bytes += pd.tot_len; 6148 } 6149 if (s->nat_src_node != NULL) { 6150 s->nat_src_node->packets++; 6151 s->nat_src_node->bytes += pd.tot_len; 6152 } 6153 } 6154 tr = r; 6155 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 6156 if (nr != NULL) { 6157 struct pf_addr *x; 6158 /* 6159 * XXX: we need to make sure that the addresses 6160 * passed to pfr_update_stats() are the same than 6161 * the addresses used during matching (pfr_match) 6162 */ 6163 if (r == &pf_default_rule) { 6164 tr = nr; 6165 x = (s == NULL || s->direction == dir) ? 6166 &pd.baddr : &pd.naddr; 6167 } else 6168 x = (s == NULL || s->direction == dir) ? 6169 &pd.naddr : &pd.baddr; 6170 if (x == &pd.baddr || s == NULL) { 6171 /* we need to change the address */ 6172 if (dir == PF_OUT) 6173 pd.src = x; 6174 else 6175 pd.dst = x; 6176 } 6177 } 6178 if (tr->src.addr.type == PF_ADDR_TABLE) 6179 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL || 6180 s->direction == dir) ? pd.src : pd.dst, pd.af, 6181 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 6182 tr->src.not); 6183 if (tr->dst.addr.type == PF_ADDR_TABLE) 6184 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL || 6185 s->direction == dir) ? pd.dst : pd.src, pd.af, 6186 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 6187 tr->dst.not); 6188 } 6189 6190 6191 if (action == PF_SYNPROXY_DROP) { 6192 m_freem(*m0); 6193 *m0 = NULL; 6194 action = PF_PASS; 6195 } else if (r->rt) 6196 /* pf_route can free the mbuf causing *m0 to become NULL */ 6197 pf_route(m0, r, dir, ifp, s); 6198 6199#ifdef __FreeBSD__ 6200 PF_UNLOCK(); 6201#endif 6202 6203 return (action); 6204} 6205#endif /* INET */ 6206 6207#ifdef INET6 6208int 6209#ifdef __FreeBSD__ 6210pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) 6211#else 6212pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0) 6213#endif 6214{ 6215 struct pfi_kif *kif; 6216 u_short action, reason = 0, log = 0; 6217 struct mbuf *m = *m0; 6218 struct ip6_hdr *h = NULL; /* make the compiler happy */ 6219 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 6220 struct pf_state *s = NULL; 6221 struct pf_ruleset *ruleset = NULL; 6222 struct pf_pdesc pd; 6223 int off, terminal = 0, dirndx; 6224 6225#ifdef __FreeBSD__ 6226 PF_LOCK(); 6227#endif 6228 6229 if (!pf_status.running || 6230#ifdef __FreeBSD__ 6231 (m->m_flags & M_SKIP_FIREWALL)) { 6232 PF_UNLOCK(); 6233#else 6234 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) { 6235#endif 6236 return (PF_PASS); 6237 } 6238 6239 kif = pfi_index2kif[ifp->if_index]; 6240 if (kif == NULL) { 6241#ifdef __FreeBSD__ 6242 PF_UNLOCK(); 6243#endif 6244 return (PF_DROP); 6245 } 6246 6247#ifdef __FreeBSD__ 6248 M_ASSERTPKTHDR(m); 6249#else 6250#ifdef DIAGNOSTIC 6251 if ((m->m_flags & M_PKTHDR) == 0) 6252 panic("non-M_PKTHDR is passed to pf_test"); 6253#endif 6254#endif 6255 6256 memset(&pd, 0, sizeof(pd)); 6257 if (m->m_pkthdr.len < (int)sizeof(*h)) { 6258 action = PF_DROP; 6259 REASON_SET(&reason, PFRES_SHORT); 6260 log = 1; 6261 goto done; 6262 } 6263 6264 /* We do IP header normalization and packet reassembly here */ 6265 if (pf_normalize_ip6(m0, dir, kif, &reason) != PF_PASS) { 6266 action = PF_DROP; 6267 goto done; 6268 } 6269 m = *m0; 6270 h = mtod(m, struct ip6_hdr *); 6271 6272 pd.src = (struct pf_addr *)&h->ip6_src; 6273 pd.dst = (struct pf_addr *)&h->ip6_dst; 6274 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET6); 6275 pd.ip_sum = NULL; 6276 pd.af = AF_INET6; 6277 pd.tos = 0; 6278 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr); 6279 6280 off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr); 6281 pd.proto = h->ip6_nxt; 6282 do { 6283 switch (pd.proto) { 6284 case IPPROTO_FRAGMENT: 6285 action = pf_test_fragment(&r, dir, kif, m, h, 6286 &pd, &a, &ruleset); 6287 if (action == PF_DROP) 6288 REASON_SET(&reason, PFRES_FRAG); 6289 goto done; 6290 case IPPROTO_AH: 6291 case IPPROTO_HOPOPTS: 6292 case IPPROTO_ROUTING: 6293 case IPPROTO_DSTOPTS: { 6294 /* get next header and header length */ 6295 struct ip6_ext opt6; 6296 6297 if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6), 6298 NULL, NULL, pd.af)) { 6299 DPFPRINTF(PF_DEBUG_MISC, 6300 ("pf: IPv6 short opt\n")); 6301 action = PF_DROP; 6302 REASON_SET(&reason, PFRES_SHORT); 6303 log = 1; 6304 goto done; 6305 } 6306 if (pd.proto == IPPROTO_AH) 6307 off += (opt6.ip6e_len + 2) * 4; 6308 else 6309 off += (opt6.ip6e_len + 1) * 8; 6310 pd.proto = opt6.ip6e_nxt; 6311 /* goto the next header */ 6312 break; 6313 } 6314 default: 6315 terminal++; 6316 break; 6317 } 6318 } while (!terminal); 6319 6320 switch (pd.proto) { 6321 6322 case IPPROTO_TCP: { 6323 struct tcphdr th; 6324 6325 pd.hdr.tcp = &th; 6326 if (!pf_pull_hdr(m, off, &th, sizeof(th), 6327 &action, &reason, AF_INET6)) { 6328 log = action != PF_PASS; 6329 goto done; 6330 } 6331 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6332 ntohs(h->ip6_plen), IPPROTO_TCP, AF_INET6)) { 6333 action = PF_DROP; 6334 goto done; 6335 } 6336 pd.p_len = pd.tot_len - off - (th.th_off << 2); 6337 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 6338 if (action == PF_DROP) 6339 goto done; 6340 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, 6341 &reason); 6342 if (action == PF_PASS) { 6343#if NPFSYNC 6344 pfsync_update_state(s); 6345#endif 6346 r = s->rule.ptr; 6347 a = s->anchor.ptr; 6348 log = s->log; 6349 } else if (s == NULL) 6350#ifdef __FreeBSD__ 6351 action = pf_test_tcp(&r, &s, dir, kif, 6352 m, off, h, &pd, &a, &ruleset, inp); 6353#else 6354 action = pf_test_tcp(&r, &s, dir, kif, 6355 m, off, h, &pd, &a, &ruleset); 6356#endif 6357 break; 6358 } 6359 6360 case IPPROTO_UDP: { 6361 struct udphdr uh; 6362 6363 pd.hdr.udp = &uh; 6364 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 6365 &action, &reason, AF_INET6)) { 6366 log = action != PF_PASS; 6367 goto done; 6368 } 6369 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 6370 off, ntohs(h->ip6_plen), IPPROTO_UDP, AF_INET6)) { 6371 action = PF_DROP; 6372 goto done; 6373 } 6374 if (uh.uh_dport == 0 || 6375 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 6376 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 6377 action = PF_DROP; 6378 goto done; 6379 } 6380 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 6381 if (action == PF_PASS) { 6382#if NPFSYNC 6383 pfsync_update_state(s); 6384#endif 6385 r = s->rule.ptr; 6386 a = s->anchor.ptr; 6387 log = s->log; 6388 } else if (s == NULL) 6389#ifdef __FreeBSD__ 6390 action = pf_test_udp(&r, &s, dir, kif, 6391 m, off, h, &pd, &a, &ruleset, inp); 6392#else 6393 action = pf_test_udp(&r, &s, dir, kif, 6394 m, off, h, &pd, &a, &ruleset); 6395#endif 6396 break; 6397 } 6398 6399 case IPPROTO_ICMPV6: { 6400 struct icmp6_hdr ih; 6401 6402 pd.hdr.icmp6 = &ih; 6403 if (!pf_pull_hdr(m, off, &ih, sizeof(ih), 6404 &action, &reason, AF_INET6)) { 6405 log = action != PF_PASS; 6406 goto done; 6407 } 6408 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6409 ntohs(h->ip6_plen), IPPROTO_ICMPV6, AF_INET6)) { 6410 action = PF_DROP; 6411 goto done; 6412 } 6413 action = pf_test_state_icmp(&s, dir, kif, 6414 m, off, h, &pd); 6415 if (action == PF_PASS) { 6416#if NPFSYNC 6417 pfsync_update_state(s); 6418#endif 6419 r = s->rule.ptr; 6420 a = s->anchor.ptr; 6421 log = s->log; 6422 } else if (s == NULL) 6423 action = pf_test_icmp(&r, &s, dir, kif, 6424 m, off, h, &pd, &a, &ruleset); 6425 break; 6426 } 6427 6428 default: 6429 action = pf_test_state_other(&s, dir, kif, &pd); 6430 if (action == PF_PASS) { 6431 r = s->rule.ptr; 6432 a = s->anchor.ptr; 6433 log = s->log; 6434 } else if (s == NULL) 6435 action = pf_test_other(&r, &s, dir, kif, m, off, h, 6436 &pd, &a, &ruleset); 6437 break; 6438 } 6439 6440done: 6441 /* XXX handle IPv6 options, if not allowed. not implemented. */ 6442 6443#ifdef ALTQ 6444 if (action == PF_PASS && r->qid) { 6445 struct m_tag *mtag; 6446 struct altq_tag *atag; 6447 6448 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); 6449 if (mtag != NULL) { 6450 atag = (struct altq_tag *)(mtag + 1); 6451 if (pd.tos == IPTOS_LOWDELAY) 6452 atag->qid = r->pqid; 6453 else 6454 atag->qid = r->qid; 6455 /* add hints for ecn */ 6456 atag->af = AF_INET6; 6457 atag->hdr = h; 6458 m_tag_prepend(m, mtag); 6459 } 6460 } 6461#endif 6462 6463 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 6464 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 6465 (s->nat_rule.ptr->action == PF_RDR || 6466 s->nat_rule.ptr->action == PF_BINAT) && 6467 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6) && 6468 pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) { 6469 action = PF_DROP; 6470 REASON_SET(&reason, PFRES_MEMORY); 6471 } 6472 6473 if (log) 6474 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, r, a, ruleset); 6475 6476 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 6477 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++; 6478 6479 if (action == PF_PASS || r->action == PF_DROP) { 6480 r->packets++; 6481 r->bytes += pd.tot_len; 6482 if (a != NULL) { 6483 a->packets++; 6484 a->bytes += pd.tot_len; 6485 } 6486 if (s != NULL) { 6487 dirndx = (dir == s->direction) ? 0 : 1; 6488 s->packets[dirndx]++; 6489 s->bytes[dirndx] += pd.tot_len; 6490 if (s->nat_rule.ptr != NULL) { 6491 s->nat_rule.ptr->packets++; 6492 s->nat_rule.ptr->bytes += pd.tot_len; 6493 } 6494 if (s->src_node != NULL) { 6495 s->src_node->packets++; 6496 s->src_node->bytes += pd.tot_len; 6497 } 6498 if (s->nat_src_node != NULL) { 6499 s->nat_src_node->packets++; 6500 s->nat_src_node->bytes += pd.tot_len; 6501 } 6502 } 6503 tr = r; 6504 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 6505 if (nr != NULL) { 6506 struct pf_addr *x; 6507 /* 6508 * XXX: we need to make sure that the addresses 6509 * passed to pfr_update_stats() are the same than 6510 * the addresses used during matching (pfr_match) 6511 */ 6512 if (r == &pf_default_rule) { 6513 tr = nr; 6514 x = (s == NULL || s->direction == dir) ? 6515 &pd.baddr : &pd.naddr; 6516 } else { 6517 x = (s == NULL || s->direction == dir) ? 6518 &pd.naddr : &pd.baddr; 6519 } 6520 if (x == &pd.baddr || s == NULL) { 6521 if (dir == PF_OUT) 6522 pd.src = x; 6523 else 6524 pd.dst = x; 6525 } 6526 } 6527 if (tr->src.addr.type == PF_ADDR_TABLE) 6528 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL || 6529 s->direction == dir) ? pd.src : pd.dst, pd.af, 6530 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 6531 tr->src.not); 6532 if (tr->dst.addr.type == PF_ADDR_TABLE) 6533 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL || 6534 s->direction == dir) ? pd.dst : pd.src, pd.af, 6535 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 6536 tr->dst.not); 6537 } 6538 6539 6540 if (action == PF_SYNPROXY_DROP) { 6541 m_freem(*m0); 6542 *m0 = NULL; 6543 action = PF_PASS; 6544 } else if (r->rt) 6545 /* pf_route6 can free the mbuf causing *m0 to become NULL */ 6546 pf_route6(m0, r, dir, ifp, s); 6547 6548#ifdef __FreeBSD__ 6549 PF_UNLOCK(); 6550#endif 6551 return (action); 6552} 6553#endif /* INET6 */ 6554