pf.c (130397) | pf.c (130613) |
---|---|
1/* $FreeBSD: head/sys/contrib/pf/net/pf.c 130397 2004-06-13 01:36:31Z mlaier $ */ 2/* $OpenBSD: pf.c,v 1.389.2.4 2004/04/30 23:27:57 brad Exp $ */ | 1/* $FreeBSD: head/sys/contrib/pf/net/pf.c 130613 2004-06-16 23:24:02Z mlaier $ */ 2/* $OpenBSD: pf.c,v 1.433 2004/03/26 22:20:57 dhartmei Exp $ */ |
3 4/* 5 * Copyright (c) 2001 Daniel Hartmeier | 3 4/* 5 * Copyright (c) 2001 Daniel Hartmeier |
6 * Copyright (c) 2002,2003 Henning Brauer |
|
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. --- 43 unchanged lines hidden (view full) --- 57#include <sys/mbuf.h> 58#include <sys/filio.h> 59#include <sys/socket.h> 60#include <sys/socketvar.h> 61#include <sys/kernel.h> 62#include <sys/time.h> 63#ifdef __FreeBSD__ 64#include <sys/sysctl.h> | 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * - Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. --- 43 unchanged lines hidden (view full) --- 58#include <sys/mbuf.h> 59#include <sys/filio.h> 60#include <sys/socket.h> 61#include <sys/socketvar.h> 62#include <sys/kernel.h> 63#include <sys/time.h> 64#ifdef __FreeBSD__ 65#include <sys/sysctl.h> |
66#include <sys/endian.h> |
|
65#else 66#include <sys/pool.h> 67#endif 68 69#include <net/if.h> 70#include <net/if_types.h> 71#include <net/bpf.h> 72#include <net/route.h> --- 13 unchanged lines hidden (view full) --- 86#include <netinet/udp_var.h> 87#include <netinet/icmp_var.h> 88 89#ifndef __FreeBSD__ 90#include <dev/rndvar.h> 91#endif 92#include <net/pfvar.h> 93#include <net/if_pflog.h> | 67#else 68#include <sys/pool.h> 69#endif 70 71#include <net/if.h> 72#include <net/if_types.h> 73#include <net/bpf.h> 74#include <net/route.h> --- 13 unchanged lines hidden (view full) --- 88#include <netinet/udp_var.h> 89#include <netinet/icmp_var.h> 90 91#ifndef __FreeBSD__ 92#include <dev/rndvar.h> 93#endif 94#include <net/pfvar.h> 95#include <net/if_pflog.h> |
96 97#if NPFSYNC > 0 |
|
94#include <net/if_pfsync.h> | 98#include <net/if_pfsync.h> |
99#endif /* NPFSYNC > 0 */ |
|
95 96#ifdef INET6 97#include <netinet/ip6.h> 98#include <netinet/in_pcb.h> 99#include <netinet/icmp6.h> 100#include <netinet6/nd6.h> 101#ifdef __FreeBSD__ 102#include <netinet6/ip6_var.h> 103#include <netinet6/in6_pcb.h> 104#endif 105#endif /* INET6 */ 106 | 100 101#ifdef INET6 102#include <netinet/ip6.h> 103#include <netinet/in_pcb.h> 104#include <netinet/icmp6.h> 105#include <netinet6/nd6.h> 106#ifdef __FreeBSD__ 107#include <netinet6/ip6_var.h> 108#include <netinet6/in6_pcb.h> 109#endif 110#endif /* INET6 */ 111 |
107#ifdef ALTQ 108#include <altq/if_altq.h> 109#endif 110 | |
111#ifdef __FreeBSD__ 112#include <machine/in_cksum.h> | 112#ifdef __FreeBSD__ 113#include <machine/in_cksum.h> |
113#if (__FreeBSD_version >= 500112) | |
114#include <sys/limits.h> | 114#include <sys/limits.h> |
115#else 116#include <machine/limits.h> 117#endif | |
118#include <sys/ucred.h> | 115#include <sys/ucred.h> |
119#endif | |
120 | 116 |
121#ifdef __FreeBSD__ | |
122extern int ip_optcopy(struct ip *, struct ip *); | 117extern 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 | 118#endif |
127#endif | |
128 129#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x | 119 120#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; | 121 122/* 123 * Global variables 124 */ 125 126struct pf_anchorqueue pf_anchors; 127struct pf_ruleset pf_main_ruleset; 128struct pf_altqqueue pf_altqs[2]; 129struct pf_palist pf_pabuf; 130struct pf_altqqueue *pf_altqs_active; 131struct pf_altqqueue *pf_altqs_inactive; 132struct pf_status pf_status; |
143struct ifnet *status_ifp; | |
144 145u_int32_t ticket_altqs_active; 146u_int32_t ticket_altqs_inactive; | 133 134u_int32_t ticket_altqs_active; 135u_int32_t ticket_altqs_inactive; |
136int altqs_inactive_open; |
|
147u_int32_t ticket_pabuf; 148 149#ifdef __FreeBSD__ 150struct callout pf_expire_to; /* expire timeout */ 151#else 152struct timeout pf_expire_to; /* expire timeout */ 153#endif 154 155 156#ifdef __FreeBSD__ | 137u_int32_t ticket_pabuf; 138 139#ifdef __FreeBSD__ 140struct callout pf_expire_to; /* expire timeout */ 141#else 142struct timeout pf_expire_to; /* expire timeout */ 143#endif 144 145 146#ifdef __FreeBSD__ |
157uma_zone_t pf_tree_pl, pf_rule_pl, pf_addr_pl; | 147uma_zone_t pf_src_tree_pl, pf_rule_pl; |
158uma_zone_t pf_state_pl, pf_altq_pl, pf_pooladdr_pl; 159#else | 148uma_zone_t pf_state_pl, pf_altq_pl, pf_pooladdr_pl; 149#else |
160struct pool pf_tree_pl, pf_rule_pl, pf_addr_pl; | 150struct pool pf_src_tree_pl, pf_rule_pl; |
161struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl; 162#endif 163 | 151struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl; 152#endif 153 |
164void pf_dynaddr_update(void *); 165#ifdef __FreeBSD__ 166void pf_dynaddr_update_event(void *arg, struct ifnet *ifp); 167#endif | |
168void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); 169void pf_print_state(struct pf_state *); 170void pf_print_flags(u_int8_t); 171 172u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t, 173 u_int8_t); 174void pf_change_ap(struct pf_addr *, u_int16_t *, 175 u_int16_t *, u_int16_t *, struct pf_addr *, --- 8 unchanged lines hidden (view full) --- 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 *, | 154void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); 155void pf_print_state(struct pf_state *); 156void pf_print_flags(u_int8_t); 157 158u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t, 159 u_int8_t); 160void pf_change_ap(struct pf_addr *, u_int16_t *, 161 u_int16_t *, u_int16_t *, struct pf_addr *, --- 8 unchanged lines hidden (view full) --- 170 u_int16_t *, u_int8_t, sa_family_t); 171void pf_send_tcp(const struct pf_rule *, sa_family_t, 172 const struct pf_addr *, const struct pf_addr *, 173 u_int16_t, u_int16_t, u_int32_t, u_int32_t, 174 u_int8_t, u_int16_t, u_int16_t, u_int8_t); 175void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t, 176 sa_family_t, struct pf_rule *); 177struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *, |
192 int, int, struct ifnet *, | 178 int, int, struct pfi_kif *, |
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 *, | 179 struct pf_addr *, u_int16_t, struct pf_addr *, 180 u_int16_t, int); 181struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *, |
196 int, int, struct ifnet *, | 182 int, int, struct pfi_kif *, struct pf_src_node **, |
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 **, | 183 struct pf_addr *, u_int16_t, 184 struct pf_addr *, u_int16_t, 185 struct pf_addr *, u_int16_t *); 186int pf_test_tcp(struct pf_rule **, struct pf_state **, |
201 int, struct ifnet *, struct mbuf *, int, int, | 187 int, struct pfi_kif *, struct mbuf *, int, |
202 void *, struct pf_pdesc *, struct pf_rule **, 203 struct pf_ruleset **); 204int pf_test_udp(struct pf_rule **, struct pf_state **, | 188 void *, struct pf_pdesc *, struct pf_rule **, 189 struct pf_ruleset **); 190int pf_test_udp(struct pf_rule **, struct pf_state **, |
205 int, struct ifnet *, struct mbuf *, int, int, | 191 int, struct pfi_kif *, struct mbuf *, int, |
206 void *, struct pf_pdesc *, struct pf_rule **, 207 struct pf_ruleset **); 208int pf_test_icmp(struct pf_rule **, struct pf_state **, | 192 void *, struct pf_pdesc *, struct pf_rule **, 193 struct pf_ruleset **); 194int pf_test_icmp(struct pf_rule **, struct pf_state **, |
209 int, struct ifnet *, struct mbuf *, int, int, | 195 int, struct pfi_kif *, struct mbuf *, int, |
210 void *, struct pf_pdesc *, struct pf_rule **, 211 struct pf_ruleset **); 212int pf_test_other(struct pf_rule **, struct pf_state **, | 196 void *, struct pf_pdesc *, struct pf_rule **, 197 struct pf_ruleset **); 198int pf_test_other(struct pf_rule **, struct pf_state **, |
213 int, struct ifnet *, struct mbuf *, int, void *, | 199 int, struct pfi_kif *, struct mbuf *, int, void *, |
214 struct pf_pdesc *, struct pf_rule **, 215 struct pf_ruleset **); 216int pf_test_fragment(struct pf_rule **, int, | 200 struct pf_pdesc *, struct pf_rule **, 201 struct pf_ruleset **); 202int pf_test_fragment(struct pf_rule **, int, |
217 struct ifnet *, struct mbuf *, void *, | 203 struct pfi_kif *, struct mbuf *, void *, |
218 struct pf_pdesc *, struct pf_rule **, 219 struct pf_ruleset **); 220int pf_test_state_tcp(struct pf_state **, int, | 204 struct pf_pdesc *, struct pf_rule **, 205 struct pf_ruleset **); 206int pf_test_state_tcp(struct pf_state **, int, |
221 struct ifnet *, struct mbuf *, int, int, | 207 struct pfi_kif *, struct mbuf *, int, |
222 void *, struct pf_pdesc *, u_short *); 223int pf_test_state_udp(struct pf_state **, int, | 208 void *, struct pf_pdesc *, u_short *); 209int pf_test_state_udp(struct pf_state **, int, |
224 struct ifnet *, struct mbuf *, int, int, | 210 struct pfi_kif *, struct mbuf *, int, |
225 void *, struct pf_pdesc *); 226int pf_test_state_icmp(struct pf_state **, int, | 211 void *, struct pf_pdesc *); 212int pf_test_state_icmp(struct pf_state **, int, |
227 struct ifnet *, struct mbuf *, int, int, | 213 struct pfi_kif *, struct mbuf *, int, |
228 void *, struct pf_pdesc *); 229int pf_test_state_other(struct pf_state **, int, | 214 void *, struct pf_pdesc *); 215int pf_test_state_other(struct pf_state **, int, |
230 struct ifnet *, struct pf_pdesc *); | 216 struct pfi_kif *, struct pf_pdesc *); |
231struct pf_tag *pf_get_tag(struct mbuf *); 232int pf_match_tag(struct mbuf *, struct pf_rule *, | 217struct pf_tag *pf_get_tag(struct mbuf *); 218int pf_match_tag(struct mbuf *, struct pf_rule *, |
233 struct pf_rule *, struct pf_rule *, 234 struct pf_tag *, int *); | 219 struct pf_rule *, struct pf_tag *, int *); |
235void pf_hash(struct pf_addr *, struct pf_addr *, 236 struct pf_poolhashkey *, sa_family_t); | 220void pf_hash(struct pf_addr *, struct pf_addr *, 221 struct pf_poolhashkey *, sa_family_t); |
237int pf_map_addr(u_int8_t, struct pf_pool *, | 222int pf_map_addr(u_int8_t, struct pf_rule *, |
238 struct pf_addr *, struct pf_addr *, | 223 struct pf_addr *, struct pf_addr *, |
239 struct pf_addr *); 240int pf_get_sport(sa_family_t, u_int8_t, struct pf_pool *, | 224 struct pf_addr *, struct pf_src_node **); 225int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *, |
241 struct pf_addr *, struct pf_addr *, u_int16_t, | 226 struct pf_addr *, struct pf_addr *, u_int16_t, |
242 struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t); | 227 struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t, 228 struct pf_src_node **); |
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 *); | 229void pf_route(struct mbuf **, struct pf_rule *, int, 230 struct ifnet *, struct pf_state *); 231void pf_route6(struct mbuf **, struct pf_rule *, int, 232 struct ifnet *, struct pf_state *); |
247int pf_socket_lookup(uid_t *, gid_t *, int, sa_family_t, | 233int pf_socket_lookup(uid_t *, gid_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 *); | 234 int, struct pf_pdesc *); 235u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t, 236 sa_family_t); 237u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t, 238 sa_family_t); 239u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, 240 u_int16_t); 241void pf_set_rt_ifp(struct pf_state *, 242 struct pf_addr *); 243int pf_check_proto_cksum(struct mbuf *, int, int, 244 u_int8_t, sa_family_t); 245int pf_addr_wrap_neq(struct pf_addr_wrap *, 246 struct pf_addr_wrap *); |
247static int pf_add_mbuf_tag(struct mbuf *, u_int); 248struct pf_state *pf_find_state_recurse(struct pfi_kif *, 249 struct pf_state *, u_int8_t); |
|
261 262#ifdef __FreeBSD__ 263int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len); 264 265struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX]; 266#else | 250 251#ifdef __FreeBSD__ 252int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len); 253 254struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX]; 255#else |
267struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = 268 { { &pf_state_pl, PFSTATE_HIWAT }, { &pf_frent_pl, PFFRAG_FRENT_HIWAT } }; | 256struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = { 257 { &pf_state_pl, PFSTATE_HIWAT }, 258 { &pf_src_tree_pl, PFSNODE_HIWAT }, 259 { &pf_frent_pl, PFFRAG_FRENT_HIWAT } 260}; |
269#endif 270 271#define STATE_LOOKUP() \ 272 do { \ 273 if (direction == PF_IN) \ | 261#endif 262 263#define STATE_LOOKUP() \ 264 do { \ 265 if (direction == PF_IN) \ |
274 *state = pf_find_state(&tree_ext_gwy, &key); \ | 266 *state = pf_find_state_recurse( \ 267 kif, &key, PF_EXT_GWY); \ |
275 else \ | 268 else \ |
276 *state = pf_find_state(&tree_lan_ext, &key); \ | 269 *state = pf_find_state_recurse( \ 270 kif, &key, PF_LAN_EXT); \ |
277 if (*state == NULL) \ 278 return (PF_DROP); \ 279 if (direction == PF_OUT && \ 280 (((*state)->rule.ptr->rt == PF_ROUTETO && \ 281 (*state)->rule.ptr->direction == PF_OUT) || \ 282 ((*state)->rule.ptr->rt == PF_REPLYTO && \ 283 (*state)->rule.ptr->direction == PF_IN)) && \ | 271 if (*state == NULL) \ 272 return (PF_DROP); \ 273 if (direction == PF_OUT && \ 274 (((*state)->rule.ptr->rt == PF_ROUTETO && \ 275 (*state)->rule.ptr->direction == PF_OUT) || \ 276 ((*state)->rule.ptr->rt == PF_REPLYTO && \ 277 (*state)->rule.ptr->direction == PF_IN)) && \ |
284 (*state)->rt_ifp != NULL && \ 285 (*state)->rt_ifp != ifp) \ | 278 (*state)->rt_kif != NULL && \ 279 (*state)->rt_kif != kif) \ |
286 return (PF_PASS); \ 287 } while (0) 288 289#define STATE_TRANSLATE(s) \ 290 (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \ 291 ((s)->af == AF_INET6 && \ 292 ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \ 293 (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \ 294 (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \ 295 (s)->lan.port != (s)->gwy.port 296 | 280 return (PF_PASS); \ 281 } while (0) 282 283#define STATE_TRANSLATE(s) \ 284 (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \ 285 ((s)->af == AF_INET6 && \ 286 ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \ 287 (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \ 288 (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \ 289 (s)->lan.port != (s)->gwy.port 290 |
297static __inline int pf_state_compare(struct pf_tree_node *, 298 struct pf_tree_node *); | 291#define BOUND_IFACE(r, k) (((r)->rule_flag & PFRULE_IFBOUND) ? (k) : \ 292 ((r)->rule_flag & PFRULE_GRBOUND) ? (k)->pfik_parent : \ 293 (k)->pfik_parent->pfik_parent) |
299 | 294 |
300struct pf_state_tree tree_lan_ext, tree_ext_gwy; 301RB_GENERATE(pf_state_tree, pf_tree_node, entry, pf_state_compare); | 295static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *); 296static __inline int pf_state_compare_lan_ext(struct pf_state *, 297 struct pf_state *); 298static __inline int pf_state_compare_ext_gwy(struct pf_state *, 299 struct pf_state *); 300static __inline int pf_state_compare_id(struct pf_state *, 301 struct pf_state *); |
302 | 302 |
303struct pf_src_tree tree_src_tracking; 304 305struct pf_state_tree_id tree_id; 306struct pf_state_queue state_updates; 307 308RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare); 309RB_GENERATE(pf_state_tree_lan_ext, pf_state, 310 u.s.entry_lan_ext, pf_state_compare_lan_ext); 311RB_GENERATE(pf_state_tree_ext_gwy, pf_state, 312 u.s.entry_ext_gwy, pf_state_compare_ext_gwy); 313RB_GENERATE(pf_state_tree_id, pf_state, 314 u.s.entry_id, pf_state_compare_id); 315 |
|
303#ifdef __FreeBSD__ 304static int 305#else 306static __inline int 307#endif | 316#ifdef __FreeBSD__ 317static int 318#else 319static __inline int 320#endif |
308pf_state_compare(struct pf_tree_node *a, struct pf_tree_node *b) | 321pf_src_compare(struct pf_src_node *a, struct pf_src_node *b) |
309{ 310 int diff; 311 | 322{ 323 int diff; 324 |
325 if (a->rule.ptr > b->rule.ptr) 326 return (1); 327 if (a->rule.ptr < b->rule.ptr) 328 return (-1); 329 if ((diff = a->af - b->af) != 0) 330 return (diff); 331 switch (a->af) { 332#ifdef INET 333 case AF_INET: 334 if (a->addr.addr32[0] > b->addr.addr32[0]) 335 return (1); 336 if (a->addr.addr32[0] < b->addr.addr32[0]) 337 return (-1); 338 break; 339#endif /* INET */ 340#ifdef INET6 341 case AF_INET6: 342 if (a->addr.addr32[3] > b->addr.addr32[3]) 343 return (1); 344 if (a->addr.addr32[3] < b->addr.addr32[3]) 345 return (-1); 346 if (a->addr.addr32[2] > b->addr.addr32[2]) 347 return (1); 348 if (a->addr.addr32[2] < b->addr.addr32[2]) 349 return (-1); 350 if (a->addr.addr32[1] > b->addr.addr32[1]) 351 return (1); 352 if (a->addr.addr32[1] < b->addr.addr32[1]) 353 return (-1); 354 if (a->addr.addr32[0] > b->addr.addr32[0]) 355 return (1); 356 if (a->addr.addr32[0] < b->addr.addr32[0]) 357 return (-1); 358 break; 359#endif /* INET6 */ 360 } 361 return (0); 362} 363 364#ifdef __FreeBSD__ 365static int 366#else 367static __inline int 368#endif 369pf_state_compare_lan_ext(struct pf_state *a, struct pf_state *b) 370{ 371 int diff; 372 |
|
312 if ((diff = a->proto - b->proto) != 0) 313 return (diff); 314 if ((diff = a->af - b->af) != 0) 315 return (diff); 316 switch (a->af) { 317#ifdef INET 318 case AF_INET: | 373 if ((diff = a->proto - b->proto) != 0) 374 return (diff); 375 if ((diff = a->af - b->af) != 0) 376 return (diff); 377 switch (a->af) { 378#ifdef INET 379 case AF_INET: |
319 if (a->addr[0].addr32[0] > b->addr[0].addr32[0]) | 380 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0]) |
320 return (1); | 381 return (1); |
321 if (a->addr[0].addr32[0] < b->addr[0].addr32[0]) | 382 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0]) |
322 return (-1); | 383 return (-1); |
323 if (a->addr[1].addr32[0] > b->addr[1].addr32[0]) | 384 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) |
324 return (1); | 385 return (1); |
325 if (a->addr[1].addr32[0] < b->addr[1].addr32[0]) | 386 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) |
326 return (-1); 327 break; 328#endif /* INET */ 329#ifdef INET6 330 case AF_INET6: | 387 return (-1); 388 break; 389#endif /* INET */ 390#ifdef INET6 391 case AF_INET6: |
331 if (a->addr[0].addr32[3] > b->addr[0].addr32[3]) | 392 if (a->lan.addr.addr32[3] > b->lan.addr.addr32[3]) |
332 return (1); | 393 return (1); |
333 if (a->addr[0].addr32[3] < b->addr[0].addr32[3]) | 394 if (a->lan.addr.addr32[3] < b->lan.addr.addr32[3]) |
334 return (-1); | 395 return (-1); |
335 if (a->addr[1].addr32[3] > b->addr[1].addr32[3]) | 396 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3]) |
336 return (1); | 397 return (1); |
337 if (a->addr[1].addr32[3] < b->addr[1].addr32[3]) | 398 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3]) |
338 return (-1); | 399 return (-1); |
339 if (a->addr[0].addr32[2] > b->addr[0].addr32[2]) | 400 if (a->lan.addr.addr32[2] > b->lan.addr.addr32[2]) |
340 return (1); | 401 return (1); |
341 if (a->addr[0].addr32[2] < b->addr[0].addr32[2]) | 402 if (a->lan.addr.addr32[2] < b->lan.addr.addr32[2]) |
342 return (-1); | 403 return (-1); |
343 if (a->addr[1].addr32[2] > b->addr[1].addr32[2]) | 404 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2]) |
344 return (1); | 405 return (1); |
345 if (a->addr[1].addr32[2] < b->addr[1].addr32[2]) | 406 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2]) |
346 return (-1); | 407 return (-1); |
347 if (a->addr[0].addr32[1] > b->addr[0].addr32[1]) | 408 if (a->lan.addr.addr32[1] > b->lan.addr.addr32[1]) |
348 return (1); | 409 return (1); |
349 if (a->addr[0].addr32[1] < b->addr[0].addr32[1]) | 410 if (a->lan.addr.addr32[1] < b->lan.addr.addr32[1]) |
350 return (-1); | 411 return (-1); |
351 if (a->addr[1].addr32[1] > b->addr[1].addr32[1]) | 412 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1]) |
352 return (1); | 413 return (1); |
353 if (a->addr[1].addr32[1] < b->addr[1].addr32[1]) | 414 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1]) |
354 return (-1); | 415 return (-1); |
355 if (a->addr[0].addr32[0] > b->addr[0].addr32[0]) | 416 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0]) |
356 return (1); | 417 return (1); |
357 if (a->addr[0].addr32[0] < b->addr[0].addr32[0]) | 418 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0]) |
358 return (-1); | 419 return (-1); |
359 if (a->addr[1].addr32[0] > b->addr[1].addr32[0]) | 420 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) |
360 return (1); | 421 return (1); |
361 if (a->addr[1].addr32[0] < b->addr[1].addr32[0]) | 422 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) |
362 return (-1); 363 break; 364#endif /* INET6 */ 365 } 366 | 423 return (-1); 424 break; 425#endif /* INET6 */ 426 } 427 |
367 if ((diff = a->port[0] - b->port[0]) != 0) | 428 if ((diff = a->lan.port - b->lan.port) != 0) |
368 return (diff); | 429 return (diff); |
369 if ((diff = a->port[1] - b->port[1]) != 0) | 430 if ((diff = a->ext.port - b->ext.port) != 0) |
370 return (diff); 371 372 return (0); 373} 374 | 431 return (diff); 432 433 return (0); 434} 435 |
436#ifdef __FreeBSD__ 437static int 438#else 439static __inline int 440#endif 441pf_state_compare_ext_gwy(struct pf_state *a, struct pf_state *b) 442{ 443 int diff; 444 445 if ((diff = a->proto - b->proto) != 0) 446 return (diff); 447 if ((diff = a->af - b->af) != 0) 448 return (diff); 449 switch (a->af) { 450#ifdef INET 451 case AF_INET: 452 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) 453 return (1); 454 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) 455 return (-1); 456 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0]) 457 return (1); 458 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0]) 459 return (-1); 460 break; 461#endif /* INET */ |
|
375#ifdef INET6 | 462#ifdef INET6 |
463 case AF_INET6: 464 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3]) 465 return (1); 466 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3]) 467 return (-1); 468 if (a->gwy.addr.addr32[3] > b->gwy.addr.addr32[3]) 469 return (1); 470 if (a->gwy.addr.addr32[3] < b->gwy.addr.addr32[3]) 471 return (-1); 472 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2]) 473 return (1); 474 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2]) 475 return (-1); 476 if (a->gwy.addr.addr32[2] > b->gwy.addr.addr32[2]) 477 return (1); 478 if (a->gwy.addr.addr32[2] < b->gwy.addr.addr32[2]) 479 return (-1); 480 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1]) 481 return (1); 482 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1]) 483 return (-1); 484 if (a->gwy.addr.addr32[1] > b->gwy.addr.addr32[1]) 485 return (1); 486 if (a->gwy.addr.addr32[1] < b->gwy.addr.addr32[1]) 487 return (-1); 488 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0]) 489 return (1); 490 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0]) 491 return (-1); 492 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0]) 493 return (1); 494 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0]) 495 return (-1); 496 break; 497#endif /* INET6 */ 498 } 499 500 if ((diff = a->ext.port - b->ext.port) != 0) 501 return (diff); 502 if ((diff = a->gwy.port - b->gwy.port) != 0) 503 return (diff); 504 505 return (0); 506} 507 508#ifdef __FreeBSD__ 509static int 510#else 511static __inline int 512#endif 513pf_state_compare_id(struct pf_state *a, struct pf_state *b) 514{ 515 if (a->id > b->id) 516 return (1); 517 if (a->id < b->id) 518 return (-1); 519 if (a->creatorid > b->creatorid) 520 return (1); 521 if (a->creatorid < b->creatorid) 522 return (-1); 523 524 return (0); 525} 526 527#ifdef INET6 |
|
376void 377pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af) 378{ 379 switch (af) { 380#ifdef INET 381 case AF_INET: 382 dst->addr32[0] = src->addr32[0]; 383 break; --- 4 unchanged lines hidden (view full) --- 388 dst->addr32[2] = src->addr32[2]; 389 dst->addr32[3] = src->addr32[3]; 390 break; 391 } 392} 393#endif 394 395struct pf_state * | 528void 529pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af) 530{ 531 switch (af) { 532#ifdef INET 533 case AF_INET: 534 dst->addr32[0] = src->addr32[0]; 535 break; --- 4 unchanged lines hidden (view full) --- 540 dst->addr32[2] = src->addr32[2]; 541 dst->addr32[3] = src->addr32[3]; 542 break; 543 } 544} 545#endif 546 547struct pf_state * |
396pf_find_state(struct pf_state_tree *tree, struct pf_tree_node *key) | 548pf_find_state_byid(struct pf_state *key) |
397{ | 549{ |
398 struct pf_tree_node *k; | 550 pf_status.fcounters[FCNT_STATE_SEARCH]++; 551 return (RB_FIND(pf_state_tree_id, &tree_id, key)); 552} |
399 | 553 |
554struct pf_state * 555pf_find_state_recurse(struct pfi_kif *kif, struct pf_state *key, u_int8_t tree) 556{ 557 struct pf_state *s; 558 |
|
400 pf_status.fcounters[FCNT_STATE_SEARCH]++; | 559 pf_status.fcounters[FCNT_STATE_SEARCH]++; |
401 k = RB_FIND(pf_state_tree, tree, key); 402 if (k) 403 return (k->state); 404 else | 560 561 switch (tree) { 562 case PF_LAN_EXT: 563 for (; kif != NULL; kif = kif->pfik_parent) { 564 s = RB_FIND(pf_state_tree_lan_ext, 565 &kif->pfik_lan_ext, key); 566 if (s != NULL) 567 return (s); 568 } |
405 return (NULL); | 569 return (NULL); |
570 case PF_EXT_GWY: 571 for (; kif != NULL; kif = kif->pfik_parent) { 572 s = RB_FIND(pf_state_tree_ext_gwy, 573 &kif->pfik_ext_gwy, key); 574 if (s != NULL) 575 return (s); 576 } 577 return (NULL); 578 default: 579 panic("pf_find_state_recurse"); 580 } |
|
406} 407 | 581} 582 |
583struct pf_state * 584pf_find_state_all(struct pf_state *key, u_int8_t tree, int *more) 585{ 586 struct pf_state *s, *ss = NULL; 587 struct pfi_kif *kif; 588 589 pf_status.fcounters[FCNT_STATE_SEARCH]++; 590 591 switch (tree) { 592 case PF_LAN_EXT: 593 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) { 594 s = RB_FIND(pf_state_tree_lan_ext, 595 &kif->pfik_lan_ext, key); 596 if (s == NULL) 597 continue; 598 if (more == NULL) 599 return (s); 600 ss = s; 601 (*more)++; 602 } 603 return (ss); 604 case PF_EXT_GWY: 605 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) { 606 s = RB_FIND(pf_state_tree_ext_gwy, 607 &kif->pfik_ext_gwy, key); 608 if (s == NULL) 609 continue; 610 if (more == NULL) 611 return (s); 612 ss = s; 613 (*more)++; 614 } 615 return (ss); 616 default: 617 panic("pf_find_state_all"); 618 } 619} 620 |
|
408int | 621int |
409pf_insert_state(struct pf_state *state) | 622pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule, 623 struct pf_addr *src, sa_family_t af) |
410{ | 624{ |
411 struct pf_tree_node *keya, *keyb; | 625 struct pf_src_node k; |
412 | 626 |
413 keya = pool_get(&pf_tree_pl, PR_NOWAIT); 414 if (keya == NULL) 415 return (-1); 416 keya->state = state; 417 keya->proto = state->proto; 418 keya->af = state->af; 419 PF_ACPY(&keya->addr[0], &state->lan.addr, state->af); 420 keya->port[0] = state->lan.port; 421 PF_ACPY(&keya->addr[1], &state->ext.addr, state->af); 422 keya->port[1] = state->ext.port; | 627 if (*sn == NULL) { 628 k.af = af; 629 PF_ACPY(&k.addr, src, af); 630 if (rule->rule_flag & PFRULE_RULESRCTRACK || 631 rule->rpool.opts & PF_POOL_STICKYADDR) 632 k.rule.ptr = rule; 633 else 634 k.rule.ptr = NULL; 635 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++; 636 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k); 637 } 638 if (*sn == NULL) { 639 if (!rule->max_src_nodes || 640 rule->src_nodes < rule->max_src_nodes) 641 (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT); 642 if ((*sn) == NULL) 643 return (-1); 644 bzero(*sn, sizeof(struct pf_src_node)); 645 (*sn)->af = af; 646 if (rule->rule_flag & PFRULE_RULESRCTRACK || 647 rule->rpool.opts & PF_POOL_STICKYADDR) 648 (*sn)->rule.ptr = rule; 649 else 650 (*sn)->rule.ptr = NULL; 651 PF_ACPY(&(*sn)->addr, src, af); 652 if (RB_INSERT(pf_src_tree, 653 &tree_src_tracking, *sn) != NULL) { 654 if (pf_status.debug >= PF_DEBUG_MISC) { 655 printf("pf: src_tree insert failed: "); 656 pf_print_host(&(*sn)->addr, 0, af); 657 printf("\n"); 658 } 659 pool_put(&pf_src_tree_pl, *sn); 660 return (-1); 661 } 662#ifdef __FreeBSD__ 663 (*sn)->creation = time_second; 664#else 665 (*sn)->creation = time.tv_sec; 666#endif 667 (*sn)->ruletype = rule->action; 668 if ((*sn)->rule.ptr != NULL) 669 (*sn)->rule.ptr->src_nodes++; 670 pf_status.scounters[SCNT_SRC_NODE_INSERT]++; 671 pf_status.src_nodes++; 672 } else { 673 if (rule->max_src_states && 674 (*sn)->states >= rule->max_src_states) 675 return (-1); 676 } 677 return (0); 678} |
423 | 679 |
680int 681pf_insert_state(struct pfi_kif *kif, struct pf_state *state) 682{ |
|
424 /* Thou MUST NOT insert multiple duplicate keys */ | 683 /* Thou MUST NOT insert multiple duplicate keys */ |
425 if (RB_INSERT(pf_state_tree, &tree_lan_ext, keya) != NULL) { | 684 state->u.s.kif = kif; 685 if (RB_INSERT(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state)) { |
426 if (pf_status.debug >= PF_DEBUG_MISC) { 427 printf("pf: state insert failed: tree_lan_ext"); 428 printf(" lan: "); 429 pf_print_host(&state->lan.addr, state->lan.port, 430 state->af); 431 printf(" gwy: "); 432 pf_print_host(&state->gwy.addr, state->gwy.port, 433 state->af); 434 printf(" ext: "); 435 pf_print_host(&state->ext.addr, state->ext.port, 436 state->af); | 686 if (pf_status.debug >= PF_DEBUG_MISC) { 687 printf("pf: state insert failed: tree_lan_ext"); 688 printf(" lan: "); 689 pf_print_host(&state->lan.addr, state->lan.port, 690 state->af); 691 printf(" gwy: "); 692 pf_print_host(&state->gwy.addr, state->gwy.port, 693 state->af); 694 printf(" ext: "); 695 pf_print_host(&state->ext.addr, state->ext.port, 696 state->af); |
697 if (state->sync_flags & PFSTATE_FROMSYNC) 698 printf(" (from sync)"); |
|
437 printf("\n"); 438 } | 699 printf("\n"); 700 } |
439 pool_put(&pf_tree_pl, keya); | |
440 return (-1); 441 } 442 | 701 return (-1); 702 } 703 |
443 keyb = pool_get(&pf_tree_pl, PR_NOWAIT); 444 if (keyb == NULL) { 445 /* Need to pull out the other state */ 446 RB_REMOVE(pf_state_tree, &tree_lan_ext, keya); 447 pool_put(&pf_tree_pl, keya); 448 return (-1); 449 } 450 keyb->state = state; 451 keyb->proto = state->proto; 452 keyb->af = state->af; 453 PF_ACPY(&keyb->addr[0], &state->ext.addr, state->af); 454 keyb->port[0] = state->ext.port; 455 PF_ACPY(&keyb->addr[1], &state->gwy.addr, state->af); 456 keyb->port[1] = state->gwy.port; 457 458 if (RB_INSERT(pf_state_tree, &tree_ext_gwy, keyb) != NULL) { | 704 if (RB_INSERT(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state)) { |
459 if (pf_status.debug >= PF_DEBUG_MISC) { 460 printf("pf: state insert failed: tree_ext_gwy"); 461 printf(" lan: "); 462 pf_print_host(&state->lan.addr, state->lan.port, 463 state->af); 464 printf(" gwy: "); 465 pf_print_host(&state->gwy.addr, state->gwy.port, 466 state->af); 467 printf(" ext: "); 468 pf_print_host(&state->ext.addr, state->ext.port, 469 state->af); | 705 if (pf_status.debug >= PF_DEBUG_MISC) { 706 printf("pf: state insert failed: tree_ext_gwy"); 707 printf(" lan: "); 708 pf_print_host(&state->lan.addr, state->lan.port, 709 state->af); 710 printf(" gwy: "); 711 pf_print_host(&state->gwy.addr, state->gwy.port, 712 state->af); 713 printf(" ext: "); 714 pf_print_host(&state->ext.addr, state->ext.port, 715 state->af); |
716 if (state->sync_flags & PFSTATE_FROMSYNC) 717 printf(" (from sync)"); |
|
470 printf("\n"); 471 } | 718 printf("\n"); 719 } |
472 RB_REMOVE(pf_state_tree, &tree_lan_ext, keya); 473 pool_put(&pf_tree_pl, keya); 474 pool_put(&pf_tree_pl, keyb); | 720 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state); |
475 return (-1); 476 } 477 | 721 return (-1); 722 } 723 |
724 if (state->id == 0 && state->creatorid == 0) { 725 state->id = htobe64(pf_status.stateid++); 726 state->creatorid = pf_status.hostid; 727 } 728 if (RB_INSERT(pf_state_tree_id, &tree_id, state) != NULL) { 729 if (pf_status.debug >= PF_DEBUG_MISC) { 730#ifdef __FreeBSD__ 731 printf("pf: state insert failed: " 732 "id: %016llx creatorid: %08x", 733 (long long)be64toh(state->id), 734 ntohl(state->creatorid)); 735#else 736 printf("pf: state insert failed: " 737 "id: %016llx creatorid: %08x", 738 betoh64(state->id), ntohl(state->creatorid)); 739#endif 740 if (state->sync_flags & PFSTATE_FROMSYNC) 741 printf(" (from sync)"); 742 printf("\n"); 743 } 744 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state); 745 RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state); 746 return (-1); 747 } 748 TAILQ_INSERT_HEAD(&state_updates, state, u.s.entry_updates); 749 |
|
478 pf_status.fcounters[FCNT_STATE_INSERT]++; 479 pf_status.states++; | 750 pf_status.fcounters[FCNT_STATE_INSERT]++; 751 pf_status.states++; |
752 pfi_attach_state(kif); |
|
480#if NPFSYNC 481 pfsync_insert_state(state); 482#endif 483 return (0); 484} 485 486void 487pf_purge_timeout(void *arg) --- 6 unchanged lines hidden (view full) --- 494 int s; 495 496#ifdef __FreeBSD__ 497 PF_LOCK(); 498#endif 499 s = splsoftnet(); 500 pf_purge_expired_states(); 501 pf_purge_expired_fragments(); | 753#if NPFSYNC 754 pfsync_insert_state(state); 755#endif 756 return (0); 757} 758 759void 760pf_purge_timeout(void *arg) --- 6 unchanged lines hidden (view full) --- 767 int s; 768 769#ifdef __FreeBSD__ 770 PF_LOCK(); 771#endif 772 s = splsoftnet(); 773 pf_purge_expired_states(); 774 pf_purge_expired_fragments(); |
775 pf_purge_expired_src_nodes(); |
|
502 splx(s); 503#ifdef __FreeBSD__ 504 PF_UNLOCK(); 505#endif 506 507#ifdef __FreeBSD__ 508 callout_reset(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz, 509 pf_purge_timeout, to); --- 47 unchanged lines hidden (view full) --- 557#else 558 return (time.tv_sec); 559#endif 560 } 561 return (state->expire + timeout); 562} 563 564void | 776 splx(s); 777#ifdef __FreeBSD__ 778 PF_UNLOCK(); 779#endif 780 781#ifdef __FreeBSD__ 782 callout_reset(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz, 783 pf_purge_timeout, to); --- 47 unchanged lines hidden (view full) --- 831#else 832 return (time.tv_sec); 833#endif 834 } 835 return (state->expire + timeout); 836} 837 838void |
565pf_purge_expired_states(void) | 839pf_purge_expired_src_nodes(void) |
566{ | 840{ |
567 struct pf_tree_node *cur, *peer, *next; 568 struct pf_tree_node key; | 841 struct pf_src_node *cur, *next; |
569 | 842 |
570 for (cur = RB_MIN(pf_state_tree, &tree_ext_gwy); cur; cur = next) { 571 next = RB_NEXT(pf_state_tree, &tree_ext_gwy, cur); | 843 for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) { 844 next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur); |
572 573#ifdef __FreeBSD__ | 845 846#ifdef __FreeBSD__ |
574 if (pf_state_expires(cur->state) <= (u_int32_t)time_second) { | 847 if (cur->states <= 0 && cur->expire <= time_second) { |
575#else | 848#else |
576 if (pf_state_expires(cur->state) <= time.tv_sec) { | 849 if (cur->states <= 0 && cur->expire <= time.tv_sec) { |
577#endif | 850#endif |
578 if (cur->state->src.state == PF_TCPS_PROXY_DST) 579 pf_send_tcp(cur->state->rule.ptr, 580 cur->state->af, 581 &cur->state->ext.addr, 582 &cur->state->lan.addr, 583 cur->state->ext.port, 584 cur->state->lan.port, 585 cur->state->src.seqhi, 586 cur->state->src.seqlo + 1, 587 0, 588 TH_RST|TH_ACK, 0, 0); 589 RB_REMOVE(pf_state_tree, &tree_ext_gwy, cur); | 851 if (cur->rule.ptr != NULL) { 852 cur->rule.ptr->src_nodes--; 853 if (cur->rule.ptr->states <= 0 && 854 cur->rule.ptr->max_src_nodes <= 0) 855 pf_rm_rule(NULL, cur->rule.ptr); 856 } 857 RB_REMOVE(pf_src_tree, &tree_src_tracking, cur); 858 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 859 pf_status.src_nodes--; 860 pool_put(&pf_src_tree_pl, cur); 861 } 862 } 863} |
590 | 864 |
591 /* Need this key's peer (in the other tree) */ 592 key.state = cur->state; 593 key.proto = cur->state->proto; 594 key.af = cur->state->af; 595 PF_ACPY(&key.addr[0], &cur->state->lan.addr, 596 cur->state->af); 597 key.port[0] = cur->state->lan.port; 598 PF_ACPY(&key.addr[1], &cur->state->ext.addr, 599 cur->state->af); 600 key.port[1] = cur->state->ext.port; | 865void 866pf_src_tree_remove_state(struct pf_state *s) 867{ 868 u_int32_t timeout; |
601 | 869 |
602 peer = RB_FIND(pf_state_tree, &tree_lan_ext, &key); | 870 if (s->src_node != NULL) { 871 if (--s->src_node->states <= 0) { 872 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE]; 873 if (!timeout) 874 timeout = 875 pf_default_rule.timeout[PFTM_SRC_NODE]; |
603#ifdef __FreeBSD__ | 876#ifdef __FreeBSD__ |
604 KASSERT((peer), ("peer null :%s", __FUNCTION__)); 605 KASSERT((peer->state == cur->state), 606 ("peer->state != cur->state: %s", __FUNCTION__)); | 877 s->src_node->expire = time_second + timeout; |
607#else | 878#else |
608 KASSERT(peer); 609 KASSERT(peer->state == cur->state); | 879 s->src_node->expire = time.tv_sec + timeout; |
610#endif | 880#endif |
611 RB_REMOVE(pf_state_tree, &tree_lan_ext, peer); | 881 } 882 } 883 if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) { 884 if (--s->nat_src_node->states <= 0) { 885 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE]; 886 if (!timeout) 887 timeout = 888 pf_default_rule.timeout[PFTM_SRC_NODE]; 889#ifdef __FreeBSD__ 890 s->nat_src_node->expire = time_second + timeout; 891#else 892 s->nat_src_node->expire = time.tv_sec + timeout; 893#endif 894 } 895 } 896 s->src_node = s->nat_src_node = NULL; 897} |
612 | 898 |
899void 900pf_purge_expired_states(void) 901{ 902 struct pf_state *cur, *next; 903 904 for (cur = RB_MIN(pf_state_tree_id, &tree_id); 905 cur; cur = next) { 906 next = RB_NEXT(pf_state_tree_id, &tree_id, cur); 907 908#ifdef __FreeBSD__ 909 if (pf_state_expires(cur) <= time_second) { 910#else 911 if (pf_state_expires(cur) <= time.tv_sec) { 912#endif 913 if (cur->src.state == PF_TCPS_PROXY_DST) 914 pf_send_tcp(cur->rule.ptr, cur->af, 915 &cur->ext.addr, &cur->lan.addr, 916 cur->ext.port, cur->lan.port, 917 cur->src.seqhi, cur->src.seqlo + 1, 0, 918 TH_RST|TH_ACK, 0, 0); 919 RB_REMOVE(pf_state_tree_ext_gwy, 920 &cur->u.s.kif->pfik_ext_gwy, cur); 921 RB_REMOVE(pf_state_tree_lan_ext, 922 &cur->u.s.kif->pfik_lan_ext, cur); 923 RB_REMOVE(pf_state_tree_id, &tree_id, cur); |
|
613#if NPFSYNC | 924#if NPFSYNC |
614 pfsync_delete_state(cur->state); | 925 pfsync_delete_state(cur); |
615#endif | 926#endif |
616 if (--cur->state->rule.ptr->states <= 0) 617 pf_rm_rule(NULL, cur->state->rule.ptr); 618 if (cur->state->nat_rule.ptr != NULL) 619 if (--cur->state->nat_rule.ptr->states <= 0) 620 pf_rm_rule(NULL, 621 cur->state->nat_rule.ptr); 622 if (cur->state->anchor.ptr != NULL) 623 if (--cur->state->anchor.ptr->states <= 0) 624 pf_rm_rule(NULL, 625 cur->state->anchor.ptr); 626 pf_normalize_tcp_cleanup(cur->state); 627 pool_put(&pf_state_pl, cur->state); 628 pool_put(&pf_tree_pl, cur); 629 pool_put(&pf_tree_pl, peer); | 927 pf_src_tree_remove_state(cur); 928 if (--cur->rule.ptr->states <= 0 && 929 cur->rule.ptr->src_nodes <= 0) 930 pf_rm_rule(NULL, cur->rule.ptr); 931 if (cur->nat_rule.ptr != NULL) 932 if (--cur->nat_rule.ptr->states <= 0 && 933 cur->nat_rule.ptr->src_nodes <= 0) 934 pf_rm_rule(NULL, cur->nat_rule.ptr); 935 if (cur->anchor.ptr != NULL) 936 if (--cur->anchor.ptr->states <= 0) 937 pf_rm_rule(NULL, cur->anchor.ptr); 938 pf_normalize_tcp_cleanup(cur); 939 pfi_detach_state(cur->u.s.kif); 940 TAILQ_REMOVE(&state_updates, cur, u.s.entry_updates); 941 pool_put(&pf_state_pl, cur); |
630 pf_status.fcounters[FCNT_STATE_REMOVALS]++; 631 pf_status.states--; 632 } 633 } 634} 635 636int 637pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw) --- 23 unchanged lines hidden (view full) --- 661 return; 662 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL) 663 kt = kt->pfrkt_root; 664 aw->p.tbl = NULL; 665 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ? 666 kt->pfrkt_cnt : -1; 667} 668 | 942 pf_status.fcounters[FCNT_STATE_REMOVALS]++; 943 pf_status.states--; 944 } 945 } 946} 947 948int 949pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw) --- 23 unchanged lines hidden (view full) --- 973 return; 974 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL) 975 kt = kt->pfrkt_root; 976 aw->p.tbl = NULL; 977 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ? 978 kt->pfrkt_cnt : -1; 979} 980 |
669int 670pf_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af) 671{ 672 if (aw->type != PF_ADDR_DYNIFTL) 673 return (0); 674 aw->p.dyn = pool_get(&pf_addr_pl, PR_NOWAIT); 675 if (aw->p.dyn == NULL) 676 return (1); 677 bcopy(aw->v.ifname, aw->p.dyn->ifname, sizeof(aw->p.dyn->ifname)); 678 aw->p.dyn->ifp = ifunit(aw->p.dyn->ifname); 679 if (aw->p.dyn->ifp == NULL) { 680 pool_put(&pf_addr_pl, aw->p.dyn); 681 aw->p.dyn = NULL; 682 return (1); 683 } 684 aw->p.dyn->addr = &aw->v.a.addr; 685 aw->p.dyn->af = af; 686 aw->p.dyn->undefined = 1; 687#ifndef __FreeBSD__ 688 aw->p.dyn->hook_cookie = hook_establish( 689 aw->p.dyn->ifp->if_addrhooks, 1, 690 pf_dynaddr_update, aw->p.dyn); 691 if (aw->p.dyn->hook_cookie == NULL) { 692 pool_put(&pf_addr_pl, aw->p.dyn); 693 aw->p.dyn = NULL; 694 return (1); 695 } 696#else 697 PF_UNLOCK(); 698 aw->p.dyn->hook_cookie = EVENTHANDLER_REGISTER(ifaddr_event, 699 pf_dynaddr_update_event, aw->p.dyn, EVENTHANDLER_PRI_ANY); 700 PF_LOCK(); 701 if (aw->p.dyn->hook_cookie == NULL) { 702 pool_put(&pf_addr_pl, aw->p.dyn); 703 aw->p.dyn = NULL; 704 return (1); 705 } 706#endif 707 pf_dynaddr_update(aw->p.dyn); 708 return (0); 709} 710 711#ifdef __FreeBSD__ | |
712void | 981void |
713pf_dynaddr_update_event(void *arg, struct ifnet *ifp) 714{ 715 PF_LOCK(); 716 pf_dynaddr_update(arg); 717 PF_UNLOCK(); 718} 719#endif 720 721void 722pf_dynaddr_update(void *p) 723{ 724 struct pf_addr_dyn *ad = (struct pf_addr_dyn *)p; 725 struct ifaddr *ia; 726 int s, changed = 0; 727 728 if (ad == NULL || ad->ifp == NULL) 729 panic("pf_dynaddr_update"); 730 s = splsoftnet(); 731 TAILQ_FOREACH(ia, &ad->ifp->if_addrlist, ifa_list) 732 if (ia->ifa_addr != NULL && 733 ia->ifa_addr->sa_family == ad->af) { 734 if (ad->af == AF_INET) { 735 struct in_addr *a, *b; 736 737 a = &ad->addr->v4; 738 b = &((struct sockaddr_in *)ia->ifa_addr) 739 ->sin_addr; 740 if (ad->undefined || 741 memcmp(a, b, sizeof(*a))) { 742 bcopy(b, a, sizeof(*a)); 743 changed = 1; 744 } 745 } else if (ad->af == AF_INET6) { 746 struct in6_addr *a, *b; 747 748 a = &ad->addr->v6; 749 b = &((struct sockaddr_in6 *)ia->ifa_addr) 750 ->sin6_addr; 751 if (ad->undefined || 752 memcmp(a, b, sizeof(*a))) { 753 bcopy(b, a, sizeof(*a)); 754 changed = 1; 755 } 756 } 757 if (changed) 758 ad->undefined = 0; 759 break; 760 } 761 if (ia == NULL) 762 ad->undefined = 1; 763 splx(s); 764} 765 766void 767pf_dynaddr_remove(struct pf_addr_wrap *aw) 768{ 769 if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL) 770 return; 771#ifndef __FreeBSD__ 772 hook_disestablish(aw->p.dyn->ifp->if_addrhooks, 773 aw->p.dyn->hook_cookie); 774#else 775 PF_UNLOCK(); 776 EVENTHANDLER_DEREGISTER(ifaddr_event, aw->p.dyn->hook_cookie); 777 PF_LOCK(); 778#endif 779 pool_put(&pf_addr_pl, aw->p.dyn); 780 aw->p.dyn = NULL; 781} 782 783void 784pf_dynaddr_copyout(struct pf_addr_wrap *aw) 785{ 786 if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL) 787 return; 788 bcopy(aw->p.dyn->ifname, aw->v.ifname, sizeof(aw->v.ifname)); 789 aw->p.dyn = (struct pf_addr_dyn *)1; 790} 791 792void | |
793pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af) 794{ 795 switch (af) { 796#ifdef INET 797 case AF_INET: { 798 u_int32_t a = ntohl(addr->addr32[0]); 799 printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255, 800 (a>>8)&255, a&255); --- 128 unchanged lines hidden (view full) --- 929 int i; 930 931 cur = TAILQ_FIRST(rules); 932 prev = cur; 933 for (i = 0; i < PF_SKIP_COUNT; ++i) 934 head[i] = cur; 935 while (cur != NULL) { 936 | 982pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af) 983{ 984 switch (af) { 985#ifdef INET 986 case AF_INET: { 987 u_int32_t a = ntohl(addr->addr32[0]); 988 printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255, 989 (a>>8)&255, a&255); --- 128 unchanged lines hidden (view full) --- 1118 int i; 1119 1120 cur = TAILQ_FIRST(rules); 1121 prev = cur; 1122 for (i = 0; i < PF_SKIP_COUNT; ++i) 1123 head[i] = cur; 1124 while (cur != NULL) { 1125 |
937 if (cur->ifp != prev->ifp || cur->ifnot != prev->ifnot) | 1126 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot) |
938 PF_SET_SKIP_STEPS(PF_SKIP_IFP); 939 if (cur->direction != prev->direction) 940 PF_SET_SKIP_STEPS(PF_SKIP_DIR); 941 if (cur->af != prev->af) 942 PF_SET_SKIP_STEPS(PF_SKIP_AF); 943 if (cur->proto != prev->proto) 944 PF_SET_SKIP_STEPS(PF_SKIP_PROTO); 945 if (cur->src.not != prev->src.not || --- 26 unchanged lines hidden (view full) --- 972 switch (aw1->type) { 973 case PF_ADDR_ADDRMASK: 974 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0)) 975 return (1); 976 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0)) 977 return (1); 978 return (0); 979 case PF_ADDR_DYNIFTL: | 1127 PF_SET_SKIP_STEPS(PF_SKIP_IFP); 1128 if (cur->direction != prev->direction) 1129 PF_SET_SKIP_STEPS(PF_SKIP_DIR); 1130 if (cur->af != prev->af) 1131 PF_SET_SKIP_STEPS(PF_SKIP_AF); 1132 if (cur->proto != prev->proto) 1133 PF_SET_SKIP_STEPS(PF_SKIP_PROTO); 1134 if (cur->src.not != prev->src.not || --- 26 unchanged lines hidden (view full) --- 1161 switch (aw1->type) { 1162 case PF_ADDR_ADDRMASK: 1163 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0)) 1164 return (1); 1165 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0)) 1166 return (1); 1167 return (0); 1168 case PF_ADDR_DYNIFTL: |
980 if (aw1->p.dyn->ifp != aw2->p.dyn->ifp) 981 return (1); 982 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0)) 983 return (1); 984 return (0); | 1169 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt); |
985 case PF_ADDR_NOROUTE: 986 return (0); 987 case PF_ADDR_TABLE: 988 return (aw1->p.tbl != aw2->p.tbl); 989 default: 990 printf("invalid address type: %d\n", aw1->type); 991 return (1); 992 } 993} 994 995void | 1170 case PF_ADDR_NOROUTE: 1171 return (0); 1172 case PF_ADDR_TABLE: 1173 return (aw1->p.tbl != aw2->p.tbl); 1174 default: 1175 printf("invalid address type: %d\n", aw1->type); 1176 return (1); 1177 } 1178} 1179 1180void |
996pf_rule_set_qid(struct pf_rulequeue *rules) 997{ 998 struct pf_rule *rule; 999 1000 TAILQ_FOREACH(rule, rules, entries) 1001 if (rule->qname[0] != 0) { 1002 rule->qid = pf_qname_to_qid(rule->qname); 1003 if (rule->pqname[0] != 0) 1004 rule->pqid = pf_qname_to_qid(rule->pqname); 1005 else 1006 rule->pqid = rule->qid; 1007 } 1008} 1009 1010u_int32_t 1011pf_qname_to_qid(char *qname) 1012{ 1013 struct pf_altq *altq; 1014 1015 TAILQ_FOREACH(altq, pf_altqs_active, entries) 1016 if (!strcmp(altq->qname, qname)) 1017 return (altq->qid); 1018 1019 return (0); 1020} 1021 1022void | |
1023pf_update_anchor_rules() 1024{ 1025 struct pf_rule *rule; 1026 int i; 1027 1028 for (i = 0; i < PF_RULESET_MAX; ++i) 1029 TAILQ_FOREACH(rule, pf_main_ruleset.rules[i].active.ptr, 1030 entries) --- 196 unchanged lines hidden (view full) --- 1227 struct ip *h = NULL; /* make the compiler happy */ 1228#endif /* INET */ 1229#ifdef INET6 1230 struct ip6_hdr *h6 = NULL; /* make the compiler happy */ 1231#endif /* INET6 */ 1232 struct tcphdr *th = NULL; /* make the compiler happy */ 1233#ifdef __FreeBSD__ 1234 struct ip *ip; | 1181pf_update_anchor_rules() 1182{ 1183 struct pf_rule *rule; 1184 int i; 1185 1186 for (i = 0; i < PF_RULESET_MAX; ++i) 1187 TAILQ_FOREACH(rule, pf_main_ruleset.rules[i].active.ptr, 1188 entries) --- 196 unchanged lines hidden (view full) --- 1385 struct ip *h = NULL; /* make the compiler happy */ 1386#endif /* INET */ 1387#ifdef INET6 1388 struct ip6_hdr *h6 = NULL; /* make the compiler happy */ 1389#endif /* INET6 */ 1390 struct tcphdr *th = NULL; /* make the compiler happy */ 1391#ifdef __FreeBSD__ 1392 struct ip *ip; |
1235#if (__FreeBSD_version < 501114) 1236 struct route ro; | |
1237#endif | 1393#endif |
1238#endif | |
1239 char *opt; 1240 1241 /* maximum segment size tcp option */ 1242 tlen = sizeof(struct tcphdr); 1243 if (mss) 1244 tlen += 4; 1245 1246 switch (af) { --- 90 unchanged lines hidden (view full) --- 1337 /* TCP checksum */ 1338 th->th_sum = in_cksum(m, len); 1339 1340 /* Finish the IP header */ 1341 h->ip_v = 4; 1342 h->ip_hl = sizeof(*h) >> 2; 1343 h->ip_tos = IPTOS_LOWDELAY; 1344#ifdef __FreeBSD__ | 1394 char *opt; 1395 1396 /* maximum segment size tcp option */ 1397 tlen = sizeof(struct tcphdr); 1398 if (mss) 1399 tlen += 4; 1400 1401 switch (af) { --- 90 unchanged lines hidden (view full) --- 1492 /* TCP checksum */ 1493 th->th_sum = in_cksum(m, len); 1494 1495 /* Finish the IP header */ 1496 h->ip_v = 4; 1497 h->ip_hl = sizeof(*h) >> 2; 1498 h->ip_tos = IPTOS_LOWDELAY; 1499#ifdef __FreeBSD__ |
1345 h->ip_off = htons(path_mtu_discovery ? IP_DF : 0); | 1500 h->ip_off = path_mtu_discovery ? IP_DF : 0; 1501 h->ip_len = len; |
1346#else 1347 h->ip_off = htons(ip_mtudisc ? IP_DF : 0); | 1502#else 1503 h->ip_off = htons(ip_mtudisc ? IP_DF : 0); |
1348#endif | |
1349 h->ip_len = htons(len); | 1504 h->ip_len = htons(len); |
1505#endif |
|
1350 h->ip_ttl = ttl ? ttl : ip_defttl; 1351 h->ip_sum = 0; 1352#ifdef __FreeBSD__ 1353 ip = mtod(m, struct ip *); | 1506 h->ip_ttl = ttl ? ttl : ip_defttl; 1507 h->ip_sum = 0; 1508#ifdef __FreeBSD__ 1509 ip = mtod(m, struct ip *); |
1354 /* 1355 * XXX 1356 * OpenBSD changed ip_len/ip_off byte ordering! 1357 * Because FreeBSD assumes host byte ordering we need to 1358 * change here. 1359 */ 1360 NTOHS(ip->ip_len); 1361 NTOHS(ip->ip_off); 1362#if (__FreeBSD_version < 501114) 1363 bzero(&ro, sizeof(ro)); 1364 ip_rtaddr(ip->ip_dst, &ro); | |
1365 PF_UNLOCK(); | 1510 PF_UNLOCK(); |
1366 ip_output(m, (void *)NULL, &ro, 0, (void *)NULL, 1367 (void *)NULL); 1368 PF_LOCK(); 1369 if(ro.ro_rt) { 1370 RTFREE(ro.ro_rt); 1371 } 1372#else /* __FreeBSD_version >= 501114 */ 1373 PF_UNLOCK(); | |
1374 ip_output(m, (void *)NULL, (void *)NULL, 0, (void *)NULL, 1375 (void *)NULL); 1376 PF_LOCK(); | 1511 ip_output(m, (void *)NULL, (void *)NULL, 0, (void *)NULL, 1512 (void *)NULL); 1513 PF_LOCK(); |
1377#endif | |
1378#else /* ! __FreeBSD__ */ 1379 ip_output(m, (void *)NULL, (void *)NULL, 0, (void *)NULL, 1380 (void *)NULL); 1381#endif 1382 break; 1383#endif /* INET */ 1384#ifdef INET6 1385 case AF_INET6: --- 61 unchanged lines hidden (view full) --- 1447 case AF_INET: 1448#ifdef __FreeBSD__ 1449 /* icmp_error() expects host byte ordering */ 1450 ip = mtod(m0, struct ip *); 1451 NTOHS(ip->ip_len); 1452 NTOHS(ip->ip_off); 1453 PF_UNLOCK(); 1454#endif | 1514#else /* ! __FreeBSD__ */ 1515 ip_output(m, (void *)NULL, (void *)NULL, 0, (void *)NULL, 1516 (void *)NULL); 1517#endif 1518 break; 1519#endif /* INET */ 1520#ifdef INET6 1521 case AF_INET6: --- 61 unchanged lines hidden (view full) --- 1583 case AF_INET: 1584#ifdef __FreeBSD__ 1585 /* icmp_error() expects host byte ordering */ 1586 ip = mtod(m0, struct ip *); 1587 NTOHS(ip->ip_len); 1588 NTOHS(ip->ip_off); 1589 PF_UNLOCK(); 1590#endif |
1455 icmp_error(m0, type, code, 0, NULL); | 1591 icmp_error(m0, type, code, 0, (void *)NULL); |
1456#ifdef __FreeBSD__ 1457 PF_LOCK(); 1458#endif 1459 break; 1460#endif /* INET */ 1461#ifdef INET6 1462 case AF_INET6: 1463#ifdef __FreeBSD__ --- 112 unchanged lines hidden (view full) --- 1576 1577 if ((mtag = m_tag_find(m, PACKET_TAG_PF_TAG, NULL)) != NULL) 1578 return ((struct pf_tag *)(mtag + 1)); 1579 else 1580 return (NULL); 1581} 1582 1583int | 1592#ifdef __FreeBSD__ 1593 PF_LOCK(); 1594#endif 1595 break; 1596#endif /* INET */ 1597#ifdef INET6 1598 case AF_INET6: 1599#ifdef __FreeBSD__ --- 112 unchanged lines hidden (view full) --- 1712 1713 if ((mtag = m_tag_find(m, PACKET_TAG_PF_TAG, NULL)) != NULL) 1714 return ((struct pf_tag *)(mtag + 1)); 1715 else 1716 return (NULL); 1717} 1718 1719int |
1584pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_rule *nat, 1585 struct pf_rule *rdr, struct pf_tag *pftag, int *tag) | 1720pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_rule *nat_rule, 1721 struct pf_tag *pftag, int *tag) |
1586{ 1587 if (*tag == -1) { /* find mbuf tag */ 1588 pftag = pf_get_tag(m); 1589 if (pftag != NULL) 1590 *tag = pftag->tag; 1591 else 1592 *tag = 0; | 1722{ 1723 if (*tag == -1) { /* find mbuf tag */ 1724 pftag = pf_get_tag(m); 1725 if (pftag != NULL) 1726 *tag = pftag->tag; 1727 else 1728 *tag = 0; |
1593 if (nat != NULL && nat->tag) 1594 *tag = nat->tag; 1595 if (rdr != NULL && rdr->tag) 1596 *tag = rdr->tag; | 1729 if (nat_rule != NULL && nat_rule->tag) 1730 *tag = nat_rule->tag; |
1597 } 1598 1599 return ((!r->match_tag_not && r->match_tag == *tag) || 1600 (r->match_tag_not && r->match_tag != *tag)); 1601} 1602 1603int 1604pf_tag_packet(struct mbuf *m, struct pf_tag *pftag, int tag) --- 67 unchanged lines hidden (view full) --- 1672 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]); 1673 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) | 1674 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]); 1675 break; 1676 } 1677} 1678 1679void | 1731 } 1732 1733 return ((!r->match_tag_not && r->match_tag == *tag) || 1734 (r->match_tag_not && r->match_tag != *tag)); 1735} 1736 1737int 1738pf_tag_packet(struct mbuf *m, struct pf_tag *pftag, int tag) --- 67 unchanged lines hidden (view full) --- 1806 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]); 1807 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) | 1808 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]); 1809 break; 1810 } 1811} 1812 1813void |
1680pf_addr_inc(struct pf_addr *addr, u_int8_t af) | 1814pf_addr_inc(struct pf_addr *addr, sa_family_t af) |
1681{ 1682 switch (af) { 1683#ifdef INET 1684 case AF_INET: 1685 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1); 1686 break; 1687#endif /* INET */ 1688 case AF_INET6: --- 72 unchanged lines hidden (view full) --- 1761 mix(a, b, c); 1762 hash->addr32[3] = c; 1763 break; 1764#endif /* INET6 */ 1765 } 1766} 1767 1768int | 1815{ 1816 switch (af) { 1817#ifdef INET 1818 case AF_INET: 1819 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1); 1820 break; 1821#endif /* INET */ 1822 case AF_INET6: --- 72 unchanged lines hidden (view full) --- 1895 mix(a, b, c); 1896 hash->addr32[3] = c; 1897 break; 1898#endif /* INET6 */ 1899 } 1900} 1901 1902int |
1769pf_map_addr(u_int8_t af, struct pf_pool *rpool, struct pf_addr *saddr, 1770 struct pf_addr *naddr, struct pf_addr *init_addr) | 1903pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr, 1904 struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn) |
1771{ 1772 unsigned char hash[16]; | 1905{ 1906 unsigned char hash[16]; |
1773 struct pf_addr *raddr; 1774 struct pf_addr *rmask; | 1907 struct pf_pool *rpool = &r->rpool; 1908 struct pf_addr *raddr = &rpool->cur->addr.v.a.addr; 1909 struct pf_addr *rmask = &rpool->cur->addr.v.a.mask; |
1775 struct pf_pooladdr *acur = rpool->cur; | 1910 struct pf_pooladdr *acur = rpool->cur; |
1911 struct pf_src_node k; |
|
1776 | 1912 |
1913 if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR && 1914 (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { 1915 k.af = af; 1916 PF_ACPY(&k.addr, saddr, af); 1917 if (r->rule_flag & PFRULE_RULESRCTRACK || 1918 r->rpool.opts & PF_POOL_STICKYADDR) 1919 k.rule.ptr = r; 1920 else 1921 k.rule.ptr = NULL; 1922 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++; 1923 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k); 1924 if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) { 1925 PF_ACPY(naddr, &(*sn)->raddr, af); 1926 if (pf_status.debug >= PF_DEBUG_MISC) { 1927 printf("pf_map_addr: src tracking maps "); 1928 pf_print_host(&k.addr, 0, af); 1929 printf(" to "); 1930 pf_print_host(naddr, 0, af); 1931 printf("\n"); 1932 } 1933 return (0); 1934 } 1935 } 1936 |
|
1777 if (rpool->cur->addr.type == PF_ADDR_NOROUTE) 1778 return (1); | 1937 if (rpool->cur->addr.type == PF_ADDR_NOROUTE) 1938 return (1); |
1779 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL && 1780 rpool->cur->addr.p.dyn->undefined) 1781 return (1); 1782 if (rpool->cur->addr.type == PF_ADDR_TABLE) { | 1939 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 1940 if (af == AF_INET) { 1941 if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 && 1942 (rpool->opts & PF_POOL_TYPEMASK) != 1943 PF_POOL_ROUNDROBIN) 1944 return (1); 1945 raddr = &rpool->cur->addr.p.dyn->pfid_addr4; 1946 rmask = &rpool->cur->addr.p.dyn->pfid_mask4; 1947 } else { 1948 if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 && 1949 (rpool->opts & PF_POOL_TYPEMASK) != 1950 PF_POOL_ROUNDROBIN) 1951 return (1); 1952 raddr = &rpool->cur->addr.p.dyn->pfid_addr6; 1953 rmask = &rpool->cur->addr.p.dyn->pfid_mask6; 1954 } 1955 } else if (rpool->cur->addr.type == PF_ADDR_TABLE) { |
1783 if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN) 1784 return (1); /* unsupported */ 1785 } else { 1786 raddr = &rpool->cur->addr.v.a.addr; 1787 rmask = &rpool->cur->addr.v.a.mask; 1788 } 1789 1790 switch (rpool->opts & PF_POOL_TYPEMASK) { --- 43 unchanged lines hidden (view full) --- 1834 PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af); 1835 break; 1836 case PF_POOL_ROUNDROBIN: 1837 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 1838 if (!pfr_pool_get(rpool->cur->addr.p.tbl, 1839 &rpool->tblidx, &rpool->counter, 1840 &raddr, &rmask, af)) 1841 goto get_addr; | 1956 if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN) 1957 return (1); /* unsupported */ 1958 } else { 1959 raddr = &rpool->cur->addr.v.a.addr; 1960 rmask = &rpool->cur->addr.v.a.mask; 1961 } 1962 1963 switch (rpool->opts & PF_POOL_TYPEMASK) { --- 43 unchanged lines hidden (view full) --- 2007 PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af); 2008 break; 2009 case PF_POOL_ROUNDROBIN: 2010 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 2011 if (!pfr_pool_get(rpool->cur->addr.p.tbl, 2012 &rpool->tblidx, &rpool->counter, 2013 &raddr, &rmask, af)) 2014 goto get_addr; |
2015 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 2016 if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 2017 &rpool->tblidx, &rpool->counter, 2018 &raddr, &rmask, af)) 2019 goto get_addr; |
|
1842 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af)) 1843 goto get_addr; 1844 1845 try_next: 1846 if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL) 1847 rpool->cur = TAILQ_FIRST(&rpool->list); 1848 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 1849 rpool->tblidx = -1; 1850 if (pfr_pool_get(rpool->cur->addr.p.tbl, 1851 &rpool->tblidx, &rpool->counter, 1852 &raddr, &rmask, af)) { | 2020 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af)) 2021 goto get_addr; 2022 2023 try_next: 2024 if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL) 2025 rpool->cur = TAILQ_FIRST(&rpool->list); 2026 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 2027 rpool->tblidx = -1; 2028 if (pfr_pool_get(rpool->cur->addr.p.tbl, 2029 &rpool->tblidx, &rpool->counter, 2030 &raddr, &rmask, af)) { |
1853 /* table contain no address of type 'af' */ | 2031 /* table contains no address of type 'af' */ |
1854 if (rpool->cur != acur) 1855 goto try_next; 1856 return (1); 1857 } | 2032 if (rpool->cur != acur) 2033 goto try_next; 2034 return (1); 2035 } |
2036 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 2037 rpool->tblidx = -1; 2038 if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 2039 &rpool->tblidx, &rpool->counter, 2040 &raddr, &rmask, af)) { 2041 /* table contains no address of type 'af' */ 2042 if (rpool->cur != acur) 2043 goto try_next; 2044 return (1); 2045 } |
|
1858 } else { 1859 raddr = &rpool->cur->addr.v.a.addr; 1860 rmask = &rpool->cur->addr.v.a.mask; 1861 PF_ACPY(&rpool->counter, raddr, af); 1862 } 1863 1864 get_addr: 1865 PF_ACPY(naddr, &rpool->counter, af); 1866 PF_AINC(&rpool->counter, af); 1867 break; 1868 } | 2046 } else { 2047 raddr = &rpool->cur->addr.v.a.addr; 2048 rmask = &rpool->cur->addr.v.a.mask; 2049 PF_ACPY(&rpool->counter, raddr, af); 2050 } 2051 2052 get_addr: 2053 PF_ACPY(naddr, &rpool->counter, af); 2054 PF_AINC(&rpool->counter, af); 2055 break; 2056 } |
2057 if (*sn != NULL) 2058 PF_ACPY(&(*sn)->raddr, naddr, af); |
|
1869 1870 if (pf_status.debug >= PF_DEBUG_MISC && 1871 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { | 2059 2060 if (pf_status.debug >= PF_DEBUG_MISC && 2061 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { |
1872 printf("pf_map_addr: selected address: "); | 2062 printf("pf_map_addr: selected address "); |
1873 pf_print_host(naddr, 0, af); 1874 printf("\n"); 1875 } 1876 1877 return (0); 1878} 1879 1880int | 2063 pf_print_host(naddr, 0, af); 2064 printf("\n"); 2065 } 2066 2067 return (0); 2068} 2069 2070int |
1881pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_pool *rpool, | 2071pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, |
1882 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport, | 2072 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport, |
1883 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high) | 2073 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high, 2074 struct pf_src_node **sn) |
1884{ | 2075{ |
1885 struct pf_tree_node key; | 2076 struct pf_state key; |
1886 struct pf_addr init_addr; 1887 u_int16_t cut; 1888 1889 bzero(&init_addr, sizeof(init_addr)); | 2077 struct pf_addr init_addr; 2078 u_int16_t cut; 2079 2080 bzero(&init_addr, sizeof(init_addr)); |
1890 if (pf_map_addr(af, rpool, saddr, naddr, &init_addr)) | 2081 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) |
1891 return (1); 1892 1893 do { 1894 key.af = af; 1895 key.proto = proto; | 2082 return (1); 2083 2084 do { 2085 key.af = af; 2086 key.proto = proto; |
1896 PF_ACPY(&key.addr[0], daddr, key.af); 1897 PF_ACPY(&key.addr[1], naddr, key.af); 1898 key.port[0] = dport; | 2087 PF_ACPY(&key.ext.addr, daddr, key.af); 2088 PF_ACPY(&key.gwy.addr, naddr, key.af); 2089 key.ext.port = dport; |
1899 1900 /* 1901 * port search; start random, step; 1902 * similar 2 portloop in in_pcbbind 1903 */ 1904 if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP)) { | 2090 2091 /* 2092 * port search; start random, step; 2093 * similar 2 portloop in in_pcbbind 2094 */ 2095 if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP)) { |
1905 key.port[1] = 0; 1906 if (pf_find_state(&tree_ext_gwy, &key) == NULL) | 2096 key.gwy.port = 0; 2097 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) |
1907 return (0); 1908 } else if (low == 0 && high == 0) { | 2098 return (0); 2099 } else if (low == 0 && high == 0) { |
1909 key.port[1] = *nport; 1910 if (pf_find_state(&tree_ext_gwy, &key) == NULL) { | 2100 key.gwy.port = *nport; 2101 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) |
1911 return (0); | 2102 return (0); |
1912 } | |
1913 } else if (low == high) { | 2103 } else if (low == high) { |
1914 key.port[1] = htons(low); 1915 if (pf_find_state(&tree_ext_gwy, &key) == NULL) { | 2104 key.gwy.port = htons(low); 2105 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) { |
1916 *nport = htons(low); 1917 return (0); 1918 } 1919 } else { 1920 u_int16_t tmp; 1921 1922 if (low > high) { 1923 tmp = low; 1924 low = high; 1925 high = tmp; 1926 } 1927 /* low < high */ 1928 cut = arc4random() % (1 + high - low) + low; 1929 /* low <= cut <= high */ 1930 for (tmp = cut; tmp <= high; ++(tmp)) { | 2106 *nport = htons(low); 2107 return (0); 2108 } 2109 } else { 2110 u_int16_t tmp; 2111 2112 if (low > high) { 2113 tmp = low; 2114 low = high; 2115 high = tmp; 2116 } 2117 /* low < high */ 2118 cut = arc4random() % (1 + high - low) + low; 2119 /* low <= cut <= high */ 2120 for (tmp = cut; tmp <= high; ++(tmp)) { |
1931 key.port[1] = htons(tmp); 1932 if (pf_find_state(&tree_ext_gwy, &key) == | 2121 key.gwy.port = htons(tmp); 2122 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == |
1933 NULL) { 1934 *nport = htons(tmp); 1935 return (0); 1936 } 1937 } 1938 for (tmp = cut - 1; tmp >= low; --(tmp)) { | 2123 NULL) { 2124 *nport = htons(tmp); 2125 return (0); 2126 } 2127 } 2128 for (tmp = cut - 1; tmp >= low; --(tmp)) { |
1939 key.port[1] = htons(tmp); 1940 if (pf_find_state(&tree_ext_gwy, &key) == | 2129 key.gwy.port = htons(tmp); 2130 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == |
1941 NULL) { 1942 *nport = htons(tmp); 1943 return (0); 1944 } 1945 } 1946 } 1947 | 2131 NULL) { 2132 *nport = htons(tmp); 2133 return (0); 2134 } 2135 } 2136 } 2137 |
1948 switch (rpool->opts & PF_POOL_TYPEMASK) { | 2138 switch (r->rpool.opts & PF_POOL_TYPEMASK) { |
1949 case PF_POOL_RANDOM: 1950 case PF_POOL_ROUNDROBIN: | 2139 case PF_POOL_RANDOM: 2140 case PF_POOL_ROUNDROBIN: |
1951 if (pf_map_addr(af, rpool, saddr, naddr, &init_addr)) | 2141 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) |
1952 return (1); 1953 break; 1954 case PF_POOL_NONE: 1955 case PF_POOL_SRCHASH: 1956 case PF_POOL_BITMASK: 1957 default: 1958 return (1); | 2142 return (1); 2143 break; 2144 case PF_POOL_NONE: 2145 case PF_POOL_SRCHASH: 2146 case PF_POOL_BITMASK: 2147 default: 2148 return (1); |
1959 break; | |
1960 } 1961 } while (! PF_AEQ(&init_addr, naddr, af) ); 1962 1963 return (1); /* none available */ 1964} 1965 1966struct pf_rule * 1967pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, | 2149 } 2150 } while (! PF_AEQ(&init_addr, naddr, af) ); 2151 2152 return (1); /* none available */ 2153} 2154 2155struct pf_rule * 2156pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, |
1968 int direction, struct ifnet *ifp, struct pf_addr *saddr, u_int16_t sport, | 2157 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport, |
1969 struct pf_addr *daddr, u_int16_t dport, int rs_num) 1970{ 1971 struct pf_rule *r, *rm = NULL, *anchorrule = NULL; 1972 struct pf_ruleset *ruleset = NULL; 1973 1974 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr); 1975 while (r && rm == NULL) { 1976 struct pf_rule_addr *src = NULL, *dst = NULL; --- 4 unchanged lines hidden (view full) --- 1981 if (r->rpool.cur != NULL) 1982 xdst = &r->rpool.cur->addr; 1983 } else { 1984 src = &r->src; 1985 dst = &r->dst; 1986 } 1987 1988 r->evaluations++; | 2158 struct pf_addr *daddr, u_int16_t dport, int rs_num) 2159{ 2160 struct pf_rule *r, *rm = NULL, *anchorrule = NULL; 2161 struct pf_ruleset *ruleset = NULL; 2162 2163 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr); 2164 while (r && rm == NULL) { 2165 struct pf_rule_addr *src = NULL, *dst = NULL; --- 4 unchanged lines hidden (view full) --- 2170 if (r->rpool.cur != NULL) 2171 xdst = &r->rpool.cur->addr; 2172 } else { 2173 src = &r->src; 2174 dst = &r->dst; 2175 } 2176 2177 r->evaluations++; |
1989 if (r->ifp != NULL && ((r->ifp != ifp && !r->ifnot) || 1990 (r->ifp == ifp && r->ifnot))) | 2178 if (r->kif != NULL && 2179 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) |
1991 r = r->skip[PF_SKIP_IFP].ptr; 1992 else if (r->direction && r->direction != direction) 1993 r = r->skip[PF_SKIP_DIR].ptr; 1994 else if (r->af && r->af != pd->af) 1995 r = r->skip[PF_SKIP_AF].ptr; 1996 else if (r->proto && r->proto != pd->proto) 1997 r = r->skip[PF_SKIP_PROTO].ptr; 1998 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, src->not)) --- 29 unchanged lines hidden (view full) --- 2028 if (rm != NULL && (rm->action == PF_NONAT || 2029 rm->action == PF_NORDR || rm->action == PF_NOBINAT)) 2030 return (NULL); 2031 return (rm); 2032} 2033 2034struct pf_rule * 2035pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, | 2180 r = r->skip[PF_SKIP_IFP].ptr; 2181 else if (r->direction && r->direction != direction) 2182 r = r->skip[PF_SKIP_DIR].ptr; 2183 else if (r->af && r->af != pd->af) 2184 r = r->skip[PF_SKIP_AF].ptr; 2185 else if (r->proto && r->proto != pd->proto) 2186 r = r->skip[PF_SKIP_PROTO].ptr; 2187 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, src->not)) --- 29 unchanged lines hidden (view full) --- 2217 if (rm != NULL && (rm->action == PF_NONAT || 2218 rm->action == PF_NORDR || rm->action == PF_NOBINAT)) 2219 return (NULL); 2220 return (rm); 2221} 2222 2223struct pf_rule * 2224pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, |
2036 struct ifnet *ifp, | 2225 struct pfi_kif *kif, struct pf_src_node **sn, |
2037 struct pf_addr *saddr, u_int16_t sport, 2038 struct pf_addr *daddr, u_int16_t dport, 2039 struct pf_addr *naddr, u_int16_t *nport) 2040{ 2041 struct pf_rule *r = NULL; 2042 2043 if (direction == PF_OUT) { | 2226 struct pf_addr *saddr, u_int16_t sport, 2227 struct pf_addr *daddr, u_int16_t dport, 2228 struct pf_addr *naddr, u_int16_t *nport) 2229{ 2230 struct pf_rule *r = NULL; 2231 2232 if (direction == PF_OUT) { |
2044 r = pf_match_translation(pd, m, off, direction, ifp, saddr, | 2233 r = pf_match_translation(pd, m, off, direction, kif, saddr, |
2045 sport, daddr, dport, PF_RULESET_BINAT); 2046 if (r == NULL) | 2234 sport, daddr, dport, PF_RULESET_BINAT); 2235 if (r == NULL) |
2047 r = pf_match_translation(pd, m, off, direction, ifp, | 2236 r = pf_match_translation(pd, m, off, direction, kif, |
2048 saddr, sport, daddr, dport, PF_RULESET_NAT); 2049 } else { | 2237 saddr, sport, daddr, dport, PF_RULESET_NAT); 2238 } else { |
2050 r = pf_match_translation(pd, m, off, direction, ifp, saddr, | 2239 r = pf_match_translation(pd, m, off, direction, kif, saddr, |
2051 sport, daddr, dport, PF_RULESET_RDR); 2052 if (r == NULL) | 2240 sport, daddr, dport, PF_RULESET_RDR); 2241 if (r == NULL) |
2053 r = pf_match_translation(pd, m, off, direction, ifp, | 2242 r = pf_match_translation(pd, m, off, direction, kif, |
2054 saddr, sport, daddr, dport, PF_RULESET_BINAT); 2055 } 2056 2057 if (r != NULL) { 2058 switch (r->action) { 2059 case PF_NONAT: 2060 case PF_NOBINAT: 2061 case PF_NORDR: 2062 return (NULL); | 2243 saddr, sport, daddr, dport, PF_RULESET_BINAT); 2244 } 2245 2246 if (r != NULL) { 2247 switch (r->action) { 2248 case PF_NONAT: 2249 case PF_NOBINAT: 2250 case PF_NORDR: 2251 return (NULL); |
2063 break; | |
2064 case PF_NAT: | 2252 case PF_NAT: |
2065 if (pf_get_sport(pd->af, pd->proto, &r->rpool, saddr, | 2253 if (pf_get_sport(pd->af, pd->proto, r, saddr, |
2066 daddr, dport, naddr, nport, r->rpool.proxy_port[0], | 2254 daddr, dport, naddr, nport, r->rpool.proxy_port[0], |
2067 r->rpool.proxy_port[1])) { | 2255 r->rpool.proxy_port[1], sn)) { |
2068 DPFPRINTF(PF_DEBUG_MISC, 2069 ("pf: NAT proxy port allocation " 2070 "(%u-%u) failed\n", 2071 r->rpool.proxy_port[0], 2072 r->rpool.proxy_port[1])); 2073 return (NULL); 2074 } 2075 break; 2076 case PF_BINAT: 2077 switch (direction) { 2078 case PF_OUT: | 2256 DPFPRINTF(PF_DEBUG_MISC, 2257 ("pf: NAT proxy port allocation " 2258 "(%u-%u) failed\n", 2259 r->rpool.proxy_port[0], 2260 r->rpool.proxy_port[1])); 2261 return (NULL); 2262 } 2263 break; 2264 case PF_BINAT: 2265 switch (direction) { 2266 case PF_OUT: |
2079 if (r->rpool.cur->addr.type == 2080 PF_ADDR_DYNIFTL && 2081 r->rpool.cur->addr.p.dyn->undefined) 2082 return (NULL); 2083 else | 2267 if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){ 2268 if (pd->af == AF_INET) { 2269 if (r->rpool.cur->addr.p.dyn-> 2270 pfid_acnt4 < 1) 2271 return (NULL); 2272 PF_POOLMASK(naddr, 2273 &r->rpool.cur->addr.p.dyn-> 2274 pfid_addr4, 2275 &r->rpool.cur->addr.p.dyn-> 2276 pfid_mask4, 2277 saddr, AF_INET); 2278 } else { 2279 if (r->rpool.cur->addr.p.dyn-> 2280 pfid_acnt6 < 1) 2281 return (NULL); 2282 PF_POOLMASK(naddr, 2283 &r->rpool.cur->addr.p.dyn-> 2284 pfid_addr6, 2285 &r->rpool.cur->addr.p.dyn-> 2286 pfid_mask6, 2287 saddr, AF_INET6); 2288 } 2289 } else |
2084 PF_POOLMASK(naddr, 2085 &r->rpool.cur->addr.v.a.addr, 2086 &r->rpool.cur->addr.v.a.mask, 2087 saddr, pd->af); 2088 break; 2089 case PF_IN: | 2290 PF_POOLMASK(naddr, 2291 &r->rpool.cur->addr.v.a.addr, 2292 &r->rpool.cur->addr.v.a.mask, 2293 saddr, pd->af); 2294 break; 2295 case PF_IN: |
2090 if (r->src.addr.type == PF_ADDR_DYNIFTL && 2091 r->src.addr.p.dyn->undefined) 2092 return (NULL); 2093 else | 2296 if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){ 2297 if (pd->af == AF_INET) { 2298 if (r->src.addr.p.dyn-> 2299 pfid_acnt4 < 1) 2300 return (NULL); 2301 PF_POOLMASK(naddr, 2302 &r->src.addr.p.dyn-> 2303 pfid_addr4, 2304 &r->src.addr.p.dyn-> 2305 pfid_mask4, 2306 daddr, AF_INET); 2307 } else { 2308 if (r->src.addr.p.dyn-> 2309 pfid_acnt6 < 1) 2310 return (NULL); 2311 PF_POOLMASK(naddr, 2312 &r->src.addr.p.dyn-> 2313 pfid_addr6, 2314 &r->src.addr.p.dyn-> 2315 pfid_mask6, 2316 daddr, AF_INET6); 2317 } 2318 } else |
2094 PF_POOLMASK(naddr, 2095 &r->src.addr.v.a.addr, 2096 &r->src.addr.v.a.mask, daddr, 2097 pd->af); 2098 break; 2099 } 2100 break; 2101 case PF_RDR: { | 2319 PF_POOLMASK(naddr, 2320 &r->src.addr.v.a.addr, 2321 &r->src.addr.v.a.mask, daddr, 2322 pd->af); 2323 break; 2324 } 2325 break; 2326 case PF_RDR: { |
2102 if (pf_map_addr(r->af, &r->rpool, saddr, naddr, NULL)) | 2327 if (pf_map_addr(r->af, r, saddr, naddr, NULL, sn)) |
2103 return (NULL); 2104 2105 if (r->rpool.proxy_port[1]) { 2106 u_int32_t tmp_nport; 2107 2108 tmp_nport = ((ntohs(dport) - 2109 ntohs(r->dst.port[0])) % 2110 (r->rpool.proxy_port[1] - --- 5 unchanged lines hidden (view full) --- 2116 tmp_nport -= 65535; 2117 *nport = htons((u_int16_t)tmp_nport); 2118 } else if (r->rpool.proxy_port[0]) 2119 *nport = htons(r->rpool.proxy_port[0]); 2120 break; 2121 } 2122 default: 2123 return (NULL); | 2328 return (NULL); 2329 2330 if (r->rpool.proxy_port[1]) { 2331 u_int32_t tmp_nport; 2332 2333 tmp_nport = ((ntohs(dport) - 2334 ntohs(r->dst.port[0])) % 2335 (r->rpool.proxy_port[1] - --- 5 unchanged lines hidden (view full) --- 2341 tmp_nport -= 65535; 2342 *nport = htons((u_int16_t)tmp_nport); 2343 } else if (r->rpool.proxy_port[0]) 2344 *nport = htons(r->rpool.proxy_port[0]); 2345 break; 2346 } 2347 default: 2348 return (NULL); |
2124 break; | |
2125 } 2126 } 2127 2128 return (r); 2129} 2130 2131int | 2349 } 2350 } 2351 2352 return (r); 2353} 2354 2355int |
2132pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, sa_family_t af, 2133 int proto, struct pf_pdesc *pd) | 2356pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd) |
2134{ 2135 struct pf_addr *saddr, *daddr; 2136 u_int16_t sport, dport; 2137#ifdef __FreeBSD__ 2138 struct inpcbinfo *pi; 2139#else 2140 struct inpcbtable *tb; 2141#endif 2142 struct inpcb *inp; 2143 2144 *uid = UID_MAX; 2145 *gid = GID_MAX; | 2357{ 2358 struct pf_addr *saddr, *daddr; 2359 u_int16_t sport, dport; 2360#ifdef __FreeBSD__ 2361 struct inpcbinfo *pi; 2362#else 2363 struct inpcbtable *tb; 2364#endif 2365 struct inpcb *inp; 2366 2367 *uid = UID_MAX; 2368 *gid = GID_MAX; |
2146 switch (proto) { | 2369 switch (pd->proto) { |
2147 case IPPROTO_TCP: 2148 sport = pd->hdr.tcp->th_sport; 2149 dport = pd->hdr.tcp->th_dport; 2150#ifdef __FreeBSD__ 2151 pi = &tcbinfo; 2152#else 2153 tb = &tcbtable; 2154#endif --- 17 unchanged lines hidden (view full) --- 2172 u_int16_t p; 2173 2174 p = sport; 2175 sport = dport; 2176 dport = p; 2177 saddr = pd->dst; 2178 daddr = pd->src; 2179 } | 2370 case IPPROTO_TCP: 2371 sport = pd->hdr.tcp->th_sport; 2372 dport = pd->hdr.tcp->th_dport; 2373#ifdef __FreeBSD__ 2374 pi = &tcbinfo; 2375#else 2376 tb = &tcbtable; 2377#endif --- 17 unchanged lines hidden (view full) --- 2395 u_int16_t p; 2396 2397 p = sport; 2398 sport = dport; 2399 dport = p; 2400 saddr = pd->dst; 2401 daddr = pd->src; 2402 } |
2180 switch(af) { | 2403 switch (pd->af) { |
2181 case AF_INET: 2182#ifdef __FreeBSD__ | 2404 case AF_INET: 2405#ifdef __FreeBSD__ |
2183#if (__FreeBSD_version >= 500043) | |
2184 INP_INFO_RLOCK(pi); /* XXX LOR */ | 2406 INP_INFO_RLOCK(pi); /* XXX LOR */ |
2185#endif | |
2186 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4, 2187 dport, 0, NULL); 2188 if (inp == NULL) { 2189 inp = in_pcblookup_hash(pi, saddr->v4, sport, 2190 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL); 2191 if(inp == NULL) { | 2407 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4, 2408 dport, 0, NULL); 2409 if (inp == NULL) { 2410 inp = in_pcblookup_hash(pi, saddr->v4, sport, 2411 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL); 2412 if(inp == NULL) { |
2192#if (__FreeBSD_version >= 500043) | |
2193 INP_INFO_RUNLOCK(pi); | 2413 INP_INFO_RUNLOCK(pi); |
2194#endif | |
2195 return (0); 2196 } 2197 } 2198#else 2199 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); 2200 if (inp == NULL) { | 2414 return (0); 2415 } 2416 } 2417#else 2418 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); 2419 if (inp == NULL) { |
2201 inp = in_pcblookup(tb, &saddr->v4, sport, &daddr->v4, 2202 dport, INPLOOKUP_WILDCARD); | 2420 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0); |
2203 if (inp == NULL) 2204 return (0); 2205 } 2206#endif 2207 break; 2208#ifdef INET6 2209 case AF_INET6: 2210#ifdef __FreeBSD__ | 2421 if (inp == NULL) 2422 return (0); 2423 } 2424#endif 2425 break; 2426#ifdef INET6 2427 case AF_INET6: 2428#ifdef __FreeBSD__ |
2211#if (__FreeBSD_version >= 500043) | |
2212 INP_INFO_RLOCK(pi); | 2429 INP_INFO_RLOCK(pi); |
2213#endif | |
2214 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 2215 &daddr->v6, dport, 0, NULL); 2216 if (inp == NULL) { 2217 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 2218 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL); 2219 if (inp == NULL) { | 2430 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 2431 &daddr->v6, dport, 0, NULL); 2432 if (inp == NULL) { 2433 inp = in6_pcblookup_hash(pi, &saddr->v6, sport, 2434 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL); 2435 if (inp == NULL) { |
2220#if (__FreeBSD_version >= 500043) | |
2221 INP_INFO_RUNLOCK(pi); | 2436 INP_INFO_RUNLOCK(pi); |
2222#endif | |
2223 return (0); 2224 } 2225 } 2226#else 2227 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, 2228 dport); 2229 if (inp == NULL) { | 2437 return (0); 2438 } 2439 } 2440#else 2441 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, 2442 dport); 2443 if (inp == NULL) { |
2230 inp = in_pcblookup(tb, &saddr->v6, sport, &daddr->v6, 2231 dport, INPLOOKUP_WILDCARD | INPLOOKUP_IPV6); | 2444 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0); |
2232 if (inp == NULL) 2233 return (0); 2234 } 2235#endif 2236 break; 2237#endif /* INET6 */ 2238 2239 default: 2240 return (0); 2241 } 2242#ifdef __FreeBSD__ | 2445 if (inp == NULL) 2446 return (0); 2447 } 2448#endif 2449 break; 2450#endif /* INET6 */ 2451 2452 default: 2453 return (0); 2454 } 2455#ifdef __FreeBSD__ |
2243#if (__FreeBSD_version >= 500043) | |
2244 INP_LOCK(inp); | 2456 INP_LOCK(inp); |
2245#endif | |
2246 *uid = inp->inp_socket->so_cred->cr_uid; 2247 *gid = inp->inp_socket->so_cred->cr_groups[0]; | 2457 *uid = inp->inp_socket->so_cred->cr_uid; 2458 *gid = inp->inp_socket->so_cred->cr_groups[0]; |
2248#if (__FreeBSD_version >= 500043) | |
2249 INP_UNLOCK(inp); 2250 INP_INFO_RUNLOCK(pi); | 2459 INP_UNLOCK(inp); 2460 INP_INFO_RUNLOCK(pi); |
2251#endif | |
2252#else 2253 *uid = inp->inp_socket->so_euid; 2254 *gid = inp->inp_socket->so_egid; 2255#endif 2256 return (1); 2257} 2258 2259u_int8_t --- 18 unchanged lines hidden (view full) --- 2278 ++opt; 2279 --hlen; 2280 break; 2281 case TCPOPT_WINDOW: 2282 wscale = opt[2]; 2283 if (wscale > TCP_MAX_WINSHIFT) 2284 wscale = TCP_MAX_WINSHIFT; 2285 wscale |= PF_WSCALE_FLAG; | 2461#else 2462 *uid = inp->inp_socket->so_euid; 2463 *gid = inp->inp_socket->so_egid; 2464#endif 2465 return (1); 2466} 2467 2468u_int8_t --- 18 unchanged lines hidden (view full) --- 2487 ++opt; 2488 --hlen; 2489 break; 2490 case TCPOPT_WINDOW: 2491 wscale = opt[2]; 2492 if (wscale > TCP_MAX_WINSHIFT) 2493 wscale = TCP_MAX_WINSHIFT; 2494 wscale |= PF_WSCALE_FLAG; |
2286 /* fallthrough */ | 2495 /* FALLTHROUGH */ |
2287 default: 2288 optlen = opt[1]; 2289 if (optlen < 2) 2290 optlen = 2; 2291 hlen -= optlen; 2292 opt += optlen; | 2496 default: 2497 optlen = opt[1]; 2498 if (optlen < 2) 2499 optlen = 2; 2500 hlen -= optlen; 2501 opt += optlen; |
2502 break; |
|
2293 } 2294 } 2295 return (wscale); 2296} 2297 2298u_int16_t 2299pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 2300{ --- 13 unchanged lines hidden (view full) --- 2314 switch (*opt) { 2315 case TCPOPT_EOL: 2316 case TCPOPT_NOP: 2317 ++opt; 2318 --hlen; 2319 break; 2320 case TCPOPT_MAXSEG: 2321 bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2); | 2503 } 2504 } 2505 return (wscale); 2506} 2507 2508u_int16_t 2509pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 2510{ --- 13 unchanged lines hidden (view full) --- 2524 switch (*opt) { 2525 case TCPOPT_EOL: 2526 case TCPOPT_NOP: 2527 ++opt; 2528 --hlen; 2529 break; 2530 case TCPOPT_MAXSEG: 2531 bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2); |
2322 /* fallthrough */ | 2532 /* FALLTHROUGH */ |
2323 default: 2324 optlen = opt[1]; 2325 if (optlen < 2) 2326 optlen = 2; 2327 hlen -= optlen; 2328 opt += optlen; | 2533 default: 2534 optlen = opt[1]; 2535 if (optlen < 2) 2536 optlen = 2; 2537 hlen -= optlen; 2538 opt += optlen; |
2539 break; |
|
2329 } 2330 } 2331 return (mss); 2332} 2333 2334u_int16_t 2335pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) 2336{ --- 63 unchanged lines hidden (view full) --- 2400 return (mss); 2401} 2402 2403void 2404pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr) 2405{ 2406 struct pf_rule *r = s->rule.ptr; 2407 | 2540 } 2541 } 2542 return (mss); 2543} 2544 2545u_int16_t 2546pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) 2547{ --- 63 unchanged lines hidden (view full) --- 2611 return (mss); 2612} 2613 2614void 2615pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr) 2616{ 2617 struct pf_rule *r = s->rule.ptr; 2618 |
2408 s->rt_ifp = NULL; | 2619 s->rt_kif = NULL; |
2409 if (!r->rt || r->rt == PF_FASTROUTE) 2410 return; 2411 switch (s->af) { 2412#ifdef INET 2413 case AF_INET: | 2620 if (!r->rt || r->rt == PF_FASTROUTE) 2621 return; 2622 switch (s->af) { 2623#ifdef INET 2624 case AF_INET: |
2414 pf_map_addr(AF_INET, &r->rpool, saddr, 2415 &s->rt_addr, NULL); 2416 s->rt_ifp = r->rpool.cur->ifp; | 2625 pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, 2626 &s->nat_src_node); 2627 s->rt_kif = r->rpool.cur->kif; |
2417 break; 2418#endif /* INET */ 2419#ifdef INET6 2420 case AF_INET6: | 2628 break; 2629#endif /* INET */ 2630#ifdef INET6 2631 case AF_INET6: |
2421 pf_map_addr(AF_INET6, &r->rpool, saddr, 2422 &s->rt_addr, NULL); 2423 s->rt_ifp = r->rpool.cur->ifp; | 2632 pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, 2633 &s->nat_src_node); 2634 s->rt_kif = r->rpool.cur->kif; |
2424 break; 2425#endif /* INET6 */ 2426 } 2427} 2428 2429int 2430pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction, | 2635 break; 2636#endif /* INET6 */ 2637 } 2638} 2639 2640int 2641pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction, |
2431 struct ifnet *ifp, struct mbuf *m, int ipoff, int off, void *h, | 2642 struct pfi_kif *kif, struct mbuf *m, int off, void *h, |
2432 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) 2433{ | 2643 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) 2644{ |
2434 struct pf_rule *nat = NULL, *rdr = NULL; | 2645 struct pf_rule *nr = NULL; |
2435 struct pf_addr *saddr = pd->src, *daddr = pd->dst; | 2646 struct pf_addr *saddr = pd->src, *daddr = pd->dst; |
2436 struct pf_addr baddr, naddr; | |
2437 struct tcphdr *th = pd->hdr.tcp; 2438 u_int16_t bport, nport = 0; 2439 sa_family_t af = pd->af; 2440 int lookup = -1; 2441 uid_t uid; 2442 gid_t gid; 2443 struct pf_rule *r, *a = NULL; 2444 struct pf_ruleset *ruleset = NULL; | 2647 struct tcphdr *th = pd->hdr.tcp; 2648 u_int16_t bport, nport = 0; 2649 sa_family_t af = pd->af; 2650 int lookup = -1; 2651 uid_t uid; 2652 gid_t gid; 2653 struct pf_rule *r, *a = NULL; 2654 struct pf_ruleset *ruleset = NULL; |
2655 struct pf_src_node *nsn = NULL; |
|
2445 u_short reason; 2446 int rewrite = 0; 2447 struct pf_tag *pftag = NULL; 2448 int tag = -1; 2449 u_int16_t mss = tcp_mssdflt; 2450 2451 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 2452 2453 if (direction == PF_OUT) { 2454 bport = nport = th->th_sport; 2455 /* check outgoing packet for BINAT/NAT */ | 2656 u_short reason; 2657 int rewrite = 0; 2658 struct pf_tag *pftag = NULL; 2659 int tag = -1; 2660 u_int16_t mss = tcp_mssdflt; 2661 2662 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 2663 2664 if (direction == PF_OUT) { 2665 bport = nport = th->th_sport; 2666 /* check outgoing packet for BINAT/NAT */ |
2456 if ((nat = pf_get_translation(pd, m, off, PF_OUT, ifp, | 2667 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, |
2457 saddr, th->th_sport, daddr, th->th_dport, | 2668 saddr, th->th_sport, daddr, th->th_dport, |
2458 &naddr, &nport)) != NULL) { 2459 PF_ACPY(&baddr, saddr, af); | 2669 &pd->naddr, &nport)) != NULL) { 2670 PF_ACPY(&pd->baddr, saddr, af); |
2460 pf_change_ap(saddr, &th->th_sport, pd->ip_sum, | 2671 pf_change_ap(saddr, &th->th_sport, pd->ip_sum, |
2461 &th->th_sum, &naddr, nport, 0, af); | 2672 &th->th_sum, &pd->naddr, nport, 0, af); |
2462 rewrite++; | 2673 rewrite++; |
2463 if (nat->natpass) | 2674 if (nr->natpass) |
2464 r = NULL; | 2675 r = NULL; |
2676 pd->nat_rule = nr; |
|
2465 } 2466 } else { 2467 bport = nport = th->th_dport; 2468 /* check incoming packet for BINAT/RDR */ | 2677 } 2678 } else { 2679 bport = nport = th->th_dport; 2680 /* check incoming packet for BINAT/RDR */ |
2469 if ((rdr = pf_get_translation(pd, m, off, PF_IN, ifp, saddr, 2470 th->th_sport, daddr, th->th_dport, 2471 &naddr, &nport)) != NULL) { 2472 PF_ACPY(&baddr, daddr, af); | 2681 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 2682 saddr, th->th_sport, daddr, th->th_dport, 2683 &pd->naddr, &nport)) != NULL) { 2684 PF_ACPY(&pd->baddr, daddr, af); |
2473 pf_change_ap(daddr, &th->th_dport, pd->ip_sum, | 2685 pf_change_ap(daddr, &th->th_dport, pd->ip_sum, |
2474 &th->th_sum, &naddr, nport, 0, af); | 2686 &th->th_sum, &pd->naddr, nport, 0, af); |
2475 rewrite++; | 2687 rewrite++; |
2476 if (rdr->natpass) | 2688 if (nr->natpass) |
2477 r = NULL; | 2689 r = NULL; |
2690 pd->nat_rule = nr; |
|
2478 } 2479 } 2480 2481 while (r != NULL) { 2482 r->evaluations++; | 2691 } 2692 } 2693 2694 while (r != NULL) { 2695 r->evaluations++; |
2483 if (r->ifp != NULL && ((r->ifp != ifp && !r->ifnot) || 2484 (r->ifp == ifp && r->ifnot))) | 2696 if (r->kif != NULL && 2697 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) |
2485 r = r->skip[PF_SKIP_IFP].ptr; 2486 else if (r->direction && r->direction != direction) 2487 r = r->skip[PF_SKIP_DIR].ptr; 2488 else if (r->af && r->af != af) 2489 r = r->skip[PF_SKIP_AF].ptr; 2490 else if (r->proto && r->proto != IPPROTO_TCP) 2491 r = r->skip[PF_SKIP_PROTO].ptr; 2492 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) --- 8 unchanged lines hidden (view full) --- 2501 r = r->skip[PF_SKIP_DST_PORT].ptr; 2502 else if (r->tos && !(r->tos & pd->tos)) 2503 r = TAILQ_NEXT(r, entries); 2504 else if (r->rule_flag & PFRULE_FRAGMENT) 2505 r = TAILQ_NEXT(r, entries); 2506 else if ((r->flagset & th->th_flags) != r->flags) 2507 r = TAILQ_NEXT(r, entries); 2508 else if (r->uid.op && (lookup != -1 || (lookup = | 2698 r = r->skip[PF_SKIP_IFP].ptr; 2699 else if (r->direction && r->direction != direction) 2700 r = r->skip[PF_SKIP_DIR].ptr; 2701 else if (r->af && r->af != af) 2702 r = r->skip[PF_SKIP_AF].ptr; 2703 else if (r->proto && r->proto != IPPROTO_TCP) 2704 r = r->skip[PF_SKIP_PROTO].ptr; 2705 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) --- 8 unchanged lines hidden (view full) --- 2714 r = r->skip[PF_SKIP_DST_PORT].ptr; 2715 else if (r->tos && !(r->tos & pd->tos)) 2716 r = TAILQ_NEXT(r, entries); 2717 else if (r->rule_flag & PFRULE_FRAGMENT) 2718 r = TAILQ_NEXT(r, entries); 2719 else if ((r->flagset & th->th_flags) != r->flags) 2720 r = TAILQ_NEXT(r, entries); 2721 else if (r->uid.op && (lookup != -1 || (lookup = |
2509 pf_socket_lookup(&uid, &gid, direction, af, IPPROTO_TCP, 2510 pd), 1)) && | 2722 pf_socket_lookup(&uid, &gid, direction, pd), 1)) && |
2511 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 2512 uid)) 2513 r = TAILQ_NEXT(r, entries); 2514 else if (r->gid.op && (lookup != -1 || (lookup = | 2723 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 2724 uid)) 2725 r = TAILQ_NEXT(r, entries); 2726 else if (r->gid.op && (lookup != -1 || (lookup = |
2515 pf_socket_lookup(&uid, &gid, direction, af, IPPROTO_TCP, 2516 pd), 1)) && | 2727 pf_socket_lookup(&uid, &gid, direction, pd), 1)) && |
2517 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 2518 gid)) 2519 r = TAILQ_NEXT(r, entries); | 2728 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 2729 gid)) 2730 r = TAILQ_NEXT(r, entries); |
2520 else if (r->match_tag && 2521 !pf_match_tag(m, r, nat, rdr, pftag, &tag)) | 2731 else if (r->match_tag && !pf_match_tag(m, r, nr, pftag, &tag)) |
2522 r = TAILQ_NEXT(r, entries); 2523 else if (r->anchorname[0] && r->anchor == NULL) 2524 r = TAILQ_NEXT(r, entries); 2525 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match( 2526 pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint)) 2527 r = TAILQ_NEXT(r, entries); 2528 else { 2529 if (r->tag) --- 12 unchanged lines hidden (view full) --- 2542 if (r == NULL && a != NULL) 2543 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 2544 PF_RULESET_FILTER); 2545 } 2546 r = *rm; 2547 a = *am; 2548 ruleset = *rsm; 2549 | 2732 r = TAILQ_NEXT(r, entries); 2733 else if (r->anchorname[0] && r->anchor == NULL) 2734 r = TAILQ_NEXT(r, entries); 2735 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match( 2736 pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint)) 2737 r = TAILQ_NEXT(r, entries); 2738 else { 2739 if (r->tag) --- 12 unchanged lines hidden (view full) --- 2752 if (r == NULL && a != NULL) 2753 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 2754 PF_RULESET_FILTER); 2755 } 2756 r = *rm; 2757 a = *am; 2758 ruleset = *rsm; 2759 |
2550 r->packets++; 2551 r->bytes += pd->tot_len; 2552 if (a != NULL) { 2553 a->packets++; 2554 a->bytes += pd->tot_len; 2555 } | |
2556 REASON_SET(&reason, PFRES_MATCH); 2557 2558 if (r->log) { 2559 if (rewrite) 2560 m_copyback(m, off, sizeof(*th), (caddr_t)th); | 2760 REASON_SET(&reason, PFRES_MATCH); 2761 2762 if (r->log) { 2763 if (rewrite) 2764 m_copyback(m, off, sizeof(*th), (caddr_t)th); |
2561 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); | 2765 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); |
2562 } 2563 2564 if ((r->action == PF_DROP) && 2565 ((r->rule_flag & PFRULE_RETURNRST) || 2566 (r->rule_flag & PFRULE_RETURNICMP) || 2567 (r->rule_flag & PFRULE_RETURN))) { 2568 /* undo NAT changes, if they have taken place */ | 2766 } 2767 2768 if ((r->action == PF_DROP) && 2769 ((r->rule_flag & PFRULE_RETURNRST) || 2770 (r->rule_flag & PFRULE_RETURNICMP) || 2771 (r->rule_flag & PFRULE_RETURN))) { 2772 /* undo NAT changes, if they have taken place */ |
2569 if (nat != NULL) { 2570 pf_change_ap(saddr, &th->th_sport, pd->ip_sum, 2571 &th->th_sum, &baddr, bport, 0, af); 2572 rewrite++; 2573 } else if (rdr != NULL) { 2574 pf_change_ap(daddr, &th->th_dport, pd->ip_sum, 2575 &th->th_sum, &baddr, bport, 0, af); 2576 rewrite++; | 2773 if (nr != NULL) { 2774 if (direction == PF_OUT) { 2775 pf_change_ap(saddr, &th->th_sport, pd->ip_sum, 2776 &th->th_sum, &pd->baddr, bport, 0, af); 2777 rewrite++; 2778 } else { 2779 pf_change_ap(daddr, &th->th_dport, pd->ip_sum, 2780 &th->th_sum, &pd->baddr, bport, 0, af); 2781 rewrite++; 2782 } |
2577 } 2578 if (((r->rule_flag & PFRULE_RETURNRST) || 2579 (r->rule_flag & PFRULE_RETURN)) && 2580 !(th->th_flags & TH_RST)) { 2581 u_int32_t ack = ntohl(th->th_seq) + pd->p_len; 2582 2583 if (th->th_flags & TH_SYN) 2584 ack++; --- 14 unchanged lines hidden (view full) --- 2599 if (r->action == PF_DROP) 2600 return (PF_DROP); 2601 2602 if (pf_tag_packet(m, pftag, tag)) { 2603 REASON_SET(&reason, PFRES_MEMORY); 2604 return (PF_DROP); 2605 } 2606 | 2783 } 2784 if (((r->rule_flag & PFRULE_RETURNRST) || 2785 (r->rule_flag & PFRULE_RETURN)) && 2786 !(th->th_flags & TH_RST)) { 2787 u_int32_t ack = ntohl(th->th_seq) + pd->p_len; 2788 2789 if (th->th_flags & TH_SYN) 2790 ack++; --- 14 unchanged lines hidden (view full) --- 2805 if (r->action == PF_DROP) 2806 return (PF_DROP); 2807 2808 if (pf_tag_packet(m, pftag, tag)) { 2809 REASON_SET(&reason, PFRES_MEMORY); 2810 return (PF_DROP); 2811 } 2812 |
2607 if (r->keep_state || nat != NULL || rdr != NULL || | 2813 if (r->keep_state || nr != NULL || |
2608 (pd->flags & PFDESC_TCP_NORM)) { 2609 /* create new state */ 2610 u_int16_t len; 2611 struct pf_state *s = NULL; | 2814 (pd->flags & PFDESC_TCP_NORM)) { 2815 /* create new state */ 2816 u_int16_t len; 2817 struct pf_state *s = NULL; |
2818 struct pf_src_node *sn = NULL; |
|
2612 2613 len = pd->tot_len - off - (th->th_off << 2); | 2819 2820 len = pd->tot_len - off - (th->th_off << 2); |
2614 if (!r->max_states || r->states < r->max_states) 2615 s = pool_get(&pf_state_pl, PR_NOWAIT); | 2821 2822 /* check maximums */ 2823 if (r->max_states && (r->states >= r->max_states)) 2824 goto cleanup; 2825 /* src node for flter rule */ 2826 if ((r->rule_flag & PFRULE_SRCTRACK || 2827 r->rpool.opts & PF_POOL_STICKYADDR) && 2828 pf_insert_src_node(&sn, r, saddr, af) != 0) 2829 goto cleanup; 2830 /* src node for translation rule */ 2831 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 2832 ((direction == PF_OUT && 2833 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 2834 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) 2835 goto cleanup; 2836 s = pool_get(&pf_state_pl, PR_NOWAIT); |
2616 if (s == NULL) { | 2837 if (s == NULL) { |
2838cleanup: 2839 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 2840 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 2841 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 2842 pf_status.src_nodes--; 2843 pool_put(&pf_src_tree_pl, sn); 2844 } 2845 if (nsn != sn && nsn != NULL && nsn->states == 0 && 2846 nsn->expire == 0) { 2847 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 2848 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 2849 pf_status.src_nodes--; 2850 pool_put(&pf_src_tree_pl, nsn); 2851 } |
|
2617 REASON_SET(&reason, PFRES_MEMORY); 2618 return (PF_DROP); 2619 } 2620 bzero(s, sizeof(*s)); 2621 r->states++; 2622 if (a != NULL) 2623 a->states++; 2624 s->rule.ptr = r; | 2852 REASON_SET(&reason, PFRES_MEMORY); 2853 return (PF_DROP); 2854 } 2855 bzero(s, sizeof(*s)); 2856 r->states++; 2857 if (a != NULL) 2858 a->states++; 2859 s->rule.ptr = r; |
2625 if (nat != NULL) 2626 s->nat_rule.ptr = nat; 2627 else 2628 s->nat_rule.ptr = rdr; | 2860 s->nat_rule.ptr = nr; |
2629 if (s->nat_rule.ptr != NULL) 2630 s->nat_rule.ptr->states++; 2631 s->anchor.ptr = a; 2632 s->allow_opts = r->allow_opts; 2633 s->log = r->log & 2; 2634 s->proto = IPPROTO_TCP; 2635 s->direction = direction; 2636 s->af = af; 2637 if (direction == PF_OUT) { 2638 PF_ACPY(&s->gwy.addr, saddr, af); 2639 s->gwy.port = th->th_sport; /* sport */ 2640 PF_ACPY(&s->ext.addr, daddr, af); 2641 s->ext.port = th->th_dport; | 2861 if (s->nat_rule.ptr != NULL) 2862 s->nat_rule.ptr->states++; 2863 s->anchor.ptr = a; 2864 s->allow_opts = r->allow_opts; 2865 s->log = r->log & 2; 2866 s->proto = IPPROTO_TCP; 2867 s->direction = direction; 2868 s->af = af; 2869 if (direction == PF_OUT) { 2870 PF_ACPY(&s->gwy.addr, saddr, af); 2871 s->gwy.port = th->th_sport; /* sport */ 2872 PF_ACPY(&s->ext.addr, daddr, af); 2873 s->ext.port = th->th_dport; |
2642 if (nat != NULL) { 2643 PF_ACPY(&s->lan.addr, &baddr, af); | 2874 if (nr != NULL) { 2875 PF_ACPY(&s->lan.addr, &pd->baddr, af); |
2644 s->lan.port = bport; 2645 } else { 2646 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 2647 s->lan.port = s->gwy.port; 2648 } 2649 } else { 2650 PF_ACPY(&s->lan.addr, daddr, af); 2651 s->lan.port = th->th_dport; 2652 PF_ACPY(&s->ext.addr, saddr, af); 2653 s->ext.port = th->th_sport; | 2876 s->lan.port = bport; 2877 } else { 2878 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 2879 s->lan.port = s->gwy.port; 2880 } 2881 } else { 2882 PF_ACPY(&s->lan.addr, daddr, af); 2883 s->lan.port = th->th_dport; 2884 PF_ACPY(&s->ext.addr, saddr, af); 2885 s->ext.port = th->th_sport; |
2654 if (rdr != NULL) { 2655 PF_ACPY(&s->gwy.addr, &baddr, af); | 2886 if (nr != NULL) { 2887 PF_ACPY(&s->gwy.addr, &pd->baddr, af); |
2656 s->gwy.port = bport; 2657 } else { 2658 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 2659 s->gwy.port = s->lan.port; 2660 } 2661 } 2662 2663 s->src.seqlo = ntohl(th->th_seq); --- 17 unchanged lines hidden (view full) --- 2681 /* Remove scale factor from initial window */ 2682 int win = s->src.max_win; 2683 win += 1 << (s->src.wscale & PF_WSCALE_MASK); 2684 s->src.max_win = (win - 1) >> 2685 (s->src.wscale & PF_WSCALE_MASK); 2686 } 2687 if (th->th_flags & TH_FIN) 2688 s->src.seqhi++; | 2888 s->gwy.port = bport; 2889 } else { 2890 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 2891 s->gwy.port = s->lan.port; 2892 } 2893 } 2894 2895 s->src.seqlo = ntohl(th->th_seq); --- 17 unchanged lines hidden (view full) --- 2913 /* Remove scale factor from initial window */ 2914 int win = s->src.max_win; 2915 win += 1 << (s->src.wscale & PF_WSCALE_MASK); 2916 s->src.max_win = (win - 1) >> 2917 (s->src.wscale & PF_WSCALE_MASK); 2918 } 2919 if (th->th_flags & TH_FIN) 2920 s->src.seqhi++; |
2689 s->dst.seqlo = 0; /* Haven't seen these yet */ | |
2690 s->dst.seqhi = 1; 2691 s->dst.max_win = 1; | 2921 s->dst.seqhi = 1; 2922 s->dst.max_win = 1; |
2692 s->dst.seqdiff = 0; /* Defer random generation */ | |
2693 s->src.state = TCPS_SYN_SENT; 2694 s->dst.state = TCPS_CLOSED; 2695#ifdef __FreeBSD__ 2696 s->creation = time_second; 2697 s->expire = time_second; 2698#else 2699 s->creation = time.tv_sec; 2700 s->expire = time.tv_sec; 2701#endif 2702 s->timeout = PFTM_TCP_FIRST_PACKET; | 2923 s->src.state = TCPS_SYN_SENT; 2924 s->dst.state = TCPS_CLOSED; 2925#ifdef __FreeBSD__ 2926 s->creation = time_second; 2927 s->expire = time_second; 2928#else 2929 s->creation = time.tv_sec; 2930 s->expire = time.tv_sec; 2931#endif 2932 s->timeout = PFTM_TCP_FIRST_PACKET; |
2703 s->packets[0] = 1; 2704 s->bytes[0] = pd->tot_len; | |
2705 pf_set_rt_ifp(s, saddr); | 2933 pf_set_rt_ifp(s, saddr); |
2706 | 2934 if (sn != NULL) { 2935 s->src_node = sn; 2936 s->src_node->states++; 2937 } 2938 if (nsn != NULL) { 2939 PF_ACPY(&nsn->raddr, &pd->naddr, af); 2940 s->nat_src_node = nsn; 2941 s->nat_src_node->states++; 2942 } |
2707 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m, 2708 off, pd, th, &s->src, &s->dst)) { 2709 REASON_SET(&reason, PFRES_MEMORY); | 2943 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m, 2944 off, pd, th, &s->src, &s->dst)) { 2945 REASON_SET(&reason, PFRES_MEMORY); |
2946 pf_src_tree_remove_state(s); |
|
2710 pool_put(&pf_state_pl, s); 2711 return (PF_DROP); 2712 } 2713 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub && 2714 pf_normalize_tcp_stateful(m, off, pd, &reason, th, &s->src, 2715 &s->dst, &rewrite)) { 2716 pf_normalize_tcp_cleanup(s); | 2947 pool_put(&pf_state_pl, s); 2948 return (PF_DROP); 2949 } 2950 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub && 2951 pf_normalize_tcp_stateful(m, off, pd, &reason, th, &s->src, 2952 &s->dst, &rewrite)) { 2953 pf_normalize_tcp_cleanup(s); |
2954 pf_src_tree_remove_state(s); |
|
2717 pool_put(&pf_state_pl, s); 2718 return (PF_DROP); 2719 } | 2955 pool_put(&pf_state_pl, s); 2956 return (PF_DROP); 2957 } |
2720 if (pf_insert_state(s)) { | 2958 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { |
2721 pf_normalize_tcp_cleanup(s); 2722 REASON_SET(&reason, PFRES_MEMORY); | 2959 pf_normalize_tcp_cleanup(s); 2960 REASON_SET(&reason, PFRES_MEMORY); |
2961 pf_src_tree_remove_state(s); |
|
2723 pool_put(&pf_state_pl, s); 2724 return (PF_DROP); 2725 } else 2726 *sm = s; 2727 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 2728 r->keep_state == PF_STATE_SYNPROXY) { 2729 s->src.state = PF_TCPS_PROXY_SRC; | 2962 pool_put(&pf_state_pl, s); 2963 return (PF_DROP); 2964 } else 2965 *sm = s; 2966 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 2967 r->keep_state == PF_STATE_SYNPROXY) { 2968 s->src.state = PF_TCPS_PROXY_SRC; |
2730 if (nat != NULL) 2731 pf_change_ap(saddr, &th->th_sport, 2732 pd->ip_sum, &th->th_sum, &baddr, 2733 bport, 0, af); 2734 else if (rdr != NULL) 2735 pf_change_ap(daddr, &th->th_dport, 2736 pd->ip_sum, &th->th_sum, &baddr, 2737 bport, 0, af); | 2969 if (nr != NULL) { 2970 if (direction == PF_OUT) { 2971 pf_change_ap(saddr, &th->th_sport, 2972 pd->ip_sum, &th->th_sum, &pd->baddr, 2973 bport, 0, af); 2974 } else { 2975 pf_change_ap(daddr, &th->th_dport, 2976 pd->ip_sum, &th->th_sum, &pd->baddr, 2977 bport, 0, af); 2978 } 2979 } |
2738 s->src.seqhi = arc4random(); 2739 /* Find mss option */ 2740 mss = pf_get_mss(m, off, th->th_off, af); 2741 mss = pf_calc_mss(saddr, af, mss); 2742 mss = pf_calc_mss(daddr, af, mss); 2743 s->src.mss = mss; 2744 pf_send_tcp(r, af, daddr, saddr, th->th_dport, | 2980 s->src.seqhi = arc4random(); 2981 /* Find mss option */ 2982 mss = pf_get_mss(m, off, th->th_off, af); 2983 mss = pf_calc_mss(saddr, af, mss); 2984 mss = pf_calc_mss(daddr, af, mss); 2985 s->src.mss = mss; 2986 pf_send_tcp(r, af, daddr, saddr, th->th_dport, |
2745 th->th_sport, s->src.seqhi, 2746 ntohl(th->th_seq) + 1, TH_SYN|TH_ACK, 0, s->src.mss, 0); | 2987 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1, 2988 TH_SYN|TH_ACK, 0, s->src.mss, 0); |
2747 return (PF_SYNPROXY_DROP); 2748 } 2749 } 2750 2751 /* copy back packet headers if we performed NAT operations */ 2752 if (rewrite) 2753 m_copyback(m, off, sizeof(*th), (caddr_t)th); 2754 2755 return (PF_PASS); 2756} 2757 2758int 2759pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction, | 2989 return (PF_SYNPROXY_DROP); 2990 } 2991 } 2992 2993 /* copy back packet headers if we performed NAT operations */ 2994 if (rewrite) 2995 m_copyback(m, off, sizeof(*th), (caddr_t)th); 2996 2997 return (PF_PASS); 2998} 2999 3000int 3001pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction, |
2760 struct ifnet *ifp, struct mbuf *m, int ipoff, int off, void *h, | 3002 struct pfi_kif *kif, struct mbuf *m, int off, void *h, |
2761 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) 2762{ | 3003 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) 3004{ |
2763 struct pf_rule *nat = NULL, *rdr = NULL; | 3005 struct pf_rule *nr = NULL; |
2764 struct pf_addr *saddr = pd->src, *daddr = pd->dst; | 3006 struct pf_addr *saddr = pd->src, *daddr = pd->dst; |
2765 struct pf_addr baddr, naddr; | |
2766 struct udphdr *uh = pd->hdr.udp; 2767 u_int16_t bport, nport = 0; 2768 sa_family_t af = pd->af; 2769 int lookup = -1; 2770 uid_t uid; 2771 gid_t gid; 2772 struct pf_rule *r, *a = NULL; 2773 struct pf_ruleset *ruleset = NULL; | 3007 struct udphdr *uh = pd->hdr.udp; 3008 u_int16_t bport, nport = 0; 3009 sa_family_t af = pd->af; 3010 int lookup = -1; 3011 uid_t uid; 3012 gid_t gid; 3013 struct pf_rule *r, *a = NULL; 3014 struct pf_ruleset *ruleset = NULL; |
3015 struct pf_src_node *nsn = NULL; |
|
2774 u_short reason; 2775 int rewrite = 0; 2776 struct pf_tag *pftag = NULL; 2777 int tag = -1; 2778 2779 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 2780 2781 if (direction == PF_OUT) { 2782 bport = nport = uh->uh_sport; 2783 /* check outgoing packet for BINAT/NAT */ | 3016 u_short reason; 3017 int rewrite = 0; 3018 struct pf_tag *pftag = NULL; 3019 int tag = -1; 3020 3021 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3022 3023 if (direction == PF_OUT) { 3024 bport = nport = uh->uh_sport; 3025 /* check outgoing packet for BINAT/NAT */ |
2784 if ((nat = pf_get_translation(pd, m, off, PF_OUT, ifp, | 3026 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, |
2785 saddr, uh->uh_sport, daddr, uh->uh_dport, | 3027 saddr, uh->uh_sport, daddr, uh->uh_dport, |
2786 &naddr, &nport)) != NULL) { 2787 PF_ACPY(&baddr, saddr, af); | 3028 &pd->naddr, &nport)) != NULL) { 3029 PF_ACPY(&pd->baddr, saddr, af); |
2788 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, | 3030 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, |
2789 &uh->uh_sum, &naddr, nport, 1, af); | 3031 &uh->uh_sum, &pd->naddr, nport, 1, af); |
2790 rewrite++; | 3032 rewrite++; |
2791 if (nat->natpass) | 3033 if (nr->natpass) |
2792 r = NULL; | 3034 r = NULL; |
3035 pd->nat_rule = nr; |
|
2793 } 2794 } else { 2795 bport = nport = uh->uh_dport; 2796 /* check incoming packet for BINAT/RDR */ | 3036 } 3037 } else { 3038 bport = nport = uh->uh_dport; 3039 /* check incoming packet for BINAT/RDR */ |
2797 if ((rdr = pf_get_translation(pd, m, off, PF_IN, ifp, saddr, 2798 uh->uh_sport, daddr, uh->uh_dport, &naddr, &nport)) 2799 != NULL) { 2800 PF_ACPY(&baddr, daddr, af); | 3040 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 3041 saddr, uh->uh_sport, daddr, uh->uh_dport, &pd->naddr, 3042 &nport)) != NULL) { 3043 PF_ACPY(&pd->baddr, daddr, af); |
2801 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, | 3044 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, |
2802 &uh->uh_sum, &naddr, nport, 1, af); | 3045 &uh->uh_sum, &pd->naddr, nport, 1, af); |
2803 rewrite++; | 3046 rewrite++; |
2804 if (rdr->natpass) | 3047 if (nr->natpass) |
2805 r = NULL; | 3048 r = NULL; |
3049 pd->nat_rule = nr; |
|
2806 } 2807 } 2808 2809 while (r != NULL) { 2810 r->evaluations++; | 3050 } 3051 } 3052 3053 while (r != NULL) { 3054 r->evaluations++; |
2811 if (r->ifp != NULL && ((r->ifp != ifp && !r->ifnot) || 2812 (r->ifp == ifp && r->ifnot))) | 3055 if (r->kif != NULL && 3056 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) |
2813 r = r->skip[PF_SKIP_IFP].ptr; 2814 else if (r->direction && r->direction != direction) 2815 r = r->skip[PF_SKIP_DIR].ptr; 2816 else if (r->af && r->af != af) 2817 r = r->skip[PF_SKIP_AF].ptr; 2818 else if (r->proto && r->proto != IPPROTO_UDP) 2819 r = r->skip[PF_SKIP_PROTO].ptr; 2820 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) --- 6 unchanged lines hidden (view full) --- 2827 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 2828 r->dst.port[0], r->dst.port[1], uh->uh_dport)) 2829 r = r->skip[PF_SKIP_DST_PORT].ptr; 2830 else if (r->tos && !(r->tos & pd->tos)) 2831 r = TAILQ_NEXT(r, entries); 2832 else if (r->rule_flag & PFRULE_FRAGMENT) 2833 r = TAILQ_NEXT(r, entries); 2834 else if (r->uid.op && (lookup != -1 || (lookup = | 3057 r = r->skip[PF_SKIP_IFP].ptr; 3058 else if (r->direction && r->direction != direction) 3059 r = r->skip[PF_SKIP_DIR].ptr; 3060 else if (r->af && r->af != af) 3061 r = r->skip[PF_SKIP_AF].ptr; 3062 else if (r->proto && r->proto != IPPROTO_UDP) 3063 r = r->skip[PF_SKIP_PROTO].ptr; 3064 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) --- 6 unchanged lines hidden (view full) --- 3071 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 3072 r->dst.port[0], r->dst.port[1], uh->uh_dport)) 3073 r = r->skip[PF_SKIP_DST_PORT].ptr; 3074 else if (r->tos && !(r->tos & pd->tos)) 3075 r = TAILQ_NEXT(r, entries); 3076 else if (r->rule_flag & PFRULE_FRAGMENT) 3077 r = TAILQ_NEXT(r, entries); 3078 else if (r->uid.op && (lookup != -1 || (lookup = |
2835 pf_socket_lookup(&uid, &gid, direction, af, IPPROTO_UDP, 2836 pd), 1)) && | 3079 pf_socket_lookup(&uid, &gid, direction, pd), 1)) && |
2837 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 2838 uid)) 2839 r = TAILQ_NEXT(r, entries); 2840 else if (r->gid.op && (lookup != -1 || (lookup = | 3080 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 3081 uid)) 3082 r = TAILQ_NEXT(r, entries); 3083 else if (r->gid.op && (lookup != -1 || (lookup = |
2841 pf_socket_lookup(&uid, &gid, direction, af, IPPROTO_UDP, 2842 pd), 1)) && | 3084 pf_socket_lookup(&uid, &gid, direction, pd), 1)) && |
2843 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 2844 gid)) 2845 r = TAILQ_NEXT(r, entries); | 3085 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 3086 gid)) 3087 r = TAILQ_NEXT(r, entries); |
2846 else if (r->match_tag && 2847 !pf_match_tag(m, r, nat, rdr, pftag, &tag)) | 3088 else if (r->match_tag && !pf_match_tag(m, r, nr, pftag, &tag)) |
2848 r = TAILQ_NEXT(r, entries); 2849 else if (r->anchorname[0] && r->anchor == NULL) 2850 r = TAILQ_NEXT(r, entries); 2851 else if (r->os_fingerprint != PF_OSFP_ANY) 2852 r = TAILQ_NEXT(r, entries); 2853 else { 2854 if (r->tag) 2855 tag = r->tag; --- 11 unchanged lines hidden (view full) --- 2867 if (r == NULL && a != NULL) 2868 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 2869 PF_RULESET_FILTER); 2870 } 2871 r = *rm; 2872 a = *am; 2873 ruleset = *rsm; 2874 | 3089 r = TAILQ_NEXT(r, entries); 3090 else if (r->anchorname[0] && r->anchor == NULL) 3091 r = TAILQ_NEXT(r, entries); 3092 else if (r->os_fingerprint != PF_OSFP_ANY) 3093 r = TAILQ_NEXT(r, entries); 3094 else { 3095 if (r->tag) 3096 tag = r->tag; --- 11 unchanged lines hidden (view full) --- 3108 if (r == NULL && a != NULL) 3109 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3110 PF_RULESET_FILTER); 3111 } 3112 r = *rm; 3113 a = *am; 3114 ruleset = *rsm; 3115 |
2875 r->packets++; 2876 r->bytes += pd->tot_len; 2877 if (a != NULL) { 2878 a->packets++; 2879 a->bytes += pd->tot_len; 2880 } | |
2881 REASON_SET(&reason, PFRES_MATCH); 2882 2883 if (r->log) { 2884 if (rewrite) 2885 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); | 3116 REASON_SET(&reason, PFRES_MATCH); 3117 3118 if (r->log) { 3119 if (rewrite) 3120 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); |
2886 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); | 3121 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); |
2887 } 2888 2889 if ((r->action == PF_DROP) && 2890 ((r->rule_flag & PFRULE_RETURNICMP) || 2891 (r->rule_flag & PFRULE_RETURN))) { 2892 /* undo NAT changes, if they have taken place */ | 3122 } 3123 3124 if ((r->action == PF_DROP) && 3125 ((r->rule_flag & PFRULE_RETURNICMP) || 3126 (r->rule_flag & PFRULE_RETURN))) { 3127 /* undo NAT changes, if they have taken place */ |
2893 if (nat != NULL) { 2894 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, 2895 &uh->uh_sum, &baddr, bport, 1, af); 2896 rewrite++; 2897 } else if (rdr != NULL) { 2898 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, 2899 &uh->uh_sum, &baddr, bport, 1, af); 2900 rewrite++; | 3128 if (nr != NULL) { 3129 if (direction == PF_OUT) { 3130 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, 3131 &uh->uh_sum, &pd->baddr, bport, 1, af); 3132 rewrite++; 3133 } else { 3134 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, 3135 &uh->uh_sum, &pd->baddr, bport, 1, af); 3136 rewrite++; 3137 } |
2901 } 2902 if ((af == AF_INET) && r->return_icmp) 2903 pf_send_icmp(m, r->return_icmp >> 8, 2904 r->return_icmp & 255, af, r); 2905 else if ((af == AF_INET6) && r->return_icmp6) 2906 pf_send_icmp(m, r->return_icmp6 >> 8, 2907 r->return_icmp6 & 255, af, r); 2908 } 2909 2910 if (r->action == PF_DROP) 2911 return (PF_DROP); 2912 2913 if (pf_tag_packet(m, pftag, tag)) { 2914 REASON_SET(&reason, PFRES_MEMORY); 2915 return (PF_DROP); 2916 } 2917 | 3138 } 3139 if ((af == AF_INET) && r->return_icmp) 3140 pf_send_icmp(m, r->return_icmp >> 8, 3141 r->return_icmp & 255, af, r); 3142 else if ((af == AF_INET6) && r->return_icmp6) 3143 pf_send_icmp(m, r->return_icmp6 >> 8, 3144 r->return_icmp6 & 255, af, r); 3145 } 3146 3147 if (r->action == PF_DROP) 3148 return (PF_DROP); 3149 3150 if (pf_tag_packet(m, pftag, tag)) { 3151 REASON_SET(&reason, PFRES_MEMORY); 3152 return (PF_DROP); 3153 } 3154 |
2918 if (r->keep_state || nat != NULL || rdr != NULL) { | 3155 if (r->keep_state || nr != NULL) { |
2919 /* create new state */ 2920 struct pf_state *s = NULL; | 3156 /* create new state */ 3157 struct pf_state *s = NULL; |
3158 struct pf_src_node *sn = NULL; |
|
2921 | 3159 |
2922 if (!r->max_states || r->states < r->max_states) 2923 s = pool_get(&pf_state_pl, PR_NOWAIT); | 3160 /* check maximums */ 3161 if (r->max_states && (r->states >= r->max_states)) 3162 goto cleanup; 3163 /* src node for flter rule */ 3164 if ((r->rule_flag & PFRULE_SRCTRACK || 3165 r->rpool.opts & PF_POOL_STICKYADDR) && 3166 pf_insert_src_node(&sn, r, saddr, af) != 0) 3167 goto cleanup; 3168 /* src node for translation rule */ 3169 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 3170 ((direction == PF_OUT && 3171 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 3172 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) 3173 goto cleanup; 3174 s = pool_get(&pf_state_pl, PR_NOWAIT); |
2924 if (s == NULL) { | 3175 if (s == NULL) { |
3176cleanup: 3177 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 3178 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 3179 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3180 pf_status.src_nodes--; 3181 pool_put(&pf_src_tree_pl, sn); 3182 } 3183 if (nsn != sn && nsn != NULL && nsn->states == 0 && 3184 nsn->expire == 0) { 3185 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 3186 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3187 pf_status.src_nodes--; 3188 pool_put(&pf_src_tree_pl, nsn); 3189 } |
|
2925 REASON_SET(&reason, PFRES_MEMORY); 2926 return (PF_DROP); 2927 } 2928 bzero(s, sizeof(*s)); 2929 r->states++; 2930 if (a != NULL) 2931 a->states++; 2932 s->rule.ptr = r; | 3190 REASON_SET(&reason, PFRES_MEMORY); 3191 return (PF_DROP); 3192 } 3193 bzero(s, sizeof(*s)); 3194 r->states++; 3195 if (a != NULL) 3196 a->states++; 3197 s->rule.ptr = r; |
2933 if (nat != NULL) 2934 s->nat_rule.ptr = nat; 2935 else 2936 s->nat_rule.ptr = rdr; | 3198 s->nat_rule.ptr = nr; |
2937 if (s->nat_rule.ptr != NULL) 2938 s->nat_rule.ptr->states++; 2939 s->anchor.ptr = a; 2940 s->allow_opts = r->allow_opts; 2941 s->log = r->log & 2; 2942 s->proto = IPPROTO_UDP; 2943 s->direction = direction; 2944 s->af = af; 2945 if (direction == PF_OUT) { 2946 PF_ACPY(&s->gwy.addr, saddr, af); 2947 s->gwy.port = uh->uh_sport; 2948 PF_ACPY(&s->ext.addr, daddr, af); 2949 s->ext.port = uh->uh_dport; | 3199 if (s->nat_rule.ptr != NULL) 3200 s->nat_rule.ptr->states++; 3201 s->anchor.ptr = a; 3202 s->allow_opts = r->allow_opts; 3203 s->log = r->log & 2; 3204 s->proto = IPPROTO_UDP; 3205 s->direction = direction; 3206 s->af = af; 3207 if (direction == PF_OUT) { 3208 PF_ACPY(&s->gwy.addr, saddr, af); 3209 s->gwy.port = uh->uh_sport; 3210 PF_ACPY(&s->ext.addr, daddr, af); 3211 s->ext.port = uh->uh_dport; |
2950 if (nat != NULL) { 2951 PF_ACPY(&s->lan.addr, &baddr, af); | 3212 if (nr != NULL) { 3213 PF_ACPY(&s->lan.addr, &pd->baddr, af); |
2952 s->lan.port = bport; 2953 } else { 2954 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 2955 s->lan.port = s->gwy.port; 2956 } 2957 } else { 2958 PF_ACPY(&s->lan.addr, daddr, af); 2959 s->lan.port = uh->uh_dport; 2960 PF_ACPY(&s->ext.addr, saddr, af); 2961 s->ext.port = uh->uh_sport; | 3214 s->lan.port = bport; 3215 } else { 3216 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 3217 s->lan.port = s->gwy.port; 3218 } 3219 } else { 3220 PF_ACPY(&s->lan.addr, daddr, af); 3221 s->lan.port = uh->uh_dport; 3222 PF_ACPY(&s->ext.addr, saddr, af); 3223 s->ext.port = uh->uh_sport; |
2962 if (rdr != NULL) { 2963 PF_ACPY(&s->gwy.addr, &baddr, af); | 3224 if (nr != NULL) { 3225 PF_ACPY(&s->gwy.addr, &pd->baddr, af); |
2964 s->gwy.port = bport; 2965 } else { 2966 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 2967 s->gwy.port = s->lan.port; 2968 } 2969 } | 3226 s->gwy.port = bport; 3227 } else { 3228 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3229 s->gwy.port = s->lan.port; 3230 } 3231 } |
2970 s->src.seqlo = 0; 2971 s->src.seqhi = 0; 2972 s->src.seqdiff = 0; 2973 s->src.max_win = 0; | |
2974 s->src.state = PFUDPS_SINGLE; | 3232 s->src.state = PFUDPS_SINGLE; |
2975 s->dst.seqlo = 0; 2976 s->dst.seqhi = 0; 2977 s->dst.seqdiff = 0; 2978 s->dst.max_win = 0; | |
2979 s->dst.state = PFUDPS_NO_TRAFFIC; 2980#ifdef __FreeBSD__ 2981 s->creation = time_second; 2982 s->expire = time_second; 2983#else 2984 s->creation = time.tv_sec; 2985 s->expire = time.tv_sec; 2986#endif 2987 s->timeout = PFTM_UDP_FIRST_PACKET; | 3233 s->dst.state = PFUDPS_NO_TRAFFIC; 3234#ifdef __FreeBSD__ 3235 s->creation = time_second; 3236 s->expire = time_second; 3237#else 3238 s->creation = time.tv_sec; 3239 s->expire = time.tv_sec; 3240#endif 3241 s->timeout = PFTM_UDP_FIRST_PACKET; |
2988 s->packets[0] = 1; 2989 s->bytes[0] = pd->tot_len; | |
2990 pf_set_rt_ifp(s, saddr); | 3242 pf_set_rt_ifp(s, saddr); |
2991 if (pf_insert_state(s)) { | 3243 if (sn != NULL) { 3244 s->src_node = sn; 3245 s->src_node->states++; 3246 } 3247 if (nsn != NULL) { 3248 PF_ACPY(&nsn->raddr, &pd->naddr, af); 3249 s->nat_src_node = nsn; 3250 s->nat_src_node->states++; 3251 } 3252 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { |
2992 REASON_SET(&reason, PFRES_MEMORY); | 3253 REASON_SET(&reason, PFRES_MEMORY); |
3254 pf_src_tree_remove_state(s); |
|
2993 pool_put(&pf_state_pl, s); 2994 return (PF_DROP); 2995 } else 2996 *sm = s; 2997 } 2998 2999 /* copy back packet headers if we performed NAT operations */ 3000 if (rewrite) 3001 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 3002 3003 return (PF_PASS); 3004} 3005 3006int 3007pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction, | 3255 pool_put(&pf_state_pl, s); 3256 return (PF_DROP); 3257 } else 3258 *sm = s; 3259 } 3260 3261 /* copy back packet headers if we performed NAT operations */ 3262 if (rewrite) 3263 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 3264 3265 return (PF_PASS); 3266} 3267 3268int 3269pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction, |
3008 struct ifnet *ifp, struct mbuf *m, int ipoff, int off, void *h, | 3270 struct pfi_kif *kif, struct mbuf *m, int off, void *h, |
3009 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) 3010{ | 3271 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm) 3272{ |
3011 struct pf_rule *nat = NULL, *rdr = NULL; | 3273 struct pf_rule *nr = NULL; |
3012 struct pf_addr *saddr = pd->src, *daddr = pd->dst; | 3274 struct pf_addr *saddr = pd->src, *daddr = pd->dst; |
3013 struct pf_addr baddr, naddr; | |
3014 struct pf_rule *r, *a = NULL; 3015 struct pf_ruleset *ruleset = NULL; | 3275 struct pf_rule *r, *a = NULL; 3276 struct pf_ruleset *ruleset = NULL; |
3277 struct pf_src_node *nsn = NULL; |
|
3016 u_short reason; 3017 u_int16_t icmpid = 0; /* make the compiler happy */ 3018 sa_family_t af = pd->af; 3019 u_int8_t icmptype = 0; /* make the compiler happy */ 3020 u_int8_t icmpcode = 0; /* make the compiler happy */ 3021 int state_icmp = 0; 3022 struct pf_tag *pftag = NULL; 3023 int tag = -1; --- 30 unchanged lines hidden (view full) --- 3054 break; 3055#endif /* INET6 */ 3056 } 3057 3058 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3059 3060 if (direction == PF_OUT) { 3061 /* check outgoing packet for BINAT/NAT */ | 3278 u_short reason; 3279 u_int16_t icmpid = 0; /* make the compiler happy */ 3280 sa_family_t af = pd->af; 3281 u_int8_t icmptype = 0; /* make the compiler happy */ 3282 u_int8_t icmpcode = 0; /* make the compiler happy */ 3283 int state_icmp = 0; 3284 struct pf_tag *pftag = NULL; 3285 int tag = -1; --- 30 unchanged lines hidden (view full) --- 3316 break; 3317#endif /* INET6 */ 3318 } 3319 3320 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3321 3322 if (direction == PF_OUT) { 3323 /* check outgoing packet for BINAT/NAT */ |
3062 if ((nat = pf_get_translation(pd, m, off, PF_OUT, ifp, saddr, 0, 3063 daddr, 0, &naddr, NULL)) != NULL) { 3064 PF_ACPY(&baddr, saddr, af); | 3324 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 3325 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { 3326 PF_ACPY(&pd->baddr, saddr, af); |
3065 switch (af) { 3066#ifdef INET 3067 case AF_INET: 3068 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, | 3327 switch (af) { 3328#ifdef INET 3329 case AF_INET: 3330 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, |
3069 naddr.v4.s_addr, 0); | 3331 pd->naddr.v4.s_addr, 0); |
3070 break; 3071#endif /* INET */ 3072#ifdef INET6 3073 case AF_INET6: 3074 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum, | 3332 break; 3333#endif /* INET */ 3334#ifdef INET6 3335 case AF_INET6: 3336 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum, |
3075 &naddr, 0); | 3337 &pd->naddr, 0); |
3076 rewrite++; 3077 break; 3078#endif /* INET6 */ 3079 } | 3338 rewrite++; 3339 break; 3340#endif /* INET6 */ 3341 } |
3080 if (nat->natpass) | 3342 if (nr->natpass) |
3081 r = NULL; | 3343 r = NULL; |
3344 pd->nat_rule = nr; |
|
3082 } 3083 } else { 3084 /* check incoming packet for BINAT/RDR */ | 3345 } 3346 } else { 3347 /* check incoming packet for BINAT/RDR */ |
3085 if ((rdr = pf_get_translation(pd, m, off, PF_IN, ifp, saddr, 0, 3086 daddr, 0, &naddr, NULL)) != NULL) { 3087 PF_ACPY(&baddr, daddr, af); | 3348 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 3349 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { 3350 PF_ACPY(&pd->baddr, daddr, af); |
3088 switch (af) { 3089#ifdef INET 3090 case AF_INET: 3091 pf_change_a(&daddr->v4.s_addr, | 3351 switch (af) { 3352#ifdef INET 3353 case AF_INET: 3354 pf_change_a(&daddr->v4.s_addr, |
3092 pd->ip_sum, naddr.v4.s_addr, 0); | 3355 pd->ip_sum, pd->naddr.v4.s_addr, 0); |
3093 break; 3094#endif /* INET */ 3095#ifdef INET6 3096 case AF_INET6: 3097 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, | 3356 break; 3357#endif /* INET */ 3358#ifdef INET6 3359 case AF_INET6: 3360 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, |
3098 &naddr, 0); | 3361 &pd->naddr, 0); |
3099 rewrite++; 3100 break; 3101#endif /* INET6 */ 3102 } | 3362 rewrite++; 3363 break; 3364#endif /* INET6 */ 3365 } |
3103 if (rdr->natpass) | 3366 if (nr->natpass) |
3104 r = NULL; | 3367 r = NULL; |
3368 pd->nat_rule = nr; |
|
3105 } 3106 } 3107 3108 while (r != NULL) { 3109 r->evaluations++; | 3369 } 3370 } 3371 3372 while (r != NULL) { 3373 r->evaluations++; |
3110 if (r->ifp != NULL && ((r->ifp != ifp && !r->ifnot) || 3111 (r->ifp == ifp && r->ifnot))) | 3374 if (r->kif != NULL && 3375 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) |
3112 r = r->skip[PF_SKIP_IFP].ptr; 3113 else if (r->direction && r->direction != direction) 3114 r = r->skip[PF_SKIP_DIR].ptr; 3115 else if (r->af && r->af != af) 3116 r = r->skip[PF_SKIP_AF].ptr; 3117 else if (r->proto && r->proto != pd->proto) 3118 r = r->skip[PF_SKIP_PROTO].ptr; 3119 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) 3120 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3121 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) 3122 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3123 else if (r->type && r->type != icmptype + 1) 3124 r = TAILQ_NEXT(r, entries); 3125 else if (r->code && r->code != icmpcode + 1) 3126 r = TAILQ_NEXT(r, entries); 3127 else if (r->tos && !(r->tos & pd->tos)) 3128 r = TAILQ_NEXT(r, entries); 3129 else if (r->rule_flag & PFRULE_FRAGMENT) 3130 r = TAILQ_NEXT(r, entries); | 3376 r = r->skip[PF_SKIP_IFP].ptr; 3377 else if (r->direction && r->direction != direction) 3378 r = r->skip[PF_SKIP_DIR].ptr; 3379 else if (r->af && r->af != af) 3380 r = r->skip[PF_SKIP_AF].ptr; 3381 else if (r->proto && r->proto != pd->proto) 3382 r = r->skip[PF_SKIP_PROTO].ptr; 3383 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.not)) 3384 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3385 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) 3386 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3387 else if (r->type && r->type != icmptype + 1) 3388 r = TAILQ_NEXT(r, entries); 3389 else if (r->code && r->code != icmpcode + 1) 3390 r = TAILQ_NEXT(r, entries); 3391 else if (r->tos && !(r->tos & pd->tos)) 3392 r = TAILQ_NEXT(r, entries); 3393 else if (r->rule_flag & PFRULE_FRAGMENT) 3394 r = TAILQ_NEXT(r, entries); |
3131 else if (r->match_tag && 3132 !pf_match_tag(m, r, nat, rdr, pftag, &tag)) | 3395 else if (r->match_tag && !pf_match_tag(m, r, nr, pftag, &tag)) |
3133 r = TAILQ_NEXT(r, entries); 3134 else if (r->anchorname[0] && r->anchor == NULL) 3135 r = TAILQ_NEXT(r, entries); 3136 else if (r->os_fingerprint != PF_OSFP_ANY) 3137 r = TAILQ_NEXT(r, entries); 3138 else { 3139 if (r->tag) 3140 tag = r->tag; --- 11 unchanged lines hidden (view full) --- 3152 if (r == NULL && a != NULL) 3153 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3154 PF_RULESET_FILTER); 3155 } 3156 r = *rm; 3157 a = *am; 3158 ruleset = *rsm; 3159 | 3396 r = TAILQ_NEXT(r, entries); 3397 else if (r->anchorname[0] && r->anchor == NULL) 3398 r = TAILQ_NEXT(r, entries); 3399 else if (r->os_fingerprint != PF_OSFP_ANY) 3400 r = TAILQ_NEXT(r, entries); 3401 else { 3402 if (r->tag) 3403 tag = r->tag; --- 11 unchanged lines hidden (view full) --- 3415 if (r == NULL && a != NULL) 3416 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3417 PF_RULESET_FILTER); 3418 } 3419 r = *rm; 3420 a = *am; 3421 ruleset = *rsm; 3422 |
3160 r->packets++; 3161 r->bytes += pd->tot_len; 3162 if (a != NULL) { 3163 a->packets++; 3164 a->bytes += pd->tot_len; 3165 } | |
3166 REASON_SET(&reason, PFRES_MATCH); 3167 3168 if (r->log) { 3169#ifdef INET6 3170 if (rewrite) 3171 m_copyback(m, off, sizeof(struct icmp6_hdr), 3172 (caddr_t)pd->hdr.icmp6); 3173#endif /* INET6 */ | 3423 REASON_SET(&reason, PFRES_MATCH); 3424 3425 if (r->log) { 3426#ifdef INET6 3427 if (rewrite) 3428 m_copyback(m, off, sizeof(struct icmp6_hdr), 3429 (caddr_t)pd->hdr.icmp6); 3430#endif /* INET6 */ |
3174 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); | 3431 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); |
3175 } 3176 3177 if (r->action != PF_PASS) 3178 return (PF_DROP); 3179 3180 if (pf_tag_packet(m, pftag, tag)) { 3181 REASON_SET(&reason, PFRES_MEMORY); 3182 return (PF_DROP); 3183 } 3184 | 3432 } 3433 3434 if (r->action != PF_PASS) 3435 return (PF_DROP); 3436 3437 if (pf_tag_packet(m, pftag, tag)) { 3438 REASON_SET(&reason, PFRES_MEMORY); 3439 return (PF_DROP); 3440 } 3441 |
3185 if (!state_icmp && (r->keep_state || 3186 nat != NULL || rdr != NULL)) { | 3442 if (!state_icmp && (r->keep_state || nr != NULL)) { |
3187 /* create new state */ 3188 struct pf_state *s = NULL; | 3443 /* create new state */ 3444 struct pf_state *s = NULL; |
3445 struct pf_src_node *sn = NULL; |
|
3189 | 3446 |
3190 if (!r->max_states || r->states < r->max_states) 3191 s = pool_get(&pf_state_pl, PR_NOWAIT); | 3447 /* check maximums */ 3448 if (r->max_states && (r->states >= r->max_states)) 3449 goto cleanup; 3450 /* src node for flter rule */ 3451 if ((r->rule_flag & PFRULE_SRCTRACK || 3452 r->rpool.opts & PF_POOL_STICKYADDR) && 3453 pf_insert_src_node(&sn, r, saddr, af) != 0) 3454 goto cleanup; 3455 /* src node for translation rule */ 3456 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 3457 ((direction == PF_OUT && 3458 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 3459 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) 3460 goto cleanup; 3461 s = pool_get(&pf_state_pl, PR_NOWAIT); |
3192 if (s == NULL) { | 3462 if (s == NULL) { |
3463cleanup: 3464 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 3465 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 3466 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3467 pf_status.src_nodes--; 3468 pool_put(&pf_src_tree_pl, sn); 3469 } 3470 if (nsn != sn && nsn != NULL && nsn->states == 0 && 3471 nsn->expire == 0) { 3472 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 3473 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3474 pf_status.src_nodes--; 3475 pool_put(&pf_src_tree_pl, nsn); 3476 } |
|
3193 REASON_SET(&reason, PFRES_MEMORY); 3194 return (PF_DROP); 3195 } 3196 bzero(s, sizeof(*s)); 3197 r->states++; 3198 if (a != NULL) 3199 a->states++; 3200 s->rule.ptr = r; | 3477 REASON_SET(&reason, PFRES_MEMORY); 3478 return (PF_DROP); 3479 } 3480 bzero(s, sizeof(*s)); 3481 r->states++; 3482 if (a != NULL) 3483 a->states++; 3484 s->rule.ptr = r; |
3201 if (nat != NULL) 3202 s->nat_rule.ptr = nat; 3203 else 3204 s->nat_rule.ptr = rdr; | 3485 s->nat_rule.ptr = nr; |
3205 if (s->nat_rule.ptr != NULL) 3206 s->nat_rule.ptr->states++; 3207 s->anchor.ptr = a; 3208 s->allow_opts = r->allow_opts; 3209 s->log = r->log & 2; 3210 s->proto = pd->proto; 3211 s->direction = direction; 3212 s->af = af; 3213 if (direction == PF_OUT) { 3214 PF_ACPY(&s->gwy.addr, saddr, af); 3215 s->gwy.port = icmpid; 3216 PF_ACPY(&s->ext.addr, daddr, af); 3217 s->ext.port = icmpid; | 3486 if (s->nat_rule.ptr != NULL) 3487 s->nat_rule.ptr->states++; 3488 s->anchor.ptr = a; 3489 s->allow_opts = r->allow_opts; 3490 s->log = r->log & 2; 3491 s->proto = pd->proto; 3492 s->direction = direction; 3493 s->af = af; 3494 if (direction == PF_OUT) { 3495 PF_ACPY(&s->gwy.addr, saddr, af); 3496 s->gwy.port = icmpid; 3497 PF_ACPY(&s->ext.addr, daddr, af); 3498 s->ext.port = icmpid; |
3218 if (nat != NULL) 3219 PF_ACPY(&s->lan.addr, &baddr, af); | 3499 if (nr != NULL) 3500 PF_ACPY(&s->lan.addr, &pd->baddr, af); |
3220 else 3221 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 3222 s->lan.port = icmpid; 3223 } else { 3224 PF_ACPY(&s->lan.addr, daddr, af); 3225 s->lan.port = icmpid; 3226 PF_ACPY(&s->ext.addr, saddr, af); 3227 s->ext.port = icmpid; | 3501 else 3502 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); 3503 s->lan.port = icmpid; 3504 } else { 3505 PF_ACPY(&s->lan.addr, daddr, af); 3506 s->lan.port = icmpid; 3507 PF_ACPY(&s->ext.addr, saddr, af); 3508 s->ext.port = icmpid; |
3228 if (rdr != NULL) 3229 PF_ACPY(&s->gwy.addr, &baddr, af); | 3509 if (nr != NULL) 3510 PF_ACPY(&s->gwy.addr, &pd->baddr, af); |
3230 else 3231 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3232 s->gwy.port = icmpid; 3233 } | 3511 else 3512 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); 3513 s->gwy.port = icmpid; 3514 } |
3234 3235 s->src.seqlo = 0; 3236 s->src.seqhi = 0; 3237 s->src.seqdiff = 0; 3238 s->src.max_win = 0; 3239 s->src.state = 0; 3240 s->dst.seqlo = 0; 3241 s->dst.seqhi = 0; 3242 s->dst.seqdiff = 0; 3243 s->dst.max_win = 0; 3244 s->dst.state = 0; | |
3245#ifdef __FreeBSD__ 3246 s->creation = time_second; 3247 s->expire = time_second; 3248#else 3249 s->creation = time.tv_sec; 3250 s->expire = time.tv_sec; 3251#endif 3252 s->timeout = PFTM_ICMP_FIRST_PACKET; | 3515#ifdef __FreeBSD__ 3516 s->creation = time_second; 3517 s->expire = time_second; 3518#else 3519 s->creation = time.tv_sec; 3520 s->expire = time.tv_sec; 3521#endif 3522 s->timeout = PFTM_ICMP_FIRST_PACKET; |
3253 s->packets[0] = 1; 3254 s->bytes[0] = pd->tot_len; | |
3255 pf_set_rt_ifp(s, saddr); | 3523 pf_set_rt_ifp(s, saddr); |
3256 if (pf_insert_state(s)) { | 3524 if (sn != NULL) { 3525 s->src_node = sn; 3526 s->src_node->states++; 3527 } 3528 if (nsn != NULL) { 3529 PF_ACPY(&nsn->raddr, &pd->naddr, af); 3530 s->nat_src_node = nsn; 3531 s->nat_src_node->states++; 3532 } 3533 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { |
3257 REASON_SET(&reason, PFRES_MEMORY); | 3534 REASON_SET(&reason, PFRES_MEMORY); |
3535 pf_src_tree_remove_state(s); |
|
3258 pool_put(&pf_state_pl, s); 3259 return (PF_DROP); 3260 } else 3261 *sm = s; 3262 } 3263 3264#ifdef INET6 3265 /* copy back packet headers if we performed IPv6 NAT operations */ 3266 if (rewrite) 3267 m_copyback(m, off, sizeof(struct icmp6_hdr), 3268 (caddr_t)pd->hdr.icmp6); 3269#endif /* INET6 */ 3270 3271 return (PF_PASS); 3272} 3273 3274int 3275pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction, | 3536 pool_put(&pf_state_pl, s); 3537 return (PF_DROP); 3538 } else 3539 *sm = s; 3540 } 3541 3542#ifdef INET6 3543 /* copy back packet headers if we performed IPv6 NAT operations */ 3544 if (rewrite) 3545 m_copyback(m, off, sizeof(struct icmp6_hdr), 3546 (caddr_t)pd->hdr.icmp6); 3547#endif /* INET6 */ 3548 3549 return (PF_PASS); 3550} 3551 3552int 3553pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction, |
3276 struct ifnet *ifp, struct mbuf *m, int off, void *h, struct pf_pdesc *pd, | 3554 struct pfi_kif *kif, struct mbuf *m, int off, void *h, struct pf_pdesc *pd, |
3277 struct pf_rule **am, struct pf_ruleset **rsm) 3278{ | 3555 struct pf_rule **am, struct pf_ruleset **rsm) 3556{ |
3279 struct pf_rule *nat = NULL, *rdr = NULL; | 3557 struct pf_rule *nr = NULL; |
3280 struct pf_rule *r, *a = NULL; 3281 struct pf_ruleset *ruleset = NULL; | 3558 struct pf_rule *r, *a = NULL; 3559 struct pf_ruleset *ruleset = NULL; |
3560 struct pf_src_node *nsn = NULL; |
|
3282 struct pf_addr *saddr = pd->src, *daddr = pd->dst; | 3561 struct pf_addr *saddr = pd->src, *daddr = pd->dst; |
3283 struct pf_addr baddr, naddr; | |
3284 sa_family_t af = pd->af; 3285 u_short reason; 3286 struct pf_tag *pftag = NULL; 3287 int tag = -1; 3288 3289 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3290 3291 if (direction == PF_OUT) { 3292 /* check outgoing packet for BINAT/NAT */ | 3562 sa_family_t af = pd->af; 3563 u_short reason; 3564 struct pf_tag *pftag = NULL; 3565 int tag = -1; 3566 3567 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3568 3569 if (direction == PF_OUT) { 3570 /* check outgoing packet for BINAT/NAT */ |
3293 if ((nat = pf_get_translation(pd, m, off, PF_OUT, ifp, saddr, 0, 3294 daddr, 0, &naddr, NULL)) != NULL) { 3295 PF_ACPY(&baddr, saddr, af); | 3571 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, 3572 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { 3573 PF_ACPY(&pd->baddr, saddr, af); |
3296 switch (af) { 3297#ifdef INET 3298 case AF_INET: 3299 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, | 3574 switch (af) { 3575#ifdef INET 3576 case AF_INET: 3577 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, |
3300 naddr.v4.s_addr, 0); | 3578 pd->naddr.v4.s_addr, 0); |
3301 break; 3302#endif /* INET */ 3303#ifdef INET6 3304 case AF_INET6: | 3579 break; 3580#endif /* INET */ 3581#ifdef INET6 3582 case AF_INET6: |
3305 PF_ACPY(saddr, &naddr, af); | 3583 PF_ACPY(saddr, &pd->naddr, af); |
3306 break; 3307#endif /* INET6 */ 3308 } | 3584 break; 3585#endif /* INET6 */ 3586 } |
3309 if (nat->natpass) | 3587 if (nr->natpass) |
3310 r = NULL; | 3588 r = NULL; |
3589 pd->nat_rule = nr; |
|
3311 } 3312 } else { 3313 /* check incoming packet for BINAT/RDR */ | 3590 } 3591 } else { 3592 /* check incoming packet for BINAT/RDR */ |
3314 if ((rdr = pf_get_translation(pd, m, off, PF_IN, ifp, saddr, 0, 3315 daddr, 0, &naddr, NULL)) != NULL) { 3316 PF_ACPY(&baddr, daddr, af); | 3593 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, 3594 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { 3595 PF_ACPY(&pd->baddr, daddr, af); |
3317 switch (af) { 3318#ifdef INET 3319 case AF_INET: 3320 pf_change_a(&daddr->v4.s_addr, | 3596 switch (af) { 3597#ifdef INET 3598 case AF_INET: 3599 pf_change_a(&daddr->v4.s_addr, |
3321 pd->ip_sum, naddr.v4.s_addr, 0); | 3600 pd->ip_sum, pd->naddr.v4.s_addr, 0); |
3322 break; 3323#endif /* INET */ 3324#ifdef INET6 3325 case AF_INET6: | 3601 break; 3602#endif /* INET */ 3603#ifdef INET6 3604 case AF_INET6: |
3326 PF_ACPY(daddr, &naddr, af); | 3605 PF_ACPY(daddr, &pd->naddr, af); |
3327 break; 3328#endif /* INET6 */ 3329 } | 3606 break; 3607#endif /* INET6 */ 3608 } |
3330 if (rdr->natpass) | 3609 if (nr->natpass) |
3331 r = NULL; | 3610 r = NULL; |
3611 pd->nat_rule = nr; |
|
3332 } 3333 } 3334 3335 while (r != NULL) { 3336 r->evaluations++; | 3612 } 3613 } 3614 3615 while (r != NULL) { 3616 r->evaluations++; |
3337 if (r->ifp != NULL && ((r->ifp != ifp && !r->ifnot) || 3338 (r->ifp == ifp && r->ifnot))) | 3617 if (r->kif != NULL && 3618 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) |
3339 r = r->skip[PF_SKIP_IFP].ptr; 3340 else if (r->direction && r->direction != direction) 3341 r = r->skip[PF_SKIP_DIR].ptr; 3342 else if (r->af && r->af != af) 3343 r = r->skip[PF_SKIP_AF].ptr; 3344 else if (r->proto && r->proto != pd->proto) 3345 r = r->skip[PF_SKIP_PROTO].ptr; 3346 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not)) 3347 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3348 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not)) 3349 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3350 else if (r->tos && !(r->tos & pd->tos)) 3351 r = TAILQ_NEXT(r, entries); 3352 else if (r->rule_flag & PFRULE_FRAGMENT) 3353 r = TAILQ_NEXT(r, entries); | 3619 r = r->skip[PF_SKIP_IFP].ptr; 3620 else if (r->direction && r->direction != direction) 3621 r = r->skip[PF_SKIP_DIR].ptr; 3622 else if (r->af && r->af != af) 3623 r = r->skip[PF_SKIP_AF].ptr; 3624 else if (r->proto && r->proto != pd->proto) 3625 r = r->skip[PF_SKIP_PROTO].ptr; 3626 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not)) 3627 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3628 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not)) 3629 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3630 else if (r->tos && !(r->tos & pd->tos)) 3631 r = TAILQ_NEXT(r, entries); 3632 else if (r->rule_flag & PFRULE_FRAGMENT) 3633 r = TAILQ_NEXT(r, entries); |
3354 else if (r->match_tag && 3355 !pf_match_tag(m, r, nat, rdr, pftag, &tag)) | 3634 else if (r->match_tag && !pf_match_tag(m, r, nr, pftag, &tag)) |
3356 r = TAILQ_NEXT(r, entries); 3357 else if (r->anchorname[0] && r->anchor == NULL) 3358 r = TAILQ_NEXT(r, entries); 3359 else if (r->os_fingerprint != PF_OSFP_ANY) 3360 r = TAILQ_NEXT(r, entries); 3361 else { 3362 if (r->tag) 3363 tag = r->tag; --- 11 unchanged lines hidden (view full) --- 3375 if (r == NULL && a != NULL) 3376 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3377 PF_RULESET_FILTER); 3378 } 3379 r = *rm; 3380 a = *am; 3381 ruleset = *rsm; 3382 | 3635 r = TAILQ_NEXT(r, entries); 3636 else if (r->anchorname[0] && r->anchor == NULL) 3637 r = TAILQ_NEXT(r, entries); 3638 else if (r->os_fingerprint != PF_OSFP_ANY) 3639 r = TAILQ_NEXT(r, entries); 3640 else { 3641 if (r->tag) 3642 tag = r->tag; --- 11 unchanged lines hidden (view full) --- 3654 if (r == NULL && a != NULL) 3655 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3656 PF_RULESET_FILTER); 3657 } 3658 r = *rm; 3659 a = *am; 3660 ruleset = *rsm; 3661 |
3383 r->packets++; 3384 r->bytes += pd->tot_len; 3385 if (a != NULL) { 3386 a->packets++; 3387 a->bytes += pd->tot_len; 3388 } | |
3389 REASON_SET(&reason, PFRES_MATCH); | 3662 REASON_SET(&reason, PFRES_MATCH); |
3663 |
|
3390 if (r->log) | 3664 if (r->log) |
3391 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); | 3665 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); |
3392 3393 if ((r->action == PF_DROP) && 3394 ((r->rule_flag & PFRULE_RETURNICMP) || 3395 (r->rule_flag & PFRULE_RETURN))) { 3396 struct pf_addr *a = NULL; 3397 | 3666 3667 if ((r->action == PF_DROP) && 3668 ((r->rule_flag & PFRULE_RETURNICMP) || 3669 (r->rule_flag & PFRULE_RETURN))) { 3670 struct pf_addr *a = NULL; 3671 |
3398 if (nat != NULL) 3399 a = saddr; 3400 else if (rdr != NULL) 3401 a = daddr; | 3672 if (nr != NULL) { 3673 if (direction == PF_OUT) 3674 a = saddr; 3675 else 3676 a = daddr; 3677 } |
3402 if (a != NULL) { 3403 switch (af) { 3404#ifdef INET 3405 case AF_INET: 3406 pf_change_a(&a->v4.s_addr, pd->ip_sum, | 3678 if (a != NULL) { 3679 switch (af) { 3680#ifdef INET 3681 case AF_INET: 3682 pf_change_a(&a->v4.s_addr, pd->ip_sum, |
3407 baddr.v4.s_addr, 0); | 3683 pd->baddr.v4.s_addr, 0); |
3408 break; 3409#endif /* INET */ 3410#ifdef INET6 3411 case AF_INET6: | 3684 break; 3685#endif /* INET */ 3686#ifdef INET6 3687 case AF_INET6: |
3412 PF_ACPY(a, &baddr, af); | 3688 PF_ACPY(a, &pd->baddr, af); |
3413 break; 3414#endif /* INET6 */ 3415 } 3416 } 3417 if ((af == AF_INET) && r->return_icmp) 3418 pf_send_icmp(m, r->return_icmp >> 8, 3419 r->return_icmp & 255, af, r); 3420 else if ((af == AF_INET6) && r->return_icmp6) --- 4 unchanged lines hidden (view full) --- 3425 if (r->action != PF_PASS) 3426 return (PF_DROP); 3427 3428 if (pf_tag_packet(m, pftag, tag)) { 3429 REASON_SET(&reason, PFRES_MEMORY); 3430 return (PF_DROP); 3431 } 3432 | 3689 break; 3690#endif /* INET6 */ 3691 } 3692 } 3693 if ((af == AF_INET) && r->return_icmp) 3694 pf_send_icmp(m, r->return_icmp >> 8, 3695 r->return_icmp & 255, af, r); 3696 else if ((af == AF_INET6) && r->return_icmp6) --- 4 unchanged lines hidden (view full) --- 3701 if (r->action != PF_PASS) 3702 return (PF_DROP); 3703 3704 if (pf_tag_packet(m, pftag, tag)) { 3705 REASON_SET(&reason, PFRES_MEMORY); 3706 return (PF_DROP); 3707 } 3708 |
3433 if (r->keep_state || nat != NULL || rdr != NULL) { | 3709 if (r->keep_state || nr != NULL) { |
3434 /* create new state */ 3435 struct pf_state *s = NULL; | 3710 /* create new state */ 3711 struct pf_state *s = NULL; |
3712 struct pf_src_node *sn = NULL; |
|
3436 | 3713 |
3437 if (!r->max_states || r->states < r->max_states) 3438 s = pool_get(&pf_state_pl, PR_NOWAIT); | 3714 /* check maximums */ 3715 if (r->max_states && (r->states >= r->max_states)) 3716 goto cleanup; 3717 /* src node for flter rule */ 3718 if ((r->rule_flag & PFRULE_SRCTRACK || 3719 r->rpool.opts & PF_POOL_STICKYADDR) && 3720 pf_insert_src_node(&sn, r, saddr, af) != 0) 3721 goto cleanup; 3722 /* src node for translation rule */ 3723 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 3724 ((direction == PF_OUT && 3725 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) || 3726 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) 3727 goto cleanup; 3728 s = pool_get(&pf_state_pl, PR_NOWAIT); |
3439 if (s == NULL) { | 3729 if (s == NULL) { |
3730cleanup: 3731 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 3732 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 3733 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3734 pf_status.src_nodes--; 3735 pool_put(&pf_src_tree_pl, sn); 3736 } 3737 if (nsn != sn && nsn != NULL && nsn->states == 0 && 3738 nsn->expire == 0) { 3739 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 3740 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 3741 pf_status.src_nodes--; 3742 pool_put(&pf_src_tree_pl, nsn); 3743 } |
|
3440 REASON_SET(&reason, PFRES_MEMORY); 3441 return (PF_DROP); 3442 } 3443 bzero(s, sizeof(*s)); 3444 r->states++; 3445 if (a != NULL) 3446 a->states++; 3447 s->rule.ptr = r; | 3744 REASON_SET(&reason, PFRES_MEMORY); 3745 return (PF_DROP); 3746 } 3747 bzero(s, sizeof(*s)); 3748 r->states++; 3749 if (a != NULL) 3750 a->states++; 3751 s->rule.ptr = r; |
3448 if (nat != NULL) 3449 s->nat_rule.ptr = nat; 3450 else 3451 s->nat_rule.ptr = rdr; | 3752 s->nat_rule.ptr = nr; |
3452 if (s->nat_rule.ptr != NULL) 3453 s->nat_rule.ptr->states++; 3454 s->anchor.ptr = a; 3455 s->allow_opts = r->allow_opts; 3456 s->log = r->log & 2; 3457 s->proto = pd->proto; 3458 s->direction = direction; 3459 s->af = af; 3460 if (direction == PF_OUT) { 3461 PF_ACPY(&s->gwy.addr, saddr, af); | 3753 if (s->nat_rule.ptr != NULL) 3754 s->nat_rule.ptr->states++; 3755 s->anchor.ptr = a; 3756 s->allow_opts = r->allow_opts; 3757 s->log = r->log & 2; 3758 s->proto = pd->proto; 3759 s->direction = direction; 3760 s->af = af; 3761 if (direction == PF_OUT) { 3762 PF_ACPY(&s->gwy.addr, saddr, af); |
3462 s->gwy.port = 0; | |
3463 PF_ACPY(&s->ext.addr, daddr, af); | 3763 PF_ACPY(&s->ext.addr, daddr, af); |
3464 s->ext.port = 0; 3465 if (nat != NULL) 3466 PF_ACPY(&s->lan.addr, &baddr, af); | 3764 if (nr != NULL) 3765 PF_ACPY(&s->lan.addr, &pd->baddr, af); |
3467 else 3468 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); | 3766 else 3767 PF_ACPY(&s->lan.addr, &s->gwy.addr, af); |
3469 s->lan.port = 0; | |
3470 } else { 3471 PF_ACPY(&s->lan.addr, daddr, af); | 3768 } else { 3769 PF_ACPY(&s->lan.addr, daddr, af); |
3472 s->lan.port = 0; | |
3473 PF_ACPY(&s->ext.addr, saddr, af); | 3770 PF_ACPY(&s->ext.addr, saddr, af); |
3474 s->ext.port = 0; 3475 if (rdr != NULL) 3476 PF_ACPY(&s->gwy.addr, &baddr, af); | 3771 if (nr != NULL) 3772 PF_ACPY(&s->gwy.addr, &pd->baddr, af); |
3477 else 3478 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); | 3773 else 3774 PF_ACPY(&s->gwy.addr, &s->lan.addr, af); |
3479 s->gwy.port = 0; | |
3480 } | 3775 } |
3481 s->src.seqlo = 0; 3482 s->src.seqhi = 0; 3483 s->src.seqdiff = 0; 3484 s->src.max_win = 0; | |
3485 s->src.state = PFOTHERS_SINGLE; | 3776 s->src.state = PFOTHERS_SINGLE; |
3486 s->dst.seqlo = 0; 3487 s->dst.seqhi = 0; 3488 s->dst.seqdiff = 0; 3489 s->dst.max_win = 0; | |
3490 s->dst.state = PFOTHERS_NO_TRAFFIC; 3491#ifdef __FreeBSD__ 3492 s->creation = time_second; 3493 s->expire = time_second; 3494#else 3495 s->creation = time.tv_sec; 3496 s->expire = time.tv_sec; 3497#endif 3498 s->timeout = PFTM_OTHER_FIRST_PACKET; | 3777 s->dst.state = PFOTHERS_NO_TRAFFIC; 3778#ifdef __FreeBSD__ 3779 s->creation = time_second; 3780 s->expire = time_second; 3781#else 3782 s->creation = time.tv_sec; 3783 s->expire = time.tv_sec; 3784#endif 3785 s->timeout = PFTM_OTHER_FIRST_PACKET; |
3499 s->packets[0] = 1; 3500 s->bytes[0] = pd->tot_len; | |
3501 pf_set_rt_ifp(s, saddr); | 3786 pf_set_rt_ifp(s, saddr); |
3502 if (pf_insert_state(s)) { | 3787 if (sn != NULL) { 3788 s->src_node = sn; 3789 s->src_node->states++; 3790 } 3791 if (nsn != NULL) { 3792 PF_ACPY(&nsn->raddr, &pd->naddr, af); 3793 s->nat_src_node = nsn; 3794 s->nat_src_node->states++; 3795 } 3796 if (pf_insert_state(BOUND_IFACE(r, kif), s)) { |
3503 REASON_SET(&reason, PFRES_MEMORY); | 3797 REASON_SET(&reason, PFRES_MEMORY); |
3504 if (r->log) 3505 PFLOG_PACKET(ifp, h, m, af, direction, reason, 3506 r, a, ruleset); | 3798 pf_src_tree_remove_state(s); |
3507 pool_put(&pf_state_pl, s); 3508 return (PF_DROP); 3509 } else 3510 *sm = s; 3511 } 3512 3513 return (PF_PASS); 3514} 3515 3516int | 3799 pool_put(&pf_state_pl, s); 3800 return (PF_DROP); 3801 } else 3802 *sm = s; 3803 } 3804 3805 return (PF_PASS); 3806} 3807 3808int |
3517pf_test_fragment(struct pf_rule **rm, int direction, struct ifnet *ifp, | 3809pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, |
3518 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, 3519 struct pf_ruleset **rsm) 3520{ 3521 struct pf_rule *r, *a = NULL; 3522 struct pf_ruleset *ruleset = NULL; 3523 sa_family_t af = pd->af; 3524 u_short reason; 3525 struct pf_tag *pftag = NULL; 3526 int tag = -1; 3527 3528 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3529 while (r != NULL) { 3530 r->evaluations++; | 3810 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, 3811 struct pf_ruleset **rsm) 3812{ 3813 struct pf_rule *r, *a = NULL; 3814 struct pf_ruleset *ruleset = NULL; 3815 sa_family_t af = pd->af; 3816 u_short reason; 3817 struct pf_tag *pftag = NULL; 3818 int tag = -1; 3819 3820 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3821 while (r != NULL) { 3822 r->evaluations++; |
3531 if (r->ifp != NULL && ((r->ifp != ifp && !r->ifnot) || 3532 (r->ifp == ifp && r->ifnot))) | 3823 if (r->kif != NULL && 3824 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot) |
3533 r = r->skip[PF_SKIP_IFP].ptr; 3534 else if (r->direction && r->direction != direction) 3535 r = r->skip[PF_SKIP_DIR].ptr; 3536 else if (r->af && r->af != af) 3537 r = r->skip[PF_SKIP_AF].ptr; 3538 else if (r->proto && r->proto != pd->proto) 3539 r = r->skip[PF_SKIP_PROTO].ptr; 3540 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not)) 3541 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3542 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not)) 3543 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3544 else if (r->tos && !(r->tos & pd->tos)) 3545 r = TAILQ_NEXT(r, entries); 3546 else if (r->src.port_op || r->dst.port_op || 3547 r->flagset || r->type || r->code || 3548 r->os_fingerprint != PF_OSFP_ANY) 3549 r = TAILQ_NEXT(r, entries); | 3825 r = r->skip[PF_SKIP_IFP].ptr; 3826 else if (r->direction && r->direction != direction) 3827 r = r->skip[PF_SKIP_DIR].ptr; 3828 else if (r->af && r->af != af) 3829 r = r->skip[PF_SKIP_AF].ptr; 3830 else if (r->proto && r->proto != pd->proto) 3831 r = r->skip[PF_SKIP_PROTO].ptr; 3832 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not)) 3833 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3834 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not)) 3835 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3836 else if (r->tos && !(r->tos & pd->tos)) 3837 r = TAILQ_NEXT(r, entries); 3838 else if (r->src.port_op || r->dst.port_op || 3839 r->flagset || r->type || r->code || 3840 r->os_fingerprint != PF_OSFP_ANY) 3841 r = TAILQ_NEXT(r, entries); |
3550 else if (r->match_tag && 3551 !pf_match_tag(m, r, NULL, NULL, pftag, &tag)) | 3842 else if (r->match_tag && !pf_match_tag(m, r, NULL, pftag, &tag)) |
3552 r = TAILQ_NEXT(r, entries); 3553 else if (r->anchorname[0] && r->anchor == NULL) 3554 r = TAILQ_NEXT(r, entries); 3555 else { 3556 if (r->anchor == NULL) { 3557 *rm = r; 3558 *am = a; 3559 *rsm = ruleset; --- 7 unchanged lines hidden (view full) --- 3567 if (r == NULL && a != NULL) 3568 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3569 PF_RULESET_FILTER); 3570 } 3571 r = *rm; 3572 a = *am; 3573 ruleset = *rsm; 3574 | 3843 r = TAILQ_NEXT(r, entries); 3844 else if (r->anchorname[0] && r->anchor == NULL) 3845 r = TAILQ_NEXT(r, entries); 3846 else { 3847 if (r->anchor == NULL) { 3848 *rm = r; 3849 *am = a; 3850 *rsm = ruleset; --- 7 unchanged lines hidden (view full) --- 3858 if (r == NULL && a != NULL) 3859 PF_STEP_OUT_OF_ANCHOR(r, a, ruleset, 3860 PF_RULESET_FILTER); 3861 } 3862 r = *rm; 3863 a = *am; 3864 ruleset = *rsm; 3865 |
3575 r->packets++; 3576 r->bytes += pd->tot_len; 3577 if (a != NULL) { 3578 a->packets++; 3579 a->bytes += pd->tot_len; 3580 } | |
3581 REASON_SET(&reason, PFRES_MATCH); | 3866 REASON_SET(&reason, PFRES_MATCH); |
3867 |
|
3582 if (r->log) | 3868 if (r->log) |
3583 PFLOG_PACKET(ifp, h, m, af, direction, reason, r, a, ruleset); | 3869 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset); |
3584 3585 if (r->action != PF_PASS) 3586 return (PF_DROP); 3587 3588 if (pf_tag_packet(m, pftag, tag)) { 3589 REASON_SET(&reason, PFRES_MEMORY); 3590 return (PF_DROP); 3591 } 3592 3593 return (PF_PASS); 3594} 3595 3596int | 3870 3871 if (r->action != PF_PASS) 3872 return (PF_DROP); 3873 3874 if (pf_tag_packet(m, pftag, tag)) { 3875 REASON_SET(&reason, PFRES_MEMORY); 3876 return (PF_DROP); 3877 } 3878 3879 return (PF_PASS); 3880} 3881 3882int |
3597pf_test_state_tcp(struct pf_state **state, int direction, struct ifnet *ifp, 3598 struct mbuf *m, int ipoff, int off, void *h, struct pf_pdesc *pd, | 3883pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, 3884 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, |
3599 u_short *reason) 3600{ | 3885 u_short *reason) 3886{ |
3601 struct pf_tree_node key; | 3887 struct pf_state key; |
3602 struct tcphdr *th = pd->hdr.tcp; 3603 u_int16_t win = ntohs(th->th_win); 3604 u_int32_t ack, end, seq; 3605 u_int8_t sws, dws; | 3888 struct tcphdr *th = pd->hdr.tcp; 3889 u_int16_t win = ntohs(th->th_win); 3890 u_int32_t ack, end, seq; 3891 u_int8_t sws, dws; |
3606 int ackskew, dirndx; | 3892 int ackskew; |
3607 int copyback = 0; 3608 struct pf_state_peer *src, *dst; 3609 3610 key.af = pd->af; 3611 key.proto = IPPROTO_TCP; | 3893 int copyback = 0; 3894 struct pf_state_peer *src, *dst; 3895 3896 key.af = pd->af; 3897 key.proto = IPPROTO_TCP; |
3612 PF_ACPY(&key.addr[0], pd->src, key.af); 3613 PF_ACPY(&key.addr[1], pd->dst, key.af); 3614 key.port[0] = th->th_sport; 3615 key.port[1] = th->th_dport; | 3898 if (direction == PF_IN) { 3899 PF_ACPY(&key.ext.addr, pd->src, key.af); 3900 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 3901 key.ext.port = th->th_sport; 3902 key.gwy.port = th->th_dport; 3903 } else { 3904 PF_ACPY(&key.lan.addr, pd->src, key.af); 3905 PF_ACPY(&key.ext.addr, pd->dst, key.af); 3906 key.lan.port = th->th_sport; 3907 key.ext.port = th->th_dport; 3908 } |
3616 3617 STATE_LOOKUP(); 3618 3619 if (direction == (*state)->direction) { 3620 src = &(*state)->src; 3621 dst = &(*state)->dst; | 3909 3910 STATE_LOOKUP(); 3911 3912 if (direction == (*state)->direction) { 3913 src = &(*state)->src; 3914 dst = &(*state)->dst; |
3622 dirndx = 0; | |
3623 } else { 3624 src = &(*state)->dst; 3625 dst = &(*state)->src; | 3915 } else { 3916 src = &(*state)->dst; 3917 dst = &(*state)->src; |
3626 dirndx = 1; | |
3627 } 3628 3629 if ((*state)->src.state == PF_TCPS_PROXY_SRC) { 3630 if (direction != (*state)->direction) 3631 return (PF_SYNPROXY_DROP); 3632 if (th->th_flags & TH_SYN) { 3633 if (ntohl(th->th_seq) != (*state)->src.seqlo) 3634 return (PF_DROP); --- 24 unchanged lines hidden (view full) --- 3659 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 3660 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) 3661 return (PF_DROP); 3662 (*state)->src.max_win = MAX(ntohs(th->th_win), 1); 3663 if ((*state)->dst.seqhi == 1) 3664 (*state)->dst.seqhi = arc4random(); 3665 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 3666 &dst->addr, src->port, dst->port, | 3918 } 3919 3920 if ((*state)->src.state == PF_TCPS_PROXY_SRC) { 3921 if (direction != (*state)->direction) 3922 return (PF_SYNPROXY_DROP); 3923 if (th->th_flags & TH_SYN) { 3924 if (ntohl(th->th_seq) != (*state)->src.seqlo) 3925 return (PF_DROP); --- 24 unchanged lines hidden (view full) --- 3950 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 3951 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) 3952 return (PF_DROP); 3953 (*state)->src.max_win = MAX(ntohs(th->th_win), 1); 3954 if ((*state)->dst.seqhi == 1) 3955 (*state)->dst.seqhi = arc4random(); 3956 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 3957 &dst->addr, src->port, dst->port, |
3667 (*state)->dst.seqhi, 0, TH_SYN, 0, (*state)->src.mss, 0); | 3958 (*state)->dst.seqhi, 0, TH_SYN, 0, 3959 (*state)->src.mss, 0); |
3668 return (PF_SYNPROXY_DROP); 3669 } else if (((th->th_flags & (TH_SYN|TH_ACK)) != 3670 (TH_SYN|TH_ACK)) || 3671 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) 3672 return (PF_DROP); 3673 else { 3674 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1); 3675 (*state)->dst.seqlo = ntohl(th->th_seq); --- 140 unchanged lines hidden (view full) --- 3816 /* Last octet inside other's window space */ 3817 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) && 3818 /* Retrans: not more than one window back */ 3819 (ackskew >= -MAXACKWINDOW) && 3820 /* Acking not more than one reassembled fragment backwards */ 3821 (ackskew <= (MAXACKWINDOW << sws))) { 3822 /* Acking not more than one window forward */ 3823 | 3960 return (PF_SYNPROXY_DROP); 3961 } else if (((th->th_flags & (TH_SYN|TH_ACK)) != 3962 (TH_SYN|TH_ACK)) || 3963 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) 3964 return (PF_DROP); 3965 else { 3966 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1); 3967 (*state)->dst.seqlo = ntohl(th->th_seq); --- 140 unchanged lines hidden (view full) --- 4108 /* Last octet inside other's window space */ 4109 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) && 4110 /* Retrans: not more than one window back */ 4111 (ackskew >= -MAXACKWINDOW) && 4112 /* Acking not more than one reassembled fragment backwards */ 4113 (ackskew <= (MAXACKWINDOW << sws))) { 4114 /* Acking not more than one window forward */ 4115 |
3824 (*state)->packets[dirndx]++; 3825 (*state)->bytes[dirndx] += pd->tot_len; 3826 | |
3827 /* update max window */ 3828 if (src->max_win < win) 3829 src->max_win = win; 3830 /* synchronize sequencing */ 3831 if (SEQ_GT(end, src->seqlo)) 3832 src->seqlo = end; 3833 /* slide the window of what the other end can send */ 3834 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) --- 72 unchanged lines hidden (view full) --- 3907 printf("pf: loose state match: "); 3908 pf_print_state(*state); 3909 pf_print_flags(th->th_flags); 3910 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d\n", 3911 seq, ack, pd->p_len, ackskew, 3912 (*state)->packets[0], (*state)->packets[1]); 3913 } 3914 | 4116 /* update max window */ 4117 if (src->max_win < win) 4118 src->max_win = win; 4119 /* synchronize sequencing */ 4120 if (SEQ_GT(end, src->seqlo)) 4121 src->seqlo = end; 4122 /* slide the window of what the other end can send */ 4123 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) --- 72 unchanged lines hidden (view full) --- 4196 printf("pf: loose state match: "); 4197 pf_print_state(*state); 4198 pf_print_flags(th->th_flags); 4199 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d\n", 4200 seq, ack, pd->p_len, ackskew, 4201 (*state)->packets[0], (*state)->packets[1]); 4202 } 4203 |
3915 (*state)->packets[dirndx]++; 3916 (*state)->bytes[dirndx] += pd->tot_len; 3917 | |
3918 /* update max window */ 3919 if (src->max_win < win) 3920 src->max_win = win; 3921 /* synchronize sequencing */ 3922 if (SEQ_GT(end, src->seqlo)) 3923 src->seqlo = end; 3924 /* slide the window of what the other end can send */ 3925 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) --- 49 unchanged lines hidden (view full) --- 3975 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4', 3976 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5', 3977 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6'); 3978 } 3979 return (PF_DROP); 3980 } 3981 3982 if (dst->scrub || src->scrub) { | 4204 /* update max window */ 4205 if (src->max_win < win) 4206 src->max_win = win; 4207 /* synchronize sequencing */ 4208 if (SEQ_GT(end, src->seqlo)) 4209 src->seqlo = end; 4210 /* slide the window of what the other end can send */ 4211 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) --- 49 unchanged lines hidden (view full) --- 4261 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4', 4262 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5', 4263 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6'); 4264 } 4265 return (PF_DROP); 4266 } 4267 4268 if (dst->scrub || src->scrub) { |
3983 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, src, dst, 3984 ©back)) | 4269 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 4270 src, dst, ©back)) |
3985 return (PF_DROP); 3986 } 3987 3988 /* Any packets which have gotten here are to be passed */ 3989 3990 /* translate source/destination address, if necessary */ 3991 if (STATE_TRANSLATE(*state)) { 3992 if (direction == PF_OUT) --- 5 unchanged lines hidden (view full) --- 3998 &th->th_sum, &(*state)->lan.addr, 3999 (*state)->lan.port, 0, pd->af); 4000 m_copyback(m, off, sizeof(*th), (caddr_t)th); 4001 } else if (copyback) { 4002 /* Copyback sequence modulation or stateful scrub changes */ 4003 m_copyback(m, off, sizeof(*th), (caddr_t)th); 4004 } 4005 | 4271 return (PF_DROP); 4272 } 4273 4274 /* Any packets which have gotten here are to be passed */ 4275 4276 /* translate source/destination address, if necessary */ 4277 if (STATE_TRANSLATE(*state)) { 4278 if (direction == PF_OUT) --- 5 unchanged lines hidden (view full) --- 4284 &th->th_sum, &(*state)->lan.addr, 4285 (*state)->lan.port, 0, pd->af); 4286 m_copyback(m, off, sizeof(*th), (caddr_t)th); 4287 } else if (copyback) { 4288 /* Copyback sequence modulation or stateful scrub changes */ 4289 m_copyback(m, off, sizeof(*th), (caddr_t)th); 4290 } 4291 |
4006 (*state)->rule.ptr->packets++; 4007 (*state)->rule.ptr->bytes += pd->tot_len; 4008 if ((*state)->nat_rule.ptr != NULL) { 4009 (*state)->nat_rule.ptr->packets++; 4010 (*state)->nat_rule.ptr->bytes += pd->tot_len; 4011 } 4012 if ((*state)->anchor.ptr != NULL) { 4013 (*state)->anchor.ptr->packets++; 4014 (*state)->anchor.ptr->bytes += pd->tot_len; 4015 } | |
4016 return (PF_PASS); 4017} 4018 4019int | 4292 return (PF_PASS); 4293} 4294 4295int |
4020pf_test_state_udp(struct pf_state **state, int direction, struct ifnet *ifp, 4021 struct mbuf *m, int ipoff, int off, void *h, struct pf_pdesc *pd) | 4296pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, 4297 struct mbuf *m, int off, void *h, struct pf_pdesc *pd) |
4022{ 4023 struct pf_state_peer *src, *dst; | 4298{ 4299 struct pf_state_peer *src, *dst; |
4024 struct pf_tree_node key; | 4300 struct pf_state key; |
4025 struct udphdr *uh = pd->hdr.udp; | 4301 struct udphdr *uh = pd->hdr.udp; |
4026 int dirndx; | |
4027 4028 key.af = pd->af; 4029 key.proto = IPPROTO_UDP; | 4302 4303 key.af = pd->af; 4304 key.proto = IPPROTO_UDP; |
4030 PF_ACPY(&key.addr[0], pd->src, key.af); 4031 PF_ACPY(&key.addr[1], pd->dst, key.af); 4032 key.port[0] = uh->uh_sport; 4033 key.port[1] = uh->uh_dport; | 4305 if (direction == PF_IN) { 4306 PF_ACPY(&key.ext.addr, pd->src, key.af); 4307 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 4308 key.ext.port = uh->uh_sport; 4309 key.gwy.port = uh->uh_dport; 4310 } else { 4311 PF_ACPY(&key.lan.addr, pd->src, key.af); 4312 PF_ACPY(&key.ext.addr, pd->dst, key.af); 4313 key.lan.port = uh->uh_sport; 4314 key.ext.port = uh->uh_dport; 4315 } |
4034 4035 STATE_LOOKUP(); 4036 4037 if (direction == (*state)->direction) { 4038 src = &(*state)->src; 4039 dst = &(*state)->dst; | 4316 4317 STATE_LOOKUP(); 4318 4319 if (direction == (*state)->direction) { 4320 src = &(*state)->src; 4321 dst = &(*state)->dst; |
4040 dirndx = 0; | |
4041 } else { 4042 src = &(*state)->dst; 4043 dst = &(*state)->src; | 4322 } else { 4323 src = &(*state)->dst; 4324 dst = &(*state)->src; |
4044 dirndx = 1; | |
4045 } 4046 | 4325 } 4326 |
4047 (*state)->packets[dirndx]++; 4048 (*state)->bytes[dirndx] += pd->tot_len; 4049 | |
4050 /* update states */ 4051 if (src->state < PFUDPS_SINGLE) 4052 src->state = PFUDPS_SINGLE; 4053 if (dst->state == PFUDPS_SINGLE) 4054 dst->state = PFUDPS_MULTIPLE; 4055 4056 /* update expire time */ 4057#ifdef __FreeBSD__ --- 14 unchanged lines hidden (view full) --- 4072 (*state)->gwy.port, 1, pd->af); 4073 else 4074 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, 4075 &uh->uh_sum, &(*state)->lan.addr, 4076 (*state)->lan.port, 1, pd->af); 4077 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 4078 } 4079 | 4327 /* update states */ 4328 if (src->state < PFUDPS_SINGLE) 4329 src->state = PFUDPS_SINGLE; 4330 if (dst->state == PFUDPS_SINGLE) 4331 dst->state = PFUDPS_MULTIPLE; 4332 4333 /* update expire time */ 4334#ifdef __FreeBSD__ --- 14 unchanged lines hidden (view full) --- 4349 (*state)->gwy.port, 1, pd->af); 4350 else 4351 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, 4352 &uh->uh_sum, &(*state)->lan.addr, 4353 (*state)->lan.port, 1, pd->af); 4354 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 4355 } 4356 |
4080 (*state)->rule.ptr->packets++; 4081 (*state)->rule.ptr->bytes += pd->tot_len; 4082 if ((*state)->nat_rule.ptr != NULL) { 4083 (*state)->nat_rule.ptr->packets++; 4084 (*state)->nat_rule.ptr->bytes += pd->tot_len; 4085 } 4086 if ((*state)->anchor.ptr != NULL) { 4087 (*state)->anchor.ptr->packets++; 4088 (*state)->anchor.ptr->bytes += pd->tot_len; 4089 } | |
4090 return (PF_PASS); 4091} 4092 4093int | 4357 return (PF_PASS); 4358} 4359 4360int |
4094pf_test_state_icmp(struct pf_state **state, int direction, struct ifnet *ifp, 4095 struct mbuf *m, int ipoff, int off, void *h, struct pf_pdesc *pd) | 4361pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, 4362 struct mbuf *m, int off, void *h, struct pf_pdesc *pd) |
4096{ 4097 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 4098 u_int16_t icmpid = 0; /* make the compiler happy */ 4099 u_int16_t *icmpsum = NULL; /* make the compiler happy */ 4100 u_int8_t icmptype = 0; /* make the compiler happy */ | 4363{ 4364 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 4365 u_int16_t icmpid = 0; /* make the compiler happy */ 4366 u_int16_t *icmpsum = NULL; /* make the compiler happy */ 4367 u_int8_t icmptype = 0; /* make the compiler happy */ |
4101 int state_icmp = 0, dirndx; | 4368 int state_icmp = 0; |
4102 4103 switch (pd->proto) { 4104#ifdef INET 4105 case IPPROTO_ICMP: 4106 icmptype = pd->hdr.icmp->icmp_type; 4107 icmpid = pd->hdr.icmp->icmp_id; 4108 icmpsum = &pd->hdr.icmp->icmp_cksum; 4109 --- 21 unchanged lines hidden (view full) --- 4131 } 4132 4133 if (!state_icmp) { 4134 4135 /* 4136 * ICMP query/reply message not related to a TCP/UDP packet. 4137 * Search for an ICMP state. 4138 */ | 4369 4370 switch (pd->proto) { 4371#ifdef INET 4372 case IPPROTO_ICMP: 4373 icmptype = pd->hdr.icmp->icmp_type; 4374 icmpid = pd->hdr.icmp->icmp_id; 4375 icmpsum = &pd->hdr.icmp->icmp_cksum; 4376 --- 21 unchanged lines hidden (view full) --- 4398 } 4399 4400 if (!state_icmp) { 4401 4402 /* 4403 * ICMP query/reply message not related to a TCP/UDP packet. 4404 * Search for an ICMP state. 4405 */ |
4139 struct pf_tree_node key; | 4406 struct pf_state key; |
4140 4141 key.af = pd->af; 4142 key.proto = pd->proto; | 4407 4408 key.af = pd->af; 4409 key.proto = pd->proto; |
4143 PF_ACPY(&key.addr[0], saddr, key.af); 4144 PF_ACPY(&key.addr[1], daddr, key.af); 4145 key.port[0] = icmpid; 4146 key.port[1] = icmpid; | 4410 if (direction == PF_IN) { 4411 PF_ACPY(&key.ext.addr, pd->src, key.af); 4412 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 4413 key.ext.port = icmpid; 4414 key.gwy.port = icmpid; 4415 } else { 4416 PF_ACPY(&key.lan.addr, pd->src, key.af); 4417 PF_ACPY(&key.ext.addr, pd->dst, key.af); 4418 key.lan.port = icmpid; 4419 key.ext.port = icmpid; 4420 } |
4147 4148 STATE_LOOKUP(); 4149 | 4421 4422 STATE_LOOKUP(); 4423 |
4150 dirndx = (direction == (*state)->direction) ? 0 : 1; 4151 (*state)->packets[dirndx]++; 4152 (*state)->bytes[dirndx] += pd->tot_len; | |
4153#ifdef __FreeBSD__ 4154 (*state)->expire = time_second; 4155#else 4156 (*state)->expire = time.tv_sec; 4157#endif 4158 (*state)->timeout = PFTM_ICMP_ERROR_REPLY; 4159 4160 /* translate source/destination address, if necessary */ --- 143 unchanged lines hidden (view full) --- 4304 break; 4305#endif /* INET6 */ 4306 } 4307 4308 switch (pd2.proto) { 4309 case IPPROTO_TCP: { 4310 struct tcphdr th; 4311 u_int32_t seq; | 4424#ifdef __FreeBSD__ 4425 (*state)->expire = time_second; 4426#else 4427 (*state)->expire = time.tv_sec; 4428#endif 4429 (*state)->timeout = PFTM_ICMP_ERROR_REPLY; 4430 4431 /* translate source/destination address, if necessary */ --- 143 unchanged lines hidden (view full) --- 4575 break; 4576#endif /* INET6 */ 4577 } 4578 4579 switch (pd2.proto) { 4580 case IPPROTO_TCP: { 4581 struct tcphdr th; 4582 u_int32_t seq; |
4312 struct pf_tree_node key; | 4583 struct pf_state key; |
4313 struct pf_state_peer *src, *dst; 4314 u_int8_t dws; 4315 int copyback = 0; 4316 4317 /* 4318 * Only the first 8 bytes of the TCP header can be 4319 * expected. Don't access any TCP header fields after 4320 * th_seq, an ackskew test is not possible. 4321 */ 4322 if (!pf_pull_hdr(m, off2, &th, 8, NULL, NULL, pd2.af)) { 4323 DPFPRINTF(PF_DEBUG_MISC, 4324 ("pf: ICMP error message too short " 4325 "(tcp)\n")); 4326 return (PF_DROP); 4327 } 4328 4329 key.af = pd2.af; 4330 key.proto = IPPROTO_TCP; | 4584 struct pf_state_peer *src, *dst; 4585 u_int8_t dws; 4586 int copyback = 0; 4587 4588 /* 4589 * Only the first 8 bytes of the TCP header can be 4590 * expected. Don't access any TCP header fields after 4591 * th_seq, an ackskew test is not possible. 4592 */ 4593 if (!pf_pull_hdr(m, off2, &th, 8, NULL, NULL, pd2.af)) { 4594 DPFPRINTF(PF_DEBUG_MISC, 4595 ("pf: ICMP error message too short " 4596 "(tcp)\n")); 4597 return (PF_DROP); 4598 } 4599 4600 key.af = pd2.af; 4601 key.proto = IPPROTO_TCP; |
4331 PF_ACPY(&key.addr[0], pd2.dst, pd2.af); 4332 key.port[0] = th.th_dport; 4333 PF_ACPY(&key.addr[1], pd2.src, pd2.af); 4334 key.port[1] = th.th_sport; | 4602 if (direction == PF_IN) { 4603 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 4604 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 4605 key.ext.port = th.th_dport; 4606 key.gwy.port = th.th_sport; 4607 } else { 4608 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 4609 PF_ACPY(&key.ext.addr, pd2.src, key.af); 4610 key.lan.port = th.th_dport; 4611 key.ext.port = th.th_sport; 4612 } |
4335 4336 STATE_LOOKUP(); 4337 4338 if (direction == (*state)->direction) { 4339 src = &(*state)->dst; 4340 dst = &(*state)->src; 4341 } else { 4342 src = &(*state)->src; 4343 dst = &(*state)->dst; 4344 } 4345 | 4613 4614 STATE_LOOKUP(); 4615 4616 if (direction == (*state)->direction) { 4617 src = &(*state)->dst; 4618 dst = &(*state)->src; 4619 } else { 4620 src = &(*state)->src; 4621 dst = &(*state)->dst; 4622 } 4623 |
4346 if (src->wscale && dst->wscale && !(th.th_flags & TH_SYN)) | 4624 if (src->wscale && dst->wscale && 4625 !(th.th_flags & TH_SYN)) |
4347 dws = dst->wscale & PF_WSCALE_MASK; 4348 else 4349 dws = 0; 4350 4351 /* Demodulate sequence number */ 4352 seq = ntohl(th.th_seq) - src->seqdiff; 4353 if (src->seqdiff) { 4354 pf_change_a(&th.th_seq, icmpsum, --- 56 unchanged lines hidden (view full) --- 4411 m_copyback(m, off2, 8, (caddr_t)&th); 4412 } 4413 4414 return (PF_PASS); 4415 break; 4416 } 4417 case IPPROTO_UDP: { 4418 struct udphdr uh; | 4626 dws = dst->wscale & PF_WSCALE_MASK; 4627 else 4628 dws = 0; 4629 4630 /* Demodulate sequence number */ 4631 seq = ntohl(th.th_seq) - src->seqdiff; 4632 if (src->seqdiff) { 4633 pf_change_a(&th.th_seq, icmpsum, --- 56 unchanged lines hidden (view full) --- 4690 m_copyback(m, off2, 8, (caddr_t)&th); 4691 } 4692 4693 return (PF_PASS); 4694 break; 4695 } 4696 case IPPROTO_UDP: { 4697 struct udphdr uh; |
4419 struct pf_tree_node key; | 4698 struct pf_state key; |
4420 4421 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh), 4422 NULL, NULL, pd2.af)) { 4423 DPFPRINTF(PF_DEBUG_MISC, 4424 ("pf: ICMP error message too short " 4425 "(udp)\n")); 4426 return (PF_DROP); 4427 } 4428 4429 key.af = pd2.af; 4430 key.proto = IPPROTO_UDP; | 4699 4700 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh), 4701 NULL, NULL, pd2.af)) { 4702 DPFPRINTF(PF_DEBUG_MISC, 4703 ("pf: ICMP error message too short " 4704 "(udp)\n")); 4705 return (PF_DROP); 4706 } 4707 4708 key.af = pd2.af; 4709 key.proto = IPPROTO_UDP; |
4431 PF_ACPY(&key.addr[0], pd2.dst, pd2.af); 4432 key.port[0] = uh.uh_dport; 4433 PF_ACPY(&key.addr[1], pd2.src, pd2.af); 4434 key.port[1] = uh.uh_sport; | 4710 if (direction == PF_IN) { 4711 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 4712 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 4713 key.ext.port = uh.uh_dport; 4714 key.gwy.port = uh.uh_sport; 4715 } else { 4716 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 4717 PF_ACPY(&key.ext.addr, pd2.src, key.af); 4718 key.lan.port = uh.uh_dport; 4719 key.ext.port = uh.uh_sport; 4720 } |
4435 4436 STATE_LOOKUP(); 4437 4438 if (STATE_TRANSLATE(*state)) { 4439 if (direction == PF_IN) { 4440 pf_change_icmp(pd2.src, &uh.uh_sport, 4441 daddr, &(*state)->lan.addr, 4442 (*state)->lan.port, &uh.uh_sum, --- 30 unchanged lines hidden (view full) --- 4473 } 4474 4475 return (PF_PASS); 4476 break; 4477 } 4478#ifdef INET 4479 case IPPROTO_ICMP: { 4480 struct icmp iih; | 4721 4722 STATE_LOOKUP(); 4723 4724 if (STATE_TRANSLATE(*state)) { 4725 if (direction == PF_IN) { 4726 pf_change_icmp(pd2.src, &uh.uh_sport, 4727 daddr, &(*state)->lan.addr, 4728 (*state)->lan.port, &uh.uh_sum, --- 30 unchanged lines hidden (view full) --- 4759 } 4760 4761 return (PF_PASS); 4762 break; 4763 } 4764#ifdef INET 4765 case IPPROTO_ICMP: { 4766 struct icmp iih; |
4481 struct pf_tree_node key; | 4767 struct pf_state key; |
4482 4483 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN, 4484 NULL, NULL, pd2.af)) { 4485 DPFPRINTF(PF_DEBUG_MISC, 4486 ("pf: ICMP error message too short i" 4487 "(icmp)\n")); 4488 return (PF_DROP); 4489 } 4490 4491 key.af = pd2.af; 4492 key.proto = IPPROTO_ICMP; | 4768 4769 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN, 4770 NULL, NULL, pd2.af)) { 4771 DPFPRINTF(PF_DEBUG_MISC, 4772 ("pf: ICMP error message too short i" 4773 "(icmp)\n")); 4774 return (PF_DROP); 4775 } 4776 4777 key.af = pd2.af; 4778 key.proto = IPPROTO_ICMP; |
4493 PF_ACPY(&key.addr[0], pd2.dst, pd2.af); 4494 key.port[0] = iih.icmp_id; 4495 PF_ACPY(&key.addr[1], pd2.src, pd2.af); 4496 key.port[1] = iih.icmp_id; | 4779 if (direction == PF_IN) { 4780 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 4781 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 4782 key.ext.port = iih.icmp_id; 4783 key.gwy.port = iih.icmp_id; 4784 } else { 4785 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 4786 PF_ACPY(&key.ext.addr, pd2.src, key.af); 4787 key.lan.port = iih.icmp_id; 4788 key.ext.port = iih.icmp_id; 4789 } |
4497 4498 STATE_LOOKUP(); 4499 4500 if (STATE_TRANSLATE(*state)) { 4501 if (direction == PF_IN) { 4502 pf_change_icmp(pd2.src, &iih.icmp_id, 4503 daddr, &(*state)->lan.addr, 4504 (*state)->lan.port, NULL, --- 16 unchanged lines hidden (view full) --- 4521 4522 return (PF_PASS); 4523 break; 4524 } 4525#endif /* INET */ 4526#ifdef INET6 4527 case IPPROTO_ICMPV6: { 4528 struct icmp6_hdr iih; | 4790 4791 STATE_LOOKUP(); 4792 4793 if (STATE_TRANSLATE(*state)) { 4794 if (direction == PF_IN) { 4795 pf_change_icmp(pd2.src, &iih.icmp_id, 4796 daddr, &(*state)->lan.addr, 4797 (*state)->lan.port, NULL, --- 16 unchanged lines hidden (view full) --- 4814 4815 return (PF_PASS); 4816 break; 4817 } 4818#endif /* INET */ 4819#ifdef INET6 4820 case IPPROTO_ICMPV6: { 4821 struct icmp6_hdr iih; |
4529 struct pf_tree_node key; | 4822 struct pf_state key; |
4530 4531 if (!pf_pull_hdr(m, off2, &iih, 4532 sizeof(struct icmp6_hdr), NULL, NULL, pd2.af)) { 4533 DPFPRINTF(PF_DEBUG_MISC, 4534 ("pf: ICMP error message too short " 4535 "(icmp6)\n")); 4536 return (PF_DROP); 4537 } 4538 4539 key.af = pd2.af; 4540 key.proto = IPPROTO_ICMPV6; | 4823 4824 if (!pf_pull_hdr(m, off2, &iih, 4825 sizeof(struct icmp6_hdr), NULL, NULL, pd2.af)) { 4826 DPFPRINTF(PF_DEBUG_MISC, 4827 ("pf: ICMP error message too short " 4828 "(icmp6)\n")); 4829 return (PF_DROP); 4830 } 4831 4832 key.af = pd2.af; 4833 key.proto = IPPROTO_ICMPV6; |
4541 PF_ACPY(&key.addr[0], pd2.dst, pd2.af); 4542 key.port[0] = iih.icmp6_id; 4543 PF_ACPY(&key.addr[1], pd2.src, pd2.af); 4544 key.port[1] = iih.icmp6_id; | 4834 if (direction == PF_IN) { 4835 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 4836 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 4837 key.ext.port = iih.icmp6_id; 4838 key.gwy.port = iih.icmp6_id; 4839 } else { 4840 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 4841 PF_ACPY(&key.ext.addr, pd2.src, key.af); 4842 key.lan.port = iih.icmp6_id; 4843 key.ext.port = iih.icmp6_id; 4844 } |
4545 4546 STATE_LOOKUP(); 4547 4548 if (STATE_TRANSLATE(*state)) { 4549 if (direction == PF_IN) { 4550 pf_change_icmp(pd2.src, &iih.icmp6_id, 4551 daddr, &(*state)->lan.addr, 4552 (*state)->lan.port, NULL, --- 14 unchanged lines hidden (view full) --- 4567 (caddr_t)&iih); 4568 } 4569 4570 return (PF_PASS); 4571 break; 4572 } 4573#endif /* INET6 */ 4574 default: { | 4845 4846 STATE_LOOKUP(); 4847 4848 if (STATE_TRANSLATE(*state)) { 4849 if (direction == PF_IN) { 4850 pf_change_icmp(pd2.src, &iih.icmp6_id, 4851 daddr, &(*state)->lan.addr, 4852 (*state)->lan.port, NULL, --- 14 unchanged lines hidden (view full) --- 4867 (caddr_t)&iih); 4868 } 4869 4870 return (PF_PASS); 4871 break; 4872 } 4873#endif /* INET6 */ 4874 default: { |
4575 struct pf_tree_node key; | 4875 struct pf_state key; |
4576 4577 key.af = pd2.af; 4578 key.proto = pd2.proto; | 4876 4877 key.af = pd2.af; 4878 key.proto = pd2.proto; |
4579 PF_ACPY(&key.addr[0], pd2.dst, pd2.af); 4580 key.port[0] = 0; 4581 PF_ACPY(&key.addr[1], pd2.src, pd2.af); 4582 key.port[1] = 0; | 4879 if (direction == PF_IN) { 4880 PF_ACPY(&key.ext.addr, pd2.dst, key.af); 4881 PF_ACPY(&key.gwy.addr, pd2.src, key.af); 4882 key.ext.port = 0; 4883 key.gwy.port = 0; 4884 } else { 4885 PF_ACPY(&key.lan.addr, pd2.dst, key.af); 4886 PF_ACPY(&key.ext.addr, pd2.src, key.af); 4887 key.lan.port = 0; 4888 key.ext.port = 0; 4889 } |
4583 4584 STATE_LOOKUP(); 4585 4586 if (STATE_TRANSLATE(*state)) { 4587 if (direction == PF_IN) { 4588 pf_change_icmp(pd2.src, NULL, 4589 daddr, &(*state)->lan.addr, 4590 0, NULL, --- 30 unchanged lines hidden (view full) --- 4621 return (PF_PASS); 4622 break; 4623 } 4624 } 4625 } 4626} 4627 4628int | 4890 4891 STATE_LOOKUP(); 4892 4893 if (STATE_TRANSLATE(*state)) { 4894 if (direction == PF_IN) { 4895 pf_change_icmp(pd2.src, NULL, 4896 daddr, &(*state)->lan.addr, 4897 0, NULL, --- 30 unchanged lines hidden (view full) --- 4928 return (PF_PASS); 4929 break; 4930 } 4931 } 4932 } 4933} 4934 4935int |
4629pf_test_state_other(struct pf_state **state, int direction, struct ifnet *ifp, | 4936pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, |
4630 struct pf_pdesc *pd) 4631{ 4632 struct pf_state_peer *src, *dst; | 4937 struct pf_pdesc *pd) 4938{ 4939 struct pf_state_peer *src, *dst; |
4633 struct pf_tree_node key; 4634 int dirndx; | 4940 struct pf_state key; |
4635 4636 key.af = pd->af; 4637 key.proto = pd->proto; | 4941 4942 key.af = pd->af; 4943 key.proto = pd->proto; |
4638 PF_ACPY(&key.addr[0], pd->src, key.af); 4639 PF_ACPY(&key.addr[1], pd->dst, key.af); 4640 key.port[0] = 0; 4641 key.port[1] = 0; | 4944 if (direction == PF_IN) { 4945 PF_ACPY(&key.ext.addr, pd->src, key.af); 4946 PF_ACPY(&key.gwy.addr, pd->dst, key.af); 4947 key.ext.port = 0; 4948 key.gwy.port = 0; 4949 } else { 4950 PF_ACPY(&key.lan.addr, pd->src, key.af); 4951 PF_ACPY(&key.ext.addr, pd->dst, key.af); 4952 key.lan.port = 0; 4953 key.ext.port = 0; 4954 } |
4642 4643 STATE_LOOKUP(); 4644 4645 if (direction == (*state)->direction) { 4646 src = &(*state)->src; 4647 dst = &(*state)->dst; | 4955 4956 STATE_LOOKUP(); 4957 4958 if (direction == (*state)->direction) { 4959 src = &(*state)->src; 4960 dst = &(*state)->dst; |
4648 dirndx = 0; | |
4649 } else { 4650 src = &(*state)->dst; 4651 dst = &(*state)->src; | 4961 } else { 4962 src = &(*state)->dst; 4963 dst = &(*state)->src; |
4652 dirndx = 1; | |
4653 } 4654 | 4964 } 4965 |
4655 (*state)->packets[dirndx]++; 4656 (*state)->bytes[dirndx] += pd->tot_len; 4657 | |
4658 /* update states */ 4659 if (src->state < PFOTHERS_SINGLE) 4660 src->state = PFOTHERS_SINGLE; 4661 if (dst->state == PFOTHERS_SINGLE) 4662 dst->state = PFOTHERS_MULTIPLE; 4663 4664 /* update expire time */ 4665#ifdef __FreeBSD__ --- 35 unchanged lines hidden (view full) --- 4701#ifdef INET6 4702 case AF_INET6: 4703 PF_ACPY(pd->dst, &(*state)->lan.addr, pd->af); 4704 break; 4705#endif /* INET6 */ 4706 } 4707 } 4708 | 4966 /* update states */ 4967 if (src->state < PFOTHERS_SINGLE) 4968 src->state = PFOTHERS_SINGLE; 4969 if (dst->state == PFOTHERS_SINGLE) 4970 dst->state = PFOTHERS_MULTIPLE; 4971 4972 /* update expire time */ 4973#ifdef __FreeBSD__ --- 35 unchanged lines hidden (view full) --- 5009#ifdef INET6 5010 case AF_INET6: 5011 PF_ACPY(pd->dst, &(*state)->lan.addr, pd->af); 5012 break; 5013#endif /* INET6 */ 5014 } 5015 } 5016 |
4709 (*state)->rule.ptr->packets++; 4710 (*state)->rule.ptr->bytes += pd->tot_len; 4711 if ((*state)->nat_rule.ptr != NULL) { 4712 (*state)->nat_rule.ptr->packets++; 4713 (*state)->nat_rule.ptr->bytes += pd->tot_len; 4714 } 4715 if ((*state)->anchor.ptr != NULL) { 4716 (*state)->anchor.ptr->packets++; 4717 (*state)->anchor.ptr->bytes += pd->tot_len; 4718 } | |
4719 return (PF_PASS); 4720} 4721 4722/* 4723 * ipoff and off are measured from the start of the mbuf chain. 4724 * h must be at "ipoff" on the mbuf chain. 4725 */ 4726void * --- 10 unchanged lines hidden (view full) --- 4737 if (fragoff >= len) 4738 ACTION_SET(actionp, PF_PASS); 4739 else { 4740 ACTION_SET(actionp, PF_DROP); 4741 REASON_SET(reasonp, PFRES_FRAG); 4742 } 4743 return (NULL); 4744 } | 5017 return (PF_PASS); 5018} 5019 5020/* 5021 * ipoff and off are measured from the start of the mbuf chain. 5022 * h must be at "ipoff" on the mbuf chain. 5023 */ 5024void * --- 10 unchanged lines hidden (view full) --- 5035 if (fragoff >= len) 5036 ACTION_SET(actionp, PF_PASS); 5037 else { 5038 ACTION_SET(actionp, PF_DROP); 5039 REASON_SET(reasonp, PFRES_FRAG); 5040 } 5041 return (NULL); 5042 } |
4745 if (m->m_pkthdr.len < off + len || ntohs(h->ip_len) < off + len) { | 5043 if (m->m_pkthdr.len < off + len || 5044 ntohs(h->ip_len) < off + len) { |
4746 ACTION_SET(actionp, PF_DROP); 4747 REASON_SET(reasonp, PFRES_SHORT); 4748 return (NULL); 4749 } 4750 break; 4751 } 4752#endif /* INET */ 4753#ifdef INET6 --- 42 unchanged lines hidden (view full) --- 4796 RTFREE(ro.ro_rt); 4797 } 4798 4799 return (ret); 4800} 4801 4802#ifdef INET 4803 | 5045 ACTION_SET(actionp, PF_DROP); 5046 REASON_SET(reasonp, PFRES_SHORT); 5047 return (NULL); 5048 } 5049 break; 5050 } 5051#endif /* INET */ 5052#ifdef INET6 --- 42 unchanged lines hidden (view full) --- 5095 RTFREE(ro.ro_rt); 5096 } 5097 5098 return (ret); 5099} 5100 5101#ifdef INET 5102 |
4804#if defined(__FreeBSD__) && (__FreeBSD_version < 501105) 4805int 4806ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu, 4807 u_long if_hwassist_flags, int sw_csum) 4808{ 4809 int error = 0; 4810 int hlen = ip->ip_hl << 2; 4811 int len = (mtu - hlen) & ~7; /* size of payload in each fragment */ 4812 int off; 4813 struct mbuf *m0 = *m_frag; /* the original packet */ 4814 int firstlen; 4815 struct mbuf **mnext; 4816 int nfrags; 4817 4818 if (ip->ip_off & IP_DF) { /* Fragmentation not allowed */ 4819 ipstat.ips_cantfrag++; 4820 return EMSGSIZE; 4821 } 4822 4823 /* 4824 * Must be able to put at least 8 bytes per fragment. 4825 */ 4826 if (len < 8) 4827 return EMSGSIZE; 4828 4829 /* 4830 * If the interface will not calculate checksums on 4831 * fragmented packets, then do it here. 4832 */ 4833 if (m0->m_pkthdr.csum_flags & CSUM_DELAY_DATA && 4834 (if_hwassist_flags & CSUM_IP_FRAGS) == 0) { 4835 in_delayed_cksum(m0); 4836 m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; 4837 } 4838 4839 if (len > PAGE_SIZE) { 4840 /* 4841 * Fragment large datagrams such that each segment 4842 * contains a multiple of PAGE_SIZE amount of data, 4843 * plus headers. This enables a receiver to perform 4844 * page-flipping zero-copy optimizations. 4845 * 4846 * XXX When does this help given that sender and receiver 4847 * could have different page sizes, and also mtu could 4848 * be less than the receiver's page size ? 4849 */ 4850 int newlen; 4851 struct mbuf *m; 4852 4853 for (m = m0, off = 0; m && (off+m->m_len) <= mtu; m = m->m_next) 4854 off += m->m_len; 4855 4856 /* 4857 * firstlen (off - hlen) must be aligned on an 4858 * 8-byte boundary 4859 */ 4860 if (off < hlen) 4861 goto smart_frag_failure; 4862 off = ((off - hlen) & ~7) + hlen; 4863 newlen = (~PAGE_MASK) & mtu; 4864 if ((newlen + sizeof (struct ip)) > mtu) { 4865 /* we failed, go back the default */ 4866smart_frag_failure: 4867 newlen = len; 4868 off = hlen + len; 4869 } 4870 len = newlen; 4871 4872 } else { 4873 off = hlen + len; 4874 } 4875 4876 firstlen = off - hlen; 4877 mnext = &m0->m_nextpkt; /* pointer to next packet */ 4878 4879 /* 4880 * Loop through length of segment after first fragment, 4881 * make new header and copy data of each part and link onto chain. 4882 * Here, m0 is the original packet, m is the fragment being created. 4883 * The fragments are linked off the m_nextpkt of the original 4884 * packet, which after processing serves as the first fragment. 4885 */ 4886 for (nfrags = 1; off < ip->ip_len; off += len, nfrags++) { 4887 struct ip *mhip; /* ip header on the fragment */ 4888 struct mbuf *m; 4889 int mhlen = sizeof (struct ip); 4890 4891 MGETHDR(m, M_DONTWAIT, MT_HEADER); 4892 if (m == 0) { 4893 error = ENOBUFS; 4894 ipstat.ips_odropped++; 4895 goto done; 4896 } 4897 m->m_flags |= (m0->m_flags & M_MCAST) | M_FRAG; 4898 /* 4899 * In the first mbuf, leave room for the link header, then 4900 * copy the original IP header including options. The payload 4901 * goes into an additional mbuf chain returned by m_copy(). 4902 */ 4903 m->m_data += max_linkhdr; 4904 mhip = mtod(m, struct ip *); 4905 *mhip = *ip; 4906 if (hlen > sizeof (struct ip)) { 4907 mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); 4908 mhip->ip_v = IPVERSION; 4909 mhip->ip_hl = mhlen >> 2; 4910 } 4911 m->m_len = mhlen; 4912 /* XXX do we need to add ip->ip_off below ? */ 4913 mhip->ip_off = ((off - hlen) >> 3) + ip->ip_off; 4914 if (off + len >= ip->ip_len) { /* last fragment */ 4915 len = ip->ip_len - off; 4916 m->m_flags |= M_LASTFRAG; 4917 } else 4918 mhip->ip_off |= IP_MF; 4919 mhip->ip_len = htons((u_short)(len + mhlen)); 4920 m->m_next = m_copy(m0, off, len); 4921 if (m->m_next == 0) { /* copy failed */ 4922 m_free(m); 4923 error = ENOBUFS; /* ??? */ 4924 ipstat.ips_odropped++; 4925 goto done; 4926 } 4927 m->m_pkthdr.len = mhlen + len; 4928 m->m_pkthdr.rcvif = (struct ifnet *)0; 4929#ifdef MAC 4930 mac_create_fragment(m0, m); 4931#endif 4932 m->m_pkthdr.csum_flags = m0->m_pkthdr.csum_flags; 4933 mhip->ip_off = htons(mhip->ip_off); 4934 mhip->ip_sum = 0; 4935 if (sw_csum & CSUM_DELAY_IP) 4936 mhip->ip_sum = in_cksum(m, mhlen); 4937 *mnext = m; 4938 mnext = &m->m_nextpkt; 4939 } 4940 ipstat.ips_ofragments += nfrags; 4941 4942 /* set first marker for fragment chain */ 4943 m0->m_flags |= M_FIRSTFRAG | M_FRAG; 4944 m0->m_pkthdr.csum_data = nfrags; 4945 4946 /* 4947 * Update first fragment by trimming what's been copied out 4948 * and updating header. 4949 */ 4950 m_adj(m0, hlen + firstlen - ip->ip_len); 4951 m0->m_pkthdr.len = hlen + firstlen; 4952 ip->ip_len = htons((u_short)m0->m_pkthdr.len); 4953 ip->ip_off |= IP_MF; 4954 ip->ip_off = htons(ip->ip_off); 4955 ip->ip_sum = 0; 4956 if (sw_csum & CSUM_DELAY_IP) 4957 ip->ip_sum = in_cksum(m0, hlen); 4958 4959done: 4960 *m_frag = m0; 4961 return error; 4962} 4963#endif /* __FreeBSD__ && __FreeBSD_version > 501105 */ 4964 | |
4965void 4966pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 4967 struct pf_state *s) 4968{ 4969 struct mbuf *m0, *m1; 4970 struct route iproute; 4971 struct route *ro = NULL; /* XXX: was uninitialized */ 4972 struct sockaddr_in *dst; 4973 struct ip *ip; 4974 struct ifnet *ifp = NULL; 4975 struct m_tag *mtag; 4976 struct pf_addr naddr; | 5103void 5104pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 5105 struct pf_state *s) 5106{ 5107 struct mbuf *m0, *m1; 5108 struct route iproute; 5109 struct route *ro = NULL; /* XXX: was uninitialized */ 5110 struct sockaddr_in *dst; 5111 struct ip *ip; 5112 struct ifnet *ifp = NULL; 5113 struct m_tag *mtag; 5114 struct pf_addr naddr; |
5115 struct pf_src_node *sn = NULL; |
|
4977 int error = 0; 4978#ifdef __FreeBSD__ 4979 int sw_csum; 4980#endif 4981 4982 if (m == NULL || *m == NULL || r == NULL || 4983 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 4984 panic("pf_route: invalid parameters"); --- 42 unchanged lines hidden (view full) --- 5027 ro->ro_rt->rt_use++; 5028 5029 if (ro->ro_rt->rt_flags & RTF_GATEWAY) 5030 dst = satosin(ro->ro_rt->rt_gateway); 5031 } else { 5032 if (TAILQ_EMPTY(&r->rpool.list)) 5033 panic("pf_route: TAILQ_EMPTY(&r->rpool.list)"); 5034 if (s == NULL) { | 5116 int error = 0; 5117#ifdef __FreeBSD__ 5118 int sw_csum; 5119#endif 5120 5121 if (m == NULL || *m == NULL || r == NULL || 5122 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 5123 panic("pf_route: invalid parameters"); --- 42 unchanged lines hidden (view full) --- 5166 ro->ro_rt->rt_use++; 5167 5168 if (ro->ro_rt->rt_flags & RTF_GATEWAY) 5169 dst = satosin(ro->ro_rt->rt_gateway); 5170 } else { 5171 if (TAILQ_EMPTY(&r->rpool.list)) 5172 panic("pf_route: TAILQ_EMPTY(&r->rpool.list)"); 5173 if (s == NULL) { |
5035 pf_map_addr(AF_INET, &r->rpool, 5036 (struct pf_addr *)&ip->ip_src, 5037 &naddr, NULL); | 5174 pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src, 5175 &naddr, NULL, &sn); |
5038 if (!PF_AZERO(&naddr, AF_INET)) 5039 dst->sin_addr.s_addr = naddr.v4.s_addr; | 5176 if (!PF_AZERO(&naddr, AF_INET)) 5177 dst->sin_addr.s_addr = naddr.v4.s_addr; |
5040 ifp = r->rpool.cur->ifp; | 5178 ifp = r->rpool.cur->kif ? 5179 r->rpool.cur->kif->pfik_ifp : NULL; |
5041 } else { 5042 if (!PF_AZERO(&s->rt_addr, AF_INET)) 5043 dst->sin_addr.s_addr = 5044 s->rt_addr.v4.s_addr; | 5180 } else { 5181 if (!PF_AZERO(&s->rt_addr, AF_INET)) 5182 dst->sin_addr.s_addr = 5183 s->rt_addr.v4.s_addr; |
5045 ifp = s->rt_ifp; | 5184 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; |
5046 } 5047 } 5048 5049 if (ifp == NULL) 5050 goto bad; 5051 | 5185 } 5186 } 5187 5188 if (ifp == NULL) 5189 goto bad; 5190 |
5052 if (m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL) != NULL) 5053 goto bad; 5054 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 5055 if (mtag == NULL) 5056 goto bad; 5057 m_tag_prepend(m0, mtag); | 5191 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 5192 if (mtag == NULL) { 5193 struct m_tag *mtag; |
5058 | 5194 |
5059 if (oifp != ifp) { | 5195 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 5196 if (mtag == NULL) 5197 goto bad; 5198 m_tag_prepend(m0, mtag); 5199 } 5200 5201 if (oifp != ifp && mtag == NULL) { |
5060#ifdef __FreeBSD__ 5061 PF_UNLOCK(); 5062 if (pf_test(PF_OUT, ifp, &m0) != PF_PASS) { 5063 PF_LOCK(); 5064 goto bad; 5065 } else if (m0 == NULL) { 5066 PF_LOCK(); 5067 goto done; --- 47 unchanged lines hidden (view full) --- 5115 PF_UNLOCK(); 5116 error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro->ro_rt); 5117 PF_LOCK(); 5118 goto done; 5119 } 5120 5121#else 5122 /* Copied from ip_output. */ | 5202#ifdef __FreeBSD__ 5203 PF_UNLOCK(); 5204 if (pf_test(PF_OUT, ifp, &m0) != PF_PASS) { 5205 PF_LOCK(); 5206 goto bad; 5207 } else if (m0 == NULL) { 5208 PF_LOCK(); 5209 goto done; --- 47 unchanged lines hidden (view full) --- 5257 PF_UNLOCK(); 5258 error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro->ro_rt); 5259 PF_LOCK(); 5260 goto done; 5261 } 5262 5263#else 5264 /* Copied from ip_output. */ |
5265#ifdef IPSEC 5266 /* 5267 * If deferred crypto processing is needed, check that the 5268 * interface supports it. 5269 */ 5270 if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL)) 5271 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) { 5272 /* Notify IPsec to do its own crypto. */ 5273 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); 5274 goto bad; 5275 } 5276#endif /* IPSEC */ 5277 5278 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */ 5279 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) { 5280 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) || 5281 ifp->if_bridge != NULL) { 5282 in_delayed_cksum(m0); 5283 m0->m_pkthdr.csum &= ~M_TCPV4_CSUM_OUT; /* Clear */ 5284 } 5285 } else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) { 5286 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) || 5287 ifp->if_bridge != NULL) { 5288 in_delayed_cksum(m0); 5289 m0->m_pkthdr.csum &= ~M_UDPV4_CSUM_OUT; /* Clear */ 5290 } 5291 } 5292 |
|
5123 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 5124 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 5125 ifp->if_bridge == NULL) { 5126 m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT; 5127 ipstat.ips_outhwcsum++; 5128 } else { 5129 ip->ip_sum = 0; 5130 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); --- 91 unchanged lines hidden (view full) --- 5222 struct mbuf *m0; 5223 struct m_tag *mtag; 5224 struct route_in6 ip6route; 5225 struct route_in6 *ro; 5226 struct sockaddr_in6 *dst; 5227 struct ip6_hdr *ip6; 5228 struct ifnet *ifp = NULL; 5229 struct pf_addr naddr; | 5293 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 5294 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 5295 ifp->if_bridge == NULL) { 5296 m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT; 5297 ipstat.ips_outhwcsum++; 5298 } else { 5299 ip->ip_sum = 0; 5300 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); --- 91 unchanged lines hidden (view full) --- 5392 struct mbuf *m0; 5393 struct m_tag *mtag; 5394 struct route_in6 ip6route; 5395 struct route_in6 *ro; 5396 struct sockaddr_in6 *dst; 5397 struct ip6_hdr *ip6; 5398 struct ifnet *ifp = NULL; 5399 struct pf_addr naddr; |
5400 struct pf_src_node *sn = NULL; |
|
5230 int error = 0; 5231 5232 if (m == NULL || *m == NULL || r == NULL || 5233 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 5234 panic("pf_route6: invalid parameters"); 5235 5236 if (r->rt == PF_DUPTO) { 5237 m0 = *m; --- 42 unchanged lines hidden (view full) --- 5280 ip6_output(m0, NULL, NULL, 0, NULL, NULL); 5281#endif 5282 return; 5283 } 5284 5285 if (TAILQ_EMPTY(&r->rpool.list)) 5286 panic("pf_route6: TAILQ_EMPTY(&r->rpool.list)"); 5287 if (s == NULL) { | 5401 int error = 0; 5402 5403 if (m == NULL || *m == NULL || r == NULL || 5404 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 5405 panic("pf_route6: invalid parameters"); 5406 5407 if (r->rt == PF_DUPTO) { 5408 m0 = *m; --- 42 unchanged lines hidden (view full) --- 5451 ip6_output(m0, NULL, NULL, 0, NULL, NULL); 5452#endif 5453 return; 5454 } 5455 5456 if (TAILQ_EMPTY(&r->rpool.list)) 5457 panic("pf_route6: TAILQ_EMPTY(&r->rpool.list)"); 5458 if (s == NULL) { |
5288 pf_map_addr(AF_INET6, &r->rpool, 5289 (struct pf_addr *)&ip6->ip6_src, &naddr, NULL); | 5459 pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, 5460 &naddr, NULL, &sn); |
5290 if (!PF_AZERO(&naddr, AF_INET6)) 5291 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 5292 &naddr, AF_INET6); | 5461 if (!PF_AZERO(&naddr, AF_INET6)) 5462 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 5463 &naddr, AF_INET6); |
5293 ifp = r->rpool.cur->ifp; | 5464 ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; |
5294 } else { 5295 if (!PF_AZERO(&s->rt_addr, AF_INET6)) 5296 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 5297 &s->rt_addr, AF_INET6); | 5465 } else { 5466 if (!PF_AZERO(&s->rt_addr, AF_INET6)) 5467 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 5468 &s->rt_addr, AF_INET6); |
5298 ifp = s->rt_ifp; | 5469 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; |
5299 } 5300 5301 if (ifp == NULL) 5302 goto bad; 5303 5304 if (oifp != ifp) { 5305 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 5306 if (mtag == NULL) { --- 193 unchanged lines hidden (view full) --- 5500#else 5501/* 5502 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 5503 * off is the offset where the protocol header starts 5504 * len is the total length of protocol header plus payload 5505 * returns 0 when the checksum is valid, otherwise returns 1. 5506 */ 5507int | 5470 } 5471 5472 if (ifp == NULL) 5473 goto bad; 5474 5475 if (oifp != ifp) { 5476 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 5477 if (mtag == NULL) { --- 193 unchanged lines hidden (view full) --- 5671#else 5672/* 5673 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 5674 * off is the offset where the protocol header starts 5675 * len is the total length of protocol header plus payload 5676 * returns 0 when the checksum is valid, otherwise returns 1. 5677 */ 5678int |
5508pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) | 5679pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, 5680 sa_family_t af) |
5509{ 5510 u_int16_t flag_ok, flag_bad; 5511 u_int16_t sum; 5512 5513 switch (p) { 5514 case IPPROTO_TCP: 5515 flag_ok = M_TCP_CSUM_IN_OK; 5516 flag_bad = M_TCP_CSUM_IN_BAD; --- 65 unchanged lines hidden (view full) --- 5582 } 5583 return (1); 5584 } 5585 m->m_pkthdr.csum |= flag_ok; 5586 return (0); 5587} 5588#endif 5589 | 5681{ 5682 u_int16_t flag_ok, flag_bad; 5683 u_int16_t sum; 5684 5685 switch (p) { 5686 case IPPROTO_TCP: 5687 flag_ok = M_TCP_CSUM_IN_OK; 5688 flag_bad = M_TCP_CSUM_IN_BAD; --- 65 unchanged lines hidden (view full) --- 5754 } 5755 return (1); 5756 } 5757 m->m_pkthdr.csum |= flag_ok; 5758 return (0); 5759} 5760#endif 5761 |
5762static int 5763pf_add_mbuf_tag(struct mbuf *m, u_int tag) 5764{ 5765 struct m_tag *mtag; 5766 5767 if (m_tag_find(m, tag, NULL) != NULL) 5768 return (0); 5769 mtag = m_tag_get(tag, 0, M_NOWAIT); 5770 if (mtag == NULL) 5771 return (1); 5772 m_tag_prepend(m, mtag); 5773 return (0); 5774} 5775 |
|
5590#ifdef INET 5591int 5592pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) 5593{ | 5776#ifdef INET 5777int 5778pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) 5779{ |
5594 u_short action, reason = 0, log = 0; 5595 struct mbuf *m = *m0; 5596 struct ip *h = NULL; /* XXX: was uninitialized */ 5597 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr; 5598 struct pf_state *s = NULL; 5599 struct pf_ruleset *ruleset = NULL; 5600 struct pf_pdesc pd; 5601 int off; 5602 int pqid = 0; | 5780 struct pfi_kif *kif; 5781 u_short action, reason = 0, log = 0; 5782 struct mbuf *m = *m0; 5783 struct ip *h = NULL; /* make the compiler happy */ 5784 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 5785 struct pf_state *s = NULL; 5786 struct pf_ruleset *ruleset = NULL; 5787 struct pf_pdesc pd; 5788 int off, dirndx, pqid = 0; |
5603 5604#ifdef __FreeBSD__ 5605 PF_LOCK(); 5606#endif 5607 if (!pf_status.running || 5608 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) { 5609#ifdef __FreeBSD__ 5610 PF_UNLOCK(); 5611#endif 5612 return (PF_PASS); 5613 } 5614 | 5789 5790#ifdef __FreeBSD__ 5791 PF_LOCK(); 5792#endif 5793 if (!pf_status.running || 5794 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) { 5795#ifdef __FreeBSD__ 5796 PF_UNLOCK(); 5797#endif 5798 return (PF_PASS); 5799 } 5800 |
5615#if defined(__FreeBSD__) && (__FreeBSD_version >= 501000) | 5801 kif = pfi_index2kif[ifp->if_index]; 5802 if (kif == NULL) { 5803#ifdef __FreeBSD__ 5804 PF_UNLOCK(); 5805#endif 5806 return (PF_DROP); 5807 } 5808 5809#ifdef __FreeBSD__ |
5616 M_ASSERTPKTHDR(m); 5617#else 5618#ifdef DIAGNOSTIC 5619 if ((m->m_flags & M_PKTHDR) == 0) 5620 panic("non-M_PKTHDR is passed to pf_test"); 5621#endif 5622#endif 5623 | 5810 M_ASSERTPKTHDR(m); 5811#else 5812#ifdef DIAGNOSTIC 5813 if ((m->m_flags & M_PKTHDR) == 0) 5814 panic("non-M_PKTHDR is passed to pf_test"); 5815#endif 5816#endif 5817 |
5818 memset(&pd, 0, sizeof(pd)); |
|
5624 if (m->m_pkthdr.len < (int)sizeof(*h)) { 5625 action = PF_DROP; 5626 REASON_SET(&reason, PFRES_SHORT); 5627 log = 1; 5628 goto done; 5629 } 5630 5631 /* We do IP header normalization and packet reassembly here */ | 5819 if (m->m_pkthdr.len < (int)sizeof(*h)) { 5820 action = PF_DROP; 5821 REASON_SET(&reason, PFRES_SHORT); 5822 log = 1; 5823 goto done; 5824 } 5825 5826 /* We do IP header normalization and packet reassembly here */ |
5632 if (pf_normalize_ip(m0, dir, ifp, &reason) != PF_PASS) { | 5827 if (pf_normalize_ip(m0, dir, kif, &reason) != PF_PASS) { |
5633 action = PF_DROP; 5634 goto done; 5635 } 5636 m = *m0; 5637 h = mtod(m, struct ip *); 5638 5639 off = h->ip_hl << 2; 5640 if (off < (int)sizeof(*h)) { 5641 action = PF_DROP; 5642 REASON_SET(&reason, PFRES_SHORT); 5643 log = 1; 5644 goto done; 5645 } 5646 | 5828 action = PF_DROP; 5829 goto done; 5830 } 5831 m = *m0; 5832 h = mtod(m, struct ip *); 5833 5834 off = h->ip_hl << 2; 5835 if (off < (int)sizeof(*h)) { 5836 action = PF_DROP; 5837 REASON_SET(&reason, PFRES_SHORT); 5838 log = 1; 5839 goto done; 5840 } 5841 |
5647 memset(&pd, 0, sizeof(pd)); | |
5648 pd.src = (struct pf_addr *)&h->ip_src; 5649 pd.dst = (struct pf_addr *)&h->ip_dst; | 5842 pd.src = (struct pf_addr *)&h->ip_src; 5843 pd.dst = (struct pf_addr *)&h->ip_dst; |
5844 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET); |
|
5650 pd.ip_sum = &h->ip_sum; 5651 pd.proto = h->ip_p; 5652 pd.af = AF_INET; 5653 pd.tos = h->ip_tos; 5654 pd.tot_len = ntohs(h->ip_len); 5655 5656 /* handle fragments that didn't get reassembled by normalization */ 5657 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) { | 5845 pd.ip_sum = &h->ip_sum; 5846 pd.proto = h->ip_p; 5847 pd.af = AF_INET; 5848 pd.tos = h->ip_tos; 5849 pd.tot_len = ntohs(h->ip_len); 5850 5851 /* handle fragments that didn't get reassembled by normalization */ 5852 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) { |
5658 action = pf_test_fragment(&r, dir, ifp, m, h, | 5853 action = pf_test_fragment(&r, dir, kif, m, h, |
5659 &pd, &a, &ruleset); 5660 goto done; 5661 } 5662 5663 switch (h->ip_p) { 5664 5665 case IPPROTO_TCP: { 5666 struct tcphdr th; --- 7 unchanged lines hidden (view full) --- 5674 if (dir == PF_IN && pf_check_proto_cksum(m, off, 5675 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) { 5676 action = PF_DROP; 5677 goto done; 5678 } 5679 pd.p_len = pd.tot_len - off - (th.th_off << 2); 5680 if ((th.th_flags & TH_ACK) && pd.p_len == 0) 5681 pqid = 1; | 5854 &pd, &a, &ruleset); 5855 goto done; 5856 } 5857 5858 switch (h->ip_p) { 5859 5860 case IPPROTO_TCP: { 5861 struct tcphdr th; --- 7 unchanged lines hidden (view full) --- 5869 if (dir == PF_IN && pf_check_proto_cksum(m, off, 5870 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) { 5871 action = PF_DROP; 5872 goto done; 5873 } 5874 pd.p_len = pd.tot_len - off - (th.th_off << 2); 5875 if ((th.th_flags & TH_ACK) && pd.p_len == 0) 5876 pqid = 1; |
5682 action = pf_normalize_tcp(dir, ifp, m, 0, off, h, &pd); | 5877 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); |
5683 if (action == PF_DROP) | 5878 if (action == PF_DROP) |
5684 break; 5685 action = pf_test_state_tcp(&s, dir, ifp, m, 0, off, h, &pd, | 5879 goto done; 5880 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, |
5686 &reason); 5687 if (action == PF_PASS) { | 5881 &reason); 5882 if (action == PF_PASS) { |
5883#if NPFSYNC 5884 pfsync_update_state(s); 5885#endif |
|
5688 r = s->rule.ptr; | 5886 r = s->rule.ptr; |
5887 a = s->anchor.ptr; |
|
5689 log = s->log; 5690 } else if (s == NULL) | 5888 log = s->log; 5889 } else if (s == NULL) |
5691 action = pf_test_tcp(&r, &s, dir, ifp, 5692 m, 0, off, h, &pd, &a, &ruleset); | 5890 action = pf_test_tcp(&r, &s, dir, kif, 5891 m, off, h, &pd, &a, &ruleset); |
5693 break; 5694 } 5695 5696 case IPPROTO_UDP: { 5697 struct udphdr uh; 5698 5699 pd.hdr.udp = &uh; 5700 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 5701 &action, &reason, AF_INET)) { 5702 log = action != PF_PASS; 5703 goto done; 5704 } 5705 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 5706 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) { 5707 action = PF_DROP; 5708 goto done; 5709 } | 5892 break; 5893 } 5894 5895 case IPPROTO_UDP: { 5896 struct udphdr uh; 5897 5898 pd.hdr.udp = &uh; 5899 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 5900 &action, &reason, AF_INET)) { 5901 log = action != PF_PASS; 5902 goto done; 5903 } 5904 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 5905 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) { 5906 action = PF_DROP; 5907 goto done; 5908 } |
5710 action = pf_test_state_udp(&s, dir, ifp, m, 0, off, h, &pd); | 5909 if (uh.uh_dport == 0 || 5910 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 5911 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 5912 action = PF_DROP; 5913 goto done; 5914 } 5915 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); |
5711 if (action == PF_PASS) { | 5916 if (action == PF_PASS) { |
5917#if NPFSYNC 5918 pfsync_update_state(s); 5919#endif |
|
5712 r = s->rule.ptr; 5713 a = s->anchor.ptr; 5714 log = s->log; 5715 } else if (s == NULL) | 5920 r = s->rule.ptr; 5921 a = s->anchor.ptr; 5922 log = s->log; 5923 } else if (s == NULL) |
5716 action = pf_test_udp(&r, &s, dir, ifp, 5717 m, 0, off, h, &pd, &a, &ruleset); | 5924 action = pf_test_udp(&r, &s, dir, kif, 5925 m, off, h, &pd, &a, &ruleset); |
5718 break; 5719 } 5720 5721 case IPPROTO_ICMP: { 5722 struct icmp ih; 5723 5724 pd.hdr.icmp = &ih; 5725 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN, 5726 &action, &reason, AF_INET)) { 5727 log = action != PF_PASS; 5728 goto done; 5729 } 5730 if (dir == PF_IN && pf_check_proto_cksum(m, off, 5731 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) { 5732 action = PF_DROP; 5733 goto done; 5734 } | 5926 break; 5927 } 5928 5929 case IPPROTO_ICMP: { 5930 struct icmp ih; 5931 5932 pd.hdr.icmp = &ih; 5933 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN, 5934 &action, &reason, AF_INET)) { 5935 log = action != PF_PASS; 5936 goto done; 5937 } 5938 if (dir == PF_IN && pf_check_proto_cksum(m, off, 5939 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) { 5940 action = PF_DROP; 5941 goto done; 5942 } |
5735 action = pf_test_state_icmp(&s, dir, ifp, m, 0, off, h, &pd); | 5943 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd); |
5736 if (action == PF_PASS) { | 5944 if (action == PF_PASS) { |
5945#if NPFSYNC 5946 pfsync_update_state(s); 5947#endif |
|
5737 r = s->rule.ptr; | 5948 r = s->rule.ptr; |
5738 r->packets++; 5739 r->bytes += ntohs(h->ip_len); | |
5740 a = s->anchor.ptr; | 5949 a = s->anchor.ptr; |
5741 if (a != NULL) { 5742 a->packets++; 5743 a->bytes += ntohs(h->ip_len); 5744 } | |
5745 log = s->log; 5746 } else if (s == NULL) | 5950 log = s->log; 5951 } else if (s == NULL) |
5747 action = pf_test_icmp(&r, &s, dir, ifp, 5748 m, 0, off, h, &pd, &a, &ruleset); | 5952 action = pf_test_icmp(&r, &s, dir, kif, 5953 m, off, h, &pd, &a, &ruleset); |
5749 break; 5750 } 5751 5752 default: | 5954 break; 5955 } 5956 5957 default: |
5753 action = pf_test_state_other(&s, dir, ifp, &pd); | 5958 action = pf_test_state_other(&s, dir, kif, &pd); |
5754 if (action == PF_PASS) { | 5959 if (action == PF_PASS) { |
5960#if NPFSYNC 5961 pfsync_update_state(s); 5962#endif |
|
5755 r = s->rule.ptr; 5756 a = s->anchor.ptr; 5757 log = s->log; 5758 } else if (s == NULL) | 5963 r = s->rule.ptr; 5964 a = s->anchor.ptr; 5965 log = s->log; 5966 } else if (s == NULL) |
5759 action = pf_test_other(&r, &s, dir, ifp, m, off, h, | 5967 action = pf_test_other(&r, &s, dir, kif, m, off, h, |
5760 &pd, &a, &ruleset); 5761 break; 5762 } 5763 | 5968 &pd, &a, &ruleset); 5969 break; 5970 } 5971 |
5764 if (ifp == status_ifp) { 5765 pf_status.bcounters[0][dir == PF_OUT] += pd.tot_len; 5766 pf_status.pcounters[0][dir == PF_OUT][action != PF_PASS]++; 5767 } 5768 | |
5769done: | 5972done: |
5770 tr = r; 5771 if (r == &pf_default_rule && s != NULL && s->nat_rule.ptr != NULL) 5772 tr = s->nat_rule.ptr; 5773 if (tr->src.addr.type == PF_ADDR_TABLE) 5774 pfr_update_stats(tr->src.addr.p.tbl, 5775 (s == NULL || s->direction == dir) ? pd.src : pd.dst, pd.af, 5776 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 5777 tr->src.not); 5778 if (tr->dst.addr.type == PF_ADDR_TABLE) 5779 pfr_update_stats(tr->dst.addr.p.tbl, 5780 (s == NULL || s->direction == dir) ? pd.dst : pd.src, pd.af, 5781 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 5782 tr->dst.not); 5783 | |
5784 if (action == PF_PASS && h->ip_hl > 5 && 5785 !((s && s->allow_opts) || r->allow_opts)) { 5786 action = PF_DROP; 5787 REASON_SET(&reason, PFRES_SHORT); 5788 log = 1; 5789 DPFPRINTF(PF_DEBUG_MISC, 5790 ("pf: dropping packet with ip options\n")); 5791 } --- 13 unchanged lines hidden (view full) --- 5805 /* add hints for ecn */ 5806 atag->af = AF_INET; 5807 atag->hdr = h; 5808 m_tag_prepend(m, mtag); 5809 } 5810 } 5811#endif 5812 | 5973 if (action == PF_PASS && h->ip_hl > 5 && 5974 !((s && s->allow_opts) || r->allow_opts)) { 5975 action = PF_DROP; 5976 REASON_SET(&reason, PFRES_SHORT); 5977 log = 1; 5978 DPFPRINTF(PF_DEBUG_MISC, 5979 ("pf: dropping packet with ip options\n")); 5980 } --- 13 unchanged lines hidden (view full) --- 5994 /* add hints for ecn */ 5995 atag->af = AF_INET; 5996 atag->hdr = h; 5997 m_tag_prepend(m, mtag); 5998 } 5999 } 6000#endif 6001 |
6002 /* 6003 * connections redirected to loopback should not match sockets 6004 * bound specifically to loopback due to security implications, 6005 * see tcp_input() and in_pcblookup_listen(). 6006 */ 6007 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 6008 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 6009 (s->nat_rule.ptr->action == PF_RDR || 6010 s->nat_rule.ptr->action == PF_BINAT) && 6011 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET && 6012 pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) { 6013 action = PF_DROP; 6014 REASON_SET(&reason, PFRES_MEMORY); 6015 } 6016 |
|
5813 if (log) | 6017 if (log) |
5814 PFLOG_PACKET(ifp, h, m, AF_INET, dir, reason, r, a, ruleset); | 6018 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, a, ruleset); |
5815 | 6019 |
6020 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 6021 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++; 6022 6023 if (action == PF_PASS || r->action == PF_DROP) { 6024 r->packets++; 6025 r->bytes += pd.tot_len; 6026 if (a != NULL) { 6027 a->packets++; 6028 a->bytes += pd.tot_len; 6029 } 6030 if (s != NULL) { 6031 dirndx = (dir == s->direction) ? 0 : 1; 6032 s->packets[dirndx]++; 6033 s->bytes[dirndx] += pd.tot_len; 6034 if (s->nat_rule.ptr != NULL) { 6035 s->nat_rule.ptr->packets++; 6036 s->nat_rule.ptr->bytes += pd.tot_len; 6037 } 6038 if (s->src_node != NULL) { 6039 s->src_node->packets++; 6040 s->src_node->bytes += pd.tot_len; 6041 } 6042 if (s->nat_src_node != NULL) { 6043 s->nat_src_node->packets++; 6044 s->nat_src_node->bytes += pd.tot_len; 6045 } 6046 } 6047 tr = r; 6048 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 6049 if (nr != NULL) { 6050 struct pf_addr *x; 6051 /* 6052 * XXX: we need to make sure that the addresses 6053 * passed to pfr_update_stats() are the same than 6054 * the addresses used during matching (pfr_match) 6055 */ 6056 if (r == &pf_default_rule) { 6057 tr = nr; 6058 x = (s == NULL || s->direction == dir) ? 6059 &pd.baddr : &pd.naddr; 6060 } else 6061 x = (s == NULL || s->direction == dir) ? 6062 &pd.naddr : &pd.baddr; 6063 if (x == &pd.baddr || s == NULL) { 6064 /* we need to change the address */ 6065 if (dir == PF_OUT) 6066 pd.src = x; 6067 else 6068 pd.dst = x; 6069 } 6070 } 6071 if (tr->src.addr.type == PF_ADDR_TABLE) 6072 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL || 6073 s->direction == dir) ? pd.src : pd.dst, pd.af, 6074 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 6075 tr->src.not); 6076 if (tr->dst.addr.type == PF_ADDR_TABLE) 6077 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL || 6078 s->direction == dir) ? pd.dst : pd.src, pd.af, 6079 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 6080 tr->dst.not); 6081 } 6082 6083 |
|
5816 if (action == PF_SYNPROXY_DROP) { 5817 m_freem(*m0); 5818 *m0 = NULL; 5819 action = PF_PASS; 5820 } else if (r->rt) 5821 /* pf_route can free the mbuf causing *m0 to become NULL */ 5822 pf_route(m0, r, dir, ifp, s); 5823 --- 4 unchanged lines hidden (view full) --- 5828 return (action); 5829} 5830#endif /* INET */ 5831 5832#ifdef INET6 5833int 5834pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0) 5835{ | 6084 if (action == PF_SYNPROXY_DROP) { 6085 m_freem(*m0); 6086 *m0 = NULL; 6087 action = PF_PASS; 6088 } else if (r->rt) 6089 /* pf_route can free the mbuf causing *m0 to become NULL */ 6090 pf_route(m0, r, dir, ifp, s); 6091 --- 4 unchanged lines hidden (view full) --- 6096 return (action); 6097} 6098#endif /* INET */ 6099 6100#ifdef INET6 6101int 6102pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0) 6103{ |
5836 u_short action, reason = 0, log = 0; 5837 struct mbuf *m = *m0; 5838 struct ip6_hdr *h = NULL; /* make the compiler happy */ 5839 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr; 5840 struct pf_state *s = NULL; 5841 struct pf_ruleset *ruleset = NULL; 5842 struct pf_pdesc pd; 5843 int off, terminal = 0; | 6104 struct pfi_kif *kif; 6105 u_short action, reason = 0, log = 0; 6106 struct mbuf *m = *m0; 6107 struct ip6_hdr *h = NULL; /* make the compiler happy */ 6108 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 6109 struct pf_state *s = NULL; 6110 struct pf_ruleset *ruleset = NULL; 6111 struct pf_pdesc pd; 6112 int off, terminal = 0, dirndx; |
5844 5845#ifdef __FreeBSD__ 5846 PF_LOCK(); 5847#endif 5848 5849 if (!pf_status.running || 5850 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) { 5851#ifdef __FreeBSD__ 5852 PF_UNLOCK(); 5853#endif 5854 return (PF_PASS); 5855 } 5856 | 6113 6114#ifdef __FreeBSD__ 6115 PF_LOCK(); 6116#endif 6117 6118 if (!pf_status.running || 6119 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) { 6120#ifdef __FreeBSD__ 6121 PF_UNLOCK(); 6122#endif 6123 return (PF_PASS); 6124 } 6125 |
5857#if defined(__FreeBSD__) && (__FreeBSD_version >= 501000) | 6126 kif = pfi_index2kif[ifp->if_index]; 6127 if (kif == NULL) { 6128#ifdef __FreeBSD__ 6129 PF_UNLOCK(); 6130#endif 6131 return (PF_DROP); 6132 } 6133 6134#ifdef __FreeBSD__ |
5858 M_ASSERTPKTHDR(m); 5859#else 5860#ifdef DIAGNOSTIC 5861 if ((m->m_flags & M_PKTHDR) == 0) 5862 panic("non-M_PKTHDR is passed to pf_test"); 5863#endif 5864#endif 5865 | 6135 M_ASSERTPKTHDR(m); 6136#else 6137#ifdef DIAGNOSTIC 6138 if ((m->m_flags & M_PKTHDR) == 0) 6139 panic("non-M_PKTHDR is passed to pf_test"); 6140#endif 6141#endif 6142 |
6143 memset(&pd, 0, sizeof(pd)); |
|
5866 if (m->m_pkthdr.len < (int)sizeof(*h)) { 5867 action = PF_DROP; 5868 REASON_SET(&reason, PFRES_SHORT); 5869 log = 1; 5870 goto done; 5871 } 5872 5873 /* We do IP header normalization and packet reassembly here */ | 6144 if (m->m_pkthdr.len < (int)sizeof(*h)) { 6145 action = PF_DROP; 6146 REASON_SET(&reason, PFRES_SHORT); 6147 log = 1; 6148 goto done; 6149 } 6150 6151 /* We do IP header normalization and packet reassembly here */ |
5874 if (pf_normalize_ip6(m0, dir, ifp, &reason) != PF_PASS) { | 6152 if (pf_normalize_ip6(m0, dir, kif, &reason) != PF_PASS) { |
5875 action = PF_DROP; 5876 goto done; 5877 } 5878 m = *m0; 5879 h = mtod(m, struct ip6_hdr *); 5880 | 6153 action = PF_DROP; 6154 goto done; 6155 } 6156 m = *m0; 6157 h = mtod(m, struct ip6_hdr *); 6158 |
5881 memset(&pd, 0, sizeof(pd)); | |
5882 pd.src = (struct pf_addr *)&h->ip6_src; 5883 pd.dst = (struct pf_addr *)&h->ip6_dst; | 6159 pd.src = (struct pf_addr *)&h->ip6_src; 6160 pd.dst = (struct pf_addr *)&h->ip6_dst; |
6161 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET6); |
|
5884 pd.ip_sum = NULL; 5885 pd.af = AF_INET6; 5886 pd.tos = 0; 5887 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr); 5888 5889 off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr); 5890 pd.proto = h->ip6_nxt; 5891 do { 5892 switch (pd.proto) { 5893 case IPPROTO_FRAGMENT: | 6162 pd.ip_sum = NULL; 6163 pd.af = AF_INET6; 6164 pd.tos = 0; 6165 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr); 6166 6167 off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr); 6168 pd.proto = h->ip6_nxt; 6169 do { 6170 switch (pd.proto) { 6171 case IPPROTO_FRAGMENT: |
5894 action = pf_test_fragment(&r, dir, ifp, m, h, | 6172 action = pf_test_fragment(&r, dir, kif, m, h, |
5895 &pd, &a, &ruleset); 5896 if (action == PF_DROP) 5897 REASON_SET(&reason, PFRES_FRAG); 5898 goto done; 5899 case IPPROTO_AH: 5900 case IPPROTO_HOPOPTS: 5901 case IPPROTO_ROUTING: 5902 case IPPROTO_DSTOPTS: { --- 35 unchanged lines hidden (view full) --- 5938 goto done; 5939 } 5940 if (dir == PF_IN && pf_check_proto_cksum(m, off, 5941 ntohs(h->ip6_plen), IPPROTO_TCP, AF_INET6)) { 5942 action = PF_DROP; 5943 goto done; 5944 } 5945 pd.p_len = pd.tot_len - off - (th.th_off << 2); | 6173 &pd, &a, &ruleset); 6174 if (action == PF_DROP) 6175 REASON_SET(&reason, PFRES_FRAG); 6176 goto done; 6177 case IPPROTO_AH: 6178 case IPPROTO_HOPOPTS: 6179 case IPPROTO_ROUTING: 6180 case IPPROTO_DSTOPTS: { --- 35 unchanged lines hidden (view full) --- 6216 goto done; 6217 } 6218 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6219 ntohs(h->ip6_plen), IPPROTO_TCP, AF_INET6)) { 6220 action = PF_DROP; 6221 goto done; 6222 } 6223 pd.p_len = pd.tot_len - off - (th.th_off << 2); |
5946 action = pf_normalize_tcp(dir, ifp, m, 0, off, h, &pd); | 6224 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); |
5947 if (action == PF_DROP) | 6225 if (action == PF_DROP) |
5948 break; 5949 action = pf_test_state_tcp(&s, dir, ifp, m, 0, off, h, &pd, | 6226 goto done; 6227 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, |
5950 &reason); 5951 if (action == PF_PASS) { | 6228 &reason); 6229 if (action == PF_PASS) { |
6230#if NPFSYNC 6231 pfsync_update_state(s); 6232#endif |
|
5952 r = s->rule.ptr; | 6233 r = s->rule.ptr; |
6234 a = s->anchor.ptr; |
|
5953 log = s->log; 5954 } else if (s == NULL) | 6235 log = s->log; 6236 } else if (s == NULL) |
5955 action = pf_test_tcp(&r, &s, dir, ifp, 5956 m, 0, off, h, &pd, &a, &ruleset); | 6237 action = pf_test_tcp(&r, &s, dir, kif, 6238 m, off, h, &pd, &a, &ruleset); |
5957 break; 5958 } 5959 5960 case IPPROTO_UDP: { 5961 struct udphdr uh; 5962 5963 pd.hdr.udp = &uh; 5964 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 5965 &action, &reason, AF_INET6)) { 5966 log = action != PF_PASS; 5967 goto done; 5968 } 5969 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 5970 off, ntohs(h->ip6_plen), IPPROTO_UDP, AF_INET6)) { 5971 action = PF_DROP; 5972 goto done; 5973 } | 6239 break; 6240 } 6241 6242 case IPPROTO_UDP: { 6243 struct udphdr uh; 6244 6245 pd.hdr.udp = &uh; 6246 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 6247 &action, &reason, AF_INET6)) { 6248 log = action != PF_PASS; 6249 goto done; 6250 } 6251 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, 6252 off, ntohs(h->ip6_plen), IPPROTO_UDP, AF_INET6)) { 6253 action = PF_DROP; 6254 goto done; 6255 } |
5974 action = pf_test_state_udp(&s, dir, ifp, m, 0, off, h, &pd); | 6256 if (uh.uh_dport == 0 || 6257 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 6258 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 6259 action = PF_DROP; 6260 goto done; 6261 } 6262 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); |
5975 if (action == PF_PASS) { | 6263 if (action == PF_PASS) { |
6264#if NPFSYNC 6265 pfsync_update_state(s); 6266#endif |
|
5976 r = s->rule.ptr; | 6267 r = s->rule.ptr; |
6268 a = s->anchor.ptr; |
|
5977 log = s->log; 5978 } else if (s == NULL) | 6269 log = s->log; 6270 } else if (s == NULL) |
5979 action = pf_test_udp(&r, &s, dir, ifp, 5980 m, 0, off, h, &pd, &a, &ruleset); | 6271 action = pf_test_udp(&r, &s, dir, kif, 6272 m, off, h, &pd, &a, &ruleset); |
5981 break; 5982 } 5983 5984 case IPPROTO_ICMPV6: { 5985 struct icmp6_hdr ih; 5986 5987 pd.hdr.icmp6 = &ih; 5988 if (!pf_pull_hdr(m, off, &ih, sizeof(ih), 5989 &action, &reason, AF_INET6)) { 5990 log = action != PF_PASS; 5991 goto done; 5992 } 5993 if (dir == PF_IN && pf_check_proto_cksum(m, off, 5994 ntohs(h->ip6_plen), IPPROTO_ICMPV6, AF_INET6)) { 5995 action = PF_DROP; 5996 goto done; 5997 } | 6273 break; 6274 } 6275 6276 case IPPROTO_ICMPV6: { 6277 struct icmp6_hdr ih; 6278 6279 pd.hdr.icmp6 = &ih; 6280 if (!pf_pull_hdr(m, off, &ih, sizeof(ih), 6281 &action, &reason, AF_INET6)) { 6282 log = action != PF_PASS; 6283 goto done; 6284 } 6285 if (dir == PF_IN && pf_check_proto_cksum(m, off, 6286 ntohs(h->ip6_plen), IPPROTO_ICMPV6, AF_INET6)) { 6287 action = PF_DROP; 6288 goto done; 6289 } |
5998 action = pf_test_state_icmp(&s, dir, ifp, 5999 m, 0, off, h, &pd); | 6290 action = pf_test_state_icmp(&s, dir, kif, 6291 m, off, h, &pd); |
6000 if (action == PF_PASS) { | 6292 if (action == PF_PASS) { |
6293#if NPFSYNC 6294 pfsync_update_state(s); 6295#endif |
|
6001 r = s->rule.ptr; | 6296 r = s->rule.ptr; |
6002 r->packets++; 6003 r->bytes += h->ip6_plen; | 6297 a = s->anchor.ptr; |
6004 log = s->log; 6005 } else if (s == NULL) | 6298 log = s->log; 6299 } else if (s == NULL) |
6006 action = pf_test_icmp(&r, &s, dir, ifp, 6007 m, 0, off, h, &pd, &a, &ruleset); | 6300 action = pf_test_icmp(&r, &s, dir, kif, 6301 m, off, h, &pd, &a, &ruleset); |
6008 break; 6009 } 6010 6011 default: | 6302 break; 6303 } 6304 6305 default: |
6012 action = pf_test_other(&r, &s, dir, ifp, m, off, h, 6013 &pd, &a, &ruleset); | 6306 action = pf_test_state_other(&s, dir, kif, &pd); 6307 if (action == PF_PASS) { 6308 r = s->rule.ptr; 6309 a = s->anchor.ptr; 6310 log = s->log; 6311 } else if (s == NULL) 6312 action = pf_test_other(&r, &s, dir, kif, m, off, h, 6313 &pd, &a, &ruleset); |
6014 break; 6015 } 6016 | 6314 break; 6315 } 6316 |
6017 if (ifp == status_ifp) { 6018 pf_status.bcounters[1][dir == PF_OUT] += pd.tot_len; 6019 pf_status.pcounters[1][dir == PF_OUT][action != PF_PASS]++; 6020 } 6021 | |
6022done: | 6317done: |
6023 tr = r; 6024 if (r == &pf_default_rule && s != NULL && s->nat_rule.ptr != NULL) 6025 tr = s->nat_rule.ptr; 6026 if (tr->src.addr.type == PF_ADDR_TABLE) 6027 pfr_update_stats(tr->src.addr.p.tbl, 6028 (s == NULL || s->direction == dir) ? pd.src : pd.dst, pd.af, 6029 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 6030 tr->src.not); 6031 if (tr->dst.addr.type == PF_ADDR_TABLE) 6032 pfr_update_stats(tr->dst.addr.p.tbl, 6033 (s == NULL || s->direction == dir) ? pd.dst : pd.src, pd.af, 6034 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 6035 tr->dst.not); 6036 | |
6037 /* XXX handle IPv6 options, if not allowed. not implemented. */ 6038 6039#ifdef ALTQ 6040 if (action == PF_PASS && r->qid) { 6041 struct m_tag *mtag; 6042 struct altq_tag *atag; 6043 6044 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); --- 6 unchanged lines hidden (view full) --- 6051 /* add hints for ecn */ 6052 atag->af = AF_INET6; 6053 atag->hdr = h; 6054 m_tag_prepend(m, mtag); 6055 } 6056 } 6057#endif 6058 | 6318 /* XXX handle IPv6 options, if not allowed. not implemented. */ 6319 6320#ifdef ALTQ 6321 if (action == PF_PASS && r->qid) { 6322 struct m_tag *mtag; 6323 struct altq_tag *atag; 6324 6325 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); --- 6 unchanged lines hidden (view full) --- 6332 /* add hints for ecn */ 6333 atag->af = AF_INET6; 6334 atag->hdr = h; 6335 m_tag_prepend(m, mtag); 6336 } 6337 } 6338#endif 6339 |
6340 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 6341 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 6342 (s->nat_rule.ptr->action == PF_RDR || 6343 s->nat_rule.ptr->action == PF_BINAT) && 6344 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6) && 6345 pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) { 6346 action = PF_DROP; 6347 REASON_SET(&reason, PFRES_MEMORY); 6348 } 6349 |
|
6059 if (log) | 6350 if (log) |
6060 PFLOG_PACKET(ifp, h, m, AF_INET6, dir, reason, r, a, ruleset); | 6351 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, r, a, ruleset); |
6061 | 6352 |
6353 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 6354 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++; 6355 6356 if (action == PF_PASS || r->action == PF_DROP) { 6357 r->packets++; 6358 r->bytes += pd.tot_len; 6359 if (a != NULL) { 6360 a->packets++; 6361 a->bytes += pd.tot_len; 6362 } 6363 if (s != NULL) { 6364 dirndx = (dir == s->direction) ? 0 : 1; 6365 s->packets[dirndx]++; 6366 s->bytes[dirndx] += pd.tot_len; 6367 if (s->nat_rule.ptr != NULL) { 6368 s->nat_rule.ptr->packets++; 6369 s->nat_rule.ptr->bytes += pd.tot_len; 6370 } 6371 if (s->src_node != NULL) { 6372 s->src_node->packets++; 6373 s->src_node->bytes += pd.tot_len; 6374 } 6375 if (s->nat_src_node != NULL) { 6376 s->nat_src_node->packets++; 6377 s->nat_src_node->bytes += pd.tot_len; 6378 } 6379 } 6380 tr = r; 6381 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 6382 if (nr != NULL) { 6383 struct pf_addr *x; 6384 /* 6385 * XXX: we need to make sure that the addresses 6386 * passed to pfr_update_stats() are the same than 6387 * the addresses used during matching (pfr_match) 6388 */ 6389 if (r == &pf_default_rule) { 6390 tr = nr; 6391 x = (s == NULL || s->direction == dir) ? 6392 &pd.baddr : &pd.naddr; 6393 } else { 6394 x = (s == NULL || s->direction == dir) ? 6395 &pd.naddr : &pd.baddr; 6396 } 6397 if (x == &pd.baddr || s == NULL) { 6398 if (dir == PF_OUT) 6399 pd.src = x; 6400 else 6401 pd.dst = x; 6402 } 6403 } 6404 if (tr->src.addr.type == PF_ADDR_TABLE) 6405 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL || 6406 s->direction == dir) ? pd.src : pd.dst, pd.af, 6407 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 6408 tr->src.not); 6409 if (tr->dst.addr.type == PF_ADDR_TABLE) 6410 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL || 6411 s->direction == dir) ? pd.dst : pd.src, pd.af, 6412 pd.tot_len, dir == PF_OUT, r->action == PF_PASS, 6413 tr->dst.not); 6414 } 6415 6416 |
|
6062 if (action == PF_SYNPROXY_DROP) { 6063 m_freem(*m0); 6064 *m0 = NULL; 6065 action = PF_PASS; 6066 } else if (r->rt) 6067 /* pf_route6 can free the mbuf causing *m0 to become NULL */ 6068 pf_route6(m0, r, dir, ifp, s); 6069 6070#ifdef __FreeBSD__ 6071 PF_UNLOCK(); 6072#endif 6073 return (action); 6074} 6075#endif /* INET6 */ | 6417 if (action == PF_SYNPROXY_DROP) { 6418 m_freem(*m0); 6419 *m0 = NULL; 6420 action = PF_PASS; 6421 } else if (r->rt) 6422 /* pf_route6 can free the mbuf causing *m0 to become NULL */ 6423 pf_route6(m0, r, dir, ifp, s); 6424 6425#ifdef __FreeBSD__ 6426 PF_UNLOCK(); 6427#endif 6428 return (action); 6429} 6430#endif /* INET6 */ |