pf.c (126259) | pf.c (126261) |
---|---|
1/* $FreeBSD: head/sys/contrib/pf/net/pf.c 126261 2004-02-26 02:34:12Z mlaier $ */ |
|
1/* $OpenBSD: pf.c,v 1.390 2003/09/24 17:18:03 mcbride Exp $ */ 2 3/* 4 * Copyright (c) 2001 Daniel Hartmeier 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 20 unchanged lines hidden (view full) --- 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 * Effort sponsored in part by the Defense Advanced Research Projects 32 * Agency (DARPA) and Air Force Research Laboratory, Air Force 33 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 34 * 35 */ 36 | 2/* $OpenBSD: pf.c,v 1.390 2003/09/24 17:18:03 mcbride Exp $ */ 3 4/* 5 * Copyright (c) 2001 Daniel Hartmeier 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 20 unchanged lines hidden (view full) --- 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#if defined(__FreeBSD__) 39#include "opt_inet.h" 40#include "opt_inet6.h" 41#endif 42 43#if defined(__FreeBSD__) && __FreeBSD__ >= 5 44#include "opt_bpf.h" 45#define NBPFILTER DEV_BPF 46#include "opt_pf.h" 47#define NPFLOG DEV_PFLOG 48#define NPFSYNC DEV_PFSYNC 49#else |
|
37#include "bpfilter.h" 38#include "pflog.h" 39#include "pfsync.h" | 50#include "bpfilter.h" 51#include "pflog.h" 52#include "pfsync.h" |
53#endif |
|
40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/mbuf.h> 44#include <sys/filio.h> 45#include <sys/socket.h> 46#include <sys/socketvar.h> 47#include <sys/kernel.h> 48#include <sys/time.h> | 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#if defined(__FreeBSD__) 64#include <sys/sysctl.h> 65#else |
|
49#include <sys/pool.h> | 66#include <sys/pool.h> |
67#endif |
|
50 51#include <net/if.h> 52#include <net/if_types.h> 53#include <net/bpf.h> 54#include <net/route.h> 55 56#include <netinet/in.h> 57#include <netinet/in_var.h> --- 5 unchanged lines hidden (view full) --- 63#include <netinet/udp.h> 64#include <netinet/ip_icmp.h> 65#include <netinet/in_pcb.h> 66#include <netinet/tcp_timer.h> 67#include <netinet/tcp_var.h> 68#include <netinet/udp_var.h> 69#include <netinet/icmp_var.h> 70 | 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> --- 5 unchanged lines hidden (view full) --- 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#if !defined(__FreeBSD__) |
|
71#include <dev/rndvar.h> | 90#include <dev/rndvar.h> |
91#endif |
|
72#include <net/pfvar.h> 73#include <net/if_pflog.h> 74#include <net/if_pfsync.h> 75 76#ifdef INET6 77#include <netinet/ip6.h> 78#include <netinet/in_pcb.h> 79#include <netinet/icmp6.h> 80#include <netinet6/nd6.h> | 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#if defined(__FreeBSD__) 102#include <netinet6/ip6_var.h> 103#include <netinet6/in6_pcb.h> 104#endif |
|
81#endif /* INET6 */ 82 83#ifdef ALTQ 84#include <altq/if_altq.h> 85#endif 86 | 105#endif /* INET6 */ 106 107#ifdef ALTQ 108#include <altq/if_altq.h> 109#endif 110 |
111#if defined(__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 |
|
87 | 120 |
121#if defined(__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 |
|
88#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x 89struct pf_state_tree; 90 91/* 92 * Global variables 93 */ 94 95struct pf_anchorqueue pf_anchors; --- 4 unchanged lines hidden (view full) --- 100struct pf_altqqueue *pf_altqs_inactive; 101struct pf_status pf_status; 102struct ifnet *status_ifp; 103 104u_int32_t ticket_altqs_active; 105u_int32_t ticket_altqs_inactive; 106u_int32_t ticket_pabuf; 107 | 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; --- 4 unchanged lines hidden (view full) --- 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#if defined(__FreeBSD__) 150struct callout pf_expire_to; /* expire timeout */ 151#else |
|
108struct timeout pf_expire_to; /* expire timeout */ | 152struct timeout pf_expire_to; /* expire timeout */ |
153#endif |
|
109 | 154 |
155 156#if defined(__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 |
|
110struct pool pf_tree_pl, pf_rule_pl, pf_addr_pl; 111struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl; | 160struct pool pf_tree_pl, pf_rule_pl, pf_addr_pl; 161struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl; |
162#endif |
|
112 113void pf_dynaddr_update(void *); | 163 164void pf_dynaddr_update(void *); |
165#if defined(__FreeBSD__) && defined(HOOK_HACK) 166void pf_dynaddr_update_event(void *arg, struct ifnet *ifp); 167#endif |
|
114void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); 115void pf_print_state(struct pf_state *); 116void pf_print_flags(u_int8_t); 117 118u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t, 119 u_int8_t); 120void pf_change_ap(struct pf_addr *, u_int16_t *, 121 u_int16_t *, u_int16_t *, struct pf_addr *, --- 78 unchanged lines hidden (view full) --- 200 u_int16_t); 201void pf_set_rt_ifp(struct pf_state *, 202 struct pf_addr *); 203int pf_check_proto_cksum(struct mbuf *, int, int, 204 u_int8_t, sa_family_t); 205int pf_addr_wrap_neq(struct pf_addr_wrap *, 206 struct pf_addr_wrap *); 207 | 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 *, --- 78 unchanged lines hidden (view full) --- 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#if defined(__FreeBSD__) 263int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len); 264#endif |
|
208 | 265 |
266#if defined(__FreeBSD__) 267struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX]; 268#else |
|
209struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = 210 { { &pf_state_pl, PFSTATE_HIWAT }, { &pf_frent_pl, PFFRAG_FRENT_HIWAT } }; | 269struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = 270 { { &pf_state_pl, PFSTATE_HIWAT }, { &pf_frent_pl, PFFRAG_FRENT_HIWAT } }; |
271#endif |
|
211 212#define STATE_LOOKUP() \ 213 do { \ 214 if (direction == PF_IN) \ 215 *state = pf_find_state(&tree_ext_gwy, &key); \ 216 else \ 217 *state = pf_find_state(&tree_lan_ext, &key); \ 218 if (*state == NULL) \ --- 199 unchanged lines hidden (view full) --- 418 pfsync_insert_state(state); 419#endif 420 return (0); 421} 422 423void 424pf_purge_timeout(void *arg) 425{ | 272 273#define STATE_LOOKUP() \ 274 do { \ 275 if (direction == PF_IN) \ 276 *state = pf_find_state(&tree_ext_gwy, &key); \ 277 else \ 278 *state = pf_find_state(&tree_lan_ext, &key); \ 279 if (*state == NULL) \ --- 199 unchanged lines hidden (view full) --- 479 pfsync_insert_state(state); 480#endif 481 return (0); 482} 483 484void 485pf_purge_timeout(void *arg) 486{ |
487#if defined(__FreeBSD__) 488 struct callout *to = arg; 489#else |
|
426 struct timeout *to = arg; | 490 struct timeout *to = arg; |
491#endif |
|
427 int s; 428 | 492 int s; 493 |
494#if defined(__FreeBSD__) 495 PF_LOCK(); 496#endif |
|
429 s = splsoftnet(); 430 pf_purge_expired_states(); 431 pf_purge_expired_fragments(); 432 splx(s); | 497 s = splsoftnet(); 498 pf_purge_expired_states(); 499 pf_purge_expired_fragments(); 500 splx(s); |
501#if defined(__FreeBSD__) 502 PF_UNLOCK(); 503#endif |
|
433 | 504 |
505#if defined(__FreeBSD__) 506 callout_reset(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz, 507 pf_purge_timeout, to); 508#else |
|
434 timeout_add(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz); | 509 timeout_add(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz); |
510#endif |
|
435} 436 437u_int32_t 438pf_state_expires(const struct pf_state *state) 439{ 440 u_int32_t timeout; 441 u_int32_t start; 442 u_int32_t end; 443 u_int32_t states; 444 445 /* handle all PFTM_* > PFTM_MAX here */ 446 if (state->timeout == PFTM_PURGE) | 511} 512 513u_int32_t 514pf_state_expires(const struct pf_state *state) 515{ 516 u_int32_t timeout; 517 u_int32_t start; 518 u_int32_t end; 519 u_int32_t states; 520 521 /* handle all PFTM_* > PFTM_MAX here */ 522 if (state->timeout == PFTM_PURGE) |
523#if defined(__FreeBSD__) 524 return (time_second); 525#else |
|
447 return (time.tv_sec); | 526 return (time.tv_sec); |
527#endif |
|
448 if (state->timeout == PFTM_UNTIL_PACKET) 449 return (0); | 528 if (state->timeout == PFTM_UNTIL_PACKET) 529 return (0); |
530#if defined(__FreeBSD__) 531 KASSERT((state->timeout < PFTM_MAX), 532 ("pf_state_expires: timeout > PFTM_MAX")); 533#else |
|
450 KASSERT(state->timeout < PFTM_MAX); | 534 KASSERT(state->timeout < PFTM_MAX); |
535#endif |
|
451 timeout = state->rule.ptr->timeout[state->timeout]; 452 if (!timeout) 453 timeout = pf_default_rule.timeout[state->timeout]; 454 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START]; 455 if (start) { 456 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END]; 457 states = state->rule.ptr->states; 458 } else { 459 start = pf_default_rule.timeout[PFTM_ADAPTIVE_START]; 460 end = pf_default_rule.timeout[PFTM_ADAPTIVE_END]; 461 states = pf_status.states; 462 } 463 if (end && states > start && start < end) { 464 if (states < end) 465 return (state->expire + timeout * (end - states) / 466 (end - start)); 467 else | 536 timeout = state->rule.ptr->timeout[state->timeout]; 537 if (!timeout) 538 timeout = pf_default_rule.timeout[state->timeout]; 539 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START]; 540 if (start) { 541 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END]; 542 states = state->rule.ptr->states; 543 } else { 544 start = pf_default_rule.timeout[PFTM_ADAPTIVE_START]; 545 end = pf_default_rule.timeout[PFTM_ADAPTIVE_END]; 546 states = pf_status.states; 547 } 548 if (end && states > start && start < end) { 549 if (states < end) 550 return (state->expire + timeout * (end - states) / 551 (end - start)); 552 else |
553#if defined(__FreeBSD__) 554 return (time_second); 555#else |
|
468 return (time.tv_sec); | 556 return (time.tv_sec); |
557#endif |
|
469 } 470 return (state->expire + timeout); 471} 472 473void 474pf_purge_expired_states(void) 475{ 476 struct pf_tree_node *cur, *peer, *next; 477 struct pf_tree_node key; 478 479 for (cur = RB_MIN(pf_state_tree, &tree_ext_gwy); cur; cur = next) { 480 next = RB_NEXT(pf_state_tree, &tree_ext_gwy, cur); 481 | 558 } 559 return (state->expire + timeout); 560} 561 562void 563pf_purge_expired_states(void) 564{ 565 struct pf_tree_node *cur, *peer, *next; 566 struct pf_tree_node key; 567 568 for (cur = RB_MIN(pf_state_tree, &tree_ext_gwy); cur; cur = next) { 569 next = RB_NEXT(pf_state_tree, &tree_ext_gwy, cur); 570 |
571#if defined(__FreeBSD__) 572 if (pf_state_expires(cur->state) <= (u_int32_t)time_second) { 573#else |
|
482 if (pf_state_expires(cur->state) <= time.tv_sec) { | 574 if (pf_state_expires(cur->state) <= time.tv_sec) { |
575#endif |
|
483 if (cur->state->src.state == PF_TCPS_PROXY_DST) 484 pf_send_tcp(cur->state->rule.ptr, 485 cur->state->af, 486 &cur->state->ext.addr, 487 &cur->state->lan.addr, 488 cur->state->ext.port, 489 cur->state->lan.port, 490 cur->state->src.seqhi, --- 9 unchanged lines hidden (view full) --- 500 PF_ACPY(&key.addr[0], &cur->state->lan.addr, 501 cur->state->af); 502 key.port[0] = cur->state->lan.port; 503 PF_ACPY(&key.addr[1], &cur->state->ext.addr, 504 cur->state->af); 505 key.port[1] = cur->state->ext.port; 506 507 peer = RB_FIND(pf_state_tree, &tree_lan_ext, &key); | 576 if (cur->state->src.state == PF_TCPS_PROXY_DST) 577 pf_send_tcp(cur->state->rule.ptr, 578 cur->state->af, 579 &cur->state->ext.addr, 580 &cur->state->lan.addr, 581 cur->state->ext.port, 582 cur->state->lan.port, 583 cur->state->src.seqhi, --- 9 unchanged lines hidden (view full) --- 593 PF_ACPY(&key.addr[0], &cur->state->lan.addr, 594 cur->state->af); 595 key.port[0] = cur->state->lan.port; 596 PF_ACPY(&key.addr[1], &cur->state->ext.addr, 597 cur->state->af); 598 key.port[1] = cur->state->ext.port; 599 600 peer = RB_FIND(pf_state_tree, &tree_lan_ext, &key); |
601#if defined(__FreeBSD__) 602 KASSERT((peer), ("peer null :%s", __FUNCTION__)); 603 KASSERT((peer->state == cur->state), 604 ("peer->state != cur->state: %s", __FUNCTION__)); 605#else |
|
508 KASSERT(peer); 509 KASSERT(peer->state == cur->state); | 606 KASSERT(peer); 607 KASSERT(peer->state == cur->state); |
608#endif |
|
510 RB_REMOVE(pf_state_tree, &tree_lan_ext, peer); 511 512#if NPFSYNC 513 pfsync_delete_state(cur->state); 514#endif 515 if (--cur->state->rule.ptr->states <= 0) 516 pf_rm_rule(NULL, cur->state->rule.ptr); 517 if (cur->state->nat_rule.ptr != NULL) --- 60 unchanged lines hidden (view full) --- 578 if (aw->p.dyn->ifp == NULL) { 579 pool_put(&pf_addr_pl, aw->p.dyn); 580 aw->p.dyn = NULL; 581 return (1); 582 } 583 aw->p.dyn->addr = &aw->v.a.addr; 584 aw->p.dyn->af = af; 585 aw->p.dyn->undefined = 1; | 609 RB_REMOVE(pf_state_tree, &tree_lan_ext, peer); 610 611#if NPFSYNC 612 pfsync_delete_state(cur->state); 613#endif 614 if (--cur->state->rule.ptr->states <= 0) 615 pf_rm_rule(NULL, cur->state->rule.ptr); 616 if (cur->state->nat_rule.ptr != NULL) --- 60 unchanged lines hidden (view full) --- 677 if (aw->p.dyn->ifp == NULL) { 678 pool_put(&pf_addr_pl, aw->p.dyn); 679 aw->p.dyn = NULL; 680 return (1); 681 } 682 aw->p.dyn->addr = &aw->v.a.addr; 683 aw->p.dyn->af = af; 684 aw->p.dyn->undefined = 1; |
685#if !defined(__FreeBSD__) |
|
586 aw->p.dyn->hook_cookie = hook_establish( 587 aw->p.dyn->ifp->if_addrhooks, 1, 588 pf_dynaddr_update, aw->p.dyn); 589 if (aw->p.dyn->hook_cookie == NULL) { 590 pool_put(&pf_addr_pl, aw->p.dyn); 591 aw->p.dyn = NULL; 592 return (1); 593 } | 686 aw->p.dyn->hook_cookie = hook_establish( 687 aw->p.dyn->ifp->if_addrhooks, 1, 688 pf_dynaddr_update, aw->p.dyn); 689 if (aw->p.dyn->hook_cookie == NULL) { 690 pool_put(&pf_addr_pl, aw->p.dyn); 691 aw->p.dyn = NULL; 692 return (1); 693 } |
694#elif defined(__FreeBSD__) && defined(HOOK_HACK) 695 PF_UNLOCK(); 696 aw->p.dyn->hook_cookie = EVENTHANDLER_REGISTER(ifaddr_event, 697 pf_dynaddr_update_event, aw->p.dyn, EVENTHANDLER_PRI_ANY); 698 PF_LOCK(); 699 if (aw->p.dyn->hook_cookie == NULL) { 700 pool_put(&pf_addr_pl, aw->p.dyn); 701 aw->p.dyn = NULL; 702 return (1); 703 } 704#else 705 /* 706 * XXX 707 * We have no hook_establish(9)/dohooks(9) kernel interfaces. 708 * This means that we do not aware of interface address changes(add, 709 * remove, etc). User should update pf rule manually after interface 710 * address changed. This may not be possible solution if you use xDSL. 711 * ipfw/ipfw2's approach with this situation(with me keyword) is not 712 * very efficient due to analyzing interface address during runtime. 713 * Another solution is to use a user-land daemon watching address 714 * changes with socket interface. Neither one is good. 715 * Supporting hook_establish(9) requries modification of in_control() 716 * located in netinet/in.c. 717 */ 718#endif |
|
594 pf_dynaddr_update(aw->p.dyn); 595 return (0); 596} 597 | 719 pf_dynaddr_update(aw->p.dyn); 720 return (0); 721} 722 |
723#if defined(__FreeBSD__) && defined(HOOK_HACK) |
|
598void | 724void |
725pf_dynaddr_update_event(void *arg, struct ifnet *ifp) 726{ 727 PF_LOCK(); 728 pf_dynaddr_update(arg); 729 PF_UNLOCK(); 730} 731#endif 732 733void |
|
599pf_dynaddr_update(void *p) 600{ 601 struct pf_addr_dyn *ad = (struct pf_addr_dyn *)p; 602 struct ifaddr *ia; 603 int s, changed = 0; 604 605 if (ad == NULL || ad->ifp == NULL) 606 panic("pf_dynaddr_update"); --- 33 unchanged lines hidden (view full) --- 640 splx(s); 641} 642 643void 644pf_dynaddr_remove(struct pf_addr_wrap *aw) 645{ 646 if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL) 647 return; | 734pf_dynaddr_update(void *p) 735{ 736 struct pf_addr_dyn *ad = (struct pf_addr_dyn *)p; 737 struct ifaddr *ia; 738 int s, changed = 0; 739 740 if (ad == NULL || ad->ifp == NULL) 741 panic("pf_dynaddr_update"); --- 33 unchanged lines hidden (view full) --- 775 splx(s); 776} 777 778void 779pf_dynaddr_remove(struct pf_addr_wrap *aw) 780{ 781 if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL) 782 return; |
783#if !defined(__FreeBSD__) |
|
648 hook_disestablish(aw->p.dyn->ifp->if_addrhooks, 649 aw->p.dyn->hook_cookie); | 784 hook_disestablish(aw->p.dyn->ifp->if_addrhooks, 785 aw->p.dyn->hook_cookie); |
786#elif defined(__FreeBSD__) && defined(HOOK_HACK) 787 PF_UNLOCK(); 788 EVENTHANDLER_DEREGISTER(ifaddr_event, aw->p.dyn->hook_cookie); 789 PF_LOCK(); 790#else 791 /* 792 * XXX 793 * We have no hook_establish(9)/dohooks(9) kernel interfaces. 794 * See comments above function, pf_dynaddr_setup(). 795 */ 796#endif |
|
650 pool_put(&pf_addr_pl, aw->p.dyn); 651 aw->p.dyn = NULL; 652} 653 654void 655pf_dynaddr_copyout(struct pf_addr_wrap *aw) 656{ 657 if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL) --- 438 unchanged lines hidden (view full) --- 1096 int len, tlen; 1097#ifdef INET 1098 struct ip *h; 1099#endif /* INET */ 1100#ifdef INET6 1101 struct ip6_hdr *h6; 1102#endif /* INET6 */ 1103 struct tcphdr *th; | 797 pool_put(&pf_addr_pl, aw->p.dyn); 798 aw->p.dyn = NULL; 799} 800 801void 802pf_dynaddr_copyout(struct pf_addr_wrap *aw) 803{ 804 if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL) --- 438 unchanged lines hidden (view full) --- 1243 int len, tlen; 1244#ifdef INET 1245 struct ip *h; 1246#endif /* INET */ 1247#ifdef INET6 1248 struct ip6_hdr *h6; 1249#endif /* INET6 */ 1250 struct tcphdr *th; |
1251#if defined(__FreeBSD__) 1252 struct ip *ip; 1253#if (__FreeBSD_version < 501114) 1254 struct route ro; 1255#endif 1256#endif |
|
1104 char *opt; 1105 1106 /* maximum segment size tcp option */ 1107 tlen = sizeof(struct tcphdr); 1108 if (mss) 1109 tlen += 4; 1110 1111 switch (af) { --- 89 unchanged lines hidden (view full) --- 1201 case AF_INET: 1202 /* TCP checksum */ 1203 th->th_sum = in_cksum(m, len); 1204 1205 /* Finish the IP header */ 1206 h->ip_v = 4; 1207 h->ip_hl = sizeof(*h) >> 2; 1208 h->ip_tos = IPTOS_LOWDELAY; | 1257 char *opt; 1258 1259 /* maximum segment size tcp option */ 1260 tlen = sizeof(struct tcphdr); 1261 if (mss) 1262 tlen += 4; 1263 1264 switch (af) { --- 89 unchanged lines hidden (view full) --- 1354 case AF_INET: 1355 /* TCP checksum */ 1356 th->th_sum = in_cksum(m, len); 1357 1358 /* Finish the IP header */ 1359 h->ip_v = 4; 1360 h->ip_hl = sizeof(*h) >> 2; 1361 h->ip_tos = IPTOS_LOWDELAY; |
1209 h->ip_len = htons(len); | 1362#if defined(__FreeBSD__) 1363 h->ip_off = htons(path_mtu_discovery ? IP_DF : 0); 1364#else |
1210 h->ip_off = htons(ip_mtudisc ? IP_DF : 0); | 1365 h->ip_off = htons(ip_mtudisc ? IP_DF : 0); |
1366#endif 1367 h->ip_len = htons(len); |
|
1211 h->ip_ttl = ttl ? ttl : ip_defttl; 1212 h->ip_sum = 0; | 1368 h->ip_ttl = ttl ? ttl : ip_defttl; 1369 h->ip_sum = 0; |
1370#if defined(__FreeBSD__) 1371 ip = mtod(m, struct ip *); 1372 /* 1373 * XXX 1374 * OpenBSD changed ip_len/ip_off byte ordering! 1375 * Because FreeBSD assumes host byte ordering we need to 1376 * change here. 1377 */ 1378 NTOHS(ip->ip_len); 1379 NTOHS(ip->ip_off); 1380#if (__FreeBSD_version < 501114) 1381 bzero(&ro, sizeof(ro)); 1382 ip_rtaddr(ip->ip_dst, &ro); 1383 PF_UNLOCK(); 1384 ip_output(m, (void *)NULL, &ro, 0, (void *)NULL, 1385 (void *)NULL); 1386 PF_LOCK(); 1387 if(ro.ro_rt) { 1388 RTFREE(ro.ro_rt); 1389 } 1390#else /* __FreeBSD_version >= 501114 */ 1391 PF_UNLOCK(); |
|
1213 ip_output(m, (void *)NULL, (void *)NULL, 0, (void *)NULL, | 1392 ip_output(m, (void *)NULL, (void *)NULL, 0, (void *)NULL, |
1393 (void *)NULL); 1394 PF_LOCK(); 1395#endif 1396#else /* ! __FreeBSD__ */ 1397 ip_output(m, (void *)NULL, (void *)NULL, 0, (void *)NULL, |
|
1214 (void *)NULL); | 1398 (void *)NULL); |
1399#endif |
|
1215 break; 1216#endif /* INET */ 1217#ifdef INET6 1218 case AF_INET6: 1219 /* TCP checksum */ 1220 th->th_sum = in6_cksum(m, IPPROTO_TCP, 1221 sizeof(struct ip6_hdr), tlen); 1222 1223 h6->ip6_vfc |= IPV6_VERSION; 1224 h6->ip6_hlim = IPV6_DEFHLIM; 1225 | 1400 break; 1401#endif /* INET */ 1402#ifdef INET6 1403 case AF_INET6: 1404 /* TCP checksum */ 1405 th->th_sum = in6_cksum(m, IPPROTO_TCP, 1406 sizeof(struct ip6_hdr), tlen); 1407 1408 h6->ip6_vfc |= IPV6_VERSION; 1409 h6->ip6_hlim = IPV6_DEFHLIM; 1410 |
1411#if defined(__FreeBSD__) 1412 PF_UNLOCK(); 1413 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); 1414 PF_LOCK(); 1415#else |
|
1226 ip6_output(m, NULL, NULL, 0, NULL, NULL); | 1416 ip6_output(m, NULL, NULL, 0, NULL, NULL); |
1417#endif |
|
1227 break; 1228#endif /* INET6 */ 1229 } 1230} 1231 1232void 1233pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, 1234 struct pf_rule *r) 1235{ 1236 struct m_tag *mtag; 1237 struct mbuf *m0; | 1418 break; 1419#endif /* INET6 */ 1420 } 1421} 1422 1423void 1424pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, 1425 struct pf_rule *r) 1426{ 1427 struct m_tag *mtag; 1428 struct mbuf *m0; |
1429#if defined(__FreeBSD__) 1430 struct ip *ip; 1431#endif |
|
1238 1239 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 1240 if (mtag == NULL) 1241 return; | 1432 1433 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 1434 if (mtag == NULL) 1435 return; |
1436#if defined(__FreeBSD__) 1437 m0 = m_copypacket(m, M_DONTWAIT); 1438#else |
|
1242 m0 = m_copy(m, 0, M_COPYALL); | 1439 m0 = m_copy(m, 0, M_COPYALL); |
1440#endif |
|
1243 if (m0 == NULL) { 1244 m_tag_free(mtag); 1245 return; 1246 } 1247 m_tag_prepend(m0, mtag); 1248 1249#ifdef ALTQ 1250 if (r->qid) { --- 9 unchanged lines hidden (view full) --- 1260 m_tag_prepend(m0, mtag); 1261 } 1262 } 1263#endif 1264 1265 switch (af) { 1266#ifdef INET 1267 case AF_INET: | 1441 if (m0 == NULL) { 1442 m_tag_free(mtag); 1443 return; 1444 } 1445 m_tag_prepend(m0, mtag); 1446 1447#ifdef ALTQ 1448 if (r->qid) { --- 9 unchanged lines hidden (view full) --- 1458 m_tag_prepend(m0, mtag); 1459 } 1460 } 1461#endif 1462 1463 switch (af) { 1464#ifdef INET 1465 case AF_INET: |
1268 icmp_error(m0, type, code, 0, 0); | 1466#if defined(__FreeBSD__) 1467 /* icmp_error() expects host byte ordering */ 1468 ip = mtod(m0, struct ip *); 1469 NTOHS(ip->ip_len); 1470 NTOHS(ip->ip_off); 1471 PF_UNLOCK(); 1472#endif 1473 icmp_error(m0, type, code, 0, NULL); 1474#if defined(__FreeBSD__) 1475 PF_LOCK(); 1476#endif |
1269 break; 1270#endif /* INET */ 1271#ifdef INET6 1272 case AF_INET6: | 1477 break; 1478#endif /* INET */ 1479#ifdef INET6 1480 case AF_INET6: |
1481#if defined(__FreeBSD__) 1482 PF_UNLOCK(); 1483#endif |
|
1273 icmp6_error(m0, type, code, 0); | 1484 icmp6_error(m0, type, code, 0); |
1485#if defined(__FreeBSD__) 1486 PF_LOCK(); 1487#endif |
|
1274 break; 1275#endif /* INET6 */ 1276 } 1277} 1278 1279/* 1280 * Return 1 if the addresses a and b match (with mask m), otherwise return 0. 1281 * If n is 0, they match if they are equal. If n is != 0, they match if they --- 610 unchanged lines hidden (view full) --- 1892 break; 1893 case PF_IN: 1894 if (r->src.addr.type == PF_ADDR_DYNIFTL && 1895 r->src.addr.p.dyn->undefined) 1896 return (NULL); 1897 else 1898 PF_POOLMASK(naddr, 1899 &r->src.addr.v.a.addr, | 1488 break; 1489#endif /* INET6 */ 1490 } 1491} 1492 1493/* 1494 * Return 1 if the addresses a and b match (with mask m), otherwise return 0. 1495 * If n is 0, they match if they are equal. If n is != 0, they match if they --- 610 unchanged lines hidden (view full) --- 2106 break; 2107 case PF_IN: 2108 if (r->src.addr.type == PF_ADDR_DYNIFTL && 2109 r->src.addr.p.dyn->undefined) 2110 return (NULL); 2111 else 2112 PF_POOLMASK(naddr, 2113 &r->src.addr.v.a.addr, |
1900 &r->src.addr.v.a.mask, saddr, | 2114 &r->src.addr.v.a.mask, daddr, |
1901 pd->af); 1902 break; 1903 } 1904 break; 1905 case PF_RDR: { 1906 if (pf_map_addr(r->af, &r->rpool, saddr, naddr, NULL)) 1907 return (NULL); 1908 --- 24 unchanged lines hidden (view full) --- 1933} 1934 1935int 1936pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, sa_family_t af, 1937 int proto, struct pf_pdesc *pd) 1938{ 1939 struct pf_addr *saddr, *daddr; 1940 u_int16_t sport, dport; | 2115 pd->af); 2116 break; 2117 } 2118 break; 2119 case PF_RDR: { 2120 if (pf_map_addr(r->af, &r->rpool, saddr, naddr, NULL)) 2121 return (NULL); 2122 --- 24 unchanged lines hidden (view full) --- 2147} 2148 2149int 2150pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, sa_family_t af, 2151 int proto, struct pf_pdesc *pd) 2152{ 2153 struct pf_addr *saddr, *daddr; 2154 u_int16_t sport, dport; |
2155#if defined(__FreeBSD__) 2156 struct inpcbinfo *pi; 2157#else |
|
1941 struct inpcbtable *tb; | 2158 struct inpcbtable *tb; |
2159#endif |
|
1942 struct inpcb *inp; 1943 1944 *uid = UID_MAX; 1945 *gid = GID_MAX; 1946 switch (proto) { 1947 case IPPROTO_TCP: 1948 sport = pd->hdr.tcp->th_sport; 1949 dport = pd->hdr.tcp->th_dport; | 2160 struct inpcb *inp; 2161 2162 *uid = UID_MAX; 2163 *gid = GID_MAX; 2164 switch (proto) { 2165 case IPPROTO_TCP: 2166 sport = pd->hdr.tcp->th_sport; 2167 dport = pd->hdr.tcp->th_dport; |
2168#if defined(__FreeBSD__) 2169 pi = &tcbinfo; 2170#else |
|
1950 tb = &tcbtable; | 2171 tb = &tcbtable; |
2172#endif |
|
1951 break; 1952 case IPPROTO_UDP: 1953 sport = pd->hdr.udp->uh_sport; 1954 dport = pd->hdr.udp->uh_dport; | 2173 break; 2174 case IPPROTO_UDP: 2175 sport = pd->hdr.udp->uh_sport; 2176 dport = pd->hdr.udp->uh_dport; |
2177#if defined(__FreeBSD__) 2178 pi = &udbinfo; 2179#else |
|
1955 tb = &udbtable; | 2180 tb = &udbtable; |
2181#endif |
|
1956 break; 1957 default: 1958 return (0); 1959 } 1960 if (direction == PF_IN) { 1961 saddr = pd->src; 1962 daddr = pd->dst; 1963 } else { 1964 u_int16_t p; 1965 1966 p = sport; 1967 sport = dport; 1968 dport = p; 1969 saddr = pd->dst; 1970 daddr = pd->src; 1971 } 1972 switch(af) { 1973 case AF_INET: | 2182 break; 2183 default: 2184 return (0); 2185 } 2186 if (direction == PF_IN) { 2187 saddr = pd->src; 2188 daddr = pd->dst; 2189 } else { 2190 u_int16_t p; 2191 2192 p = sport; 2193 sport = dport; 2194 dport = p; 2195 saddr = pd->dst; 2196 daddr = pd->src; 2197 } 2198 switch(af) { 2199 case AF_INET: |
2200#if defined(__FreeBSD__) 2201#if (__FreeBSD_version >= 500043) 2202 INP_INFO_RLOCK(pi); /* XXX LOR */ 2203#endif 2204 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4, 2205 dport, 0, NULL); 2206 if (inp == NULL) { 2207 inp = in_pcblookup_hash(pi, saddr->v4, sport, 2208 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL); 2209 if(inp == NULL) { 2210#if (__FreeBSD_version >= 500043) 2211 INP_INFO_RUNLOCK(pi); 2212#endif 2213 return (0); 2214 } 2215 } 2216#else |
|
1974 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); 1975 if (inp == NULL) { 1976 inp = in_pcblookup(tb, &saddr->v4, sport, &daddr->v4, 1977 dport, INPLOOKUP_WILDCARD); 1978 if (inp == NULL) 1979 return (0); 1980 } | 2217 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); 2218 if (inp == NULL) { 2219 inp = in_pcblookup(tb, &saddr->v4, sport, &daddr->v4, 2220 dport, INPLOOKUP_WILDCARD); 2221 if (inp == NULL) 2222 return (0); 2223 } |
2224#endif |
|
1981 break; 1982#ifdef INET6 1983 case AF_INET6: | 2225 break; 2226#ifdef INET6 2227 case AF_INET6: |
2228#if defined(__FreeBSD__) 2229#if (__FreeBSD_version >= 500043) 2230 INP_INFO_RLOCK(pi); 2231#endif 2232 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 2233 &daddr->v6, dport, 0, NULL); 2234 if (inp == NULL) { 2235 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 2236 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL); 2237 if (inp == NULL) { 2238#if (__FreeBSD_version >= 500043) 2239 INP_INFO_RUNLOCK(pi); 2240#endif 2241 return (0); 2242 } 2243 } 2244#else |
|
1984 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, 1985 dport); 1986 if (inp == NULL) { 1987 inp = in_pcblookup(tb, &saddr->v6, sport, &daddr->v6, 1988 dport, INPLOOKUP_WILDCARD | INPLOOKUP_IPV6); 1989 if (inp == NULL) 1990 return (0); 1991 } | 2245 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, 2246 dport); 2247 if (inp == NULL) { 2248 inp = in_pcblookup(tb, &saddr->v6, sport, &daddr->v6, 2249 dport, INPLOOKUP_WILDCARD | INPLOOKUP_IPV6); 2250 if (inp == NULL) 2251 return (0); 2252 } |
2253#endif |
|
1992 break; 1993#endif /* INET6 */ 1994 1995 default: 1996 return (0); 1997 } | 2254 break; 2255#endif /* INET6 */ 2256 2257 default: 2258 return (0); 2259 } |
2260#if defined(__FreeBSD__) 2261#if (__FreeBSD_version >= 500043) 2262 INP_LOCK(inp); 2263#endif 2264 *uid = inp->inp_socket->so_cred->cr_uid; 2265 *gid = inp->inp_socket->so_cred->cr_groups[0]; 2266#if (__FreeBSD_version >= 500043) 2267 INP_UNLOCK(inp); 2268 INP_INFO_RUNLOCK(pi); 2269#endif 2270#else |
|
1998 *uid = inp->inp_socket->so_euid; 1999 *gid = inp->inp_socket->so_egid; | 2271 *uid = inp->inp_socket->so_euid; 2272 *gid = inp->inp_socket->so_egid; |
2273#endif |
|
2000 return (1); 2001} 2002 2003u_int8_t 2004pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 2005{ 2006 int hlen; 2007 u_int8_t hdr[60]; --- 86 unchanged lines hidden (view full) --- 2094#ifdef INET 2095 case AF_INET: 2096 hlen = sizeof(struct ip); 2097 bzero(&ro, sizeof(ro)); 2098 dst = (struct sockaddr_in *)&ro.ro_dst; 2099 dst->sin_family = AF_INET; 2100 dst->sin_len = sizeof(*dst); 2101 dst->sin_addr = addr->v4; | 2274 return (1); 2275} 2276 2277u_int8_t 2278pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 2279{ 2280 int hlen; 2281 u_int8_t hdr[60]; --- 86 unchanged lines hidden (view full) --- 2368#ifdef INET 2369 case AF_INET: 2370 hlen = sizeof(struct ip); 2371 bzero(&ro, sizeof(ro)); 2372 dst = (struct sockaddr_in *)&ro.ro_dst; 2373 dst->sin_family = AF_INET; 2374 dst->sin_len = sizeof(*dst); 2375 dst->sin_addr = addr->v4; |
2376#if defined(__FreeBSD__) 2377#ifdef RTF_PRCLONING 2378 rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING)); 2379#else /* !RTF_PRCLONING */ 2380 rtalloc_ign(&ro, RTF_CLONING); 2381#endif 2382#else /* ! __FreeBSD__ */ |
|
2102 rtalloc_noclone(&ro, NO_CLONING); | 2383 rtalloc_noclone(&ro, NO_CLONING); |
2384#endif |
|
2103 rt = ro.ro_rt; 2104 break; 2105#endif /* INET */ 2106#ifdef INET6 2107 case AF_INET6: 2108 hlen = sizeof(struct ip6_hdr); 2109 bzero(&ro6, sizeof(ro6)); 2110 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst; 2111 dst6->sin6_family = AF_INET6; 2112 dst6->sin6_len = sizeof(*dst6); 2113 dst6->sin6_addr = addr->v6; | 2385 rt = ro.ro_rt; 2386 break; 2387#endif /* INET */ 2388#ifdef INET6 2389 case AF_INET6: 2390 hlen = sizeof(struct ip6_hdr); 2391 bzero(&ro6, sizeof(ro6)); 2392 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst; 2393 dst6->sin6_family = AF_INET6; 2394 dst6->sin6_len = sizeof(*dst6); 2395 dst6->sin6_addr = addr->v6; |
2396#if defined(__FreeBSD__) 2397#ifdef RTF_PRCLONING 2398 rtalloc_ign((struct route *)&ro6, 2399 (RTF_CLONING | RTF_PRCLONING)); 2400#else /* !RTF_PRCLONING */ 2401 rtalloc_ign((struct route *)&ro6, RTF_CLONING); 2402#endif 2403#else /* ! __FreeBSD__ */ |
|
2114 rtalloc_noclone((struct route *)&ro6, NO_CLONING); | 2404 rtalloc_noclone((struct route *)&ro6, NO_CLONING); |
2405#endif |
|
2115 rt = ro6.ro_rt; 2116 break; 2117#endif /* INET6 */ 2118 } 2119 2120 if (rt && rt->rt_ifp) { 2121 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr); 2122 mss = max(tcp_mssdflt, mss); --- 156 unchanged lines hidden (view full) --- 2279 if (a != NULL) { 2280 a->packets++; 2281 a->bytes += pd->tot_len; 2282 } 2283 REASON_SET(&reason, PFRES_MATCH); 2284 2285 if (r->log) { 2286 if (rewrite) | 2406 rt = ro6.ro_rt; 2407 break; 2408#endif /* INET6 */ 2409 } 2410 2411 if (rt && rt->rt_ifp) { 2412 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr); 2413 mss = max(tcp_mssdflt, mss); --- 156 unchanged lines hidden (view full) --- 2570 if (a != NULL) { 2571 a->packets++; 2572 a->bytes += pd->tot_len; 2573 } 2574 REASON_SET(&reason, PFRES_MATCH); 2575 2576 if (r->log) { 2577 if (rewrite) |
2287 m_copyback(m, off, sizeof(*th), th); | 2578 m_copyback(m, off, sizeof(*th), (caddr_t)th); |
2288 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); 2289 } 2290 2291 if ((r->action == PF_DROP) && 2292 ((r->rule_flag & PFRULE_RETURNRST) || 2293 (r->rule_flag & PFRULE_RETURNICMP) || 2294 (r->rule_flag & PFRULE_RETURN))) { 2295 /* undo NAT changes, if they have taken place */ --- 116 unchanged lines hidden (view full) --- 2412 (s->src.wscale & PF_WSCALE_MASK); 2413 } 2414 if (th->th_flags & TH_FIN) 2415 s->src.seqhi++; 2416 s->dst.seqhi = 1; 2417 s->dst.max_win = 1; 2418 s->src.state = TCPS_SYN_SENT; 2419 s->dst.state = TCPS_CLOSED; | 2579 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); 2580 } 2581 2582 if ((r->action == PF_DROP) && 2583 ((r->rule_flag & PFRULE_RETURNRST) || 2584 (r->rule_flag & PFRULE_RETURNICMP) || 2585 (r->rule_flag & PFRULE_RETURN))) { 2586 /* undo NAT changes, if they have taken place */ --- 116 unchanged lines hidden (view full) --- 2703 (s->src.wscale & PF_WSCALE_MASK); 2704 } 2705 if (th->th_flags & TH_FIN) 2706 s->src.seqhi++; 2707 s->dst.seqhi = 1; 2708 s->dst.max_win = 1; 2709 s->src.state = TCPS_SYN_SENT; 2710 s->dst.state = TCPS_CLOSED; |
2711#if defined(__FreeBSD__) 2712 s->creation = time_second; 2713 s->expire = time_second; 2714#else |
|
2420 s->creation = time.tv_sec; 2421 s->expire = time.tv_sec; | 2715 s->creation = time.tv_sec; 2716 s->expire = time.tv_sec; |
2717#endif |
|
2422 s->timeout = PFTM_TCP_FIRST_PACKET; 2423 s->packets[0] = 1; 2424 s->bytes[0] = pd->tot_len; 2425 pf_set_rt_ifp(s, saddr); 2426 2427 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m, 2428 off, pd, th, &s->src, &s->dst)) { 2429 REASON_SET(&reason, PFRES_MEMORY); --- 35 unchanged lines hidden (view full) --- 2465 th->th_sport, s->src.seqhi, 2466 ntohl(th->th_seq) + 1, TH_SYN|TH_ACK, 0, s->src.mss, 0); 2467 return (PF_SYNPROXY_DROP); 2468 } 2469 } 2470 2471 /* copy back packet headers if we performed NAT operations */ 2472 if (rewrite) | 2718 s->timeout = PFTM_TCP_FIRST_PACKET; 2719 s->packets[0] = 1; 2720 s->bytes[0] = pd->tot_len; 2721 pf_set_rt_ifp(s, saddr); 2722 2723 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m, 2724 off, pd, th, &s->src, &s->dst)) { 2725 REASON_SET(&reason, PFRES_MEMORY); --- 35 unchanged lines hidden (view full) --- 2761 th->th_sport, s->src.seqhi, 2762 ntohl(th->th_seq) + 1, TH_SYN|TH_ACK, 0, s->src.mss, 0); 2763 return (PF_SYNPROXY_DROP); 2764 } 2765 } 2766 2767 /* copy back packet headers if we performed NAT operations */ 2768 if (rewrite) |
2473 m_copyback(m, off, sizeof(*th), th); | 2769 m_copyback(m, off, sizeof(*th), (caddr_t)th); |
2474 2475 return (PF_PASS); 2476} 2477 2478int 2479pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction, 2480 struct ifnet *ifp, struct mbuf *m, int ipoff, int off, void *h, 2481 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) --- 115 unchanged lines hidden (view full) --- 2597 if (a != NULL) { 2598 a->packets++; 2599 a->bytes += pd->tot_len; 2600 } 2601 REASON_SET(&reason, PFRES_MATCH); 2602 2603 if (r->log) { 2604 if (rewrite) | 2770 2771 return (PF_PASS); 2772} 2773 2774int 2775pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction, 2776 struct ifnet *ifp, struct mbuf *m, int ipoff, int off, void *h, 2777 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) --- 115 unchanged lines hidden (view full) --- 2893 if (a != NULL) { 2894 a->packets++; 2895 a->bytes += pd->tot_len; 2896 } 2897 REASON_SET(&reason, PFRES_MATCH); 2898 2899 if (r->log) { 2900 if (rewrite) |
2605 m_copyback(m, off, sizeof(*uh), uh); | 2901 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); |
2606 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); 2607 } 2608 2609 if ((r->action == PF_DROP) && 2610 ((r->rule_flag & PFRULE_RETURNICMP) || 2611 (r->rule_flag & PFRULE_RETURN))) { 2612 /* undo NAT changes, if they have taken place */ 2613 if (nat != NULL) { --- 70 unchanged lines hidden (view full) --- 2684 s->gwy.port = bport; 2685 } else { 2686 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 2687 s->gwy.port = s->lan.port; 2688 } 2689 } 2690 s->src.state = PFUDPS_SINGLE; 2691 s->dst.state = PFUDPS_NO_TRAFFIC; | 2902 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); 2903 } 2904 2905 if ((r->action == PF_DROP) && 2906 ((r->rule_flag & PFRULE_RETURNICMP) || 2907 (r->rule_flag & PFRULE_RETURN))) { 2908 /* undo NAT changes, if they have taken place */ 2909 if (nat != NULL) { --- 70 unchanged lines hidden (view full) --- 2980 s->gwy.port = bport; 2981 } else { 2982 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 2983 s->gwy.port = s->lan.port; 2984 } 2985 } 2986 s->src.state = PFUDPS_SINGLE; 2987 s->dst.state = PFUDPS_NO_TRAFFIC; |
2988#if defined(__FreeBSD__) 2989 s->creation = time_second; 2990 s->expire = time_second; 2991#else |
|
2692 s->creation = time.tv_sec; 2693 s->expire = time.tv_sec; | 2992 s->creation = time.tv_sec; 2993 s->expire = time.tv_sec; |
2994#endif |
|
2694 s->timeout = PFTM_UDP_FIRST_PACKET; 2695 s->packets[0] = 1; 2696 s->bytes[0] = pd->tot_len; 2697 pf_set_rt_ifp(s, saddr); 2698 if (pf_insert_state(s)) { 2699 REASON_SET(&reason, PFRES_MEMORY); 2700 pool_put(&pf_state_pl, s); 2701 return (PF_DROP); 2702 } else 2703 *sm = s; 2704 } 2705 2706 /* copy back packet headers if we performed NAT operations */ 2707 if (rewrite) | 2995 s->timeout = PFTM_UDP_FIRST_PACKET; 2996 s->packets[0] = 1; 2997 s->bytes[0] = pd->tot_len; 2998 pf_set_rt_ifp(s, saddr); 2999 if (pf_insert_state(s)) { 3000 REASON_SET(&reason, PFRES_MEMORY); 3001 pool_put(&pf_state_pl, s); 3002 return (PF_DROP); 3003 } else 3004 *sm = s; 3005 } 3006 3007 /* copy back packet headers if we performed NAT operations */ 3008 if (rewrite) |
2708 m_copyback(m, off, sizeof(*uh), uh); | 3009 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); |
2709 2710 return (PF_PASS); 2711} 2712 2713int 2714pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction, 2715 struct ifnet *ifp, struct mbuf *m, int ipoff, int off, void *h, 2716 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) --- 153 unchanged lines hidden (view full) --- 2870 a->bytes += pd->tot_len; 2871 } 2872 REASON_SET(&reason, PFRES_MATCH); 2873 2874 if (r->log) { 2875#ifdef INET6 2876 if (rewrite) 2877 m_copyback(m, off, sizeof(struct icmp6_hdr), | 3010 3011 return (PF_PASS); 3012} 3013 3014int 3015pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction, 3016 struct ifnet *ifp, struct mbuf *m, int ipoff, int off, void *h, 3017 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) --- 153 unchanged lines hidden (view full) --- 3171 a->bytes += pd->tot_len; 3172 } 3173 REASON_SET(&reason, PFRES_MATCH); 3174 3175 if (r->log) { 3176#ifdef INET6 3177 if (rewrite) 3178 m_copyback(m, off, sizeof(struct icmp6_hdr), |
2878 pd->hdr.icmp6); | 3179 (caddr_t)pd->hdr.icmp6); |
2879#endif /* INET6 */ 2880 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); 2881 } 2882 2883 if (r->action != PF_PASS) 2884 return (PF_DROP); 2885 2886 if (pf_tag_packet(m, pftag, tag)) { --- 45 unchanged lines hidden (view full) --- 2932 PF_ACPY(&s->ext.addr, saddr, af); 2933 s->ext.port = icmpid; 2934 if (rdr != NULL) 2935 PF_ACPY(&s->gwy.addr, &baddr, af); 2936 else 2937 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 2938 s->gwy.port = icmpid; 2939 } | 3180#endif /* INET6 */ 3181 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); 3182 } 3183 3184 if (r->action != PF_PASS) 3185 return (PF_DROP); 3186 3187 if (pf_tag_packet(m, pftag, tag)) { --- 45 unchanged lines hidden (view full) --- 3233 PF_ACPY(&s->ext.addr, saddr, af); 3234 s->ext.port = icmpid; 3235 if (rdr != NULL) 3236 PF_ACPY(&s->gwy.addr, &baddr, af); 3237 else 3238 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3239 s->gwy.port = icmpid; 3240 } |
3241 3242#if defined(__FreeBSD__) 3243 s->creation = time_second; 3244 s->expire = time_second; 3245#else |
|
2940 s->creation = time.tv_sec; 2941 s->expire = time.tv_sec; | 3246 s->creation = time.tv_sec; 3247 s->expire = time.tv_sec; |
3248#endif |
|
2942 s->timeout = PFTM_ICMP_FIRST_PACKET; 2943 s->packets[0] = 1; 2944 s->bytes[0] = pd->tot_len; 2945 pf_set_rt_ifp(s, saddr); 2946 if (pf_insert_state(s)) { 2947 REASON_SET(&reason, PFRES_MEMORY); 2948 pool_put(&pf_state_pl, s); 2949 return (PF_DROP); 2950 } else 2951 *sm = s; 2952 } 2953 2954#ifdef INET6 2955 /* copy back packet headers if we performed IPv6 NAT operations */ 2956 if (rewrite) 2957 m_copyback(m, off, sizeof(struct icmp6_hdr), | 3249 s->timeout = PFTM_ICMP_FIRST_PACKET; 3250 s->packets[0] = 1; 3251 s->bytes[0] = pd->tot_len; 3252 pf_set_rt_ifp(s, saddr); 3253 if (pf_insert_state(s)) { 3254 REASON_SET(&reason, PFRES_MEMORY); 3255 pool_put(&pf_state_pl, s); 3256 return (PF_DROP); 3257 } else 3258 *sm = s; 3259 } 3260 3261#ifdef INET6 3262 /* copy back packet headers if we performed IPv6 NAT operations */ 3263 if (rewrite) 3264 m_copyback(m, off, sizeof(struct icmp6_hdr), |
2958 pd->hdr.icmp6); | 3265 (caddr_t)pd->hdr.icmp6); |
2959#endif /* INET6 */ 2960 2961 return (PF_PASS); 2962} 2963 2964int 2965pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction, 2966 struct ifnet *ifp, struct mbuf *m, int off, void *h, struct pf_pdesc *pd, --- 192 unchanged lines hidden (view full) --- 3159 PF_ACPY(&s->ext.addr, saddr, af); 3160 if (rdr != NULL) 3161 PF_ACPY(&s->gwy.addr, &baddr, af); 3162 else 3163 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3164 } 3165 s->src.state = PFOTHERS_SINGLE; 3166 s->dst.state = PFOTHERS_NO_TRAFFIC; | 3266#endif /* INET6 */ 3267 3268 return (PF_PASS); 3269} 3270 3271int 3272pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction, 3273 struct ifnet *ifp, struct mbuf *m, int off, void *h, struct pf_pdesc *pd, --- 192 unchanged lines hidden (view full) --- 3466 PF_ACPY(&s->ext.addr, saddr, af); 3467 if (rdr != NULL) 3468 PF_ACPY(&s->gwy.addr, &baddr, af); 3469 else 3470 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3471 } 3472 s->src.state = PFOTHERS_SINGLE; 3473 s->dst.state = PFOTHERS_NO_TRAFFIC; |
3474#if defined(__FreeBSD__) 3475 s->creation = time_second; 3476 s->expire = time_second; 3477#else |
|
3167 s->creation = time.tv_sec; 3168 s->expire = time.tv_sec; | 3478 s->creation = time.tv_sec; 3479 s->expire = time.tv_sec; |
3480#endif |
|
3169 s->timeout = PFTM_OTHER_FIRST_PACKET; 3170 s->packets[0] = 1; 3171 s->bytes[0] = pd->tot_len; 3172 pf_set_rt_ifp(s, saddr); 3173 if (pf_insert_state(s)) { 3174 REASON_SET(&reason, PFRES_MEMORY); 3175 if (r->log) 3176 PFLOG_PACKET(ifp, h, m, af, direction, reason, --- 341 unchanged lines hidden (view full) --- 3518 dst->state = TCPS_ESTABLISHED; 3519 else if (dst->state == TCPS_CLOSING) 3520 dst->state = TCPS_FIN_WAIT_2; 3521 } 3522 if (th->th_flags & TH_RST) 3523 src->state = dst->state = TCPS_TIME_WAIT; 3524 3525 /* update expire time */ | 3481 s->timeout = PFTM_OTHER_FIRST_PACKET; 3482 s->packets[0] = 1; 3483 s->bytes[0] = pd->tot_len; 3484 pf_set_rt_ifp(s, saddr); 3485 if (pf_insert_state(s)) { 3486 REASON_SET(&reason, PFRES_MEMORY); 3487 if (r->log) 3488 PFLOG_PACKET(ifp, h, m, af, direction, reason, --- 341 unchanged lines hidden (view full) --- 3830 dst->state = TCPS_ESTABLISHED; 3831 else if (dst->state == TCPS_CLOSING) 3832 dst->state = TCPS_FIN_WAIT_2; 3833 } 3834 if (th->th_flags & TH_RST) 3835 src->state = dst->state = TCPS_TIME_WAIT; 3836 3837 /* update expire time */ |
3838#if defined(__FreeBSD__) 3839 (*state)->expire = time_second; 3840#else |
|
3526 (*state)->expire = time.tv_sec; | 3841 (*state)->expire = time.tv_sec; |
3842#endif |
|
3527 if (src->state >= TCPS_FIN_WAIT_2 && 3528 dst->state >= TCPS_FIN_WAIT_2) 3529 (*state)->timeout = PFTM_TCP_CLOSED; 3530 else if (src->state >= TCPS_FIN_WAIT_2 || 3531 dst->state >= TCPS_FIN_WAIT_2) 3532 (*state)->timeout = PFTM_TCP_FIN_WAIT; 3533 else if (src->state < TCPS_ESTABLISHED || 3534 dst->state < TCPS_ESTABLISHED) --- 124 unchanged lines hidden (view full) --- 3659 if (direction == PF_OUT) 3660 pf_change_ap(pd->src, &th->th_sport, pd->ip_sum, 3661 &th->th_sum, &(*state)->gwy.addr, 3662 (*state)->gwy.port, 0, pd->af); 3663 else 3664 pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, 3665 &th->th_sum, &(*state)->lan.addr, 3666 (*state)->lan.port, 0, pd->af); | 3843 if (src->state >= TCPS_FIN_WAIT_2 && 3844 dst->state >= TCPS_FIN_WAIT_2) 3845 (*state)->timeout = PFTM_TCP_CLOSED; 3846 else if (src->state >= TCPS_FIN_WAIT_2 || 3847 dst->state >= TCPS_FIN_WAIT_2) 3848 (*state)->timeout = PFTM_TCP_FIN_WAIT; 3849 else if (src->state < TCPS_ESTABLISHED || 3850 dst->state < TCPS_ESTABLISHED) --- 124 unchanged lines hidden (view full) --- 3975 if (direction == PF_OUT) 3976 pf_change_ap(pd->src, &th->th_sport, pd->ip_sum, 3977 &th->th_sum, &(*state)->gwy.addr, 3978 (*state)->gwy.port, 0, pd->af); 3979 else 3980 pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, 3981 &th->th_sum, &(*state)->lan.addr, 3982 (*state)->lan.port, 0, pd->af); |
3667 m_copyback(m, off, sizeof(*th), th); | 3983 m_copyback(m, off, sizeof(*th), (caddr_t)th); |
3668 } else if (copyback) { 3669 /* Copyback sequence modulation or stateful scrub changes */ | 3984 } else if (copyback) { 3985 /* Copyback sequence modulation or stateful scrub changes */ |
3670 m_copyback(m, off, sizeof(*th), th); | 3986 m_copyback(m, off, sizeof(*th), (caddr_t)th); |
3671 } 3672 3673 (*state)->rule.ptr->packets++; 3674 (*state)->rule.ptr->bytes += pd->tot_len; 3675 if ((*state)->nat_rule.ptr != NULL) { 3676 (*state)->nat_rule.ptr->packets++; 3677 (*state)->nat_rule.ptr->bytes += pd->tot_len; 3678 } --- 37 unchanged lines hidden (view full) --- 3716 3717 /* update states */ 3718 if (src->state < PFUDPS_SINGLE) 3719 src->state = PFUDPS_SINGLE; 3720 if (dst->state == PFUDPS_SINGLE) 3721 dst->state = PFUDPS_MULTIPLE; 3722 3723 /* update expire time */ | 3987 } 3988 3989 (*state)->rule.ptr->packets++; 3990 (*state)->rule.ptr->bytes += pd->tot_len; 3991 if ((*state)->nat_rule.ptr != NULL) { 3992 (*state)->nat_rule.ptr->packets++; 3993 (*state)->nat_rule.ptr->bytes += pd->tot_len; 3994 } --- 37 unchanged lines hidden (view full) --- 4032 4033 /* update states */ 4034 if (src->state < PFUDPS_SINGLE) 4035 src->state = PFUDPS_SINGLE; 4036 if (dst->state == PFUDPS_SINGLE) 4037 dst->state = PFUDPS_MULTIPLE; 4038 4039 /* update expire time */ |
4040#if defined(__FreeBSD__) 4041 (*state)->expire = time_second; 4042#else |
|
3724 (*state)->expire = time.tv_sec; | 4043 (*state)->expire = time.tv_sec; |
4044#endif |
|
3725 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE) 3726 (*state)->timeout = PFTM_UDP_MULTIPLE; 3727 else 3728 (*state)->timeout = PFTM_UDP_SINGLE; 3729 3730 /* translate source/destination address, if necessary */ 3731 if (STATE_TRANSLATE(*state)) { 3732 if (direction == PF_OUT) 3733 pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum, 3734 &uh->uh_sum, &(*state)->gwy.addr, 3735 (*state)->gwy.port, 1, pd->af); 3736 else 3737 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, 3738 &uh->uh_sum, &(*state)->lan.addr, 3739 (*state)->lan.port, 1, pd->af); | 4045 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE) 4046 (*state)->timeout = PFTM_UDP_MULTIPLE; 4047 else 4048 (*state)->timeout = PFTM_UDP_SINGLE; 4049 4050 /* translate source/destination address, if necessary */ 4051 if (STATE_TRANSLATE(*state)) { 4052 if (direction == PF_OUT) 4053 pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum, 4054 &uh->uh_sum, &(*state)->gwy.addr, 4055 (*state)->gwy.port, 1, pd->af); 4056 else 4057 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, 4058 &uh->uh_sum, &(*state)->lan.addr, 4059 (*state)->lan.port, 1, pd->af); |
3740 m_copyback(m, off, sizeof(*uh), uh); | 4060 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); |
3741 } 3742 3743 (*state)->rule.ptr->packets++; 3744 (*state)->rule.ptr->bytes += pd->tot_len; 3745 if ((*state)->nat_rule.ptr != NULL) { 3746 (*state)->nat_rule.ptr->packets++; 3747 (*state)->nat_rule.ptr->bytes += pd->tot_len; 3748 } --- 58 unchanged lines hidden (view full) --- 3807 key.port[0] = icmpid; 3808 key.port[1] = icmpid; 3809 3810 STATE_LOOKUP(); 3811 3812 dirndx = (direction == (*state)->direction) ? 0 : 1; 3813 (*state)->packets[dirndx]++; 3814 (*state)->bytes[dirndx] += pd->tot_len; | 4061 } 4062 4063 (*state)->rule.ptr->packets++; 4064 (*state)->rule.ptr->bytes += pd->tot_len; 4065 if ((*state)->nat_rule.ptr != NULL) { 4066 (*state)->nat_rule.ptr->packets++; 4067 (*state)->nat_rule.ptr->bytes += pd->tot_len; 4068 } --- 58 unchanged lines hidden (view full) --- 4127 key.port[0] = icmpid; 4128 key.port[1] = icmpid; 4129 4130 STATE_LOOKUP(); 4131 4132 dirndx = (direction == (*state)->direction) ? 0 : 1; 4133 (*state)->packets[dirndx]++; 4134 (*state)->bytes[dirndx] += pd->tot_len; |
4135#if defined(__FreeBSD__) 4136 (*state)->expire = time_second; 4137#else |
|
3815 (*state)->expire = time.tv_sec; | 4138 (*state)->expire = time.tv_sec; |
4139#endif |
|
3816 (*state)->timeout = PFTM_ICMP_ERROR_REPLY; 3817 3818 /* translate source/destination address, if necessary */ 3819 if (PF_ANEQ(&(*state)->lan.addr, &(*state)->gwy.addr, pd->af)) { 3820 if (direction == PF_OUT) { 3821 switch (pd->af) { 3822#ifdef INET 3823 case AF_INET: --- 4 unchanged lines hidden (view full) --- 3828#endif /* INET */ 3829#ifdef INET6 3830 case AF_INET6: 3831 pf_change_a6(saddr, 3832 &pd->hdr.icmp6->icmp6_cksum, 3833 &(*state)->gwy.addr, 0); 3834 m_copyback(m, off, 3835 sizeof(struct icmp6_hdr), | 4140 (*state)->timeout = PFTM_ICMP_ERROR_REPLY; 4141 4142 /* translate source/destination address, if necessary */ 4143 if (PF_ANEQ(&(*state)->lan.addr, &(*state)->gwy.addr, pd->af)) { 4144 if (direction == PF_OUT) { 4145 switch (pd->af) { 4146#ifdef INET 4147 case AF_INET: --- 4 unchanged lines hidden (view full) --- 4152#endif /* INET */ 4153#ifdef INET6 4154 case AF_INET6: 4155 pf_change_a6(saddr, 4156 &pd->hdr.icmp6->icmp6_cksum, 4157 &(*state)->gwy.addr, 0); 4158 m_copyback(m, off, 4159 sizeof(struct icmp6_hdr), |
3836 pd->hdr.icmp6); | 4160 (caddr_t)pd->hdr.icmp6); |
3837 break; 3838#endif /* INET6 */ 3839 } 3840 } else { 3841 switch (pd->af) { 3842#ifdef INET 3843 case AF_INET: 3844 pf_change_a(&daddr->v4.s_addr, 3845 pd->ip_sum, 3846 (*state)->lan.addr.v4.s_addr, 0); 3847 break; 3848#endif /* INET */ 3849#ifdef INET6 3850 case AF_INET6: 3851 pf_change_a6(daddr, 3852 &pd->hdr.icmp6->icmp6_cksum, 3853 &(*state)->lan.addr, 0); 3854 m_copyback(m, off, 3855 sizeof(struct icmp6_hdr), | 4161 break; 4162#endif /* INET6 */ 4163 } 4164 } else { 4165 switch (pd->af) { 4166#ifdef INET 4167 case AF_INET: 4168 pf_change_a(&daddr->v4.s_addr, 4169 pd->ip_sum, 4170 (*state)->lan.addr.v4.s_addr, 0); 4171 break; 4172#endif /* INET */ 4173#ifdef INET6 4174 case AF_INET6: 4175 pf_change_a6(daddr, 4176 &pd->hdr.icmp6->icmp6_cksum, 4177 &(*state)->lan.addr, 0); 4178 m_copyback(m, off, 4179 sizeof(struct icmp6_hdr), |
3856 pd->hdr.icmp6); | 4180 (caddr_t)pd->hdr.icmp6); |
3857 break; 3858#endif /* INET6 */ 3859 } 3860 } 3861 } 3862 3863 return (PF_PASS); 3864 --- 174 unchanged lines hidden (view full) --- 4039 (*state)->gwy.port, NULL, 4040 pd2.ip_sum, icmpsum, 4041 pd->ip_sum, 0, pd2.af); 4042 } 4043 switch (pd2.af) { 4044#ifdef INET 4045 case AF_INET: 4046 m_copyback(m, off, ICMP_MINLEN, | 4181 break; 4182#endif /* INET6 */ 4183 } 4184 } 4185 } 4186 4187 return (PF_PASS); 4188 --- 174 unchanged lines hidden (view full) --- 4363 (*state)->gwy.port, NULL, 4364 pd2.ip_sum, icmpsum, 4365 pd->ip_sum, 0, pd2.af); 4366 } 4367 switch (pd2.af) { 4368#ifdef INET 4369 case AF_INET: 4370 m_copyback(m, off, ICMP_MINLEN, |
4047 pd->hdr.icmp); | 4371 (caddr_t)pd->hdr.icmp); |
4048 m_copyback(m, ipoff2, sizeof(h2), | 4372 m_copyback(m, ipoff2, sizeof(h2), |
4049 &h2); | 4373 (caddr_t)&h2); |
4050 break; 4051#endif /* INET */ 4052#ifdef INET6 4053 case AF_INET6: 4054 m_copyback(m, off, 4055 sizeof(struct icmp6_hdr), | 4374 break; 4375#endif /* INET */ 4376#ifdef INET6 4377 case AF_INET6: 4378 m_copyback(m, off, 4379 sizeof(struct icmp6_hdr), |
4056 pd->hdr.icmp6); | 4380 (caddr_t)pd->hdr.icmp6); |
4057 m_copyback(m, ipoff2, sizeof(h2_6), | 4381 m_copyback(m, ipoff2, sizeof(h2_6), |
4058 &h2_6); | 4382 (caddr_t)&h2_6); |
4059 break; 4060#endif /* INET6 */ 4061 } | 4383 break; 4384#endif /* INET6 */ 4385 } |
4062 m_copyback(m, off2, 8, &th); | 4386 m_copyback(m, off2, 8, (caddr_t)&th); |
4063 } else if (src->seqdiff) { | 4387 } else if (src->seqdiff) { |
4064 m_copyback(m, off2, 8, &th); | 4388 m_copyback(m, off2, 8, (caddr_t)&th); |
4065 } 4066 4067 return (PF_PASS); 4068 break; 4069 } 4070 case IPPROTO_UDP: { 4071 struct udphdr uh; 4072 struct pf_tree_node key; --- 28 unchanged lines hidden (view full) --- 4101 (*state)->gwy.port, &uh.uh_sum, 4102 pd2.ip_sum, icmpsum, 4103 pd->ip_sum, 1, pd2.af); 4104 } 4105 switch (pd2.af) { 4106#ifdef INET 4107 case AF_INET: 4108 m_copyback(m, off, ICMP_MINLEN, | 4389 } 4390 4391 return (PF_PASS); 4392 break; 4393 } 4394 case IPPROTO_UDP: { 4395 struct udphdr uh; 4396 struct pf_tree_node key; --- 28 unchanged lines hidden (view full) --- 4425 (*state)->gwy.port, &uh.uh_sum, 4426 pd2.ip_sum, icmpsum, 4427 pd->ip_sum, 1, pd2.af); 4428 } 4429 switch (pd2.af) { 4430#ifdef INET 4431 case AF_INET: 4432 m_copyback(m, off, ICMP_MINLEN, |
4109 pd->hdr.icmp); 4110 m_copyback(m, ipoff2, sizeof(h2), &h2); | 4433 (caddr_t)pd->hdr.icmp); 4434 m_copyback(m, ipoff2, sizeof(h2), 4435 (caddr_t)&h2); |
4111 break; 4112#endif /* INET */ 4113#ifdef INET6 4114 case AF_INET6: 4115 m_copyback(m, off, 4116 sizeof(struct icmp6_hdr), | 4436 break; 4437#endif /* INET */ 4438#ifdef INET6 4439 case AF_INET6: 4440 m_copyback(m, off, 4441 sizeof(struct icmp6_hdr), |
4117 pd->hdr.icmp6); | 4442 (caddr_t)pd->hdr.icmp6); |
4118 m_copyback(m, ipoff2, sizeof(h2_6), | 4443 m_copyback(m, ipoff2, sizeof(h2_6), |
4119 &h2_6); | 4444 (caddr_t)&h2_6); |
4120 break; 4121#endif /* INET6 */ 4122 } | 4445 break; 4446#endif /* INET6 */ 4447 } |
4123 m_copyback(m, off2, sizeof(uh), &uh); | 4448 m_copyback(m, off2, sizeof(uh), 4449 (caddr_t)&uh); |
4124 } 4125 4126 return (PF_PASS); 4127 break; 4128 } 4129#ifdef INET 4130 case IPPROTO_ICMP: { 4131 struct icmp iih; --- 25 unchanged lines hidden (view full) --- 4157 pd->ip_sum, 0, AF_INET); 4158 } else { 4159 pf_change_icmp(pd2.dst, &iih.icmp_id, 4160 saddr, &(*state)->gwy.addr, 4161 (*state)->gwy.port, NULL, 4162 pd2.ip_sum, icmpsum, 4163 pd->ip_sum, 0, AF_INET); 4164 } | 4450 } 4451 4452 return (PF_PASS); 4453 break; 4454 } 4455#ifdef INET 4456 case IPPROTO_ICMP: { 4457 struct icmp iih; --- 25 unchanged lines hidden (view full) --- 4483 pd->ip_sum, 0, AF_INET); 4484 } else { 4485 pf_change_icmp(pd2.dst, &iih.icmp_id, 4486 saddr, &(*state)->gwy.addr, 4487 (*state)->gwy.port, NULL, 4488 pd2.ip_sum, icmpsum, 4489 pd->ip_sum, 0, AF_INET); 4490 } |
4165 m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp); 4166 m_copyback(m, ipoff2, sizeof(h2), &h2); 4167 m_copyback(m, off2, ICMP_MINLEN, &iih); | 4491 m_copyback(m, off, ICMP_MINLEN, 4492 (caddr_t)pd->hdr.icmp); 4493 m_copyback(m, ipoff2, sizeof(h2), 4494 (caddr_t)&h2); 4495 m_copyback(m, off2, ICMP_MINLEN, 4496 (caddr_t)&iih); |
4168 } 4169 4170 return (PF_PASS); 4171 break; 4172 } 4173#endif /* INET */ 4174#ifdef INET6 4175 case IPPROTO_ICMPV6: { --- 27 unchanged lines hidden (view full) --- 4203 } else { 4204 pf_change_icmp(pd2.dst, &iih.icmp6_id, 4205 saddr, &(*state)->gwy.addr, 4206 (*state)->gwy.port, NULL, 4207 pd2.ip_sum, icmpsum, 4208 pd->ip_sum, 0, AF_INET6); 4209 } 4210 m_copyback(m, off, sizeof(struct icmp6_hdr), | 4497 } 4498 4499 return (PF_PASS); 4500 break; 4501 } 4502#endif /* INET */ 4503#ifdef INET6 4504 case IPPROTO_ICMPV6: { --- 27 unchanged lines hidden (view full) --- 4532 } else { 4533 pf_change_icmp(pd2.dst, &iih.icmp6_id, 4534 saddr, &(*state)->gwy.addr, 4535 (*state)->gwy.port, NULL, 4536 pd2.ip_sum, icmpsum, 4537 pd->ip_sum, 0, AF_INET6); 4538 } 4539 m_copyback(m, off, sizeof(struct icmp6_hdr), |
4211 pd->hdr.icmp6); 4212 m_copyback(m, ipoff2, sizeof(h2_6), &h2_6); | 4540 (caddr_t)pd->hdr.icmp6); 4541 m_copyback(m, ipoff2, sizeof(h2_6), 4542 (caddr_t)&h2_6); |
4213 m_copyback(m, off2, sizeof(struct icmp6_hdr), | 4543 m_copyback(m, off2, sizeof(struct icmp6_hdr), |
4214 &iih); | 4544 (caddr_t)&iih); |
4215 } 4216 4217 return (PF_PASS); 4218 break; 4219 } 4220#endif /* INET6 */ 4221 default: { 4222 struct pf_tree_node key; --- 20 unchanged lines hidden (view full) --- 4243 0, NULL, 4244 pd2.ip_sum, icmpsum, 4245 pd->ip_sum, 0, pd2.af); 4246 } 4247 switch (pd2.af) { 4248#ifdef INET 4249 case AF_INET: 4250 m_copyback(m, off, ICMP_MINLEN, | 4545 } 4546 4547 return (PF_PASS); 4548 break; 4549 } 4550#endif /* INET6 */ 4551 default: { 4552 struct pf_tree_node key; --- 20 unchanged lines hidden (view full) --- 4573 0, NULL, 4574 pd2.ip_sum, icmpsum, 4575 pd->ip_sum, 0, pd2.af); 4576 } 4577 switch (pd2.af) { 4578#ifdef INET 4579 case AF_INET: 4580 m_copyback(m, off, ICMP_MINLEN, |
4251 pd->hdr.icmp); 4252 m_copyback(m, ipoff2, sizeof(h2), &h2); | 4581 (caddr_t)pd->hdr.icmp); 4582 m_copyback(m, ipoff2, sizeof(h2), 4583 (caddr_t)&h2); |
4253 break; 4254#endif /* INET */ 4255#ifdef INET6 4256 case AF_INET6: 4257 m_copyback(m, off, 4258 sizeof(struct icmp6_hdr), | 4584 break; 4585#endif /* INET */ 4586#ifdef INET6 4587 case AF_INET6: 4588 m_copyback(m, off, 4589 sizeof(struct icmp6_hdr), |
4259 pd->hdr.icmp6); | 4590 (caddr_t)pd->hdr.icmp6); |
4260 m_copyback(m, ipoff2, sizeof(h2_6), | 4591 m_copyback(m, ipoff2, sizeof(h2_6), |
4261 &h2_6); | 4592 (caddr_t)&h2_6); |
4262 break; 4263#endif /* INET6 */ 4264 } 4265 } 4266 4267 return (PF_PASS); 4268 break; 4269 } --- 33 unchanged lines hidden (view full) --- 4303 4304 /* update states */ 4305 if (src->state < PFOTHERS_SINGLE) 4306 src->state = PFOTHERS_SINGLE; 4307 if (dst->state == PFOTHERS_SINGLE) 4308 dst->state = PFOTHERS_MULTIPLE; 4309 4310 /* update expire time */ | 4593 break; 4594#endif /* INET6 */ 4595 } 4596 } 4597 4598 return (PF_PASS); 4599 break; 4600 } --- 33 unchanged lines hidden (view full) --- 4634 4635 /* update states */ 4636 if (src->state < PFOTHERS_SINGLE) 4637 src->state = PFOTHERS_SINGLE; 4638 if (dst->state == PFOTHERS_SINGLE) 4639 dst->state = PFOTHERS_MULTIPLE; 4640 4641 /* update expire time */ |
4642#if defined(__FreeBSD__) 4643 (*state)->expire = time_second; 4644#else |
|
4311 (*state)->expire = time.tv_sec; | 4645 (*state)->expire = time.tv_sec; |
4646#endif |
|
4312 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE) 4313 (*state)->timeout = PFTM_OTHER_MULTIPLE; 4314 else 4315 (*state)->timeout = PFTM_OTHER_SINGLE; 4316 4317 /* translate source/destination address, if necessary */ 4318 if (STATE_TRANSLATE(*state)) { 4319 if (direction == PF_OUT) --- 98 unchanged lines hidden (view full) --- 4418 struct route ro; 4419 int ret = 0; 4420 4421 bzero(&ro, sizeof(ro)); 4422 dst = satosin(&ro.ro_dst); 4423 dst->sin_family = af; 4424 dst->sin_len = sizeof(*dst); 4425 dst->sin_addr = addr->v4; | 4647 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE) 4648 (*state)->timeout = PFTM_OTHER_MULTIPLE; 4649 else 4650 (*state)->timeout = PFTM_OTHER_SINGLE; 4651 4652 /* translate source/destination address, if necessary */ 4653 if (STATE_TRANSLATE(*state)) { 4654 if (direction == PF_OUT) --- 98 unchanged lines hidden (view full) --- 4753 struct route ro; 4754 int ret = 0; 4755 4756 bzero(&ro, sizeof(ro)); 4757 dst = satosin(&ro.ro_dst); 4758 dst->sin_family = af; 4759 dst->sin_len = sizeof(*dst); 4760 dst->sin_addr = addr->v4; |
4761#if defined(__FreeBSD__) 4762#ifdef RTF_PRCLONING 4763 rtalloc_ign(&ro, (RTF_CLONING|RTF_PRCLONING)); 4764#else /* !RTF_PRCLONING */ 4765 rtalloc_ign(&ro, RTF_CLONING); 4766#endif 4767#else /* ! __FreeBSD__ */ |
|
4426 rtalloc_noclone(&ro, NO_CLONING); | 4768 rtalloc_noclone(&ro, NO_CLONING); |
4769#endif |
|
4427 4428 if (ro.ro_rt != NULL) { 4429 ret = 1; 4430 RTFREE(ro.ro_rt); 4431 } 4432 4433 return (ret); 4434} 4435 4436#ifdef INET | 4770 4771 if (ro.ro_rt != NULL) { 4772 ret = 1; 4773 RTFREE(ro.ro_rt); 4774 } 4775 4776 return (ret); 4777} 4778 4779#ifdef INET |
4780 4781#if defined(__FreeBSD__) && (__FreeBSD_version < 501105) 4782int 4783ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu, 4784 u_long if_hwassist_flags, int sw_csum) 4785{ 4786 int error = 0; 4787 int hlen = ip->ip_hl << 2; 4788 int len = (mtu - hlen) & ~7; /* size of payload in each fragment */ 4789 int off; 4790 struct mbuf *m0 = *m_frag; /* the original packet */ 4791 int firstlen; 4792 struct mbuf **mnext; 4793 int nfrags; 4794 4795 if (ip->ip_off & IP_DF) { /* Fragmentation not allowed */ 4796 ipstat.ips_cantfrag++; 4797 return EMSGSIZE; 4798 } 4799 4800 /* 4801 * Must be able to put at least 8 bytes per fragment. 4802 */ 4803 if (len < 8) 4804 return EMSGSIZE; 4805 4806 /* 4807 * If the interface will not calculate checksums on 4808 * fragmented packets, then do it here. 4809 */ 4810 if (m0->m_pkthdr.csum_flags & CSUM_DELAY_DATA && 4811 (if_hwassist_flags & CSUM_IP_FRAGS) == 0) { 4812 in_delayed_cksum(m0); 4813 m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; 4814 } 4815 4816 if (len > PAGE_SIZE) { 4817 /* 4818 * Fragment large datagrams such that each segment 4819 * contains a multiple of PAGE_SIZE amount of data, 4820 * plus headers. This enables a receiver to perform 4821 * page-flipping zero-copy optimizations. 4822 * 4823 * XXX When does this help given that sender and receiver 4824 * could have different page sizes, and also mtu could 4825 * be less than the receiver's page size ? 4826 */ 4827 int newlen; 4828 struct mbuf *m; 4829 4830 for (m = m0, off = 0; m && (off+m->m_len) <= mtu; m = m->m_next) 4831 off += m->m_len; 4832 4833 /* 4834 * firstlen (off - hlen) must be aligned on an 4835 * 8-byte boundary 4836 */ 4837 if (off < hlen) 4838 goto smart_frag_failure; 4839 off = ((off - hlen) & ~7) + hlen; 4840 newlen = (~PAGE_MASK) & mtu; 4841 if ((newlen + sizeof (struct ip)) > mtu) { 4842 /* we failed, go back the default */ 4843smart_frag_failure: 4844 newlen = len; 4845 off = hlen + len; 4846 } 4847 len = newlen; 4848 4849 } else { 4850 off = hlen + len; 4851 } 4852 4853 firstlen = off - hlen; 4854 mnext = &m0->m_nextpkt; /* pointer to next packet */ 4855 4856 /* 4857 * Loop through length of segment after first fragment, 4858 * make new header and copy data of each part and link onto chain. 4859 * Here, m0 is the original packet, m is the fragment being created. 4860 * The fragments are linked off the m_nextpkt of the original 4861 * packet, which after processing serves as the first fragment. 4862 */ 4863 for (nfrags = 1; off < ip->ip_len; off += len, nfrags++) { 4864 struct ip *mhip; /* ip header on the fragment */ 4865 struct mbuf *m; 4866 int mhlen = sizeof (struct ip); 4867 4868 MGETHDR(m, M_DONTWAIT, MT_HEADER); 4869 if (m == 0) { 4870 error = ENOBUFS; 4871 ipstat.ips_odropped++; 4872 goto done; 4873 } 4874 m->m_flags |= (m0->m_flags & M_MCAST) | M_FRAG; 4875 /* 4876 * In the first mbuf, leave room for the link header, then 4877 * copy the original IP header including options. The payload 4878 * goes into an additional mbuf chain returned by m_copy(). 4879 */ 4880 m->m_data += max_linkhdr; 4881 mhip = mtod(m, struct ip *); 4882 *mhip = *ip; 4883 if (hlen > sizeof (struct ip)) { 4884 mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); 4885 mhip->ip_v = IPVERSION; 4886 mhip->ip_hl = mhlen >> 2; 4887 } 4888 m->m_len = mhlen; 4889 /* XXX do we need to add ip->ip_off below ? */ 4890 mhip->ip_off = ((off - hlen) >> 3) + ip->ip_off; 4891 if (off + len >= ip->ip_len) { /* last fragment */ 4892 len = ip->ip_len - off; 4893 m->m_flags |= M_LASTFRAG; 4894 } else 4895 mhip->ip_off |= IP_MF; 4896 mhip->ip_len = htons((u_short)(len + mhlen)); 4897 m->m_next = m_copy(m0, off, len); 4898 if (m->m_next == 0) { /* copy failed */ 4899 m_free(m); 4900 error = ENOBUFS; /* ??? */ 4901 ipstat.ips_odropped++; 4902 goto done; 4903 } 4904 m->m_pkthdr.len = mhlen + len; 4905 m->m_pkthdr.rcvif = (struct ifnet *)0; 4906#ifdef MAC 4907 mac_create_fragment(m0, m); 4908#endif 4909 m->m_pkthdr.csum_flags = m0->m_pkthdr.csum_flags; 4910 mhip->ip_off = htons(mhip->ip_off); 4911 mhip->ip_sum = 0; 4912 if (sw_csum & CSUM_DELAY_IP) 4913 mhip->ip_sum = in_cksum(m, mhlen); 4914 *mnext = m; 4915 mnext = &m->m_nextpkt; 4916 } 4917 ipstat.ips_ofragments += nfrags; 4918 4919 /* set first marker for fragment chain */ 4920 m0->m_flags |= M_FIRSTFRAG | M_FRAG; 4921 m0->m_pkthdr.csum_data = nfrags; 4922 4923 /* 4924 * Update first fragment by trimming what's been copied out 4925 * and updating header. 4926 */ 4927 m_adj(m0, hlen + firstlen - ip->ip_len); 4928 m0->m_pkthdr.len = hlen + firstlen; 4929 ip->ip_len = htons((u_short)m0->m_pkthdr.len); 4930 ip->ip_off |= IP_MF; 4931 ip->ip_off = htons(ip->ip_off); 4932 ip->ip_sum = 0; 4933 if (sw_csum & CSUM_DELAY_IP) 4934 ip->ip_sum = in_cksum(m0, hlen); 4935 4936done: 4937 *m_frag = m0; 4938 return error; 4939} 4940#endif /* __FreeBSD__ && __FreeBSD_version > 501105 */ 4941 |
|
4437void 4438pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 4439 struct pf_state *s) 4440{ 4441 struct mbuf *m0, *m1; 4442 struct route iproute; 4443 struct route *ro; 4444 struct sockaddr_in *dst; 4445 struct ip *ip; 4446 struct ifnet *ifp = NULL; 4447 struct m_tag *mtag; 4448 struct pf_addr naddr; 4449 int error = 0; | 4942void 4943pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 4944 struct pf_state *s) 4945{ 4946 struct mbuf *m0, *m1; 4947 struct route iproute; 4948 struct route *ro; 4949 struct sockaddr_in *dst; 4950 struct ip *ip; 4951 struct ifnet *ifp = NULL; 4952 struct m_tag *mtag; 4953 struct pf_addr naddr; 4954 int error = 0; |
4955#if defined(__FreeBSD__) 4956 int sw_csum; 4957#endif |
|
4450 4451 if (m == NULL || *m == NULL || r == NULL || 4452 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 4453 panic("pf_route: invalid parameters"); 4454 4455 if (r->rt == PF_DUPTO) { 4456 m0 = *m; 4457 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 4458 if (mtag == NULL) { 4459 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 4460 if (mtag == NULL) 4461 goto bad; 4462 m_tag_prepend(m0, mtag); 4463 } | 4958 4959 if (m == NULL || *m == NULL || r == NULL || 4960 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 4961 panic("pf_route: invalid parameters"); 4962 4963 if (r->rt == PF_DUPTO) { 4964 m0 = *m; 4965 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 4966 if (mtag == NULL) { 4967 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 4968 if (mtag == NULL) 4969 goto bad; 4970 m_tag_prepend(m0, mtag); 4971 } |
4972#if defined(__FreeBSD__) 4973 m0 = m_dup(*m, M_DONTWAIT); 4974#else |
|
4464 m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT); | 4975 m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT); |
4976#endif |
|
4465 if (m0 == NULL) 4466 return; 4467 } else { 4468 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 4469 return; 4470 m0 = *m; 4471 } 4472 --- 47 unchanged lines hidden (view full) --- 4520 4521 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 4522 if (mtag == NULL) 4523 goto bad; 4524 m_tag_prepend(m0, mtag); 4525 } 4526 4527 if (oifp != ifp && mtag == NULL) { | 4977 if (m0 == NULL) 4978 return; 4979 } else { 4980 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 4981 return; 4982 m0 = *m; 4983 } 4984 --- 47 unchanged lines hidden (view full) --- 5032 5033 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 5034 if (mtag == NULL) 5035 goto bad; 5036 m_tag_prepend(m0, mtag); 5037 } 5038 5039 if (oifp != ifp && mtag == NULL) { |
5040#if defined(__FreeBSD__) 5041 PF_UNLOCK(); 5042 if (pf_test(PF_OUT, ifp, &m0) != PF_PASS) { 5043 PF_LOCK(); 5044 goto bad; 5045 } else if (m0 == NULL) { 5046 PF_LOCK(); 5047 goto done; 5048 } 5049 PF_LOCK(); 5050#else |
|
4528 if (pf_test(PF_OUT, ifp, &m0) != PF_PASS) 4529 goto bad; 4530 else if (m0 == NULL) 4531 goto done; | 5051 if (pf_test(PF_OUT, ifp, &m0) != PF_PASS) 5052 goto bad; 5053 else if (m0 == NULL) 5054 goto done; |
5055#endif |
|
4532 if (m0->m_len < sizeof(struct ip)) 4533 panic("pf_route: m0->m_len < sizeof(struct ip)"); 4534 ip = mtod(m0, struct ip *); 4535 } 4536 | 5056 if (m0->m_len < sizeof(struct ip)) 5057 panic("pf_route: m0->m_len < sizeof(struct ip)"); 5058 ip = mtod(m0, struct ip *); 5059 } 5060 |
5061#if defined(__FreeBSD__) 5062 /* Copied from FreeBSD 5.1-CURRENT ip_output. */ 5063 m0->m_pkthdr.csum_flags |= CSUM_IP; 5064 sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist; 5065 if (sw_csum & CSUM_DELAY_DATA) { 5066 /* 5067 * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least) 5068 */ 5069 NTOHS(ip->ip_len); 5070 NTOHS(ip->ip_off); /* XXX: needed? */ 5071 in_delayed_cksum(m0); 5072 HTONS(ip->ip_len); 5073 HTONS(ip->ip_off); 5074 sw_csum &= ~CSUM_DELAY_DATA; 5075 } 5076 m0->m_pkthdr.csum_flags &= ifp->if_hwassist; 5077 5078 if (ntohs(ip->ip_len) <= ifp->if_mtu || 5079 (ifp->if_hwassist & CSUM_FRAGMENT && 5080 ((ip->ip_off & htons(IP_DF)) == 0))) { 5081 /* 5082 * ip->ip_len = htons(ip->ip_len); 5083 * ip->ip_off = htons(ip->ip_off); 5084 */ 5085 ip->ip_sum = 0; 5086 if (sw_csum & CSUM_DELAY_IP) { 5087 /* From KAME */ 5088 if (ip->ip_v == IPVERSION && 5089 (ip->ip_hl << 2) == sizeof(*ip)) { 5090 ip->ip_sum = in_cksum_hdr(ip); 5091 } else { 5092 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 5093 } 5094 } 5095 PF_UNLOCK(); 5096 error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro->ro_rt); 5097 PF_LOCK(); 5098 goto done; 5099 } 5100 5101#else |
|
4537 /* Copied from ip_output. */ 4538 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 4539 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 4540 ifp->if_bridge == NULL) { 4541 m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT; 4542 ipstat.ips_outhwcsum++; 4543 } else { 4544 ip->ip_sum = 0; 4545 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 4546 } 4547 /* Update relevant hardware checksum stats for TCP/UDP */ 4548 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) 4549 tcpstat.tcps_outhwcsum++; 4550 else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) 4551 udpstat.udps_outhwcsum++; 4552 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); 4553 goto done; 4554 } | 5102 /* Copied from ip_output. */ 5103 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 5104 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 5105 ifp->if_bridge == NULL) { 5106 m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT; 5107 ipstat.ips_outhwcsum++; 5108 } else { 5109 ip->ip_sum = 0; 5110 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 5111 } 5112 /* Update relevant hardware checksum stats for TCP/UDP */ 5113 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) 5114 tcpstat.tcps_outhwcsum++; 5115 else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) 5116 udpstat.udps_outhwcsum++; 5117 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); 5118 goto done; 5119 } |
4555 | 5120#endif |
4556 /* 4557 * Too large for interface; fragment if possible. 4558 * Must be able to put at least 8 bytes per fragment. 4559 */ 4560 if (ip->ip_off & htons(IP_DF)) { 4561 ipstat.ips_cantfrag++; 4562 if (r->rt != PF_DUPTO) { | 5121 /* 5122 * Too large for interface; fragment if possible. 5123 * Must be able to put at least 8 bytes per fragment. 5124 */ 5125 if (ip->ip_off & htons(IP_DF)) { 5126 ipstat.ips_cantfrag++; 5127 if (r->rt != PF_DUPTO) { |
5128#if defined(__FreeBSD__) 5129 /* icmp_error() expects host byte ordering */ 5130 NTOHS(ip->ip_len); 5131 NTOHS(ip->ip_off); 5132 PF_UNLOCK(); 5133#endif |
|
4563 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 4564 ifp); | 5134 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 5135 ifp); |
5136#if defined(__FreeBSD__) 5137 PF_LOCK(); 5138#endif |
|
4565 goto done; 4566 } else 4567 goto bad; 4568 } 4569 4570 m1 = m0; | 5139 goto done; 5140 } else 5141 goto bad; 5142 } 5143 5144 m1 = m0; |
5145#if defined(__FreeBSD__) 5146 /* 5147 * XXX: is cheaper + less error prone than own function 5148 */ 5149 NTOHS(ip->ip_len); 5150 NTOHS(ip->ip_off); 5151 error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum); 5152#else |
|
4571 error = ip_fragment(m0, ifp, ifp->if_mtu); | 5153 error = ip_fragment(m0, ifp, ifp->if_mtu); |
5154#endif 5155#if defined(__FreeBSD__) 5156 if (error) 5157#else |
|
4572 if (error == EMSGSIZE) | 5158 if (error == EMSGSIZE) |
5159#endif |
|
4573 goto bad; 4574 4575 for (m0 = m1; m0; m0 = m1) { 4576 m1 = m0->m_nextpkt; 4577 m0->m_nextpkt = 0; | 5160 goto bad; 5161 5162 for (m0 = m1; m0; m0 = m1) { 5163 m1 = m0->m_nextpkt; 5164 m0->m_nextpkt = 0; |
5165#if defined(__FreeBSD__) 5166 if (error == 0) { 5167 PF_UNLOCK(); 5168 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 5169 NULL); 5170 PF_LOCK(); 5171 } else 5172#else |
|
4578 if (error == 0) 4579 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 4580 NULL); 4581 else | 5173 if (error == 0) 5174 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 5175 NULL); 5176 else |
5177#endif |
|
4582 m_freem(m0); 4583 } 4584 4585 if (error == 0) 4586 ipstat.ips_fragmented++; 4587 4588done: 4589 if (r->rt != PF_DUPTO) --- 31 unchanged lines hidden (view full) --- 4621 m0 = *m; 4622 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 4623 if (mtag == NULL) { 4624 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 4625 if (mtag == NULL) 4626 goto bad; 4627 m_tag_prepend(m0, mtag); 4628 } | 5178 m_freem(m0); 5179 } 5180 5181 if (error == 0) 5182 ipstat.ips_fragmented++; 5183 5184done: 5185 if (r->rt != PF_DUPTO) --- 31 unchanged lines hidden (view full) --- 5217 m0 = *m; 5218 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 5219 if (mtag == NULL) { 5220 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 5221 if (mtag == NULL) 5222 goto bad; 5223 m_tag_prepend(m0, mtag); 5224 } |
5225#if defined(__FreeBSD__) 5226 m0 = m_dup(*m, M_DONTWAIT); 5227#else |
|
4629 m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT); | 5228 m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT); |
5229#endif |
|
4630 if (m0 == NULL) 4631 return; 4632 } else { 4633 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 4634 return; 4635 m0 = *m; 4636 } 4637 --- 9 unchanged lines hidden (view full) --- 4647 dst->sin6_addr = ip6->ip6_dst; 4648 4649 /* Cheat. */ 4650 if (r->rt == PF_FASTROUTE) { 4651 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 4652 if (mtag == NULL) 4653 goto bad; 4654 m_tag_prepend(m0, mtag); | 5230 if (m0 == NULL) 5231 return; 5232 } else { 5233 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 5234 return; 5235 m0 = *m; 5236 } 5237 --- 9 unchanged lines hidden (view full) --- 5247 dst->sin6_addr = ip6->ip6_dst; 5248 5249 /* Cheat. */ 5250 if (r->rt == PF_FASTROUTE) { 5251 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 5252 if (mtag == NULL) 5253 goto bad; 5254 m_tag_prepend(m0, mtag); |
5255#if defined(__FreeBSD__) 5256 PF_UNLOCK(); 5257 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 5258 PF_LOCK(); 5259#else |
|
4655 ip6_output(m0, NULL, NULL, 0, NULL, NULL); | 5260 ip6_output(m0, NULL, NULL, 0, NULL, NULL); |
5261#endif |
|
4656 return; 4657 } 4658 4659 if (TAILQ_EMPTY(&r->rpool.list)) 4660 panic("pf_route6: TAILQ_EMPTY(&r->rpool.list)"); 4661 if (s == NULL) { 4662 pf_map_addr(AF_INET6, &r->rpool, 4663 (struct pf_addr *)&ip6->ip6_src, &naddr, NULL); --- 13 unchanged lines hidden (view full) --- 4677 4678 if (oifp != ifp) { 4679 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 4680 if (mtag == NULL) { 4681 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 4682 if (mtag == NULL) 4683 goto bad; 4684 m_tag_prepend(m0, mtag); | 5262 return; 5263 } 5264 5265 if (TAILQ_EMPTY(&r->rpool.list)) 5266 panic("pf_route6: TAILQ_EMPTY(&r->rpool.list)"); 5267 if (s == NULL) { 5268 pf_map_addr(AF_INET6, &r->rpool, 5269 (struct pf_addr *)&ip6->ip6_src, &naddr, NULL); --- 13 unchanged lines hidden (view full) --- 5283 5284 if (oifp != ifp) { 5285 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 5286 if (mtag == NULL) { 5287 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 5288 if (mtag == NULL) 5289 goto bad; 5290 m_tag_prepend(m0, mtag); |
5291#if defined(__FreeBSD__) 5292 PF_UNLOCK(); 5293 if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS) { 5294 PF_LOCK(); 5295 goto bad; 5296 } else if (m0 == NULL) { 5297 PF_LOCK(); 5298 goto done; 5299 } 5300 PF_LOCK(); 5301#else |
|
4685 if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS) 4686 goto bad; 4687 else if (m0 == NULL) 4688 goto done; | 5302 if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS) 5303 goto bad; 5304 else if (m0 == NULL) 5305 goto done; |
5306#endif |
|
4689 } 4690 } 4691 4692 /* 4693 * If the packet is too large for the outgoing interface, 4694 * send back an icmp6 error. 4695 */ 4696 if (IN6_IS_ADDR_LINKLOCAL(&dst->sin6_addr)) 4697 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); 4698 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { | 5307 } 5308 } 5309 5310 /* 5311 * If the packet is too large for the outgoing interface, 5312 * send back an icmp6 error. 5313 */ 5314 if (IN6_IS_ADDR_LINKLOCAL(&dst->sin6_addr)) 5315 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); 5316 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { |
5317#if defined(__FreeBSD__) 5318 PF_UNLOCK(); 5319#endif |
|
4699 error = nd6_output(ifp, ifp, m0, dst, NULL); | 5320 error = nd6_output(ifp, ifp, m0, dst, NULL); |
5321#if defined(__FreeBSD__) 5322 PF_LOCK(); 5323#endif |
|
4700 } else { 4701 in6_ifstat_inc(ifp, ifs6_in_toobig); | 5324 } else { 5325 in6_ifstat_inc(ifp, ifs6_in_toobig); |
5326#if defined(__FreeBSD__) 5327 if (r->rt != PF_DUPTO) { 5328 PF_UNLOCK(); 5329 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 5330 PF_LOCK(); 5331 } else 5332#else |
|
4702 if (r->rt != PF_DUPTO) 4703 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 4704 else | 5333 if (r->rt != PF_DUPTO) 5334 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 5335 else |
5336#endif |
|
4705 goto bad; 4706 } 4707 4708done: 4709 if (r->rt != PF_DUPTO) 4710 *m = NULL; 4711 return; 4712 4713bad: 4714 m_freem(m0); 4715 goto done; 4716} 4717#endif /* INET6 */ 4718 4719 | 5337 goto bad; 5338 } 5339 5340done: 5341 if (r->rt != PF_DUPTO) 5342 *m = NULL; 5343 return; 5344 5345bad: 5346 m_freem(m0); 5347 goto done; 5348} 5349#endif /* INET6 */ 5350 5351 |
5352#if defined(__FreeBSD__) |
|
4720/* | 5353/* |
5354 * XXX 5355 * FreeBSD supports cksum offload for the following drivers. 5356 * em(4), gx(4), lge(4), nge(4), ti(4), xl(4) 5357 * If we can make full use of it we would outperform ipfw/ipfilter in 5358 * very heavy traffic. 5359 * I have not tested 'cause I don't have NICs that supports cksum offload. 5360 * (There might be problems. Typical phenomena would be 5361 * 1. No route message for UDP packet. 5362 * 2. No connection acceptance from external hosts regardless of rule set.) 5363 */ 5364int 5365pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) 5366{ 5367 u_int16_t sum = 0; 5368 int hw_assist = 0; 5369 struct ip *ip; 5370 5371 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 5372 return (1); 5373 if (m->m_pkthdr.len < off + len) 5374 return (1); 5375 5376 switch (p) { 5377 case IPPROTO_TCP: 5378 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 5379 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 5380 sum = m->m_pkthdr.csum_data; 5381 } else { 5382 ip = mtod(m, struct ip *); 5383 sum = in_pseudo(ip->ip_src.s_addr, 5384 ip->ip_dst.s_addr, 5385 htonl(m->m_pkthdr.csum_data + 5386 IPPROTO_TCP) + ip->ip_len); 5387 } 5388 sum ^= 0xffff; 5389 ++hw_assist; 5390 } 5391 break; 5392 case IPPROTO_UDP: 5393 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 5394 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 5395 sum = m->m_pkthdr.csum_data; 5396 } else { 5397 ip = mtod(m, struct ip *); 5398 sum = in_pseudo(ip->ip_src.s_addr, 5399 ip->ip_dst.s_addr, htonl((u_short)len + 5400 m->m_pkthdr.csum_data + IPPROTO_UDP)); 5401 } 5402 sum ^= 0xffff; 5403 ++hw_assist; 5404 } 5405 break; 5406 case IPPROTO_ICMP: 5407#ifdef INET6 5408 case IPPROTO_ICMPV6: 5409#endif /* INET6 */ 5410 break; 5411 default: 5412 return (1); 5413 } 5414 5415 if (!hw_assist) { 5416 switch (af) { 5417 case AF_INET: 5418 if (p == IPPROTO_ICMP) { 5419 if (m->m_len < off) 5420 return (1); 5421 m->m_data += off; 5422 m->m_len -= off; 5423 sum = in_cksum(m, len); 5424 m->m_data -= off; 5425 m->m_len += off; 5426 } else { 5427 if (m->m_len < sizeof(struct ip)) 5428 return (1); 5429 sum = in4_cksum(m, p, off, len); 5430 if (sum == 0) { 5431 m->m_pkthdr.csum_flags |= 5432 (CSUM_DATA_VALID | 5433 CSUM_PSEUDO_HDR); 5434 m->m_pkthdr.csum_data = 0xffff; 5435 } 5436 } 5437 break; 5438#ifdef INET6 5439 case AF_INET6: 5440 if (m->m_len < sizeof(struct ip6_hdr)) 5441 return (1); 5442 sum = in6_cksum(m, p, off, len); 5443 /* 5444 * XXX 5445 * IPv6 H/W cksum off-load not supported yet! 5446 * 5447 * if (sum == 0) { 5448 * m->m_pkthdr.csum_flags |= 5449 * (CSUM_DATA_VALID|CSUM_PSEUDO_HDR); 5450 * m->m_pkthdr.csum_data = 0xffff; 5451 *} 5452 */ 5453 break; 5454#endif /* INET6 */ 5455 default: 5456 return (1); 5457 } 5458 } 5459 if (sum) { 5460 switch (p) { 5461 case IPPROTO_TCP: 5462 tcpstat.tcps_rcvbadsum++; 5463 break; 5464 case IPPROTO_UDP: 5465 udpstat.udps_badsum++; 5466 break; 5467 case IPPROTO_ICMP: 5468 icmpstat.icps_checksum++; 5469 break; 5470#ifdef INET6 5471 case IPPROTO_ICMPV6: 5472 icmp6stat.icp6s_checksum++; 5473 break; 5474#endif /* INET6 */ 5475 } 5476 return (1); 5477 } 5478 return (0); 5479} 5480#else 5481/* |
|
4721 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 4722 * off is the offset where the protocol header starts 4723 * len is the total length of protocol header plus payload 4724 * returns 0 when the checksum is valid, otherwise returns 1. 4725 */ 4726int 4727pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) 4728{ --- 70 unchanged lines hidden (view full) --- 4799 break; 4800#endif /* INET6 */ 4801 } 4802 return (1); 4803 } 4804 m->m_pkthdr.csum |= flag_ok; 4805 return (0); 4806} | 5482 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 5483 * off is the offset where the protocol header starts 5484 * len is the total length of protocol header plus payload 5485 * returns 0 when the checksum is valid, otherwise returns 1. 5486 */ 5487int 5488pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) 5489{ --- 70 unchanged lines hidden (view full) --- 5560 break; 5561#endif /* INET6 */ 5562 } 5563 return (1); 5564 } 5565 m->m_pkthdr.csum |= flag_ok; 5566 return (0); 5567} |
5568#endif |
|
4807 4808#ifdef INET 4809int 4810pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) 4811{ 4812 u_short action, reason = 0, log = 0; 4813 struct mbuf *m = *m0; 4814 struct ip *h; 4815 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr; 4816 struct pf_state *s = NULL; 4817 struct pf_ruleset *ruleset = NULL; 4818 struct pf_pdesc pd; 4819 int off; 4820 int pqid = 0; 4821 | 5569 5570#ifdef INET 5571int 5572pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) 5573{ 5574 u_short action, reason = 0, log = 0; 5575 struct mbuf *m = *m0; 5576 struct ip *h; 5577 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr; 5578 struct pf_state *s = NULL; 5579 struct pf_ruleset *ruleset = NULL; 5580 struct pf_pdesc pd; 5581 int off; 5582 int pqid = 0; 5583 |
5584#if defined(__FreeBSD__) 5585 PF_LOCK(); 5586#endif |
|
4822 if (!pf_status.running || | 5587 if (!pf_status.running || |
4823 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) 4824 return (PF_PASS); | 5588 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) { 5589#if defined(__FreeBSD__) 5590 PF_UNLOCK(); 5591#endif 5592 return (PF_PASS); 5593 } |
4825 | 5594 |
5595#if defined(__FreeBSD__) && (__FreeBSD_version >= 501000) 5596 M_ASSERTPKTHDR(m); 5597#else |
|
4826#ifdef DIAGNOSTIC 4827 if ((m->m_flags & M_PKTHDR) == 0) 4828 panic("non-M_PKTHDR is passed to pf_test"); 4829#endif | 5598#ifdef DIAGNOSTIC 5599 if ((m->m_flags & M_PKTHDR) == 0) 5600 panic("non-M_PKTHDR is passed to pf_test"); 5601#endif |
5602#endif |
|
4830 4831 if (m->m_pkthdr.len < (int)sizeof(*h)) { 4832 action = PF_DROP; 4833 REASON_SET(&reason, PFRES_SHORT); 4834 log = 1; 4835 goto done; 4836 } 4837 --- 185 unchanged lines hidden (view full) --- 5023 if (action == PF_SYNPROXY_DROP) { 5024 m_freem(*m0); 5025 *m0 = NULL; 5026 action = PF_PASS; 5027 } else if (r->rt) 5028 /* pf_route can free the mbuf causing *m0 to become NULL */ 5029 pf_route(m0, r, dir, ifp, s); 5030 | 5603 5604 if (m->m_pkthdr.len < (int)sizeof(*h)) { 5605 action = PF_DROP; 5606 REASON_SET(&reason, PFRES_SHORT); 5607 log = 1; 5608 goto done; 5609 } 5610 --- 185 unchanged lines hidden (view full) --- 5796 if (action == PF_SYNPROXY_DROP) { 5797 m_freem(*m0); 5798 *m0 = NULL; 5799 action = PF_PASS; 5800 } else if (r->rt) 5801 /* pf_route can free the mbuf causing *m0 to become NULL */ 5802 pf_route(m0, r, dir, ifp, s); 5803 |
5804#if defined(__FreeBSD__) 5805 PF_UNLOCK(); 5806#endif 5807 |
|
5031 return (action); 5032} 5033#endif /* INET */ 5034 5035#ifdef INET6 5036int 5037pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0) 5038{ 5039 u_short action, reason = 0, log = 0; 5040 struct mbuf *m = *m0; 5041 struct ip6_hdr *h; 5042 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr; 5043 struct pf_state *s = NULL; 5044 struct pf_ruleset *ruleset = NULL; 5045 struct pf_pdesc pd; 5046 int off, terminal = 0; 5047 | 5808 return (action); 5809} 5810#endif /* INET */ 5811 5812#ifdef INET6 5813int 5814pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0) 5815{ 5816 u_short action, reason = 0, log = 0; 5817 struct mbuf *m = *m0; 5818 struct ip6_hdr *h; 5819 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr; 5820 struct pf_state *s = NULL; 5821 struct pf_ruleset *ruleset = NULL; 5822 struct pf_pdesc pd; 5823 int off, terminal = 0; 5824 |
5825#if defined(__FreeBSD__) 5826 PF_LOCK(); 5827#endif 5828 |
|
5048 if (!pf_status.running || | 5829 if (!pf_status.running || |
5049 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) | 5830 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) { 5831#if defined(__FreeBSD__) 5832 PF_UNLOCK(); 5833#endif |
5050 return (PF_PASS); | 5834 return (PF_PASS); |
5835 } |
|
5051 | 5836 |
5837#if defined(__FreeBSD__) && (__FreeBSD_version >= 501000) 5838 M_ASSERTPKTHDR(m); 5839#else |
|
5052#ifdef DIAGNOSTIC 5053 if ((m->m_flags & M_PKTHDR) == 0) 5054 panic("non-M_PKTHDR is passed to pf_test"); 5055#endif | 5840#ifdef DIAGNOSTIC 5841 if ((m->m_flags & M_PKTHDR) == 0) 5842 panic("non-M_PKTHDR is passed to pf_test"); 5843#endif |
5844#endif |
|
5056 5057 if (m->m_pkthdr.len < (int)sizeof(*h)) { 5058 action = PF_DROP; 5059 REASON_SET(&reason, PFRES_SHORT); 5060 log = 1; 5061 goto done; 5062 } 5063 --- 189 unchanged lines hidden (view full) --- 5253 if (action == PF_SYNPROXY_DROP) { 5254 m_freem(*m0); 5255 *m0 = NULL; 5256 action = PF_PASS; 5257 } else if (r->rt) 5258 /* pf_route6 can free the mbuf causing *m0 to become NULL */ 5259 pf_route6(m0, r, dir, ifp, s); 5260 | 5845 5846 if (m->m_pkthdr.len < (int)sizeof(*h)) { 5847 action = PF_DROP; 5848 REASON_SET(&reason, PFRES_SHORT); 5849 log = 1; 5850 goto done; 5851 } 5852 --- 189 unchanged lines hidden (view full) --- 6042 if (action == PF_SYNPROXY_DROP) { 6043 m_freem(*m0); 6044 *m0 = NULL; 6045 action = PF_PASS; 6046 } else if (r->rt) 6047 /* pf_route6 can free the mbuf causing *m0 to become NULL */ 6048 pf_route6(m0, r, dir, ifp, s); 6049 |
6050#if defined(__FreeBSD__) 6051 PF_UNLOCK(); 6052#endif |
|
5261 return (action); 5262} 5263#endif /* INET6 */ | 6053 return (action); 6054} 6055#endif /* INET6 */ |