pf.c revision 128129
1/* $FreeBSD: head/sys/contrib/pf/net/pf.c 128129 2004-04-11 17:35:40Z mlaier $ */ 2/* $OpenBSD: pf.c,v 1.389.2.3 2004/04/10 09:38:19 brad 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 = 0; /* make the compiler happy */ 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 = 0, tlen; /* make the compiler happy */ 1226#ifdef INET 1227 struct ip *h = NULL; /* make the compiler happy */ 1228#endif /* INET */ 1229#ifdef INET6 1230 struct ip6_hdr *h6 = NULL; /* make the compiler happy */ 1231#endif /* INET6 */ 1232 struct tcphdr *th = NULL; /* make the compiler happy */ 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 = 0; /* make the compiler happy */ 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.seqlo = 0; /* Haven't seen these yet */ 2690 s->dst.seqhi = 1; 2691 s->dst.max_win = 1; 2692 s->dst.seqdiff = 0; /* Defer random generation */ 2693 s->src.state = TCPS_SYN_SENT; 2694 s->dst.state = TCPS_CLOSED; 2695#ifdef __FreeBSD__ 2696 s->creation = time_second; 2697 s->expire = time_second; 2698#else 2699 s->creation = time.tv_sec; 2700 s->expire = time.tv_sec; 2701#endif 2702 s->timeout = PFTM_TCP_FIRST_PACKET; 2703 s->packets[0] = 1; 2704 s->bytes[0] = pd->tot_len; 2705 pf_set_rt_ifp(s, saddr); 2706 2707 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m, 2708 off, pd, th, &s->src, &s->dst)) { 2709 REASON_SET(&reason, PFRES_MEMORY); 2710 pool_put(&pf_state_pl, s); 2711 return (PF_DROP); 2712 } 2713 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub && 2714 pf_normalize_tcp_stateful(m, off, pd, &reason, th, &s->src, 2715 &s->dst, &rewrite)) { 2716 pf_normalize_tcp_cleanup(s); 2717 pool_put(&pf_state_pl, s); 2718 return (PF_DROP); 2719 } 2720 if (pf_insert_state(s)) { 2721 pf_normalize_tcp_cleanup(s); 2722 REASON_SET(&reason, PFRES_MEMORY); 2723 pool_put(&pf_state_pl, s); 2724 return (PF_DROP); 2725 } else 2726 *sm = s; 2727 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 2728 r->keep_state == PF_STATE_SYNPROXY) { 2729 s->src.state = PF_TCPS_PROXY_SRC; 2730 if (nat != NULL) 2731 pf_change_ap(saddr, &th->th_sport, 2732 pd->ip_sum, &th->th_sum, &baddr, 2733 bport, 0, af); 2734 else if (rdr != NULL) 2735 pf_change_ap(daddr, &th->th_dport, 2736 pd->ip_sum, &th->th_sum, &baddr, 2737 bport, 0, af); 2738 s->src.seqhi = arc4random(); 2739 /* Find mss option */ 2740 mss = pf_get_mss(m, off, th->th_off, af); 2741 mss = pf_calc_mss(saddr, af, mss); 2742 mss = pf_calc_mss(daddr, af, mss); 2743 s->src.mss = mss; 2744 pf_send_tcp(r, af, daddr, saddr, th->th_dport, 2745 th->th_sport, s->src.seqhi, 2746 ntohl(th->th_seq) + 1, TH_SYN|TH_ACK, 0, s->src.mss, 0); 2747 return (PF_SYNPROXY_DROP); 2748 } 2749 } 2750 2751 /* copy back packet headers if we performed NAT operations */ 2752 if (rewrite) 2753 m_copyback(m, off, sizeof(*th), (caddr_t)th); 2754 2755 return (PF_PASS); 2756} 2757 2758int 2759pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction, 2760 struct ifnet *ifp, struct mbuf *m, int ipoff, int off, void *h, 2761 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) 2762{ 2763 struct pf_rule *nat = NULL, *rdr = NULL; 2764 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 2765 struct pf_addr baddr, naddr; 2766 struct udphdr *uh = pd->hdr.udp; 2767 u_int16_t bport, nport = 0; 2768 sa_family_t af = pd->af; 2769 int lookup = -1; 2770 uid_t uid; 2771 gid_t gid; 2772 struct pf_rule *r, *a = NULL; 2773 struct pf_ruleset *ruleset = NULL; 2774 u_short reason; 2775 int rewrite = 0; 2776 struct pf_tag *pftag = NULL; 2777 int tag = -1; 2778 2779 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 2780 2781 if (direction == PF_OUT) { 2782 bport = nport = uh->uh_sport; 2783 /* check outgoing packet for BINAT/NAT */ 2784 if ((nat = pf_get_translation(pd, m, off, PF_OUT, ifp, 2785 saddr, uh->uh_sport, daddr, uh->uh_dport, 2786 &naddr, &nport)) != NULL) { 2787 PF_ACPY(&baddr, saddr, af); 2788 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, 2789 &uh->uh_sum, &naddr, nport, 1, af); 2790 rewrite++; 2791 if (nat->natpass) 2792 r = NULL; 2793 } 2794 } else { 2795 bport = nport = uh->uh_dport; 2796 /* check incoming packet for BINAT/RDR */ 2797 if ((rdr = pf_get_translation(pd, m, off, PF_IN, ifp, saddr, 2798 uh->uh_sport, daddr, uh->uh_dport, &naddr, &nport)) 2799 != NULL) { 2800 PF_ACPY(&baddr, daddr, af); 2801 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, 2802 &uh->uh_sum, &naddr, nport, 1, af); 2803 rewrite++; 2804 if (rdr->natpass) 2805 r = NULL; 2806 } 2807 } 2808 2809 while (r != NULL) { 2810 r->evaluations++; 2811 if (r->ifp != NULL && ((r->ifp != ifp && !r->ifnot) || 2812 (r->ifp == ifp && r->ifnot))) 2813 r = r->skip[PF_SKIP_IFP].ptr; 2814 else if (r->direction && r->direction != direction) 2815 r = r->skip[PF_SKIP_DIR].ptr; 2816 else if (r->af && r->af != af) 2817 r = r->skip[PF_SKIP_AF].ptr; 2818 else if (r->proto && r->proto != IPPROTO_UDP) 2819 r = r->skip[PF_SKIP_PROTO].ptr; 2820 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) 2821 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 2822 else if (r->src.port_op && !pf_match_port(r->src.port_op, 2823 r->src.port[0], r->src.port[1], uh->uh_sport)) 2824 r = r->skip[PF_SKIP_SRC_PORT].ptr; 2825 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) 2826 r = r->skip[PF_SKIP_DST_ADDR].ptr; 2827 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 2828 r->dst.port[0], r->dst.port[1], uh->uh_dport)) 2829 r = r->skip[PF_SKIP_DST_PORT].ptr; 2830 else if (r->tos && !(r->tos & pd->tos)) 2831 r = TAILQ_NEXT(r, entries); 2832 else if (r->rule_flag & PFRULE_FRAGMENT) 2833 r = TAILQ_NEXT(r, entries); 2834 else if (r->uid.op && (lookup != -1 || (lookup = 2835 pf_socket_lookup(&uid, &gid, direction, af, IPPROTO_UDP, 2836 pd), 1)) && 2837 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 2838 uid)) 2839 r = TAILQ_NEXT(r, entries); 2840 else if (r->gid.op && (lookup != -1 || (lookup = 2841 pf_socket_lookup(&uid, &gid, direction, af, IPPROTO_UDP, 2842 pd), 1)) && 2843 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 2844 gid)) 2845 r = TAILQ_NEXT(r, entries); 2846 else if (r->match_tag && 2847 !pf_match_tag(m, r, nat, rdr, pftag, &tag)) 2848 r = TAILQ_NEXT(r, entries); 2849 else if (r->anchorname[0] && r->anchor == NULL) 2850 r = TAILQ_NEXT(r, entries); 2851 else if (r->os_fingerprint != PF_OSFP_ANY) 2852 r = TAILQ_NEXT(r, entries); 2853 else { 2854 if (r->tag) 2855 tag = r->tag; 2856 if (r->anchor == NULL) { 2857 *rm = r; 2858 *am = a; 2859 *rsm = ruleset; 2860 if ((*rm)->quick) 2861 break; 2862 r = TAILQ_NEXT(r, entries); 2863 } else 2864 PF_STEP_INTO_ANCHOR(r, a, ruleset, 2865 PF_RULESET_FILTER); 2866 } 2867 if (r == NULL && a != NULL) 2868 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 2869 PF_RULESET_FILTER); 2870 } 2871 r = *rm; 2872 a = *am; 2873 ruleset = *rsm; 2874 2875 r->packets++; 2876 r->bytes += pd->tot_len; 2877 if (a != NULL) { 2878 a->packets++; 2879 a->bytes += pd->tot_len; 2880 } 2881 REASON_SET(&reason, PFRES_MATCH); 2882 2883 if (r->log) { 2884 if (rewrite) 2885 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 2886 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); 2887 } 2888 2889 if ((r->action == PF_DROP) && 2890 ((r->rule_flag & PFRULE_RETURNICMP) || 2891 (r->rule_flag & PFRULE_RETURN))) { 2892 /* undo NAT changes, if they have taken place */ 2893 if (nat != NULL) { 2894 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, 2895 &uh->uh_sum, &baddr, bport, 1, af); 2896 rewrite++; 2897 } else if (rdr != NULL) { 2898 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, 2899 &uh->uh_sum, &baddr, bport, 1, af); 2900 rewrite++; 2901 } 2902 if ((af == AF_INET) && r->return_icmp) 2903 pf_send_icmp(m, r->return_icmp >> 8, 2904 r->return_icmp & 255, af, r); 2905 else if ((af == AF_INET6) && r->return_icmp6) 2906 pf_send_icmp(m, r->return_icmp6 >> 8, 2907 r->return_icmp6 & 255, af, r); 2908 } 2909 2910 if (r->action == PF_DROP) 2911 return (PF_DROP); 2912 2913 if (pf_tag_packet(m, pftag, tag)) { 2914 REASON_SET(&reason, PFRES_MEMORY); 2915 return (PF_DROP); 2916 } 2917 2918 if (r->keep_state || nat != NULL || rdr != NULL) { 2919 /* create new state */ 2920 struct pf_state *s = NULL; 2921 2922 if (!r->max_states || r->states < r->max_states) 2923 s = pool_get(&pf_state_pl, PR_NOWAIT); 2924 if (s == NULL) { 2925 REASON_SET(&reason, PFRES_MEMORY); 2926 return (PF_DROP); 2927 } 2928 bzero(s, sizeof(*s)); 2929 r->states++; 2930 if (a != NULL) 2931 a->states++; 2932 s->rule.ptr = r; 2933 if (nat != NULL) 2934 s->nat_rule.ptr = nat; 2935 else 2936 s->nat_rule.ptr = rdr; 2937 if (s->nat_rule.ptr != NULL) 2938 s->nat_rule.ptr->states++; 2939 s->anchor.ptr = a; 2940 s->allow_opts = r->allow_opts; 2941 s->log = r->log & 2; 2942 s->proto = IPPROTO_UDP; 2943 s->direction = direction; 2944 s->af = af; 2945 if (direction == PF_OUT) { 2946 PF_ACPY(&s->gwy.addr, saddr, af); 2947 s->gwy.port = uh->uh_sport; 2948 PF_ACPY(&s->ext.addr, daddr, af); 2949 s->ext.port = uh->uh_dport; 2950 if (nat != NULL) { 2951 PF_ACPY(&s->lan.addr, &baddr, af); 2952 s->lan.port = bport; 2953 } else { 2954 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 2955 s->lan.port = s->gwy.port; 2956 } 2957 } else { 2958 PF_ACPY(&s->lan.addr, daddr, af); 2959 s->lan.port = uh->uh_dport; 2960 PF_ACPY(&s->ext.addr, saddr, af); 2961 s->ext.port = uh->uh_sport; 2962 if (rdr != NULL) { 2963 PF_ACPY(&s->gwy.addr, &baddr, af); 2964 s->gwy.port = bport; 2965 } else { 2966 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 2967 s->gwy.port = s->lan.port; 2968 } 2969 } 2970 s->src.seqlo = 0; 2971 s->src.seqhi = 0; 2972 s->src.seqdiff = 0; 2973 s->src.max_win = 0; 2974 s->src.state = PFUDPS_SINGLE; 2975 s->dst.seqlo = 0; 2976 s->dst.seqhi = 0; 2977 s->dst.seqdiff = 0; 2978 s->dst.max_win = 0; 2979 s->dst.state = PFUDPS_NO_TRAFFIC; 2980#ifdef __FreeBSD__ 2981 s->creation = time_second; 2982 s->expire = time_second; 2983#else 2984 s->creation = time.tv_sec; 2985 s->expire = time.tv_sec; 2986#endif 2987 s->timeout = PFTM_UDP_FIRST_PACKET; 2988 s->packets[0] = 1; 2989 s->bytes[0] = pd->tot_len; 2990 pf_set_rt_ifp(s, saddr); 2991 if (pf_insert_state(s)) { 2992 REASON_SET(&reason, PFRES_MEMORY); 2993 pool_put(&pf_state_pl, s); 2994 return (PF_DROP); 2995 } else 2996 *sm = s; 2997 } 2998 2999 /* copy back packet headers if we performed NAT operations */ 3000 if (rewrite) 3001 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 3002 3003 return (PF_PASS); 3004} 3005 3006int 3007pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction, 3008 struct ifnet *ifp, struct mbuf *m, int ipoff, int off, void *h, 3009 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) 3010{ 3011 struct pf_rule *nat = NULL, *rdr = NULL; 3012 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3013 struct pf_addr baddr, naddr; 3014 struct pf_rule *r, *a = NULL; 3015 struct pf_ruleset *ruleset = NULL; 3016 u_short reason; 3017 u_int16_t icmpid = 0; /* make the compiler happy */ 3018 sa_family_t af = pd->af; 3019 u_int8_t icmptype = 0; /* make the compiler happy */ 3020 u_int8_t icmpcode = 0; /* make the compiler happy */ 3021 int state_icmp = 0; 3022 struct pf_tag *pftag = NULL; 3023 int tag = -1; 3024#ifdef INET6 3025 int rewrite = 0; 3026#endif /* INET6 */ 3027 3028 switch (pd->proto) { 3029#ifdef INET 3030 case IPPROTO_ICMP: 3031 icmptype = pd->hdr.icmp->icmp_type; 3032 icmpcode = pd->hdr.icmp->icmp_code; 3033 icmpid = pd->hdr.icmp->icmp_id; 3034 3035 if (icmptype == ICMP_UNREACH || 3036 icmptype == ICMP_SOURCEQUENCH || 3037 icmptype == ICMP_REDIRECT || 3038 icmptype == ICMP_TIMXCEED || 3039 icmptype == ICMP_PARAMPROB) 3040 state_icmp++; 3041 break; 3042#endif /* INET */ 3043#ifdef INET6 3044 case IPPROTO_ICMPV6: 3045 icmptype = pd->hdr.icmp6->icmp6_type; 3046 icmpcode = pd->hdr.icmp6->icmp6_code; 3047 icmpid = pd->hdr.icmp6->icmp6_id; 3048 3049 if (icmptype == ICMP6_DST_UNREACH || 3050 icmptype == ICMP6_PACKET_TOO_BIG || 3051 icmptype == ICMP6_TIME_EXCEEDED || 3052 icmptype == ICMP6_PARAM_PROB) 3053 state_icmp++; 3054 break; 3055#endif /* INET6 */ 3056 } 3057 3058 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3059 3060 if (direction == PF_OUT) { 3061 /* check outgoing packet for BINAT/NAT */ 3062 if ((nat = pf_get_translation(pd, m, off, PF_OUT, ifp, saddr, 0, 3063 daddr, 0, &naddr, NULL)) != NULL) { 3064 PF_ACPY(&baddr, saddr, af); 3065 switch (af) { 3066#ifdef INET 3067 case AF_INET: 3068 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, 3069 naddr.v4.s_addr, 0); 3070 break; 3071#endif /* INET */ 3072#ifdef INET6 3073 case AF_INET6: 3074 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum, 3075 &naddr, 0); 3076 rewrite++; 3077 break; 3078#endif /* INET6 */ 3079 } 3080 if (nat->natpass) 3081 r = NULL; 3082 } 3083 } else { 3084 /* check incoming packet for BINAT/RDR */ 3085 if ((rdr = pf_get_translation(pd, m, off, PF_IN, ifp, saddr, 0, 3086 daddr, 0, &naddr, NULL)) != NULL) { 3087 PF_ACPY(&baddr, daddr, af); 3088 switch (af) { 3089#ifdef INET 3090 case AF_INET: 3091 pf_change_a(&daddr->v4.s_addr, 3092 pd->ip_sum, naddr.v4.s_addr, 0); 3093 break; 3094#endif /* INET */ 3095#ifdef INET6 3096 case AF_INET6: 3097 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, 3098 &naddr, 0); 3099 rewrite++; 3100 break; 3101#endif /* INET6 */ 3102 } 3103 if (rdr->natpass) 3104 r = NULL; 3105 } 3106 } 3107 3108 while (r != NULL) { 3109 r->evaluations++; 3110 if (r->ifp != NULL && ((r->ifp != ifp && !r->ifnot) || 3111 (r->ifp == ifp && r->ifnot))) 3112 r = r->skip[PF_SKIP_IFP].ptr; 3113 else if (r->direction && r->direction != direction) 3114 r = r->skip[PF_SKIP_DIR].ptr; 3115 else if (r->af && r->af != af) 3116 r = r->skip[PF_SKIP_AF].ptr; 3117 else if (r->proto && r->proto != pd->proto) 3118 r = r->skip[PF_SKIP_PROTO].ptr; 3119 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) 3120 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3121 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) 3122 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3123 else if (r->type && r->type != icmptype + 1) 3124 r = TAILQ_NEXT(r, entries); 3125 else if (r->code && r->code != icmpcode + 1) 3126 r = TAILQ_NEXT(r, entries); 3127 else if (r->tos && !(r->tos & pd->tos)) 3128 r = TAILQ_NEXT(r, entries); 3129 else if (r->rule_flag & PFRULE_FRAGMENT) 3130 r = TAILQ_NEXT(r, entries); 3131 else if (r->match_tag && 3132 !pf_match_tag(m, r, nat, rdr, pftag, &tag)) 3133 r = TAILQ_NEXT(r, entries); 3134 else if (r->anchorname[0] && r->anchor == NULL) 3135 r = TAILQ_NEXT(r, entries); 3136 else if (r->os_fingerprint != PF_OSFP_ANY) 3137 r = TAILQ_NEXT(r, entries); 3138 else { 3139 if (r->tag) 3140 tag = r->tag; 3141 if (r->anchor == NULL) { 3142 *rm = r; 3143 *am = a; 3144 *rsm = ruleset; 3145 if ((*rm)->quick) 3146 break; 3147 r = TAILQ_NEXT(r, entries); 3148 } else 3149 PF_STEP_INTO_ANCHOR(r, a, ruleset, 3150 PF_RULESET_FILTER); 3151 } 3152 if (r == NULL && a != NULL) 3153 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3154 PF_RULESET_FILTER); 3155 } 3156 r = *rm; 3157 a = *am; 3158 ruleset = *rsm; 3159 3160 r->packets++; 3161 r->bytes += pd->tot_len; 3162 if (a != NULL) { 3163 a->packets++; 3164 a->bytes += pd->tot_len; 3165 } 3166 REASON_SET(&reason, PFRES_MATCH); 3167 3168 if (r->log) { 3169#ifdef INET6 3170 if (rewrite) 3171 m_copyback(m, off, sizeof(struct icmp6_hdr), 3172 (caddr_t)pd->hdr.icmp6); 3173#endif /* INET6 */ 3174 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); 3175 } 3176 3177 if (r->action != PF_PASS) 3178 return (PF_DROP); 3179 3180 if (pf_tag_packet(m, pftag, tag)) { 3181 REASON_SET(&reason, PFRES_MEMORY); 3182 return (PF_DROP); 3183 } 3184 3185 if (!state_icmp && (r->keep_state || 3186 nat != NULL || rdr != NULL)) { 3187 /* create new state */ 3188 struct pf_state *s = NULL; 3189 3190 if (!r->max_states || r->states < r->max_states) 3191 s = pool_get(&pf_state_pl, PR_NOWAIT); 3192 if (s == NULL) { 3193 REASON_SET(&reason, PFRES_MEMORY); 3194 return (PF_DROP); 3195 } 3196 bzero(s, sizeof(*s)); 3197 r->states++; 3198 if (a != NULL) 3199 a->states++; 3200 s->rule.ptr = r; 3201 if (nat != NULL) 3202 s->nat_rule.ptr = nat; 3203 else 3204 s->nat_rule.ptr = rdr; 3205 if (s->nat_rule.ptr != NULL) 3206 s->nat_rule.ptr->states++; 3207 s->anchor.ptr = a; 3208 s->allow_opts = r->allow_opts; 3209 s->log = r->log & 2; 3210 s->proto = pd->proto; 3211 s->direction = direction; 3212 s->af = af; 3213 if (direction == PF_OUT) { 3214 PF_ACPY(&s->gwy.addr, saddr, af); 3215 s->gwy.port = icmpid; 3216 PF_ACPY(&s->ext.addr, daddr, af); 3217 s->ext.port = icmpid; 3218 if (nat != NULL) 3219 PF_ACPY(&s->lan.addr, &baddr, af); 3220 else 3221 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 3222 s->lan.port = icmpid; 3223 } else { 3224 PF_ACPY(&s->lan.addr, daddr, af); 3225 s->lan.port = icmpid; 3226 PF_ACPY(&s->ext.addr, saddr, af); 3227 s->ext.port = icmpid; 3228 if (rdr != NULL) 3229 PF_ACPY(&s->gwy.addr, &baddr, af); 3230 else 3231 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3232 s->gwy.port = icmpid; 3233 } 3234 3235 s->src.seqlo = 0; 3236 s->src.seqhi = 0; 3237 s->src.seqdiff = 0; 3238 s->src.max_win = 0; 3239 s->src.state = 0; 3240 s->dst.seqlo = 0; 3241 s->dst.seqhi = 0; 3242 s->dst.seqdiff = 0; 3243 s->dst.max_win = 0; 3244 s->dst.state = 0; 3245#ifdef __FreeBSD__ 3246 s->creation = time_second; 3247 s->expire = time_second; 3248#else 3249 s->creation = time.tv_sec; 3250 s->expire = time.tv_sec; 3251#endif 3252 s->timeout = PFTM_ICMP_FIRST_PACKET; 3253 s->packets[0] = 1; 3254 s->bytes[0] = pd->tot_len; 3255 pf_set_rt_ifp(s, saddr); 3256 if (pf_insert_state(s)) { 3257 REASON_SET(&reason, PFRES_MEMORY); 3258 pool_put(&pf_state_pl, s); 3259 return (PF_DROP); 3260 } else 3261 *sm = s; 3262 } 3263 3264#ifdef INET6 3265 /* copy back packet headers if we performed IPv6 NAT operations */ 3266 if (rewrite) 3267 m_copyback(m, off, sizeof(struct icmp6_hdr), 3268 (caddr_t)pd->hdr.icmp6); 3269#endif /* INET6 */ 3270 3271 return (PF_PASS); 3272} 3273 3274int 3275pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction, 3276 struct ifnet *ifp, struct mbuf *m, int off, void *h, struct pf_pdesc *pd, 3277 struct pf_rule **am, struct pf_ruleset **rsm) 3278{ 3279 struct pf_rule *nat = NULL, *rdr = NULL; 3280 struct pf_rule *r, *a = NULL; 3281 struct pf_ruleset *ruleset = NULL; 3282 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3283 struct pf_addr baddr, naddr; 3284 sa_family_t af = pd->af; 3285 u_short reason; 3286 struct pf_tag *pftag = NULL; 3287 int tag = -1; 3288 3289 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3290 3291 if (direction == PF_OUT) { 3292 /* check outgoing packet for BINAT/NAT */ 3293 if ((nat = pf_get_translation(pd, m, off, PF_OUT, ifp, saddr, 0, 3294 daddr, 0, &naddr, NULL)) != NULL) { 3295 PF_ACPY(&baddr, saddr, af); 3296 switch (af) { 3297#ifdef INET 3298 case AF_INET: 3299 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, 3300 naddr.v4.s_addr, 0); 3301 break; 3302#endif /* INET */ 3303#ifdef INET6 3304 case AF_INET6: 3305 PF_ACPY(saddr, &naddr, af); 3306 break; 3307#endif /* INET6 */ 3308 } 3309 if (nat->natpass) 3310 r = NULL; 3311 } 3312 } else { 3313 /* check incoming packet for BINAT/RDR */ 3314 if ((rdr = pf_get_translation(pd, m, off, PF_IN, ifp, saddr, 0, 3315 daddr, 0, &naddr, NULL)) != NULL) { 3316 PF_ACPY(&baddr, daddr, af); 3317 switch (af) { 3318#ifdef INET 3319 case AF_INET: 3320 pf_change_a(&daddr->v4.s_addr, 3321 pd->ip_sum, naddr.v4.s_addr, 0); 3322 break; 3323#endif /* INET */ 3324#ifdef INET6 3325 case AF_INET6: 3326 PF_ACPY(daddr, &naddr, af); 3327 break; 3328#endif /* INET6 */ 3329 } 3330 if (rdr->natpass) 3331 r = NULL; 3332 } 3333 } 3334 3335 while (r != NULL) { 3336 r->evaluations++; 3337 if (r->ifp != NULL && ((r->ifp != ifp && !r->ifnot) || 3338 (r->ifp == ifp && r->ifnot))) 3339 r = r->skip[PF_SKIP_IFP].ptr; 3340 else if (r->direction && r->direction != direction) 3341 r = r->skip[PF_SKIP_DIR].ptr; 3342 else if (r->af && r->af != af) 3343 r = r->skip[PF_SKIP_AF].ptr; 3344 else if (r->proto && r->proto != pd->proto) 3345 r = r->skip[PF_SKIP_PROTO].ptr; 3346 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not)) 3347 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3348 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not)) 3349 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3350 else if (r->tos && !(r->tos & pd->tos)) 3351 r = TAILQ_NEXT(r, entries); 3352 else if (r->rule_flag & PFRULE_FRAGMENT) 3353 r = TAILQ_NEXT(r, entries); 3354 else if (r->match_tag && 3355 !pf_match_tag(m, r, nat, rdr, pftag, &tag)) 3356 r = TAILQ_NEXT(r, entries); 3357 else if (r->anchorname[0] && r->anchor == NULL) 3358 r = TAILQ_NEXT(r, entries); 3359 else if (r->os_fingerprint != PF_OSFP_ANY) 3360 r = TAILQ_NEXT(r, entries); 3361 else { 3362 if (r->tag) 3363 tag = r->tag; 3364 if (r->anchor == NULL) { 3365 *rm = r; 3366 *am = a; 3367 *rsm = ruleset; 3368 if ((*rm)->quick) 3369 break; 3370 r = TAILQ_NEXT(r, entries); 3371 } else 3372 PF_STEP_INTO_ANCHOR(r, a, ruleset, 3373 PF_RULESET_FILTER); 3374 } 3375 if (r == NULL && a != NULL) 3376 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3377 PF_RULESET_FILTER); 3378 } 3379 r = *rm; 3380 a = *am; 3381 ruleset = *rsm; 3382 3383 r->packets++; 3384 r->bytes += pd->tot_len; 3385 if (a != NULL) { 3386 a->packets++; 3387 a->bytes += pd->tot_len; 3388 } 3389 REASON_SET(&reason, PFRES_MATCH); 3390 if (r->log) 3391 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); 3392 3393 if ((r->action == PF_DROP) && 3394 ((r->rule_flag & PFRULE_RETURNICMP) || 3395 (r->rule_flag & PFRULE_RETURN))) { 3396 struct pf_addr *a = NULL; 3397 3398 if (nat != NULL) 3399 a = saddr; 3400 else if (rdr != NULL) 3401 a = daddr; 3402 if (a != NULL) { 3403 switch (af) { 3404#ifdef INET 3405 case AF_INET: 3406 pf_change_a(&a->v4.s_addr, pd->ip_sum, 3407 baddr.v4.s_addr, 0); 3408 break; 3409#endif /* INET */ 3410#ifdef INET6 3411 case AF_INET6: 3412 PF_ACPY(a, &baddr, af); 3413 break; 3414#endif /* INET6 */ 3415 } 3416 } 3417 if ((af == AF_INET) && r->return_icmp) 3418 pf_send_icmp(m, r->return_icmp >> 8, 3419 r->return_icmp & 255, af, r); 3420 else if ((af == AF_INET6) && r->return_icmp6) 3421 pf_send_icmp(m, r->return_icmp6 >> 8, 3422 r->return_icmp6 & 255, af, r); 3423 } 3424 3425 if (r->action != PF_PASS) 3426 return (PF_DROP); 3427 3428 if (pf_tag_packet(m, pftag, tag)) { 3429 REASON_SET(&reason, PFRES_MEMORY); 3430 return (PF_DROP); 3431 } 3432 3433 if (r->keep_state || nat != NULL || rdr != NULL) { 3434 /* create new state */ 3435 struct pf_state *s = NULL; 3436 3437 if (!r->max_states || r->states < r->max_states) 3438 s = pool_get(&pf_state_pl, PR_NOWAIT); 3439 if (s == NULL) { 3440 REASON_SET(&reason, PFRES_MEMORY); 3441 return (PF_DROP); 3442 } 3443 bzero(s, sizeof(*s)); 3444 r->states++; 3445 if (a != NULL) 3446 a->states++; 3447 s->rule.ptr = r; 3448 if (nat != NULL) 3449 s->nat_rule.ptr = nat; 3450 else 3451 s->nat_rule.ptr = rdr; 3452 if (s->nat_rule.ptr != NULL) 3453 s->nat_rule.ptr->states++; 3454 s->anchor.ptr = a; 3455 s->allow_opts = r->allow_opts; 3456 s->log = r->log & 2; 3457 s->proto = pd->proto; 3458 s->direction = direction; 3459 s->af = af; 3460 if (direction == PF_OUT) { 3461 PF_ACPY(&s->gwy.addr, saddr, af); 3462 s->gwy.port = 0; 3463 PF_ACPY(&s->ext.addr, daddr, af); 3464 s->ext.port = 0; 3465 if (nat != NULL) 3466 PF_ACPY(&s->lan.addr, &baddr, af); 3467 else 3468 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 3469 s->lan.port = 0; 3470 } else { 3471 PF_ACPY(&s->lan.addr, daddr, af); 3472 s->lan.port = 0; 3473 PF_ACPY(&s->ext.addr, saddr, af); 3474 s->ext.port = 0; 3475 if (rdr != NULL) 3476 PF_ACPY(&s->gwy.addr, &baddr, af); 3477 else 3478 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3479 s->gwy.port = 0; 3480 } 3481 s->src.seqlo = 0; 3482 s->src.seqhi = 0; 3483 s->src.seqdiff = 0; 3484 s->src.max_win = 0; 3485 s->src.state = PFOTHERS_SINGLE; 3486 s->dst.seqlo = 0; 3487 s->dst.seqhi = 0; 3488 s->dst.seqdiff = 0; 3489 s->dst.max_win = 0; 3490 s->dst.state = PFOTHERS_NO_TRAFFIC; 3491#ifdef __FreeBSD__ 3492 s->creation = time_second; 3493 s->expire = time_second; 3494#else 3495 s->creation = time.tv_sec; 3496 s->expire = time.tv_sec; 3497#endif 3498 s->timeout = PFTM_OTHER_FIRST_PACKET; 3499 s->packets[0] = 1; 3500 s->bytes[0] = pd->tot_len; 3501 pf_set_rt_ifp(s, saddr); 3502 if (pf_insert_state(s)) { 3503 REASON_SET(&reason, PFRES_MEMORY); 3504 if (r->log) 3505 PFLOG_PACKET(ifp, h, m, af, direction, reason, 3506 r, a, ruleset); 3507 pool_put(&pf_state_pl, s); 3508 return (PF_DROP); 3509 } else 3510 *sm = s; 3511 } 3512 3513 return (PF_PASS); 3514} 3515 3516int 3517pf_test_fragment(struct pf_rule **rm, int direction, struct ifnet *ifp, 3518 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, 3519 struct pf_ruleset **rsm) 3520{ 3521 struct pf_rule *r, *a = NULL; 3522 struct pf_ruleset *ruleset = NULL; 3523 sa_family_t af = pd->af; 3524 u_short reason; 3525 struct pf_tag *pftag = NULL; 3526 int tag = -1; 3527 3528 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3529 while (r != NULL) { 3530 r->evaluations++; 3531 if (r->ifp != NULL && ((r->ifp != ifp && !r->ifnot) || 3532 (r->ifp == ifp && r->ifnot))) 3533 r = r->skip[PF_SKIP_IFP].ptr; 3534 else if (r->direction && r->direction != direction) 3535 r = r->skip[PF_SKIP_DIR].ptr; 3536 else if (r->af && r->af != af) 3537 r = r->skip[PF_SKIP_AF].ptr; 3538 else if (r->proto && r->proto != pd->proto) 3539 r = r->skip[PF_SKIP_PROTO].ptr; 3540 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not)) 3541 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3542 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not)) 3543 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3544 else if (r->tos && !(r->tos & pd->tos)) 3545 r = TAILQ_NEXT(r, entries); 3546 else if (r->src.port_op || r->dst.port_op || 3547 r->flagset || r->type || r->code || 3548 r->os_fingerprint != PF_OSFP_ANY) 3549 r = TAILQ_NEXT(r, entries); 3550 else if (r->match_tag && 3551 !pf_match_tag(m, r, NULL, NULL, pftag, &tag)) 3552 r = TAILQ_NEXT(r, entries); 3553 else if (r->anchorname[0] && r->anchor == NULL) 3554 r = TAILQ_NEXT(r, entries); 3555 else { 3556 if (r->anchor == NULL) { 3557 *rm = r; 3558 *am = a; 3559 *rsm = ruleset; 3560 if ((*rm)->quick) 3561 break; 3562 r = TAILQ_NEXT(r, entries); 3563 } else 3564 PF_STEP_INTO_ANCHOR(r, a, ruleset, 3565 PF_RULESET_FILTER); 3566 } 3567 if (r == NULL && a != NULL) 3568 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3569 PF_RULESET_FILTER); 3570 } 3571 r = *rm; 3572 a = *am; 3573 ruleset = *rsm; 3574 3575 r->packets++; 3576 r->bytes += pd->tot_len; 3577 if (a != NULL) { 3578 a->packets++; 3579 a->bytes += pd->tot_len; 3580 } 3581 REASON_SET(&reason, PFRES_MATCH); 3582 if (r->log) 3583 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); 3584 3585 if (r->action != PF_PASS) 3586 return (PF_DROP); 3587 3588 if (pf_tag_packet(m, pftag, tag)) { 3589 REASON_SET(&reason, PFRES_MEMORY); 3590 return (PF_DROP); 3591 } 3592 3593 return (PF_PASS); 3594} 3595 3596int 3597pf_test_state_tcp(struct pf_state **state, int direction, struct ifnet *ifp, 3598 struct mbuf *m, int ipoff, int off, void *h, struct pf_pdesc *pd, 3599 u_short *reason) 3600{ 3601 struct pf_tree_node key; 3602 struct tcphdr *th = pd->hdr.tcp; 3603 u_int16_t win = ntohs(th->th_win); 3604 u_int32_t ack, end, seq; 3605 u_int8_t sws, dws; 3606 int ackskew, dirndx; 3607 int copyback = 0; 3608 struct pf_state_peer *src, *dst; 3609 3610 key.af = pd->af; 3611 key.proto = IPPROTO_TCP; 3612 PF_ACPY(&key.addr[0], pd->src, key.af); 3613 PF_ACPY(&key.addr[1], pd->dst, key.af); 3614 key.port[0] = th->th_sport; 3615 key.port[1] = th->th_dport; 3616 3617 STATE_LOOKUP(); 3618 3619 if (direction == (*state)->direction) { 3620 src = &(*state)->src; 3621 dst = &(*state)->dst; 3622 dirndx = 0; 3623 } else { 3624 src = &(*state)->dst; 3625 dst = &(*state)->src; 3626 dirndx = 1; 3627 } 3628 3629 if ((*state)->src.state == PF_TCPS_PROXY_SRC) { 3630 if (direction != (*state)->direction) 3631 return (PF_SYNPROXY_DROP); 3632 if (th->th_flags & TH_SYN) { 3633 if (ntohl(th->th_seq) != (*state)->src.seqlo) 3634 return (PF_DROP); 3635 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 3636 pd->src, th->th_dport, th->th_sport, 3637 (*state)->src.seqhi, ntohl(th->th_seq) + 1, 3638 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0); 3639 return (PF_SYNPROXY_DROP); 3640 } else if (!(th->th_flags & TH_ACK) || 3641 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 3642 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) 3643 return (PF_DROP); 3644 else 3645 (*state)->src.state = PF_TCPS_PROXY_DST; 3646 } 3647 if ((*state)->src.state == PF_TCPS_PROXY_DST) { 3648 struct pf_state_host *src, *dst; 3649 3650 if (direction == PF_OUT) { 3651 src = &(*state)->gwy; 3652 dst = &(*state)->ext; 3653 } else { 3654 src = &(*state)->ext; 3655 dst = &(*state)->lan; 3656 } 3657 if (direction == (*state)->direction) { 3658 if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) || 3659 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 3660 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) 3661 return (PF_DROP); 3662 (*state)->src.max_win = MAX(ntohs(th->th_win), 1); 3663 if ((*state)->dst.seqhi == 1) 3664 (*state)->dst.seqhi = arc4random(); 3665 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 3666 &dst->addr, src->port, dst->port, 3667 (*state)->dst.seqhi, 0, TH_SYN, 0, (*state)->src.mss, 0); 3668 return (PF_SYNPROXY_DROP); 3669 } else if (((th->th_flags & (TH_SYN|TH_ACK)) != 3670 (TH_SYN|TH_ACK)) || 3671 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) 3672 return (PF_DROP); 3673 else { 3674 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1); 3675 (*state)->dst.seqlo = ntohl(th->th_seq); 3676 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 3677 pd->src, th->th_dport, th->th_sport, 3678 ntohl(th->th_ack), ntohl(th->th_seq) + 1, 3679 TH_ACK, (*state)->src.max_win, 0, 0); 3680 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 3681 &dst->addr, src->port, dst->port, 3682 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1, 3683 TH_ACK, (*state)->dst.max_win, 0, 0); 3684 (*state)->src.seqdiff = (*state)->dst.seqhi - 3685 (*state)->src.seqlo; 3686 (*state)->dst.seqdiff = (*state)->src.seqhi - 3687 (*state)->dst.seqlo; 3688 (*state)->src.seqhi = (*state)->src.seqlo + 3689 (*state)->src.max_win; 3690 (*state)->dst.seqhi = (*state)->dst.seqlo + 3691 (*state)->dst.max_win; 3692 (*state)->src.wscale = (*state)->dst.wscale = 0; 3693 (*state)->src.state = (*state)->dst.state = 3694 TCPS_ESTABLISHED; 3695 return (PF_SYNPROXY_DROP); 3696 } 3697 } 3698 3699 if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) { 3700 sws = src->wscale & PF_WSCALE_MASK; 3701 dws = dst->wscale & PF_WSCALE_MASK; 3702 } else 3703 sws = dws = 0; 3704 3705 /* 3706 * Sequence tracking algorithm from Guido van Rooij's paper: 3707 * http://www.madison-gurkha.com/publications/tcp_filtering/ 3708 * tcp_filtering.ps 3709 */ 3710 3711 seq = ntohl(th->th_seq); 3712 if (src->seqlo == 0) { 3713 /* First packet from this end. Set its state */ 3714 3715 if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) && 3716 src->scrub == NULL) { 3717 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) { 3718 REASON_SET(reason, PFRES_MEMORY); 3719 return (PF_DROP); 3720 } 3721 } 3722 3723 /* Deferred generation of sequence number modulator */ 3724 if (dst->seqdiff && !src->seqdiff) { 3725 while ((src->seqdiff = arc4random()) == 0) 3726 ; 3727 ack = ntohl(th->th_ack) - dst->seqdiff; 3728 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 3729 src->seqdiff), 0); 3730 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 3731 copyback = 1; 3732 } else { 3733 ack = ntohl(th->th_ack); 3734 } 3735 3736 end = seq + pd->p_len; 3737 if (th->th_flags & TH_SYN) { 3738 end++; 3739 if (dst->wscale & PF_WSCALE_FLAG) { 3740 src->wscale = pf_get_wscale(m, off, th->th_off, 3741 pd->af); 3742 if (src->wscale & PF_WSCALE_FLAG) { 3743 /* Remove scale factor from initial 3744 * window */ 3745 sws = src->wscale & PF_WSCALE_MASK; 3746 win = ((u_int32_t)win + (1 << sws) - 1) 3747 >> sws; 3748 dws = dst->wscale & PF_WSCALE_MASK; 3749 } else { 3750 /* fixup other window */ 3751 dst->max_win <<= dst->wscale & 3752 PF_WSCALE_MASK; 3753 /* in case of a retrans SYN|ACK */ 3754 dst->wscale = 0; 3755 } 3756 } 3757 } 3758 if (th->th_flags & TH_FIN) 3759 end++; 3760 3761 src->seqlo = seq; 3762 if (src->state < TCPS_SYN_SENT) 3763 src->state = TCPS_SYN_SENT; 3764 3765 /* 3766 * May need to slide the window (seqhi may have been set by 3767 * the crappy stack check or if we picked up the connection 3768 * after establishment) 3769 */ 3770 if (src->seqhi == 1 || 3771 SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi)) 3772 src->seqhi = end + MAX(1, dst->max_win << dws); 3773 if (win > src->max_win) 3774 src->max_win = win; 3775 3776 } else { 3777 ack = ntohl(th->th_ack) - dst->seqdiff; 3778 if (src->seqdiff) { 3779 /* Modulate sequence numbers */ 3780 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 3781 src->seqdiff), 0); 3782 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 3783 copyback = 1; 3784 } 3785 end = seq + pd->p_len; 3786 if (th->th_flags & TH_SYN) 3787 end++; 3788 if (th->th_flags & TH_FIN) 3789 end++; 3790 } 3791 3792 if ((th->th_flags & TH_ACK) == 0) { 3793 /* Let it pass through the ack skew check */ 3794 ack = dst->seqlo; 3795 } else if ((ack == 0 && 3796 (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) || 3797 /* broken tcp stacks do not set ack */ 3798 (dst->state < TCPS_SYN_SENT)) { 3799 /* 3800 * Many stacks (ours included) will set the ACK number in an 3801 * FIN|ACK if the SYN times out -- no sequence to ACK. 3802 */ 3803 ack = dst->seqlo; 3804 } 3805 3806 if (seq == end) { 3807 /* Ease sequencing restrictions on no data packets */ 3808 seq = src->seqlo; 3809 end = seq; 3810 } 3811 3812 ackskew = dst->seqlo - ack; 3813 3814#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */ 3815 if (SEQ_GEQ(src->seqhi, end) && 3816 /* Last octet inside other's window space */ 3817 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) && 3818 /* Retrans: not more than one window back */ 3819 (ackskew >= -MAXACKWINDOW) && 3820 /* Acking not more than one reassembled fragment backwards */ 3821 (ackskew <= (MAXACKWINDOW << sws))) { 3822 /* Acking not more than one window forward */ 3823 3824 (*state)->packets[dirndx]++; 3825 (*state)->bytes[dirndx] += pd->tot_len; 3826 3827 /* update max window */ 3828 if (src->max_win < win) 3829 src->max_win = win; 3830 /* synchronize sequencing */ 3831 if (SEQ_GT(end, src->seqlo)) 3832 src->seqlo = end; 3833 /* slide the window of what the other end can send */ 3834 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) 3835 dst->seqhi = ack + MAX((win << sws), 1); 3836 3837 3838 /* update states */ 3839 if (th->th_flags & TH_SYN) 3840 if (src->state < TCPS_SYN_SENT) 3841 src->state = TCPS_SYN_SENT; 3842 if (th->th_flags & TH_FIN) 3843 if (src->state < TCPS_CLOSING) 3844 src->state = TCPS_CLOSING; 3845 if (th->th_flags & TH_ACK) { 3846 if (dst->state == TCPS_SYN_SENT) 3847 dst->state = TCPS_ESTABLISHED; 3848 else if (dst->state == TCPS_CLOSING) 3849 dst->state = TCPS_FIN_WAIT_2; 3850 } 3851 if (th->th_flags & TH_RST) 3852 src->state = dst->state = TCPS_TIME_WAIT; 3853 3854 /* update expire time */ 3855#ifdef __FreeBSD__ 3856 (*state)->expire = time_second; 3857#else 3858 (*state)->expire = time.tv_sec; 3859#endif 3860 if (src->state >= TCPS_FIN_WAIT_2 && 3861 dst->state >= TCPS_FIN_WAIT_2) 3862 (*state)->timeout = PFTM_TCP_CLOSED; 3863 else if (src->state >= TCPS_FIN_WAIT_2 || 3864 dst->state >= TCPS_FIN_WAIT_2) 3865 (*state)->timeout = PFTM_TCP_FIN_WAIT; 3866 else if (src->state < TCPS_ESTABLISHED || 3867 dst->state < TCPS_ESTABLISHED) 3868 (*state)->timeout = PFTM_TCP_OPENING; 3869 else if (src->state >= TCPS_CLOSING || 3870 dst->state >= TCPS_CLOSING) 3871 (*state)->timeout = PFTM_TCP_CLOSING; 3872 else 3873 (*state)->timeout = PFTM_TCP_ESTABLISHED; 3874 3875 /* Fall through to PASS packet */ 3876 3877 } else if ((dst->state < TCPS_SYN_SENT || 3878 dst->state >= TCPS_FIN_WAIT_2 || 3879 src->state >= TCPS_FIN_WAIT_2) && 3880 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) && 3881 /* Within a window forward of the originating packet */ 3882 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) { 3883 /* Within a window backward of the originating packet */ 3884 3885 /* 3886 * This currently handles three situations: 3887 * 1) Stupid stacks will shotgun SYNs before their peer 3888 * replies. 3889 * 2) When PF catches an already established stream (the 3890 * firewall rebooted, the state table was flushed, routes 3891 * changed...) 3892 * 3) Packets get funky immediately after the connection 3893 * closes (this should catch Solaris spurious ACK|FINs 3894 * that web servers like to spew after a close) 3895 * 3896 * This must be a little more careful than the above code 3897 * since packet floods will also be caught here. We don't 3898 * update the TTL here to mitigate the damage of a packet 3899 * flood and so the same code can handle awkward establishment 3900 * and a loosened connection close. 3901 * In the establishment case, a correct peer response will 3902 * validate the connection, go through the normal state code 3903 * and keep updating the state TTL. 3904 */ 3905 3906 if (pf_status.debug >= PF_DEBUG_MISC) { 3907 printf("pf: loose state match: "); 3908 pf_print_state(*state); 3909 pf_print_flags(th->th_flags); 3910 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d\n", 3911 seq, ack, pd->p_len, ackskew, 3912 (*state)->packets[0], (*state)->packets[1]); 3913 } 3914 3915 (*state)->packets[dirndx]++; 3916 (*state)->bytes[dirndx] += pd->tot_len; 3917 3918 /* update max window */ 3919 if (src->max_win < win) 3920 src->max_win = win; 3921 /* synchronize sequencing */ 3922 if (SEQ_GT(end, src->seqlo)) 3923 src->seqlo = end; 3924 /* slide the window of what the other end can send */ 3925 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) 3926 dst->seqhi = ack + MAX((win << sws), 1); 3927 3928 /* 3929 * Cannot set dst->seqhi here since this could be a shotgunned 3930 * SYN and not an already established connection. 3931 */ 3932 3933 if (th->th_flags & TH_FIN) 3934 if (src->state < TCPS_CLOSING) 3935 src->state = TCPS_CLOSING; 3936 if (th->th_flags & TH_RST) 3937 src->state = dst->state = TCPS_TIME_WAIT; 3938 3939 /* Fall through to PASS packet */ 3940 3941 } else { 3942 if ((*state)->dst.state == TCPS_SYN_SENT && 3943 (*state)->src.state == TCPS_SYN_SENT) { 3944 /* Send RST for state mismatches during handshake */ 3945 if (!(th->th_flags & TH_RST)) { 3946 u_int32_t ack = ntohl(th->th_seq) + pd->p_len; 3947 3948 if (th->th_flags & TH_SYN) 3949 ack++; 3950 if (th->th_flags & TH_FIN) 3951 ack++; 3952 pf_send_tcp((*state)->rule.ptr, pd->af, 3953 pd->dst, pd->src, th->th_dport, 3954 th->th_sport, ntohl(th->th_ack), ack, 3955 TH_RST|TH_ACK, 0, 0, 3956 (*state)->rule.ptr->return_ttl); 3957 } 3958 src->seqlo = 0; 3959 src->seqhi = 1; 3960 src->max_win = 1; 3961 } else if (pf_status.debug >= PF_DEBUG_MISC) { 3962 printf("pf: BAD state: "); 3963 pf_print_state(*state); 3964 pf_print_flags(th->th_flags); 3965 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d " 3966 "dir=%s,%s\n", seq, ack, pd->p_len, ackskew, 3967 (*state)->packets[0], (*state)->packets[1], 3968 direction == PF_IN ? "in" : "out", 3969 direction == (*state)->direction ? "fwd" : "rev"); 3970 printf("pf: State failure on: %c %c %c %c | %c %c\n", 3971 SEQ_GEQ(src->seqhi, end) ? ' ' : '1', 3972 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ? 3973 ' ': '2', 3974 (ackskew >= -MAXACKWINDOW) ? ' ' : '3', 3975 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4', 3976 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5', 3977 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6'); 3978 } 3979 return (PF_DROP); 3980 } 3981 3982 if (dst->scrub || src->scrub) { 3983 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, src, dst, 3984 ©back)) 3985 return (PF_DROP); 3986 } 3987 3988 /* Any packets which have gotten here are to be passed */ 3989 3990 /* translate source/destination address, if necessary */ 3991 if (STATE_TRANSLATE(*state)) { 3992 if (direction == PF_OUT) 3993 pf_change_ap(pd->src, &th->th_sport, pd->ip_sum, 3994 &th->th_sum, &(*state)->gwy.addr, 3995 (*state)->gwy.port, 0, pd->af); 3996 else 3997 pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, 3998 &th->th_sum, &(*state)->lan.addr, 3999 (*state)->lan.port, 0, pd->af); 4000 m_copyback(m, off, sizeof(*th), (caddr_t)th); 4001 } else if (copyback) { 4002 /* Copyback sequence modulation or stateful scrub changes */ 4003 m_copyback(m, off, sizeof(*th), (caddr_t)th); 4004 } 4005 4006 (*state)->rule.ptr->packets++; 4007 (*state)->rule.ptr->bytes += pd->tot_len; 4008 if ((*state)->nat_rule.ptr != NULL) { 4009 (*state)->nat_rule.ptr->packets++; 4010 (*state)->nat_rule.ptr->bytes += pd->tot_len; 4011 } 4012 if ((*state)->anchor.ptr != NULL) { 4013 (*state)->anchor.ptr->packets++; 4014 (*state)->anchor.ptr->bytes += pd->tot_len; 4015 } 4016 return (PF_PASS); 4017} 4018 4019int 4020pf_test_state_udp(struct pf_state **state, int direction, struct ifnet *ifp, 4021 struct mbuf *m, int ipoff, int off, void *h, struct pf_pdesc *pd) 4022{ 4023 struct pf_state_peer *src, *dst; 4024 struct pf_tree_node key; 4025 struct udphdr *uh = pd->hdr.udp; 4026 int dirndx; 4027 4028 key.af = pd->af; 4029 key.proto = IPPROTO_UDP; 4030 PF_ACPY(&key.addr[0], pd->src, key.af); 4031 PF_ACPY(&key.addr[1], pd->dst, key.af); 4032 key.port[0] = uh->uh_sport; 4033 key.port[1] = uh->uh_dport; 4034 4035 STATE_LOOKUP(); 4036 4037 if (direction == (*state)->direction) { 4038 src = &(*state)->src; 4039 dst = &(*state)->dst; 4040 dirndx = 0; 4041 } else { 4042 src = &(*state)->dst; 4043 dst = &(*state)->src; 4044 dirndx = 1; 4045 } 4046 4047 (*state)->packets[dirndx]++; 4048 (*state)->bytes[dirndx] += pd->tot_len; 4049 4050 /* update states */ 4051 if (src->state < PFUDPS_SINGLE) 4052 src->state = PFUDPS_SINGLE; 4053 if (dst->state == PFUDPS_SINGLE) 4054 dst->state = PFUDPS_MULTIPLE; 4055 4056 /* update expire time */ 4057#ifdef __FreeBSD__ 4058 (*state)->expire = time_second; 4059#else 4060 (*state)->expire = time.tv_sec; 4061#endif 4062 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE) 4063 (*state)->timeout = PFTM_UDP_MULTIPLE; 4064 else 4065 (*state)->timeout = PFTM_UDP_SINGLE; 4066 4067 /* translate source/destination address, if necessary */ 4068 if (STATE_TRANSLATE(*state)) { 4069 if (direction == PF_OUT) 4070 pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum, 4071 &uh->uh_sum, &(*state)->gwy.addr, 4072 (*state)->gwy.port, 1, pd->af); 4073 else 4074 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, 4075 &uh->uh_sum, &(*state)->lan.addr, 4076 (*state)->lan.port, 1, pd->af); 4077 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 4078 } 4079 4080 (*state)->rule.ptr->packets++; 4081 (*state)->rule.ptr->bytes += pd->tot_len; 4082 if ((*state)->nat_rule.ptr != NULL) { 4083 (*state)->nat_rule.ptr->packets++; 4084 (*state)->nat_rule.ptr->bytes += pd->tot_len; 4085 } 4086 if ((*state)->anchor.ptr != NULL) { 4087 (*state)->anchor.ptr->packets++; 4088 (*state)->anchor.ptr->bytes += pd->tot_len; 4089 } 4090 return (PF_PASS); 4091} 4092 4093int 4094pf_test_state_icmp(struct pf_state **state, int direction, struct ifnet *ifp, 4095 struct mbuf *m, int ipoff, int off, void *h, struct pf_pdesc *pd) 4096{ 4097 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 4098 u_int16_t icmpid = 0; /* make the compiler happy */ 4099 u_int16_t *icmpsum = NULL; /* make the compiler happy */ 4100 u_int8_t icmptype = 0; /* make the compiler happy */ 4101 int state_icmp = 0, dirndx; 4102 4103 switch (pd->proto) { 4104#ifdef INET 4105 case IPPROTO_ICMP: 4106 icmptype = pd->hdr.icmp->icmp_type; 4107 icmpid = pd->hdr.icmp->icmp_id; 4108 icmpsum = &pd->hdr.icmp->icmp_cksum; 4109 4110 if (icmptype == ICMP_UNREACH || 4111 icmptype == ICMP_SOURCEQUENCH || 4112 icmptype == ICMP_REDIRECT || 4113 icmptype == ICMP_TIMXCEED || 4114 icmptype == ICMP_PARAMPROB) 4115 state_icmp++; 4116 break; 4117#endif /* INET */ 4118#ifdef INET6 4119 case IPPROTO_ICMPV6: 4120 icmptype = pd->hdr.icmp6->icmp6_type; 4121 icmpid = pd->hdr.icmp6->icmp6_id; 4122 icmpsum = &pd->hdr.icmp6->icmp6_cksum; 4123 4124 if (icmptype == ICMP6_DST_UNREACH || 4125 icmptype == ICMP6_PACKET_TOO_BIG || 4126 icmptype == ICMP6_TIME_EXCEEDED || 4127 icmptype == ICMP6_PARAM_PROB) 4128 state_icmp++; 4129 break; 4130#endif /* INET6 */ 4131 } 4132 4133 if (!state_icmp) { 4134 4135 /* 4136 * ICMP query/reply message not related to a TCP/UDP packet. 4137 * Search for an ICMP state. 4138 */ 4139 struct pf_tree_node key; 4140 4141 key.af = pd->af; 4142 key.proto = pd->proto; 4143 PF_ACPY(&key.addr[0], saddr, key.af); 4144 PF_ACPY(&key.addr[1], daddr, key.af); 4145 key.port[0] = icmpid; 4146 key.port[1] = icmpid; 4147 4148 STATE_LOOKUP(); 4149 4150 dirndx = (direction == (*state)->direction) ? 0 : 1; 4151 (*state)->packets[dirndx]++; 4152 (*state)->bytes[dirndx] += pd->tot_len; 4153#ifdef __FreeBSD__ 4154 (*state)->expire = time_second; 4155#else 4156 (*state)->expire = time.tv_sec; 4157#endif 4158 (*state)->timeout = PFTM_ICMP_ERROR_REPLY; 4159 4160 /* translate source/destination address, if necessary */ 4161 if (PF_ANEQ(&(*state)->lan.addr, &(*state)->gwy.addr, pd->af)) { 4162 if (direction == PF_OUT) { 4163 switch (pd->af) { 4164#ifdef INET 4165 case AF_INET: 4166 pf_change_a(&saddr->v4.s_addr, 4167 pd->ip_sum, 4168 (*state)->gwy.addr.v4.s_addr, 0); 4169 break; 4170#endif /* INET */ 4171#ifdef INET6 4172 case AF_INET6: 4173 pf_change_a6(saddr, 4174 &pd->hdr.icmp6->icmp6_cksum, 4175 &(*state)->gwy.addr, 0); 4176 m_copyback(m, off, 4177 sizeof(struct icmp6_hdr), 4178 (caddr_t)pd->hdr.icmp6); 4179 break; 4180#endif /* INET6 */ 4181 } 4182 } else { 4183 switch (pd->af) { 4184#ifdef INET 4185 case AF_INET: 4186 pf_change_a(&daddr->v4.s_addr, 4187 pd->ip_sum, 4188 (*state)->lan.addr.v4.s_addr, 0); 4189 break; 4190#endif /* INET */ 4191#ifdef INET6 4192 case AF_INET6: 4193 pf_change_a6(daddr, 4194 &pd->hdr.icmp6->icmp6_cksum, 4195 &(*state)->lan.addr, 0); 4196 m_copyback(m, off, 4197 sizeof(struct icmp6_hdr), 4198 (caddr_t)pd->hdr.icmp6); 4199 break; 4200#endif /* INET6 */ 4201 } 4202 } 4203 } 4204 4205 return (PF_PASS); 4206 4207 } else { 4208 /* 4209 * ICMP error message in response to a TCP/UDP packet. 4210 * Extract the inner TCP/UDP header and search for that state. 4211 */ 4212 4213 struct pf_pdesc pd2; 4214#ifdef INET 4215 struct ip h2; 4216#endif /* INET */ 4217#ifdef INET6 4218 struct ip6_hdr h2_6; 4219 int terminal = 0; 4220#endif /* INET6 */ 4221 int ipoff2 = 0; /* make the compiler happy */ 4222 int off2 = 0; /* make the compiler happy */ 4223 4224 pd2.af = pd->af; 4225 switch (pd->af) { 4226#ifdef INET 4227 case AF_INET: 4228 /* offset of h2 in mbuf chain */ 4229 ipoff2 = off + ICMP_MINLEN; 4230 4231 if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2), 4232 NULL, NULL, pd2.af)) { 4233 DPFPRINTF(PF_DEBUG_MISC, 4234 ("pf: ICMP error message too short " 4235 "(ip)\n")); 4236 return (PF_DROP); 4237 } 4238 /* 4239 * ICMP error messages don't refer to non-first 4240 * fragments 4241 */ 4242 if (h2.ip_off & htons(IP_OFFMASK)) 4243 return (PF_DROP); 4244 4245 /* offset of protocol header that follows h2 */ 4246 off2 = ipoff2 + (h2.ip_hl << 2); 4247 4248 pd2.proto = h2.ip_p; 4249 pd2.src = (struct pf_addr *)&h2.ip_src; 4250 pd2.dst = (struct pf_addr *)&h2.ip_dst; 4251 pd2.ip_sum = &h2.ip_sum; 4252 break; 4253#endif /* INET */ 4254#ifdef INET6 4255 case AF_INET6: 4256 ipoff2 = off + sizeof(struct icmp6_hdr); 4257 4258 if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6), 4259 NULL, NULL, pd2.af)) { 4260 DPFPRINTF(PF_DEBUG_MISC, 4261 ("pf: ICMP error message too short " 4262 "(ip6)\n")); 4263 return (PF_DROP); 4264 } 4265 pd2.proto = h2_6.ip6_nxt; 4266 pd2.src = (struct pf_addr *)&h2_6.ip6_src; 4267 pd2.dst = (struct pf_addr *)&h2_6.ip6_dst; 4268 pd2.ip_sum = NULL; 4269 off2 = ipoff2 + sizeof(h2_6); 4270 do { 4271 switch (pd2.proto) { 4272 case IPPROTO_FRAGMENT: 4273 /* 4274 * ICMPv6 error messages for 4275 * non-first fragments 4276 */ 4277 return (PF_DROP); 4278 case IPPROTO_AH: 4279 case IPPROTO_HOPOPTS: 4280 case IPPROTO_ROUTING: 4281 case IPPROTO_DSTOPTS: { 4282 /* get next header and header length */ 4283 struct ip6_ext opt6; 4284 4285 if (!pf_pull_hdr(m, off2, &opt6, 4286 sizeof(opt6), NULL, NULL, pd2.af)) { 4287 DPFPRINTF(PF_DEBUG_MISC, 4288 ("pf: ICMPv6 short opt\n")); 4289 return (PF_DROP); 4290 } 4291 if (pd2.proto == IPPROTO_AH) 4292 off2 += (opt6.ip6e_len + 2) * 4; 4293 else 4294 off2 += (opt6.ip6e_len + 1) * 8; 4295 pd2.proto = opt6.ip6e_nxt; 4296 /* goto the next header */ 4297 break; 4298 } 4299 default: 4300 terminal++; 4301 break; 4302 } 4303 } while (!terminal); 4304 break; 4305#endif /* INET6 */ 4306 } 4307 4308 switch (pd2.proto) { 4309 case IPPROTO_TCP: { 4310 struct tcphdr th; 4311 u_int32_t seq; 4312 struct pf_tree_node key; 4313 struct pf_state_peer *src, *dst; 4314 u_int8_t dws; 4315 int copyback = 0; 4316 4317 /* 4318 * Only the first 8 bytes of the TCP header can be 4319 * expected. Don't access any TCP header fields after 4320 * th_seq, an ackskew test is not possible. 4321 */ 4322 if (!pf_pull_hdr(m, off2, &th, 8, NULL, NULL, pd2.af)) { 4323 DPFPRINTF(PF_DEBUG_MISC, 4324 ("pf: ICMP error message too short " 4325 "(tcp)\n")); 4326 return (PF_DROP); 4327 } 4328 4329 key.af = pd2.af; 4330 key.proto = IPPROTO_TCP; 4331 PF_ACPY(&key.addr[0], pd2.dst, pd2.af); 4332 key.port[0] = th.th_dport; 4333 PF_ACPY(&key.addr[1], pd2.src, pd2.af); 4334 key.port[1] = th.th_sport; 4335 4336 STATE_LOOKUP(); 4337 4338 if (direction == (*state)->direction) { 4339 src = &(*state)->dst; 4340 dst = &(*state)->src; 4341 } else { 4342 src = &(*state)->src; 4343 dst = &(*state)->dst; 4344 } 4345 4346 if (src->wscale && dst->wscale && !(th.th_flags & TH_SYN)) 4347 dws = dst->wscale & PF_WSCALE_MASK; 4348 else 4349 dws = 0; 4350 4351 /* Demodulate sequence number */ 4352 seq = ntohl(th.th_seq) - src->seqdiff; 4353 if (src->seqdiff) { 4354 pf_change_a(&th.th_seq, icmpsum, 4355 htonl(seq), 0); 4356 copyback = 1; 4357 } 4358 4359 if (!SEQ_GEQ(src->seqhi, seq) || 4360 !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws))) { 4361 if (pf_status.debug >= PF_DEBUG_MISC) { 4362 printf("pf: BAD ICMP %d:%d ", 4363 icmptype, pd->hdr.icmp->icmp_code); 4364 pf_print_host(pd->src, 0, pd->af); 4365 printf(" -> "); 4366 pf_print_host(pd->dst, 0, pd->af); 4367 printf(" state: "); 4368 pf_print_state(*state); 4369 printf(" seq=%u\n", seq); 4370 } 4371 return (PF_DROP); 4372 } 4373 4374 if (STATE_TRANSLATE(*state)) { 4375 if (direction == PF_IN) { 4376 pf_change_icmp(pd2.src, &th.th_sport, 4377 daddr, &(*state)->lan.addr, 4378 (*state)->lan.port, NULL, 4379 pd2.ip_sum, icmpsum, 4380 pd->ip_sum, 0, pd2.af); 4381 } else { 4382 pf_change_icmp(pd2.dst, &th.th_dport, 4383 saddr, &(*state)->gwy.addr, 4384 (*state)->gwy.port, NULL, 4385 pd2.ip_sum, icmpsum, 4386 pd->ip_sum, 0, pd2.af); 4387 } 4388 copyback = 1; 4389 } 4390 4391 if (copyback) { 4392 switch (pd2.af) { 4393#ifdef INET 4394 case AF_INET: 4395 m_copyback(m, off, ICMP_MINLEN, 4396 (caddr_t)pd->hdr.icmp); 4397 m_copyback(m, ipoff2, sizeof(h2), 4398 (caddr_t)&h2); 4399 break; 4400#endif /* INET */ 4401#ifdef INET6 4402 case AF_INET6: 4403 m_copyback(m, off, 4404 sizeof(struct icmp6_hdr), 4405 (caddr_t)pd->hdr.icmp6); 4406 m_copyback(m, ipoff2, sizeof(h2_6), 4407 (caddr_t)&h2_6); 4408 break; 4409#endif /* INET6 */ 4410 } 4411 m_copyback(m, off2, 8, (caddr_t)&th); 4412 } 4413 4414 return (PF_PASS); 4415 break; 4416 } 4417 case IPPROTO_UDP: { 4418 struct udphdr uh; 4419 struct pf_tree_node key; 4420 4421 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh), 4422 NULL, NULL, pd2.af)) { 4423 DPFPRINTF(PF_DEBUG_MISC, 4424 ("pf: ICMP error message too short " 4425 "(udp)\n")); 4426 return (PF_DROP); 4427 } 4428 4429 key.af = pd2.af; 4430 key.proto = IPPROTO_UDP; 4431 PF_ACPY(&key.addr[0], pd2.dst, pd2.af); 4432 key.port[0] = uh.uh_dport; 4433 PF_ACPY(&key.addr[1], pd2.src, pd2.af); 4434 key.port[1] = uh.uh_sport; 4435 4436 STATE_LOOKUP(); 4437 4438 if (STATE_TRANSLATE(*state)) { 4439 if (direction == PF_IN) { 4440 pf_change_icmp(pd2.src, &uh.uh_sport, 4441 daddr, &(*state)->lan.addr, 4442 (*state)->lan.port, &uh.uh_sum, 4443 pd2.ip_sum, icmpsum, 4444 pd->ip_sum, 1, pd2.af); 4445 } else { 4446 pf_change_icmp(pd2.dst, &uh.uh_dport, 4447 saddr, &(*state)->gwy.addr, 4448 (*state)->gwy.port, &uh.uh_sum, 4449 pd2.ip_sum, icmpsum, 4450 pd->ip_sum, 1, pd2.af); 4451 } 4452 switch (pd2.af) { 4453#ifdef INET 4454 case AF_INET: 4455 m_copyback(m, off, ICMP_MINLEN, 4456 (caddr_t)pd->hdr.icmp); 4457 m_copyback(m, ipoff2, sizeof(h2), 4458 (caddr_t)&h2); 4459 break; 4460#endif /* INET */ 4461#ifdef INET6 4462 case AF_INET6: 4463 m_copyback(m, off, 4464 sizeof(struct icmp6_hdr), 4465 (caddr_t)pd->hdr.icmp6); 4466 m_copyback(m, ipoff2, sizeof(h2_6), 4467 (caddr_t)&h2_6); 4468 break; 4469#endif /* INET6 */ 4470 } 4471 m_copyback(m, off2, sizeof(uh), 4472 (caddr_t)&uh); 4473 } 4474 4475 return (PF_PASS); 4476 break; 4477 } 4478#ifdef INET 4479 case IPPROTO_ICMP: { 4480 struct icmp iih; 4481 struct pf_tree_node key; 4482 4483 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN, 4484 NULL, NULL, pd2.af)) { 4485 DPFPRINTF(PF_DEBUG_MISC, 4486 ("pf: ICMP error message too short i" 4487 "(icmp)\n")); 4488 return (PF_DROP); 4489 } 4490 4491 key.af = pd2.af; 4492 key.proto = IPPROTO_ICMP; 4493 PF_ACPY(&key.addr[0], pd2.dst, pd2.af); 4494 key.port[0] = iih.icmp_id; 4495 PF_ACPY(&key.addr[1], pd2.src, pd2.af); 4496 key.port[1] = iih.icmp_id; 4497 4498 STATE_LOOKUP(); 4499 4500 if (STATE_TRANSLATE(*state)) { 4501 if (direction == PF_IN) { 4502 pf_change_icmp(pd2.src, &iih.icmp_id, 4503 daddr, &(*state)->lan.addr, 4504 (*state)->lan.port, NULL, 4505 pd2.ip_sum, icmpsum, 4506 pd->ip_sum, 0, AF_INET); 4507 } else { 4508 pf_change_icmp(pd2.dst, &iih.icmp_id, 4509 saddr, &(*state)->gwy.addr, 4510 (*state)->gwy.port, NULL, 4511 pd2.ip_sum, icmpsum, 4512 pd->ip_sum, 0, AF_INET); 4513 } 4514 m_copyback(m, off, ICMP_MINLEN, 4515 (caddr_t)pd->hdr.icmp); 4516 m_copyback(m, ipoff2, sizeof(h2), 4517 (caddr_t)&h2); 4518 m_copyback(m, off2, ICMP_MINLEN, 4519 (caddr_t)&iih); 4520 } 4521 4522 return (PF_PASS); 4523 break; 4524 } 4525#endif /* INET */ 4526#ifdef INET6 4527 case IPPROTO_ICMPV6: { 4528 struct icmp6_hdr iih; 4529 struct pf_tree_node key; 4530 4531 if (!pf_pull_hdr(m, off2, &iih, 4532 sizeof(struct icmp6_hdr), NULL, NULL, pd2.af)) { 4533 DPFPRINTF(PF_DEBUG_MISC, 4534 ("pf: ICMP error message too short " 4535 "(icmp6)\n")); 4536 return (PF_DROP); 4537 } 4538 4539 key.af = pd2.af; 4540 key.proto = IPPROTO_ICMPV6; 4541 PF_ACPY(&key.addr[0], pd2.dst, pd2.af); 4542 key.port[0] = iih.icmp6_id; 4543 PF_ACPY(&key.addr[1], pd2.src, pd2.af); 4544 key.port[1] = iih.icmp6_id; 4545 4546 STATE_LOOKUP(); 4547 4548 if (STATE_TRANSLATE(*state)) { 4549 if (direction == PF_IN) { 4550 pf_change_icmp(pd2.src, &iih.icmp6_id, 4551 daddr, &(*state)->lan.addr, 4552 (*state)->lan.port, NULL, 4553 pd2.ip_sum, icmpsum, 4554 pd->ip_sum, 0, AF_INET6); 4555 } else { 4556 pf_change_icmp(pd2.dst, &iih.icmp6_id, 4557 saddr, &(*state)->gwy.addr, 4558 (*state)->gwy.port, NULL, 4559 pd2.ip_sum, icmpsum, 4560 pd->ip_sum, 0, AF_INET6); 4561 } 4562 m_copyback(m, off, sizeof(struct icmp6_hdr), 4563 (caddr_t)pd->hdr.icmp6); 4564 m_copyback(m, ipoff2, sizeof(h2_6), 4565 (caddr_t)&h2_6); 4566 m_copyback(m, off2, sizeof(struct icmp6_hdr), 4567 (caddr_t)&iih); 4568 } 4569 4570 return (PF_PASS); 4571 break; 4572 } 4573#endif /* INET6 */ 4574 default: { 4575 struct pf_tree_node key; 4576 4577 key.af = pd2.af; 4578 key.proto = pd2.proto; 4579 PF_ACPY(&key.addr[0], pd2.dst, pd2.af); 4580 key.port[0] = 0; 4581 PF_ACPY(&key.addr[1], pd2.src, pd2.af); 4582 key.port[1] = 0; 4583 4584 STATE_LOOKUP(); 4585 4586 if (STATE_TRANSLATE(*state)) { 4587 if (direction == PF_IN) { 4588 pf_change_icmp(pd2.src, NULL, 4589 daddr, &(*state)->lan.addr, 4590 0, NULL, 4591 pd2.ip_sum, icmpsum, 4592 pd->ip_sum, 0, pd2.af); 4593 } else { 4594 pf_change_icmp(pd2.dst, NULL, 4595 saddr, &(*state)->gwy.addr, 4596 0, NULL, 4597 pd2.ip_sum, icmpsum, 4598 pd->ip_sum, 0, pd2.af); 4599 } 4600 switch (pd2.af) { 4601#ifdef INET 4602 case AF_INET: 4603 m_copyback(m, off, ICMP_MINLEN, 4604 (caddr_t)pd->hdr.icmp); 4605 m_copyback(m, ipoff2, sizeof(h2), 4606 (caddr_t)&h2); 4607 break; 4608#endif /* INET */ 4609#ifdef INET6 4610 case AF_INET6: 4611 m_copyback(m, off, 4612 sizeof(struct icmp6_hdr), 4613 (caddr_t)pd->hdr.icmp6); 4614 m_copyback(m, ipoff2, sizeof(h2_6), 4615 (caddr_t)&h2_6); 4616 break; 4617#endif /* INET6 */ 4618 } 4619 } 4620 4621 return (PF_PASS); 4622 break; 4623 } 4624 } 4625 } 4626} 4627 4628int 4629pf_test_state_other(struct pf_state **state, int direction, struct ifnet *ifp, 4630 struct pf_pdesc *pd) 4631{ 4632 struct pf_state_peer *src, *dst; 4633 struct pf_tree_node key; 4634 int dirndx; 4635 4636 key.af = pd->af; 4637 key.proto = pd->proto; 4638 PF_ACPY(&key.addr[0], pd->src, key.af); 4639 PF_ACPY(&key.addr[1], pd->dst, key.af); 4640 key.port[0] = 0; 4641 key.port[1] = 0; 4642 4643 STATE_LOOKUP(); 4644 4645 if (direction == (*state)->direction) { 4646 src = &(*state)->src; 4647 dst = &(*state)->dst; 4648 dirndx = 0; 4649 } else { 4650 src = &(*state)->dst; 4651 dst = &(*state)->src; 4652 dirndx = 1; 4653 } 4654 4655 (*state)->packets[dirndx]++; 4656 (*state)->bytes[dirndx] += pd->tot_len; 4657 4658 /* update states */ 4659 if (src->state < PFOTHERS_SINGLE) 4660 src->state = PFOTHERS_SINGLE; 4661 if (dst->state == PFOTHERS_SINGLE) 4662 dst->state = PFOTHERS_MULTIPLE; 4663 4664 /* update expire time */ 4665#ifdef __FreeBSD__ 4666 (*state)->expire = time_second; 4667#else 4668 (*state)->expire = time.tv_sec; 4669#endif 4670 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE) 4671 (*state)->timeout = PFTM_OTHER_MULTIPLE; 4672 else 4673 (*state)->timeout = PFTM_OTHER_SINGLE; 4674 4675 /* translate source/destination address, if necessary */ 4676 if (STATE_TRANSLATE(*state)) { 4677 if (direction == PF_OUT) 4678 switch (pd->af) { 4679#ifdef INET 4680 case AF_INET: 4681 pf_change_a(&pd->src->v4.s_addr, 4682 pd->ip_sum, (*state)->gwy.addr.v4.s_addr, 4683 0); 4684 break; 4685#endif /* INET */ 4686#ifdef INET6 4687 case AF_INET6: 4688 PF_ACPY(pd->src, &(*state)->gwy.addr, pd->af); 4689 break; 4690#endif /* INET6 */ 4691 } 4692 else 4693 switch (pd->af) { 4694#ifdef INET 4695 case AF_INET: 4696 pf_change_a(&pd->dst->v4.s_addr, 4697 pd->ip_sum, (*state)->lan.addr.v4.s_addr, 4698 0); 4699 break; 4700#endif /* INET */ 4701#ifdef INET6 4702 case AF_INET6: 4703 PF_ACPY(pd->dst, &(*state)->lan.addr, pd->af); 4704 break; 4705#endif /* INET6 */ 4706 } 4707 } 4708 4709 (*state)->rule.ptr->packets++; 4710 (*state)->rule.ptr->bytes += pd->tot_len; 4711 if ((*state)->nat_rule.ptr != NULL) { 4712 (*state)->nat_rule.ptr->packets++; 4713 (*state)->nat_rule.ptr->bytes += pd->tot_len; 4714 } 4715 if ((*state)->anchor.ptr != NULL) { 4716 (*state)->anchor.ptr->packets++; 4717 (*state)->anchor.ptr->bytes += pd->tot_len; 4718 } 4719 return (PF_PASS); 4720} 4721 4722/* 4723 * ipoff and off are measured from the start of the mbuf chain. 4724 * h must be at "ipoff" on the mbuf chain. 4725 */ 4726void * 4727pf_pull_hdr(struct mbuf *m, int off, void *p, int len, 4728 u_short *actionp, u_short *reasonp, sa_family_t af) 4729{ 4730 switch (af) { 4731#ifdef INET 4732 case AF_INET: { 4733 struct ip *h = mtod(m, struct ip *); 4734 u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3; 4735 4736 if (fragoff) { 4737 if (fragoff >= len) 4738 ACTION_SET(actionp, PF_PASS); 4739 else { 4740 ACTION_SET(actionp, PF_DROP); 4741 REASON_SET(reasonp, PFRES_FRAG); 4742 } 4743 return (NULL); 4744 } 4745 if (m->m_pkthdr.len < off + len || ntohs(h->ip_len) < off + len) { 4746 ACTION_SET(actionp, PF_DROP); 4747 REASON_SET(reasonp, PFRES_SHORT); 4748 return (NULL); 4749 } 4750 break; 4751 } 4752#endif /* INET */ 4753#ifdef INET6 4754 case AF_INET6: { 4755 struct ip6_hdr *h = mtod(m, struct ip6_hdr *); 4756 4757 if (m->m_pkthdr.len < off + len || 4758 (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) < 4759 (unsigned)(off + len)) { 4760 ACTION_SET(actionp, PF_DROP); 4761 REASON_SET(reasonp, PFRES_SHORT); 4762 return (NULL); 4763 } 4764 break; 4765 } 4766#endif /* INET6 */ 4767 } 4768 m_copydata(m, off, len, p); 4769 return (p); 4770} 4771 4772int 4773pf_routable(struct pf_addr *addr, sa_family_t af) 4774{ 4775 struct sockaddr_in *dst; 4776 struct route ro; 4777 int ret = 0; 4778 4779 bzero(&ro, sizeof(ro)); 4780 dst = satosin(&ro.ro_dst); 4781 dst->sin_family = af; 4782 dst->sin_len = sizeof(*dst); 4783 dst->sin_addr = addr->v4; 4784#ifdef __FreeBSD__ 4785#ifdef RTF_PRCLONING 4786 rtalloc_ign(&ro, (RTF_CLONING|RTF_PRCLONING)); 4787#else /* !RTF_PRCLONING */ 4788 rtalloc_ign(&ro, RTF_CLONING); 4789#endif 4790#else /* ! __FreeBSD__ */ 4791 rtalloc_noclone(&ro, NO_CLONING); 4792#endif 4793 4794 if (ro.ro_rt != NULL) { 4795 ret = 1; 4796 RTFREE(ro.ro_rt); 4797 } 4798 4799 return (ret); 4800} 4801 4802#ifdef INET 4803 4804#if defined(__FreeBSD__) && (__FreeBSD_version < 501105) 4805int 4806ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu, 4807 u_long if_hwassist_flags, int sw_csum) 4808{ 4809 int error = 0; 4810 int hlen = ip->ip_hl << 2; 4811 int len = (mtu - hlen) & ~7; /* size of payload in each fragment */ 4812 int off; 4813 struct mbuf *m0 = *m_frag; /* the original packet */ 4814 int firstlen; 4815 struct mbuf **mnext; 4816 int nfrags; 4817 4818 if (ip->ip_off & IP_DF) { /* Fragmentation not allowed */ 4819 ipstat.ips_cantfrag++; 4820 return EMSGSIZE; 4821 } 4822 4823 /* 4824 * Must be able to put at least 8 bytes per fragment. 4825 */ 4826 if (len < 8) 4827 return EMSGSIZE; 4828 4829 /* 4830 * If the interface will not calculate checksums on 4831 * fragmented packets, then do it here. 4832 */ 4833 if (m0->m_pkthdr.csum_flags & CSUM_DELAY_DATA && 4834 (if_hwassist_flags & CSUM_IP_FRAGS) == 0) { 4835 in_delayed_cksum(m0); 4836 m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; 4837 } 4838 4839 if (len > PAGE_SIZE) { 4840 /* 4841 * Fragment large datagrams such that each segment 4842 * contains a multiple of PAGE_SIZE amount of data, 4843 * plus headers. This enables a receiver to perform 4844 * page-flipping zero-copy optimizations. 4845 * 4846 * XXX When does this help given that sender and receiver 4847 * could have different page sizes, and also mtu could 4848 * be less than the receiver's page size ? 4849 */ 4850 int newlen; 4851 struct mbuf *m; 4852 4853 for (m = m0, off = 0; m && (off+m->m_len) <= mtu; m = m->m_next) 4854 off += m->m_len; 4855 4856 /* 4857 * firstlen (off - hlen) must be aligned on an 4858 * 8-byte boundary 4859 */ 4860 if (off < hlen) 4861 goto smart_frag_failure; 4862 off = ((off - hlen) & ~7) + hlen; 4863 newlen = (~PAGE_MASK) & mtu; 4864 if ((newlen + sizeof (struct ip)) > mtu) { 4865 /* we failed, go back the default */ 4866smart_frag_failure: 4867 newlen = len; 4868 off = hlen + len; 4869 } 4870 len = newlen; 4871 4872 } else { 4873 off = hlen + len; 4874 } 4875 4876 firstlen = off - hlen; 4877 mnext = &m0->m_nextpkt; /* pointer to next packet */ 4878 4879 /* 4880 * Loop through length of segment after first fragment, 4881 * make new header and copy data of each part and link onto chain. 4882 * Here, m0 is the original packet, m is the fragment being created. 4883 * The fragments are linked off the m_nextpkt of the original 4884 * packet, which after processing serves as the first fragment. 4885 */ 4886 for (nfrags = 1; off < ip->ip_len; off += len, nfrags++) { 4887 struct ip *mhip; /* ip header on the fragment */ 4888 struct mbuf *m; 4889 int mhlen = sizeof (struct ip); 4890 4891 MGETHDR(m, M_DONTWAIT, MT_HEADER); 4892 if (m == 0) { 4893 error = ENOBUFS; 4894 ipstat.ips_odropped++; 4895 goto done; 4896 } 4897 m->m_flags |= (m0->m_flags & M_MCAST) | M_FRAG; 4898 /* 4899 * In the first mbuf, leave room for the link header, then 4900 * copy the original IP header including options. The payload 4901 * goes into an additional mbuf chain returned by m_copy(). 4902 */ 4903 m->m_data += max_linkhdr; 4904 mhip = mtod(m, struct ip *); 4905 *mhip = *ip; 4906 if (hlen > sizeof (struct ip)) { 4907 mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); 4908 mhip->ip_v = IPVERSION; 4909 mhip->ip_hl = mhlen >> 2; 4910 } 4911 m->m_len = mhlen; 4912 /* XXX do we need to add ip->ip_off below ? */ 4913 mhip->ip_off = ((off - hlen) >> 3) + ip->ip_off; 4914 if (off + len >= ip->ip_len) { /* last fragment */ 4915 len = ip->ip_len - off; 4916 m->m_flags |= M_LASTFRAG; 4917 } else 4918 mhip->ip_off |= IP_MF; 4919 mhip->ip_len = htons((u_short)(len + mhlen)); 4920 m->m_next = m_copy(m0, off, len); 4921 if (m->m_next == 0) { /* copy failed */ 4922 m_free(m); 4923 error = ENOBUFS; /* ??? */ 4924 ipstat.ips_odropped++; 4925 goto done; 4926 } 4927 m->m_pkthdr.len = mhlen + len; 4928 m->m_pkthdr.rcvif = (struct ifnet *)0; 4929#ifdef MAC 4930 mac_create_fragment(m0, m); 4931#endif 4932 m->m_pkthdr.csum_flags = m0->m_pkthdr.csum_flags; 4933 mhip->ip_off = htons(mhip->ip_off); 4934 mhip->ip_sum = 0; 4935 if (sw_csum & CSUM_DELAY_IP) 4936 mhip->ip_sum = in_cksum(m, mhlen); 4937 *mnext = m; 4938 mnext = &m->m_nextpkt; 4939 } 4940 ipstat.ips_ofragments += nfrags; 4941 4942 /* set first marker for fragment chain */ 4943 m0->m_flags |= M_FIRSTFRAG | M_FRAG; 4944 m0->m_pkthdr.csum_data = nfrags; 4945 4946 /* 4947 * Update first fragment by trimming what's been copied out 4948 * and updating header. 4949 */ 4950 m_adj(m0, hlen + firstlen - ip->ip_len); 4951 m0->m_pkthdr.len = hlen + firstlen; 4952 ip->ip_len = htons((u_short)m0->m_pkthdr.len); 4953 ip->ip_off |= IP_MF; 4954 ip->ip_off = htons(ip->ip_off); 4955 ip->ip_sum = 0; 4956 if (sw_csum & CSUM_DELAY_IP) 4957 ip->ip_sum = in_cksum(m0, hlen); 4958 4959done: 4960 *m_frag = m0; 4961 return error; 4962} 4963#endif /* __FreeBSD__ && __FreeBSD_version > 501105 */ 4964 4965void 4966pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 4967 struct pf_state *s) 4968{ 4969 struct mbuf *m0, *m1; 4970 struct route iproute; 4971 struct route *ro = NULL; /* XXX: was uninitialized */ 4972 struct sockaddr_in *dst; 4973 struct ip *ip; 4974 struct ifnet *ifp = NULL; 4975 struct m_tag *mtag; 4976 struct pf_addr naddr; 4977 int error = 0; 4978#ifdef __FreeBSD__ 4979 int sw_csum; 4980#endif 4981 4982 if (m == NULL || *m == NULL || r == NULL || 4983 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 4984 panic("pf_route: invalid parameters"); 4985 4986 if (r->rt == PF_DUPTO) { 4987 m0 = *m; 4988 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 4989 if (mtag == NULL) { 4990 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 4991 if (mtag == NULL) 4992 goto bad; 4993 m_tag_prepend(m0, mtag); 4994 } 4995#ifdef __FreeBSD__ 4996 m0 = m_dup(*m, M_DONTWAIT); 4997#else 4998 m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT); 4999#endif 5000 if (m0 == NULL) 5001 return; 5002 } else { 5003 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 5004 return; 5005 m0 = *m; 5006 } 5007 5008 if (m0->m_len < sizeof(struct ip)) 5009 panic("pf_route: m0->m_len < sizeof(struct ip)"); 5010 ip = mtod(m0, struct ip *); 5011 5012 ro = &iproute; 5013 bzero((caddr_t)ro, sizeof(*ro)); 5014 dst = satosin(&ro->ro_dst); 5015 dst->sin_family = AF_INET; 5016 dst->sin_len = sizeof(*dst); 5017 dst->sin_addr = ip->ip_dst; 5018 5019 if (r->rt == PF_FASTROUTE) { 5020 rtalloc(ro); 5021 if (ro->ro_rt == 0) { 5022 ipstat.ips_noroute++; 5023 goto bad; 5024 } 5025 5026 ifp = ro->ro_rt->rt_ifp; 5027 ro->ro_rt->rt_use++; 5028 5029 if (ro->ro_rt->rt_flags & RTF_GATEWAY) 5030 dst = satosin(ro->ro_rt->rt_gateway); 5031 } else { 5032 if (TAILQ_EMPTY(&r->rpool.list)) 5033 panic("pf_route: TAILQ_EMPTY(&r->rpool.list)"); 5034 if (s == NULL) { 5035 pf_map_addr(AF_INET, &r->rpool, 5036 (struct pf_addr *)&ip->ip_src, 5037 &naddr, NULL); 5038 if (!PF_AZERO(&naddr, AF_INET)) 5039 dst->sin_addr.s_addr = naddr.v4.s_addr; 5040 ifp = r->rpool.cur->ifp; 5041 } else { 5042 if (!PF_AZERO(&s->rt_addr, AF_INET)) 5043 dst->sin_addr.s_addr = 5044 s->rt_addr.v4.s_addr; 5045 ifp = s->rt_ifp; 5046 } 5047 } 5048 5049 if (ifp == NULL) 5050 goto bad; 5051 5052 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 5053 if (mtag == NULL) { 5054 struct m_tag *mtag; 5055 5056 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 5057 if (mtag == NULL) 5058 goto bad; 5059 m_tag_prepend(m0, mtag); 5060 } 5061 5062 if (oifp != ifp && mtag == NULL) { 5063#ifdef __FreeBSD__ 5064 PF_UNLOCK(); 5065 if (pf_test(PF_OUT, ifp, &m0) != PF_PASS) { 5066 PF_LOCK(); 5067 goto bad; 5068 } else if (m0 == NULL) { 5069 PF_LOCK(); 5070 goto done; 5071 } 5072 PF_LOCK(); 5073#else 5074 if (pf_test(PF_OUT, ifp, &m0) != PF_PASS) 5075 goto bad; 5076 else if (m0 == NULL) 5077 goto done; 5078#endif 5079 if (m0->m_len < sizeof(struct ip)) 5080 panic("pf_route: m0->m_len < sizeof(struct ip)"); 5081 ip = mtod(m0, struct ip *); 5082 } 5083 5084#ifdef __FreeBSD__ 5085 /* Copied from FreeBSD 5.1-CURRENT ip_output. */ 5086 m0->m_pkthdr.csum_flags |= CSUM_IP; 5087 sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist; 5088 if (sw_csum & CSUM_DELAY_DATA) { 5089 /* 5090 * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least) 5091 */ 5092 NTOHS(ip->ip_len); 5093 NTOHS(ip->ip_off); /* XXX: needed? */ 5094 in_delayed_cksum(m0); 5095 HTONS(ip->ip_len); 5096 HTONS(ip->ip_off); 5097 sw_csum &= ~CSUM_DELAY_DATA; 5098 } 5099 m0->m_pkthdr.csum_flags &= ifp->if_hwassist; 5100 5101 if (ntohs(ip->ip_len) <= ifp->if_mtu || 5102 (ifp->if_hwassist & CSUM_FRAGMENT && 5103 ((ip->ip_off & htons(IP_DF)) == 0))) { 5104 /* 5105 * ip->ip_len = htons(ip->ip_len); 5106 * ip->ip_off = htons(ip->ip_off); 5107 */ 5108 ip->ip_sum = 0; 5109 if (sw_csum & CSUM_DELAY_IP) { 5110 /* From KAME */ 5111 if (ip->ip_v == IPVERSION && 5112 (ip->ip_hl << 2) == sizeof(*ip)) { 5113 ip->ip_sum = in_cksum_hdr(ip); 5114 } else { 5115 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 5116 } 5117 } 5118 PF_UNLOCK(); 5119 error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro->ro_rt); 5120 PF_LOCK(); 5121 goto done; 5122 } 5123 5124#else 5125 /* Copied from ip_output. */ 5126 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 5127 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 5128 ifp->if_bridge == NULL) { 5129 m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT; 5130 ipstat.ips_outhwcsum++; 5131 } else { 5132 ip->ip_sum = 0; 5133 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 5134 } 5135 /* Update relevant hardware checksum stats for TCP/UDP */ 5136 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) 5137 tcpstat.tcps_outhwcsum++; 5138 else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) 5139 udpstat.udps_outhwcsum++; 5140 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); 5141 goto done; 5142 } 5143#endif 5144 /* 5145 * Too large for interface; fragment if possible. 5146 * Must be able to put at least 8 bytes per fragment. 5147 */ 5148 if (ip->ip_off & htons(IP_DF)) { 5149 ipstat.ips_cantfrag++; 5150 if (r->rt != PF_DUPTO) { 5151#ifdef __FreeBSD__ 5152 /* icmp_error() expects host byte ordering */ 5153 NTOHS(ip->ip_len); 5154 NTOHS(ip->ip_off); 5155 PF_UNLOCK(); 5156#endif 5157 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 5158 ifp); 5159#ifdef __FreeBSD__ 5160 PF_LOCK(); 5161#endif 5162 goto done; 5163 } else 5164 goto bad; 5165 } 5166 5167 m1 = m0; 5168#ifdef __FreeBSD__ 5169 /* 5170 * XXX: is cheaper + less error prone than own function 5171 */ 5172 NTOHS(ip->ip_len); 5173 NTOHS(ip->ip_off); 5174 error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum); 5175#else 5176 error = ip_fragment(m0, ifp, ifp->if_mtu); 5177#endif 5178 if (error) { 5179#ifndef __FreeBSD__ /* ip_fragment does not do m_freem() on FreeBSD */ 5180 m0 = NULL; 5181#endif 5182 goto bad; 5183 } 5184 5185 for (m0 = m1; m0; m0 = m1) { 5186 m1 = m0->m_nextpkt; 5187 m0->m_nextpkt = 0; 5188#ifdef __FreeBSD__ 5189 if (error == 0) { 5190 PF_UNLOCK(); 5191 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 5192 NULL); 5193 PF_LOCK(); 5194 } else 5195#else 5196 if (error == 0) 5197 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 5198 NULL); 5199 else 5200#endif 5201 m_freem(m0); 5202 } 5203 5204 if (error == 0) 5205 ipstat.ips_fragmented++; 5206 5207done: 5208 if (r->rt != PF_DUPTO) 5209 *m = NULL; 5210 if (ro == &iproute && ro->ro_rt) 5211 RTFREE(ro->ro_rt); 5212 return; 5213 5214bad: 5215 m_freem(m0); 5216 goto done; 5217} 5218#endif /* INET */ 5219 5220#ifdef INET6 5221void 5222pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 5223 struct pf_state *s) 5224{ 5225 struct mbuf *m0; 5226 struct m_tag *mtag; 5227 struct route_in6 ip6route; 5228 struct route_in6 *ro; 5229 struct sockaddr_in6 *dst; 5230 struct ip6_hdr *ip6; 5231 struct ifnet *ifp = NULL; 5232 struct pf_addr naddr; 5233 int error = 0; 5234 5235 if (m == NULL || *m == NULL || r == NULL || 5236 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 5237 panic("pf_route6: invalid parameters"); 5238 5239 if (r->rt == PF_DUPTO) { 5240 m0 = *m; 5241 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 5242 if (mtag == NULL) { 5243 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 5244 if (mtag == NULL) 5245 goto bad; 5246 m_tag_prepend(m0, mtag); 5247 } 5248#ifdef __FreeBSD__ 5249 m0 = m_dup(*m, M_DONTWAIT); 5250#else 5251 m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT); 5252#endif 5253 if (m0 == NULL) 5254 return; 5255 } else { 5256 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 5257 return; 5258 m0 = *m; 5259 } 5260 5261 if (m0->m_len < sizeof(struct ip6_hdr)) 5262 panic("pf_route6: m0->m_len < sizeof(struct ip6_hdr)"); 5263 ip6 = mtod(m0, struct ip6_hdr *); 5264 5265 ro = &ip6route; 5266 bzero((caddr_t)ro, sizeof(*ro)); 5267 dst = (struct sockaddr_in6 *)&ro->ro_dst; 5268 dst->sin6_family = AF_INET6; 5269 dst->sin6_len = sizeof(*dst); 5270 dst->sin6_addr = ip6->ip6_dst; 5271 5272 /* Cheat. */ 5273 if (r->rt == PF_FASTROUTE) { 5274 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 5275 if (mtag == NULL) 5276 goto bad; 5277 m_tag_prepend(m0, mtag); 5278#ifdef __FreeBSD__ 5279 PF_UNLOCK(); 5280 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 5281 PF_LOCK(); 5282#else 5283 ip6_output(m0, NULL, NULL, 0, NULL, NULL); 5284#endif 5285 return; 5286 } 5287 5288 if (TAILQ_EMPTY(&r->rpool.list)) 5289 panic("pf_route6: TAILQ_EMPTY(&r->rpool.list)"); 5290 if (s == NULL) { 5291 pf_map_addr(AF_INET6, &r->rpool, 5292 (struct pf_addr *)&ip6->ip6_src, &naddr, NULL); 5293 if (!PF_AZERO(&naddr, AF_INET6)) 5294 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 5295 &naddr, AF_INET6); 5296 ifp = r->rpool.cur->ifp; 5297 } else { 5298 if (!PF_AZERO(&s->rt_addr, AF_INET6)) 5299 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 5300 &s->rt_addr, AF_INET6); 5301 ifp = s->rt_ifp; 5302 } 5303 5304 if (ifp == NULL) 5305 goto bad; 5306 5307 if (oifp != ifp) { 5308 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 5309 if (mtag == NULL) { 5310 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 5311 if (mtag == NULL) 5312 goto bad; 5313 m_tag_prepend(m0, mtag); 5314#ifdef __FreeBSD__ 5315 PF_UNLOCK(); 5316 if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS) { 5317 PF_LOCK(); 5318 goto bad; 5319 } else if (m0 == NULL) { 5320 PF_LOCK(); 5321 goto done; 5322 } 5323 PF_LOCK(); 5324#else 5325 if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS) 5326 goto bad; 5327 else if (m0 == NULL) 5328 goto done; 5329#endif 5330 } 5331 } 5332 5333 /* 5334 * If the packet is too large for the outgoing interface, 5335 * send back an icmp6 error. 5336 */ 5337 if (IN6_IS_ADDR_LINKLOCAL(&dst->sin6_addr)) 5338 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); 5339 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { 5340#ifdef __FreeBSD__ 5341 PF_UNLOCK(); 5342#endif 5343 error = nd6_output(ifp, ifp, m0, dst, NULL); 5344#ifdef __FreeBSD__ 5345 PF_LOCK(); 5346#endif 5347 } else { 5348 in6_ifstat_inc(ifp, ifs6_in_toobig); 5349#ifdef __FreeBSD__ 5350 if (r->rt != PF_DUPTO) { 5351 PF_UNLOCK(); 5352 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 5353 PF_LOCK(); 5354 } else 5355#else 5356 if (r->rt != PF_DUPTO) 5357 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 5358 else 5359#endif 5360 goto bad; 5361 } 5362 5363done: 5364 if (r->rt != PF_DUPTO) 5365 *m = NULL; 5366 return; 5367 5368bad: 5369 m_freem(m0); 5370 goto done; 5371} 5372#endif /* INET6 */ 5373 5374 5375#ifdef __FreeBSD__ 5376/* 5377 * XXX 5378 * FreeBSD supports cksum offload for the following drivers. 5379 * em(4), gx(4), lge(4), nge(4), ti(4), xl(4) 5380 * If we can make full use of it we would outperform ipfw/ipfilter in 5381 * very heavy traffic. 5382 * I have not tested 'cause I don't have NICs that supports cksum offload. 5383 * (There might be problems. Typical phenomena would be 5384 * 1. No route message for UDP packet. 5385 * 2. No connection acceptance from external hosts regardless of rule set.) 5386 */ 5387int 5388pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) 5389{ 5390 u_int16_t sum = 0; 5391 int hw_assist = 0; 5392 struct ip *ip; 5393 5394 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 5395 return (1); 5396 if (m->m_pkthdr.len < off + len) 5397 return (1); 5398 5399 switch (p) { 5400 case IPPROTO_TCP: 5401 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 5402 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 5403 sum = m->m_pkthdr.csum_data; 5404 } else { 5405 ip = mtod(m, struct ip *); 5406 sum = in_pseudo(ip->ip_src.s_addr, 5407 ip->ip_dst.s_addr, 5408 htonl(m->m_pkthdr.csum_data + 5409 IPPROTO_TCP) + ip->ip_len); 5410 } 5411 sum ^= 0xffff; 5412 ++hw_assist; 5413 } 5414 break; 5415 case IPPROTO_UDP: 5416 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 5417 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 5418 sum = m->m_pkthdr.csum_data; 5419 } else { 5420 ip = mtod(m, struct ip *); 5421 sum = in_pseudo(ip->ip_src.s_addr, 5422 ip->ip_dst.s_addr, htonl((u_short)len + 5423 m->m_pkthdr.csum_data + IPPROTO_UDP)); 5424 } 5425 sum ^= 0xffff; 5426 ++hw_assist; 5427 } 5428 break; 5429 case IPPROTO_ICMP: 5430#ifdef INET6 5431 case IPPROTO_ICMPV6: 5432#endif /* INET6 */ 5433 break; 5434 default: 5435 return (1); 5436 } 5437 5438 if (!hw_assist) { 5439 switch (af) { 5440 case AF_INET: 5441 if (p == IPPROTO_ICMP) { 5442 if (m->m_len < off) 5443 return (1); 5444 m->m_data += off; 5445 m->m_len -= off; 5446 sum = in_cksum(m, len); 5447 m->m_data -= off; 5448 m->m_len += off; 5449 } else { 5450 if (m->m_len < sizeof(struct ip)) 5451 return (1); 5452 sum = in4_cksum(m, p, off, len); 5453 if (sum == 0) { 5454 m->m_pkthdr.csum_flags |= 5455 (CSUM_DATA_VALID | 5456 CSUM_PSEUDO_HDR); 5457 m->m_pkthdr.csum_data = 0xffff; 5458 } 5459 } 5460 break; 5461#ifdef INET6 5462 case AF_INET6: 5463 if (m->m_len < sizeof(struct ip6_hdr)) 5464 return (1); 5465 sum = in6_cksum(m, p, off, len); 5466 /* 5467 * XXX 5468 * IPv6 H/W cksum off-load not supported yet! 5469 * 5470 * if (sum == 0) { 5471 * m->m_pkthdr.csum_flags |= 5472 * (CSUM_DATA_VALID|CSUM_PSEUDO_HDR); 5473 * m->m_pkthdr.csum_data = 0xffff; 5474 *} 5475 */ 5476 break; 5477#endif /* INET6 */ 5478 default: 5479 return (1); 5480 } 5481 } 5482 if (sum) { 5483 switch (p) { 5484 case IPPROTO_TCP: 5485 tcpstat.tcps_rcvbadsum++; 5486 break; 5487 case IPPROTO_UDP: 5488 udpstat.udps_badsum++; 5489 break; 5490 case IPPROTO_ICMP: 5491 icmpstat.icps_checksum++; 5492 break; 5493#ifdef INET6 5494 case IPPROTO_ICMPV6: 5495 icmp6stat.icp6s_checksum++; 5496 break; 5497#endif /* INET6 */ 5498 } 5499 return (1); 5500 } 5501 return (0); 5502} 5503#else 5504/* 5505 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 5506 * off is the offset where the protocol header starts 5507 * len is the total length of protocol header plus payload 5508 * returns 0 when the checksum is valid, otherwise returns 1. 5509 */ 5510int 5511pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) 5512{ 5513 u_int16_t flag_ok, flag_bad; 5514 u_int16_t sum; 5515 5516 switch (p) { 5517 case IPPROTO_TCP: 5518 flag_ok = M_TCP_CSUM_IN_OK; 5519 flag_bad = M_TCP_CSUM_IN_BAD; 5520 break; 5521 case IPPROTO_UDP: 5522 flag_ok = M_UDP_CSUM_IN_OK; 5523 flag_bad = M_UDP_CSUM_IN_BAD; 5524 break; 5525 case IPPROTO_ICMP: 5526#ifdef INET6 5527 case IPPROTO_ICMPV6: 5528#endif /* INET6 */ 5529 flag_ok = flag_bad = 0; 5530 break; 5531 default: 5532 return (1); 5533 } 5534 if (m->m_pkthdr.csum & flag_ok) 5535 return (0); 5536 if (m->m_pkthdr.csum & flag_bad) 5537 return (1); 5538 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 5539 return (1); 5540 if (m->m_pkthdr.len < off + len) 5541 return (1); 5542 switch (af) { 5543 case AF_INET: 5544 if (p == IPPROTO_ICMP) { 5545 if (m->m_len < off) 5546 return (1); 5547 m->m_data += off; 5548 m->m_len -= off; 5549 sum = in_cksum(m, len); 5550 m->m_data -= off; 5551 m->m_len += off; 5552 } else { 5553 if (m->m_len < sizeof(struct ip)) 5554 return (1); 5555 sum = in4_cksum(m, p, off, len); 5556 } 5557 break; 5558#ifdef INET6 5559 case AF_INET6: 5560 if (m->m_len < sizeof(struct ip6_hdr)) 5561 return (1); 5562 sum = in6_cksum(m, p, off, len); 5563 break; 5564#endif /* INET6 */ 5565 default: 5566 return (1); 5567 } 5568 if (sum) { 5569 m->m_pkthdr.csum |= flag_bad; 5570 switch (p) { 5571 case IPPROTO_TCP: 5572 tcpstat.tcps_rcvbadsum++; 5573 break; 5574 case IPPROTO_UDP: 5575 udpstat.udps_badsum++; 5576 break; 5577 case IPPROTO_ICMP: 5578 icmpstat.icps_checksum++; 5579 break; 5580#ifdef INET6 5581 case IPPROTO_ICMPV6: 5582 icmp6stat.icp6s_checksum++; 5583 break; 5584#endif /* INET6 */ 5585 } 5586 return (1); 5587 } 5588 m->m_pkthdr.csum |= flag_ok; 5589 return (0); 5590} 5591#endif 5592 5593#ifdef INET 5594int 5595pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) 5596{ 5597 u_short action, reason = 0, log = 0; 5598 struct mbuf *m = *m0; 5599 struct ip *h = NULL; /* XXX: was uninitialized */ 5600 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr; 5601 struct pf_state *s = NULL; 5602 struct pf_ruleset *ruleset = NULL; 5603 struct pf_pdesc pd; 5604 int off; 5605 int pqid = 0; 5606 5607#ifdef __FreeBSD__ 5608 PF_LOCK(); 5609#endif 5610 if (!pf_status.running || 5611 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) { 5612#ifdef __FreeBSD__ 5613 PF_UNLOCK(); 5614#endif 5615 return (PF_PASS); 5616 } 5617 5618#if defined(__FreeBSD__) && (__FreeBSD_version >= 501000) 5619 M_ASSERTPKTHDR(m); 5620#else 5621#ifdef DIAGNOSTIC 5622 if ((m->m_flags & M_PKTHDR) == 0) 5623 panic("non-M_PKTHDR is passed to pf_test"); 5624#endif 5625#endif 5626 5627 if (m->m_pkthdr.len < (int)sizeof(*h)) { 5628 action = PF_DROP; 5629 REASON_SET(&reason, PFRES_SHORT); 5630 log = 1; 5631 goto done; 5632 } 5633 5634 /* We do IP header normalization and packet reassembly here */ 5635 if (pf_normalize_ip(m0, dir, ifp, &reason) != PF_PASS) { 5636 action = PF_DROP; 5637 goto done; 5638 } 5639 m = *m0; 5640 h = mtod(m, struct ip *); 5641 5642 off = h->ip_hl << 2; 5643 if (off < (int)sizeof(*h)) { 5644 action = PF_DROP; 5645 REASON_SET(&reason, PFRES_SHORT); 5646 log = 1; 5647 goto done; 5648 } 5649 5650 memset(&pd, 0, sizeof(pd)); 5651 pd.src = (struct pf_addr *)&h->ip_src; 5652 pd.dst = (struct pf_addr *)&h->ip_dst; 5653 pd.ip_sum = &h->ip_sum; 5654 pd.proto = h->ip_p; 5655 pd.af = AF_INET; 5656 pd.tos = h->ip_tos; 5657 pd.tot_len = ntohs(h->ip_len); 5658 5659 /* handle fragments that didn't get reassembled by normalization */ 5660 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) { 5661 action = pf_test_fragment(&r, dir, ifp, m, h, 5662 &pd, &a, &ruleset); 5663 goto done; 5664 } 5665 5666 switch (h->ip_p) { 5667 5668 case IPPROTO_TCP: { 5669 struct tcphdr th; 5670 5671 pd.hdr.tcp = &th; 5672 if (!pf_pull_hdr(m, off, &th, sizeof(th), 5673 &action, &reason, AF_INET)) { 5674 log = action != PF_PASS; 5675 goto done; 5676 } 5677 if (dir == PF_IN && pf_check_proto_cksum(m, off, 5678 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) { 5679 action = PF_DROP; 5680 goto done; 5681 } 5682 pd.p_len = pd.tot_len - off - (th.th_off << 2); 5683 if ((th.th_flags & TH_ACK) && pd.p_len == 0) 5684 pqid = 1; 5685 action = pf_normalize_tcp(dir, ifp, m, 0, off, h, &pd); 5686 if (action == PF_DROP) 5687 break; 5688 action = pf_test_state_tcp(&s, dir, ifp, m, 0, off, h, &pd, 5689 &reason); 5690 if (action == PF_PASS) { 5691 r = s->rule.ptr; 5692 log = s->log; 5693 } else if (s == NULL) 5694 action = pf_test_tcp(&r, &s, dir, ifp, 5695 m, 0, off, h, &pd, &a, &ruleset); 5696 break; 5697 } 5698 5699 case IPPROTO_UDP: { 5700 struct udphdr uh; 5701 5702 pd.hdr.udp = &uh; 5703 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 5704 &action, &reason, AF_INET)) { 5705 log = action != PF_PASS; 5706 goto done; 5707 } 5708 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 5709 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) { 5710 action = PF_DROP; 5711 goto done; 5712 } 5713 action = pf_test_state_udp(&s, dir, ifp, m, 0, off, h, &pd); 5714 if (action == PF_PASS) { 5715 r = s->rule.ptr; 5716 a = s->anchor.ptr; 5717 log = s->log; 5718 } else if (s == NULL) 5719 action = pf_test_udp(&r, &s, dir, ifp, 5720 m, 0, off, h, &pd, &a, &ruleset); 5721 break; 5722 } 5723 5724 case IPPROTO_ICMP: { 5725 struct icmp ih; 5726 5727 pd.hdr.icmp = &ih; 5728 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN, 5729 &action, &reason, AF_INET)) { 5730 log = action != PF_PASS; 5731 goto done; 5732 } 5733 if (dir == PF_IN && pf_check_proto_cksum(m, off, 5734 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) { 5735 action = PF_DROP; 5736 goto done; 5737 } 5738 action = pf_test_state_icmp(&s, dir, ifp, m, 0, off, h, &pd); 5739 if (action == PF_PASS) { 5740 r = s->rule.ptr; 5741 r->packets++; 5742 r->bytes += ntohs(h->ip_len); 5743 a = s->anchor.ptr; 5744 if (a != NULL) { 5745 a->packets++; 5746 a->bytes += ntohs(h->ip_len); 5747 } 5748 log = s->log; 5749 } else if (s == NULL) 5750 action = pf_test_icmp(&r, &s, dir, ifp, 5751 m, 0, off, h, &pd, &a, &ruleset); 5752 break; 5753 } 5754 5755 default: 5756 action = pf_test_state_other(&s, dir, ifp, &pd); 5757 if (action == PF_PASS) { 5758 r = s->rule.ptr; 5759 a = s->anchor.ptr; 5760 log = s->log; 5761 } else if (s == NULL) 5762 action = pf_test_other(&r, &s, dir, ifp, m, off, h, 5763 &pd, &a, &ruleset); 5764 break; 5765 } 5766 5767 if (ifp == status_ifp) { 5768 pf_status.bcounters[0][dir == PF_OUT] += pd.tot_len; 5769 pf_status.pcounters[0][dir == PF_OUT][action != PF_PASS]++; 5770 } 5771 5772done: 5773 tr = r; 5774 if (r == &pf_default_rule && s != NULL && s->nat_rule.ptr != NULL) 5775 tr = s->nat_rule.ptr; 5776 if (tr->src.addr.type == PF_ADDR_TABLE) 5777 pfr_update_stats(tr->src.addr.p.tbl, 5778 (s == NULL || s->direction == dir) ? pd.src : pd.dst, pd.af, 5779 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 5780 tr->src.not); 5781 if (tr->dst.addr.type == PF_ADDR_TABLE) 5782 pfr_update_stats(tr->dst.addr.p.tbl, 5783 (s == NULL || s->direction == dir) ? pd.dst : pd.src, pd.af, 5784 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 5785 tr->dst.not); 5786 5787 if (action == PF_PASS && h->ip_hl > 5 && 5788 !((s && s->allow_opts) || r->allow_opts)) { 5789 action = PF_DROP; 5790 REASON_SET(&reason, PFRES_SHORT); 5791 log = 1; 5792 DPFPRINTF(PF_DEBUG_MISC, 5793 ("pf: dropping packet with ip options\n")); 5794 } 5795 5796#ifdef ALTQ 5797 if (action == PF_PASS && r->qid) { 5798 struct m_tag *mtag; 5799 struct altq_tag *atag; 5800 5801 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); 5802 if (mtag != NULL) { 5803 atag = (struct altq_tag *)(mtag + 1); 5804 if (pqid || pd.tos == IPTOS_LOWDELAY) 5805 atag->qid = r->pqid; 5806 else 5807 atag->qid = r->qid; 5808 /* add hints for ecn */ 5809 atag->af = AF_INET; 5810 atag->hdr = h; 5811 m_tag_prepend(m, mtag); 5812 } 5813 } 5814#endif 5815 5816 if (log) 5817 PFLOG_PACKET(ifp, h, m, AF_INET, dir, reason, r, a, ruleset); 5818 5819 if (action == PF_SYNPROXY_DROP) { 5820 m_freem(*m0); 5821 *m0 = NULL; 5822 action = PF_PASS; 5823 } else if (r->rt) 5824 /* pf_route can free the mbuf causing *m0 to become NULL */ 5825 pf_route(m0, r, dir, ifp, s); 5826 5827#ifdef __FreeBSD__ 5828 PF_UNLOCK(); 5829#endif 5830 5831 return (action); 5832} 5833#endif /* INET */ 5834 5835#ifdef INET6 5836int 5837pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0) 5838{ 5839 u_short action, reason = 0, log = 0; 5840 struct mbuf *m = *m0; 5841 struct ip6_hdr *h; 5842 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr; 5843 struct pf_state *s = NULL; 5844 struct pf_ruleset *ruleset = NULL; 5845 struct pf_pdesc pd; 5846 int off, terminal = 0; 5847 5848#ifdef __FreeBSD__ 5849 PF_LOCK(); 5850#endif 5851 5852 if (!pf_status.running || 5853 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) { 5854#ifdef __FreeBSD__ 5855 PF_UNLOCK(); 5856#endif 5857 return (PF_PASS); 5858 } 5859 5860#if defined(__FreeBSD__) && (__FreeBSD_version >= 501000) 5861 M_ASSERTPKTHDR(m); 5862#else 5863#ifdef DIAGNOSTIC 5864 if ((m->m_flags & M_PKTHDR) == 0) 5865 panic("non-M_PKTHDR is passed to pf_test"); 5866#endif 5867#endif 5868 5869 if (m->m_pkthdr.len < (int)sizeof(*h)) { 5870 action = PF_DROP; 5871 REASON_SET(&reason, PFRES_SHORT); 5872 log = 1; 5873 goto done; 5874 } 5875 5876 /* We do IP header normalization and packet reassembly here */ 5877 if (pf_normalize_ip6(m0, dir, ifp, &reason) != PF_PASS) { 5878 action = PF_DROP; 5879 goto done; 5880 } 5881 m = *m0; 5882 h = mtod(m, struct ip6_hdr *); 5883 5884 memset(&pd, 0, sizeof(pd)); 5885 pd.src = (struct pf_addr *)&h->ip6_src; 5886 pd.dst = (struct pf_addr *)&h->ip6_dst; 5887 pd.ip_sum = NULL; 5888 pd.af = AF_INET6; 5889 pd.tos = 0; 5890 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr); 5891 5892 off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr); 5893 pd.proto = h->ip6_nxt; 5894 do { 5895 switch (pd.proto) { 5896 case IPPROTO_FRAGMENT: 5897 action = pf_test_fragment(&r, dir, ifp, m, h, 5898 &pd, &a, &ruleset); 5899 if (action == PF_DROP) 5900 REASON_SET(&reason, PFRES_FRAG); 5901 goto done; 5902 case IPPROTO_AH: 5903 case IPPROTO_HOPOPTS: 5904 case IPPROTO_ROUTING: 5905 case IPPROTO_DSTOPTS: { 5906 /* get next header and header length */ 5907 struct ip6_ext opt6; 5908 5909 if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6), 5910 NULL, NULL, pd.af)) { 5911 DPFPRINTF(PF_DEBUG_MISC, 5912 ("pf: IPv6 short opt\n")); 5913 action = PF_DROP; 5914 REASON_SET(&reason, PFRES_SHORT); 5915 log = 1; 5916 goto done; 5917 } 5918 if (pd.proto == IPPROTO_AH) 5919 off += (opt6.ip6e_len + 2) * 4; 5920 else 5921 off += (opt6.ip6e_len + 1) * 8; 5922 pd.proto = opt6.ip6e_nxt; 5923 /* goto the next header */ 5924 break; 5925 } 5926 default: 5927 terminal++; 5928 break; 5929 } 5930 } while (!terminal); 5931 5932 switch (pd.proto) { 5933 5934 case IPPROTO_TCP: { 5935 struct tcphdr th; 5936 5937 pd.hdr.tcp = &th; 5938 if (!pf_pull_hdr(m, off, &th, sizeof(th), 5939 &action, &reason, AF_INET6)) { 5940 log = action != PF_PASS; 5941 goto done; 5942 } 5943 if (dir == PF_IN && pf_check_proto_cksum(m, off, 5944 ntohs(h->ip6_plen), IPPROTO_TCP, AF_INET6)) { 5945 action = PF_DROP; 5946 goto done; 5947 } 5948 pd.p_len = pd.tot_len - off - (th.th_off << 2); 5949 action = pf_normalize_tcp(dir, ifp, m, 0, off, h, &pd); 5950 if (action == PF_DROP) 5951 break; 5952 action = pf_test_state_tcp(&s, dir, ifp, m, 0, off, h, &pd, 5953 &reason); 5954 if (action == PF_PASS) { 5955 r = s->rule.ptr; 5956 log = s->log; 5957 } else if (s == NULL) 5958 action = pf_test_tcp(&r, &s, dir, ifp, 5959 m, 0, off, h, &pd, &a, &ruleset); 5960 break; 5961 } 5962 5963 case IPPROTO_UDP: { 5964 struct udphdr uh; 5965 5966 pd.hdr.udp = &uh; 5967 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 5968 &action, &reason, AF_INET6)) { 5969 log = action != PF_PASS; 5970 goto done; 5971 } 5972 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 5973 off, ntohs(h->ip6_plen), IPPROTO_UDP, AF_INET6)) { 5974 action = PF_DROP; 5975 goto done; 5976 } 5977 action = pf_test_state_udp(&s, dir, ifp, m, 0, off, h, &pd); 5978 if (action == PF_PASS) { 5979 r = s->rule.ptr; 5980 log = s->log; 5981 } else if (s == NULL) 5982 action = pf_test_udp(&r, &s, dir, ifp, 5983 m, 0, off, h, &pd, &a, &ruleset); 5984 break; 5985 } 5986 5987 case IPPROTO_ICMPV6: { 5988 struct icmp6_hdr ih; 5989 5990 pd.hdr.icmp6 = &ih; 5991 if (!pf_pull_hdr(m, off, &ih, sizeof(ih), 5992 &action, &reason, AF_INET6)) { 5993 log = action != PF_PASS; 5994 goto done; 5995 } 5996 if (dir == PF_IN && pf_check_proto_cksum(m, off, 5997 ntohs(h->ip6_plen), IPPROTO_ICMPV6, AF_INET6)) { 5998 action = PF_DROP; 5999 goto done; 6000 } 6001 action = pf_test_state_icmp(&s, dir, ifp, 6002 m, 0, off, h, &pd); 6003 if (action == PF_PASS) { 6004 r = s->rule.ptr; 6005 r->packets++; 6006 r->bytes += h->ip6_plen; 6007 log = s->log; 6008 } else if (s == NULL) 6009 action = pf_test_icmp(&r, &s, dir, ifp, 6010 m, 0, off, h, &pd, &a, &ruleset); 6011 break; 6012 } 6013 6014 default: 6015 action = pf_test_other(&r, &s, dir, ifp, m, off, h, 6016 &pd, &a, &ruleset); 6017 break; 6018 } 6019 6020 if (ifp == status_ifp) { 6021 pf_status.bcounters[1][dir == PF_OUT] += pd.tot_len; 6022 pf_status.pcounters[1][dir == PF_OUT][action != PF_PASS]++; 6023 } 6024 6025done: 6026 tr = r; 6027 if (r == &pf_default_rule && s != NULL && s->nat_rule.ptr != NULL) 6028 tr = s->nat_rule.ptr; 6029 if (tr->src.addr.type == PF_ADDR_TABLE) 6030 pfr_update_stats(tr->src.addr.p.tbl, 6031 (s == NULL || s->direction == dir) ? pd.src : pd.dst, pd.af, 6032 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 6033 tr->src.not); 6034 if (tr->dst.addr.type == PF_ADDR_TABLE) 6035 pfr_update_stats(tr->dst.addr.p.tbl, 6036 (s == NULL || s->direction == dir) ? pd.dst : pd.src, pd.af, 6037 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 6038 tr->dst.not); 6039 6040 /* XXX handle IPv6 options, if not allowed. not implemented. */ 6041 6042#ifdef ALTQ 6043 if (action == PF_PASS && r->qid) { 6044 struct m_tag *mtag; 6045 struct altq_tag *atag; 6046 6047 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); 6048 if (mtag != NULL) { 6049 atag = (struct altq_tag *)(mtag + 1); 6050 if (pd.tos == IPTOS_LOWDELAY) 6051 atag->qid = r->pqid; 6052 else 6053 atag->qid = r->qid; 6054 /* add hints for ecn */ 6055 atag->af = AF_INET6; 6056 atag->hdr = h; 6057 m_tag_prepend(m, mtag); 6058 } 6059 } 6060#endif 6061 6062 if (log) 6063 PFLOG_PACKET(ifp, h, m, AF_INET6, dir, reason, r, a, ruleset); 6064 6065 if (action == PF_SYNPROXY_DROP) { 6066 m_freem(*m0); 6067 *m0 = NULL; 6068 action = PF_PASS; 6069 } else if (r->rt) 6070 /* pf_route6 can free the mbuf causing *m0 to become NULL */ 6071 pf_route6(m0, r, dir, ifp, s); 6072 6073#ifdef __FreeBSD__ 6074 PF_UNLOCK(); 6075#endif 6076 return (action); 6077} 6078#endif /* INET6 */ 6079