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