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