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
|
6 * Copyright (c) 2002,2003 Henning Brauer |
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. 15 * - Redistributions in binary form must reproduce the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer in the documentation and/or other materials provided 18 * with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * 33 * Effort sponsored in part by the Defense Advanced Research Projects 34 * Agency (DARPA) and Air Force Research Laboratory, Air Force 35 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 36 * 37 */ 38 39#ifdef __FreeBSD__ 40#include "opt_inet.h" 41#include "opt_inet6.h" 42#endif 43 44#ifdef __FreeBSD__ 45#include "opt_bpf.h" 46#include "opt_pf.h" 47#define NBPFILTER DEV_BPF 48#define NPFLOG DEV_PFLOG 49#define NPFSYNC DEV_PFSYNC 50#else 51#include "bpfilter.h" 52#include "pflog.h" 53#include "pfsync.h" 54#endif 55 56#include <sys/param.h> 57#include <sys/systm.h> 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> |
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> 75 76#include <netinet/in.h> 77#include <netinet/in_var.h> 78#include <netinet/in_systm.h> 79#include <netinet/ip.h> 80#include <netinet/ip_var.h> 81#include <netinet/tcp.h> 82#include <netinet/tcp_seq.h> 83#include <netinet/udp.h> 84#include <netinet/ip_icmp.h> 85#include <netinet/in_pcb.h> 86#include <netinet/tcp_timer.h> 87#include <netinet/tcp_var.h> 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 |
98#include <net/if_pfsync.h>
|
99#endif /* NPFSYNC > 0 */ |
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
|
112#ifdef __FreeBSD__ 113#include <machine/in_cksum.h>
|
113#if (__FreeBSD_version >= 500112)
|
114#include <sys/limits.h>
|
115#else
116#include <machine/limits.h>
117#endif
|
115#include <sys/ucred.h>
|
119#endif
|
116
|
121#ifdef __FreeBSD__
|
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);
|
118#endif
|
127#endif
|
119 120#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
|
130struct pf_state_tree;
|
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;
|
133 134u_int32_t ticket_altqs_active; 135u_int32_t ticket_altqs_inactive;
|
136int altqs_inactive_open; |
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; |
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; |
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
|
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 *, 162 u_int16_t, u_int8_t, sa_family_t); 163#ifdef INET6 164void pf_change_a6(struct pf_addr *, u_int16_t *, 165 struct pf_addr *, u_int8_t); 166#endif /* INET6 */ 167void pf_change_icmp(struct pf_addr *, u_int16_t *, 168 struct pf_addr *, struct pf_addr *, u_int16_t, 169 u_int16_t *, u_int16_t *, u_int16_t *, 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 *, |
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 **, |
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, |
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, |
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, |
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 *, |
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 *, |
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, |
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, |
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, |
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 *); |
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 *); |
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 *, |
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 *, |
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 **); |
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 *, |
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); |
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}; |
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); \ |
268 else \
|
276 *state = pf_find_state(&tree_lan_ext, &key); \
|
269 *state = pf_find_state_recurse( \ 270 kif, &key, PF_LAN_EXT); \ |
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) \ |
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) |
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
|
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 |
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) |
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 |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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]) |
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) |
429 return (diff);
|
369 if ((diff = a->port[1] - b->port[1]) != 0)
|
430 if ((diff = a->ext.port - b->ext.port) != 0) |
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 */ |
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 |
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; 536#endif /* INET */ 537 case AF_INET6: 538 dst->addr32[0] = src->addr32[0]; 539 dst->addr32[1] = src->addr32[1]; 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) |
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} |
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 |
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 } |
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 } |
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 |
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) |
624{
|
411 struct pf_tree_node *keya, *keyb;
|
625 struct pf_src_node k; |
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} |
679
|
680int 681pf_insert_state(struct pfi_kif *kif, struct pf_state *state) 682{ |
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)) { |
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)"); |
699 printf("\n"); 700 }
|
439 pool_put(&pf_tree_pl, keya);
|
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)) { |
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)"); |
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); |
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 |
750 pf_status.fcounters[FCNT_STATE_INSERT]++; 751 pf_status.states++;
|
752 pfi_attach_state(kif); |
753#if NPFSYNC 754 pfsync_insert_state(state); 755#endif 756 return (0); 757} 758 759void 760pf_purge_timeout(void *arg) 761{ 762#ifdef __FreeBSD__ 763 struct callout *to = arg; 764#else 765 struct timeout *to = arg; 766#endif 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(); |
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); 784#else 785 timeout_add(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz); 786#endif 787} 788 789u_int32_t 790pf_state_expires(const struct pf_state *state) 791{ 792 u_int32_t timeout; 793 u_int32_t start; 794 u_int32_t end; 795 u_int32_t states; 796 797 /* handle all PFTM_* > PFTM_MAX here */ 798 if (state->timeout == PFTM_PURGE) 799#ifdef __FreeBSD__ 800 return (time_second); 801#else 802 return (time.tv_sec); 803#endif 804 if (state->timeout == PFTM_UNTIL_PACKET) 805 return (0); 806#ifdef __FreeBSD__ 807 KASSERT((state->timeout < PFTM_MAX), 808 ("pf_state_expires: timeout > PFTM_MAX")); 809#else 810 KASSERT(state->timeout < PFTM_MAX); 811#endif 812 timeout = state->rule.ptr->timeout[state->timeout]; 813 if (!timeout) 814 timeout = pf_default_rule.timeout[state->timeout]; 815 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START]; 816 if (start) { 817 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END]; 818 states = state->rule.ptr->states; 819 } else { 820 start = pf_default_rule.timeout[PFTM_ADAPTIVE_START]; 821 end = pf_default_rule.timeout[PFTM_ADAPTIVE_END]; 822 states = pf_status.states; 823 } 824 if (end && states > start && start < end) { 825 if (states < end) 826 return (state->expire + timeout * (end - states) / 827 (end - start)); 828 else 829#ifdef __FreeBSD__ 830 return (time_second); 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) |
840{
|
567 struct pf_tree_node *cur, *peer, *next;
568 struct pf_tree_node key;
|
841 struct pf_src_node *cur, *next; |
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); |
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) { |
848#else
|
576 if (pf_state_expires(cur->state) <= time.tv_sec) {
|
849 if (cur->states <= 0 && cur->expire <= time.tv_sec) { |
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} |
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; |
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]; |
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; |
878#else
|
608 KASSERT(peer);
609 KASSERT(peer->state == cur->state);
|
879 s->src_node->expire = time.tv_sec + timeout; |
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} |
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); |
924#if NPFSYNC
|
614 pfsync_delete_state(cur->state);
|
925 pfsync_delete_state(cur); |
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); |
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) 950{ 951 if (aw->type != PF_ADDR_TABLE) 952 return (0); 953 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL) 954 return (1); 955 return (0); 956} 957 958void 959pf_tbladdr_remove(struct pf_addr_wrap *aw) 960{ 961 if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL) 962 return; 963 pfr_detach_table(aw->p.tbl); 964 aw->p.tbl = NULL; 965} 966 967void 968pf_tbladdr_copyout(struct pf_addr_wrap *aw) 969{ 970 struct pfr_ktable *kt = aw->p.tbl; 971 972 if (aw->type != PF_ADDR_TABLE || kt == NULL) 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__
|
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
|
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); 990 if (p) { 991 p = ntohs(p); 992 printf(":%u", p); 993 } 994 break; 995 } 996#endif /* INET */ 997#ifdef INET6 998 case AF_INET6: { 999 u_int16_t b; 1000 u_int8_t i, curstart = 255, curend = 0, 1001 maxstart = 0, maxend = 0; 1002 for (i = 0; i < 8; i++) { 1003 if (!addr->addr16[i]) { 1004 if (curstart == 255) 1005 curstart = i; 1006 else 1007 curend = i; 1008 } else { 1009 if (curstart) { 1010 if ((curend - curstart) > 1011 (maxend - maxstart)) { 1012 maxstart = curstart; 1013 maxend = curend; 1014 curstart = 255; 1015 } 1016 } 1017 } 1018 } 1019 for (i = 0; i < 8; i++) { 1020 if (i >= maxstart && i <= maxend) { 1021 if (maxend != 7) { 1022 if (i == maxstart) 1023 printf(":"); 1024 } else { 1025 if (i == maxend) 1026 printf(":"); 1027 } 1028 } else { 1029 b = ntohs(addr->addr16[i]); 1030 printf("%x", b); 1031 if (i < 7) 1032 printf(":"); 1033 } 1034 } 1035 if (p) { 1036 p = ntohs(p); 1037 printf("[%u]", p); 1038 } 1039 break; 1040 } 1041#endif /* INET6 */ 1042 } 1043} 1044 1045void 1046pf_print_state(struct pf_state *s) 1047{ 1048 switch (s->proto) { 1049 case IPPROTO_TCP: 1050 printf("TCP "); 1051 break; 1052 case IPPROTO_UDP: 1053 printf("UDP "); 1054 break; 1055 case IPPROTO_ICMP: 1056 printf("ICMP "); 1057 break; 1058 case IPPROTO_ICMPV6: 1059 printf("ICMPV6 "); 1060 break; 1061 default: 1062 printf("%u ", s->proto); 1063 break; 1064 } 1065 pf_print_host(&s->lan.addr, s->lan.port, s->af); 1066 printf(" "); 1067 pf_print_host(&s->gwy.addr, s->gwy.port, s->af); 1068 printf(" "); 1069 pf_print_host(&s->ext.addr, s->ext.port, s->af); 1070 printf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo, 1071 s->src.seqhi, s->src.max_win, s->src.seqdiff); 1072 if (s->src.wscale && s->dst.wscale) 1073 printf(" wscale=%u", s->src.wscale & PF_WSCALE_MASK); 1074 printf("]"); 1075 printf(" [lo=%u high=%u win=%u modulator=%u", s->dst.seqlo, 1076 s->dst.seqhi, s->dst.max_win, s->dst.seqdiff); 1077 if (s->src.wscale && s->dst.wscale) 1078 printf(" wscale=%u", s->dst.wscale & PF_WSCALE_MASK); 1079 printf("]"); 1080 printf(" %u:%u", s->src.state, s->dst.state); 1081} 1082 1083void 1084pf_print_flags(u_int8_t f) 1085{ 1086 if (f) 1087 printf(" "); 1088 if (f & TH_FIN) 1089 printf("F"); 1090 if (f & TH_SYN) 1091 printf("S"); 1092 if (f & TH_RST) 1093 printf("R"); 1094 if (f & TH_PUSH) 1095 printf("P"); 1096 if (f & TH_ACK) 1097 printf("A"); 1098 if (f & TH_URG) 1099 printf("U"); 1100 if (f & TH_ECE) 1101 printf("E"); 1102 if (f & TH_CWR) 1103 printf("W"); 1104} 1105 1106#define PF_SET_SKIP_STEPS(i) \ 1107 do { \ 1108 while (head[i] != cur) { \ 1109 head[i]->skip[i].ptr = cur; \ 1110 head[i] = TAILQ_NEXT(head[i], entries); \ 1111 } \ 1112 } while (0) 1113 1114void 1115pf_calc_skip_steps(struct pf_rulequeue *rules) 1116{ 1117 struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT]; 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) |
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 || 1135 pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr)) 1136 PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR); 1137 if (cur->src.port[0] != prev->src.port[0] || 1138 cur->src.port[1] != prev->src.port[1] || 1139 cur->src.port_op != prev->src.port_op) 1140 PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT); 1141 if (cur->dst.not != prev->dst.not || 1142 pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr)) 1143 PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR); 1144 if (cur->dst.port[0] != prev->dst.port[0] || 1145 cur->dst.port[1] != prev->dst.port[1] || 1146 cur->dst.port_op != prev->dst.port_op) 1147 PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT); 1148 1149 prev = cur; 1150 cur = TAILQ_NEXT(cur, entries); 1151 } 1152 for (i = 0; i < PF_SKIP_COUNT; ++i) 1153 PF_SET_SKIP_STEPS(i); 1154} 1155 1156int 1157pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2) 1158{ 1159 if (aw1->type != aw2->type) 1160 return (1); 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); |
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
|
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) 1189 if (rule->anchorname[0]) 1190 rule->anchor = pf_find_anchor(rule->anchorname); 1191 else 1192 rule->anchor = NULL; 1193} 1194 1195u_int16_t 1196pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp) 1197{ 1198 u_int32_t l; 1199 1200 if (udp && !cksum) 1201 return (0x0000); 1202 l = cksum + old - new; 1203 l = (l >> 16) + (l & 65535); 1204 l = l & 65535; 1205 if (udp && !l) 1206 return (0xFFFF); 1207 return (l); 1208} 1209 1210void 1211pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc, 1212 struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af) 1213{ 1214 struct pf_addr ao; 1215 u_int16_t po = *p; 1216 1217 PF_ACPY(&ao, a, af); 1218 PF_ACPY(a, an, af); 1219 1220 *p = pn; 1221 1222 switch (af) { 1223#ifdef INET 1224 case AF_INET: 1225 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic, 1226 ao.addr16[0], an->addr16[0], 0), 1227 ao.addr16[1], an->addr16[1], 0); 1228 *p = pn; 1229 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc, 1230 ao.addr16[0], an->addr16[0], u), 1231 ao.addr16[1], an->addr16[1], u), 1232 po, pn, u); 1233 break; 1234#endif /* INET */ 1235#ifdef INET6 1236 case AF_INET6: 1237 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1238 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1239 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc, 1240 ao.addr16[0], an->addr16[0], u), 1241 ao.addr16[1], an->addr16[1], u), 1242 ao.addr16[2], an->addr16[2], u), 1243 ao.addr16[3], an->addr16[3], u), 1244 ao.addr16[4], an->addr16[4], u), 1245 ao.addr16[5], an->addr16[5], u), 1246 ao.addr16[6], an->addr16[6], u), 1247 ao.addr16[7], an->addr16[7], u), 1248 po, pn, u); 1249 break; 1250#endif /* INET6 */ 1251 } 1252} 1253 1254 1255/* Changes a u_int32_t. Uses a void * so there are no align restrictions */ 1256void 1257pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u) 1258{ 1259 u_int32_t ao; 1260 1261 memcpy(&ao, a, sizeof(ao)); 1262 memcpy(a, &an, sizeof(u_int32_t)); 1263 *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u), 1264 ao % 65536, an % 65536, u); 1265} 1266 1267#ifdef INET6 1268void 1269pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u) 1270{ 1271 struct pf_addr ao; 1272 1273 PF_ACPY(&ao, a, AF_INET6); 1274 PF_ACPY(a, an, AF_INET6); 1275 1276 *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1277 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1278 pf_cksum_fixup(pf_cksum_fixup(*c, 1279 ao.addr16[0], an->addr16[0], u), 1280 ao.addr16[1], an->addr16[1], u), 1281 ao.addr16[2], an->addr16[2], u), 1282 ao.addr16[3], an->addr16[3], u), 1283 ao.addr16[4], an->addr16[4], u), 1284 ao.addr16[5], an->addr16[5], u), 1285 ao.addr16[6], an->addr16[6], u), 1286 ao.addr16[7], an->addr16[7], u); 1287} 1288#endif /* INET6 */ 1289 1290void 1291pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa, 1292 struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c, 1293 u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af) 1294{ 1295 struct pf_addr oia, ooa; 1296 1297 PF_ACPY(&oia, ia, af); 1298 PF_ACPY(&ooa, oa, af); 1299 1300 /* Change inner protocol port, fix inner protocol checksum. */ 1301 if (ip != NULL) { 1302 u_int16_t oip = *ip; 1303 u_int32_t opc = 0; /* make the compiler happy */ 1304 1305 if (pc != NULL) 1306 opc = *pc; 1307 *ip = np; 1308 if (pc != NULL) 1309 *pc = pf_cksum_fixup(*pc, oip, *ip, u); 1310 *ic = pf_cksum_fixup(*ic, oip, *ip, 0); 1311 if (pc != NULL) 1312 *ic = pf_cksum_fixup(*ic, opc, *pc, 0); 1313 } 1314 /* Change inner ip address, fix inner ip and icmp checksums. */ 1315 PF_ACPY(ia, na, af); 1316 switch (af) { 1317#ifdef INET 1318 case AF_INET: { 1319 u_int32_t oh2c = *h2c; 1320 1321 *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c, 1322 oia.addr16[0], ia->addr16[0], 0), 1323 oia.addr16[1], ia->addr16[1], 0); 1324 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic, 1325 oia.addr16[0], ia->addr16[0], 0), 1326 oia.addr16[1], ia->addr16[1], 0); 1327 *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0); 1328 break; 1329 } 1330#endif /* INET */ 1331#ifdef INET6 1332 case AF_INET6: 1333 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1334 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1335 pf_cksum_fixup(pf_cksum_fixup(*ic, 1336 oia.addr16[0], ia->addr16[0], u), 1337 oia.addr16[1], ia->addr16[1], u), 1338 oia.addr16[2], ia->addr16[2], u), 1339 oia.addr16[3], ia->addr16[3], u), 1340 oia.addr16[4], ia->addr16[4], u), 1341 oia.addr16[5], ia->addr16[5], u), 1342 oia.addr16[6], ia->addr16[6], u), 1343 oia.addr16[7], ia->addr16[7], u); 1344 break; 1345#endif /* INET6 */ 1346 } 1347 /* Change outer ip address, fix outer ip or icmpv6 checksum. */ 1348 PF_ACPY(oa, na, af); 1349 switch (af) { 1350#ifdef INET 1351 case AF_INET: 1352 *hc = pf_cksum_fixup(pf_cksum_fixup(*hc, 1353 ooa.addr16[0], oa->addr16[0], 0), 1354 ooa.addr16[1], oa->addr16[1], 0); 1355 break; 1356#endif /* INET */ 1357#ifdef INET6 1358 case AF_INET6: 1359 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1360 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 1361 pf_cksum_fixup(pf_cksum_fixup(*ic, 1362 ooa.addr16[0], oa->addr16[0], u), 1363 ooa.addr16[1], oa->addr16[1], u), 1364 ooa.addr16[2], oa->addr16[2], u), 1365 ooa.addr16[3], oa->addr16[3], u), 1366 ooa.addr16[4], oa->addr16[4], u), 1367 ooa.addr16[5], oa->addr16[5], u), 1368 ooa.addr16[6], oa->addr16[6], u), 1369 ooa.addr16[7], oa->addr16[7], u); 1370 break; 1371#endif /* INET6 */ 1372 } 1373} 1374 1375void 1376pf_send_tcp(const struct pf_rule *r, sa_family_t af, 1377 const struct pf_addr *saddr, const struct pf_addr *daddr, 1378 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack, 1379 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl) 1380{ 1381 struct mbuf *m; 1382 struct m_tag *mtag; 1383 int len = 0, tlen; /* make the compiler happy */ 1384#ifdef INET 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;
|
1393#endif
|
1238#endif
|
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) { 1402#ifdef INET 1403 case AF_INET: 1404 len = sizeof(struct ip) + tlen; 1405 break; 1406#endif /* INET */ 1407#ifdef INET6 1408 case AF_INET6: 1409 len = sizeof(struct ip6_hdr) + tlen; 1410 break; 1411#endif /* INET6 */ 1412 } 1413 1414 /* create outgoing mbuf */ 1415 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 1416 if (mtag == NULL) 1417 return; 1418 m = m_gethdr(M_DONTWAIT, MT_HEADER); 1419 if (m == NULL) { 1420 m_tag_free(mtag); 1421 return; 1422 } 1423 m_tag_prepend(m, mtag); 1424#ifdef ALTQ 1425 if (r != NULL && r->qid) { 1426 struct altq_tag *atag; 1427 1428 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); 1429 if (mtag != NULL) { 1430 atag = (struct altq_tag *)(mtag + 1); 1431 atag->qid = r->qid; 1432 /* add hints for ecn */ 1433 atag->af = af; 1434 atag->hdr = mtod(m, struct ip *); 1435 m_tag_prepend(m, mtag); 1436 } 1437 } 1438#endif 1439 m->m_data += max_linkhdr; 1440 m->m_pkthdr.len = m->m_len = len; 1441 m->m_pkthdr.rcvif = NULL; 1442 bzero(m->m_data, len); 1443 switch (af) { 1444#ifdef INET 1445 case AF_INET: 1446 h = mtod(m, struct ip *); 1447 1448 /* IP header fields included in the TCP checksum */ 1449 h->ip_p = IPPROTO_TCP; 1450 h->ip_len = htons(tlen); 1451 h->ip_src.s_addr = saddr->v4.s_addr; 1452 h->ip_dst.s_addr = daddr->v4.s_addr; 1453 1454 th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip)); 1455 break; 1456#endif /* INET */ 1457#ifdef INET6 1458 case AF_INET6: 1459 h6 = mtod(m, struct ip6_hdr *); 1460 1461 /* IP header fields included in the TCP checksum */ 1462 h6->ip6_nxt = IPPROTO_TCP; 1463 h6->ip6_plen = htons(tlen); 1464 memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr)); 1465 memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr)); 1466 1467 th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr)); 1468 break; 1469#endif /* INET6 */ 1470 } 1471 1472 /* TCP header */ 1473 th->th_sport = sport; 1474 th->th_dport = dport; 1475 th->th_seq = htonl(seq); 1476 th->th_ack = htonl(ack); 1477 th->th_off = tlen >> 2; 1478 th->th_flags = flags; 1479 th->th_win = htons(win); 1480 1481 if (mss) { 1482 opt = (char *)(th + 1); 1483 opt[0] = TCPOPT_MAXSEG; 1484 opt[1] = 4; 1485 HTONS(mss); 1486 bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2); 1487 } 1488 1489 switch (af) { 1490#ifdef INET 1491 case AF_INET: 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; |
1502#else 1503 h->ip_off = htons(ip_mtudisc ? IP_DF : 0);
|
1348#endif
|
1504 h->ip_len = htons(len);
|
1505#endif |
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);
|
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();
|
1511 ip_output(m, (void *)NULL, (void *)NULL, 0, (void *)NULL, 1512 (void *)NULL); 1513 PF_LOCK();
|
1377#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: 1522 /* TCP checksum */ 1523 th->th_sum = in6_cksum(m, IPPROTO_TCP, 1524 sizeof(struct ip6_hdr), tlen); 1525 1526 h6->ip6_vfc |= IPV6_VERSION; 1527 h6->ip6_hlim = IPV6_DEFHLIM; 1528 1529#ifdef __FreeBSD__ 1530 PF_UNLOCK(); 1531 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); 1532 PF_LOCK(); 1533#else 1534 ip6_output(m, NULL, NULL, 0, NULL, NULL); 1535#endif 1536 break; 1537#endif /* INET6 */ 1538 } 1539} 1540 1541void 1542pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, 1543 struct pf_rule *r) 1544{ 1545 struct m_tag *mtag; 1546 struct mbuf *m0; 1547#ifdef __FreeBSD__ 1548 struct ip *ip; 1549#endif 1550 1551 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 1552 if (mtag == NULL) 1553 return; 1554#ifdef __FreeBSD__ 1555 m0 = m_copypacket(m, M_DONTWAIT); 1556#else 1557 m0 = m_copy(m, 0, M_COPYALL); 1558#endif 1559 if (m0 == NULL) { 1560 m_tag_free(mtag); 1561 return; 1562 } 1563 m_tag_prepend(m0, mtag); 1564 1565#ifdef ALTQ 1566 if (r->qid) { 1567 struct altq_tag *atag; 1568 1569 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); 1570 if (mtag != NULL) { 1571 atag = (struct altq_tag *)(mtag + 1); 1572 atag->qid = r->qid; 1573 /* add hints for ecn */ 1574 atag->af = af; 1575 atag->hdr = mtod(m0, struct ip *); 1576 m_tag_prepend(m0, mtag); 1577 } 1578 } 1579#endif 1580 1581 switch (af) { 1582#ifdef INET 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); |
1592#ifdef __FreeBSD__ 1593 PF_LOCK(); 1594#endif 1595 break; 1596#endif /* INET */ 1597#ifdef INET6 1598 case AF_INET6: 1599#ifdef __FreeBSD__ 1600 PF_UNLOCK(); 1601#endif 1602 icmp6_error(m0, type, code, 0); 1603#ifdef __FreeBSD__ 1604 PF_LOCK(); 1605#endif 1606 break; 1607#endif /* INET6 */ 1608 } 1609} 1610 1611/* 1612 * Return 1 if the addresses a and b match (with mask m), otherwise return 0. 1613 * If n is 0, they match if they are equal. If n is != 0, they match if they 1614 * are different. 1615 */ 1616int 1617pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m, 1618 struct pf_addr *b, sa_family_t af) 1619{ 1620 int match = 0; 1621 1622 switch (af) { 1623#ifdef INET 1624 case AF_INET: 1625 if ((a->addr32[0] & m->addr32[0]) == 1626 (b->addr32[0] & m->addr32[0])) 1627 match++; 1628 break; 1629#endif /* INET */ 1630#ifdef INET6 1631 case AF_INET6: 1632 if (((a->addr32[0] & m->addr32[0]) == 1633 (b->addr32[0] & m->addr32[0])) && 1634 ((a->addr32[1] & m->addr32[1]) == 1635 (b->addr32[1] & m->addr32[1])) && 1636 ((a->addr32[2] & m->addr32[2]) == 1637 (b->addr32[2] & m->addr32[2])) && 1638 ((a->addr32[3] & m->addr32[3]) == 1639 (b->addr32[3] & m->addr32[3]))) 1640 match++; 1641 break; 1642#endif /* INET6 */ 1643 } 1644 if (match) { 1645 if (n) 1646 return (0); 1647 else 1648 return (1); 1649 } else { 1650 if (n) 1651 return (1); 1652 else 1653 return (0); 1654 } 1655} 1656 1657int 1658pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p) 1659{ 1660 switch (op) { 1661 case PF_OP_IRG: 1662 return ((p > a1) && (p < a2)); 1663 case PF_OP_XRG: 1664 return ((p < a1) || (p > a2)); 1665 case PF_OP_RRG: 1666 return ((p >= a1) && (p <= a2)); 1667 case PF_OP_EQ: 1668 return (p == a1); 1669 case PF_OP_NE: 1670 return (p != a1); 1671 case PF_OP_LT: 1672 return (p < a1); 1673 case PF_OP_LE: 1674 return (p <= a1); 1675 case PF_OP_GT: 1676 return (p > a1); 1677 case PF_OP_GE: 1678 return (p >= a1); 1679 } 1680 return (0); /* never reached */ 1681} 1682 1683int 1684pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p) 1685{ 1686 NTOHS(a1); 1687 NTOHS(a2); 1688 NTOHS(p); 1689 return (pf_match(op, a1, a2, p)); 1690} 1691 1692int 1693pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u) 1694{ 1695 if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 1696 return (0); 1697 return (pf_match(op, a1, a2, u)); 1698} 1699 1700int 1701pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g) 1702{ 1703 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 1704 return (0); 1705 return (pf_match(op, a1, a2, g)); 1706} 1707 1708struct pf_tag * 1709pf_get_tag(struct mbuf *m) 1710{ 1711 struct m_tag *mtag; 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) |
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; |
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) 1739{ 1740 struct m_tag *mtag; 1741 1742 if (tag <= 0) 1743 return (0); 1744 1745 if (pftag == NULL) { 1746 mtag = m_tag_get(PACKET_TAG_PF_TAG, sizeof(*pftag), M_NOWAIT); 1747 if (mtag == NULL) 1748 return (1); 1749 ((struct pf_tag *)(mtag + 1))->tag = tag; 1750 m_tag_prepend(m, mtag); 1751 } else 1752 pftag->tag = tag; 1753 1754 return (0); 1755} 1756 1757#define PF_STEP_INTO_ANCHOR(r, a, s, n) \ 1758 do { \ 1759 if ((r) == NULL || (r)->anchor == NULL || \ 1760 (s) != NULL || (a) != NULL) \ 1761 panic("PF_STEP_INTO_ANCHOR"); \ 1762 (a) = (r); \ 1763 (s) = TAILQ_FIRST(&(r)->anchor->rulesets); \ 1764 (r) = NULL; \ 1765 while ((s) != NULL && ((r) = \ 1766 TAILQ_FIRST((s)->rules[n].active.ptr)) == NULL) \ 1767 (s) = TAILQ_NEXT((s), entries); \ 1768 if ((r) == NULL) { \ 1769 (r) = TAILQ_NEXT((a), entries); \ 1770 (a) = NULL; \ 1771 } \ 1772 } while (0) 1773 1774#define PF_STEP_OUT_OF_ANCHOR(r, a, s, n) \ 1775 do { \ 1776 if ((r) != NULL || (a) == NULL || (s) == NULL) \ 1777 panic("PF_STEP_OUT_OF_ANCHOR"); \ 1778 (s) = TAILQ_NEXT((s), entries); \ 1779 while ((s) != NULL && ((r) = \ 1780 TAILQ_FIRST((s)->rules[n].active.ptr)) == NULL) \ 1781 (s) = TAILQ_NEXT((s), entries); \ 1782 if ((r) == NULL) { \ 1783 (r) = TAILQ_NEXT((a), entries); \ 1784 (a) = NULL; \ 1785 } \ 1786 } while (0) 1787 1788#ifdef INET6 1789void 1790pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr, 1791 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af) 1792{ 1793 switch (af) { 1794#ifdef INET 1795 case AF_INET: 1796 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) | 1797 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]); 1798 break; 1799#endif /* INET */ 1800 case AF_INET6: 1801 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) | 1802 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]); 1803 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) | 1804 ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]); 1805 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) | 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) |
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: 1823 if (addr->addr32[3] == 0xffffffff) { 1824 addr->addr32[3] = 0; 1825 if (addr->addr32[2] == 0xffffffff) { 1826 addr->addr32[2] = 0; 1827 if (addr->addr32[1] == 0xffffffff) { 1828 addr->addr32[1] = 0; 1829 addr->addr32[0] = 1830 htonl(ntohl(addr->addr32[0]) + 1); 1831 } else 1832 addr->addr32[1] = 1833 htonl(ntohl(addr->addr32[1]) + 1); 1834 } else 1835 addr->addr32[2] = 1836 htonl(ntohl(addr->addr32[2]) + 1); 1837 } else 1838 addr->addr32[3] = 1839 htonl(ntohl(addr->addr32[3]) + 1); 1840 break; 1841 } 1842} 1843#endif /* INET6 */ 1844 1845#define mix(a,b,c) \ 1846 do { \ 1847 a -= b; a -= c; a ^= (c >> 13); \ 1848 b -= c; b -= a; b ^= (a << 8); \ 1849 c -= a; c -= b; c ^= (b >> 13); \ 1850 a -= b; a -= c; a ^= (c >> 12); \ 1851 b -= c; b -= a; b ^= (a << 16); \ 1852 c -= a; c -= b; c ^= (b >> 5); \ 1853 a -= b; a -= c; a ^= (c >> 3); \ 1854 b -= c; b -= a; b ^= (a << 10); \ 1855 c -= a; c -= b; c ^= (b >> 15); \ 1856 } while (0) 1857 1858/* 1859 * hash function based on bridge_hash in if_bridge.c 1860 */ 1861void 1862pf_hash(struct pf_addr *inaddr, struct pf_addr *hash, 1863 struct pf_poolhashkey *key, sa_family_t af) 1864{ 1865 u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0]; 1866 1867 switch (af) { 1868#ifdef INET 1869 case AF_INET: 1870 a += inaddr->addr32[0]; 1871 b += key->key32[1]; 1872 mix(a, b, c); 1873 hash->addr32[0] = c + key->key32[2]; 1874 break; 1875#endif /* INET */ 1876#ifdef INET6 1877 case AF_INET6: 1878 a += inaddr->addr32[0]; 1879 b += inaddr->addr32[2]; 1880 mix(a, b, c); 1881 hash->addr32[0] = c; 1882 a += inaddr->addr32[1]; 1883 b += inaddr->addr32[3]; 1884 c += key->key32[1]; 1885 mix(a, b, c); 1886 hash->addr32[1] = c; 1887 a += inaddr->addr32[2]; 1888 b += inaddr->addr32[1]; 1889 c += key->key32[2]; 1890 mix(a, b, c); 1891 hash->addr32[2] = c; 1892 a += inaddr->addr32[3]; 1893 b += inaddr->addr32[0]; 1894 c += key->key32[3]; 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) |
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; |
1910 struct pf_pooladdr *acur = rpool->cur;
|
1911 struct pf_src_node k; |
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 |
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) { |
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) { 1964 case PF_POOL_NONE: 1965 PF_ACPY(naddr, raddr, af); 1966 break; 1967 case PF_POOL_BITMASK: 1968 PF_POOLMASK(naddr, raddr, rmask, saddr, af); 1969 break; 1970 case PF_POOL_RANDOM: 1971 if (init_addr != NULL && PF_AZERO(init_addr, af)) { 1972 switch (af) { 1973#ifdef INET 1974 case AF_INET: 1975 rpool->counter.addr32[0] = arc4random(); 1976 break; 1977#endif /* INET */ 1978#ifdef INET6 1979 case AF_INET6: 1980 if (rmask->addr32[3] != 0xffffffff) 1981 rpool->counter.addr32[3] = arc4random(); 1982 else 1983 break; 1984 if (rmask->addr32[2] != 0xffffffff) 1985 rpool->counter.addr32[2] = arc4random(); 1986 else 1987 break; 1988 if (rmask->addr32[1] != 0xffffffff) 1989 rpool->counter.addr32[1] = arc4random(); 1990 else 1991 break; 1992 if (rmask->addr32[0] != 0xffffffff) 1993 rpool->counter.addr32[0] = arc4random(); 1994 break; 1995#endif /* INET6 */ 1996 } 1997 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af); 1998 PF_ACPY(init_addr, naddr, af); 1999 2000 } else { 2001 PF_AINC(&rpool->counter, af); 2002 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af); 2003 } 2004 break; 2005 case PF_POOL_SRCHASH: 2006 pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af); 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; |
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' */ |
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 } |
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); |
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 "); |
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, |
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) |
2075{
|
1885 struct pf_tree_node key;
|
2076 struct pf_state key; |
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)) |
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; |
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) |
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) |
2102 return (0);
|
1912 }
|
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) { |
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) == |
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) == |
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) { |
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)) |
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;
|
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, |
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; 2166 struct pf_addr_wrap *xdst = NULL; 2167 2168 if (r->action == PF_BINAT && direction == PF_IN) { 2169 src = &r->dst; 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) |
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)) 2188 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR : 2189 PF_SKIP_DST_ADDR].ptr; 2190 else if (src->port_op && !pf_match_port(src->port_op, 2191 src->port[0], src->port[1], sport)) 2192 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT : 2193 PF_SKIP_DST_PORT].ptr; 2194 else if (dst != NULL && 2195 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->not)) 2196 r = r->skip[PF_SKIP_DST_ADDR].ptr; 2197 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, 0)) 2198 r = TAILQ_NEXT(r, entries); 2199 else if (dst != NULL && dst->port_op && 2200 !pf_match_port(dst->port_op, dst->port[0], 2201 dst->port[1], dport)) 2202 r = r->skip[PF_SKIP_DST_PORT].ptr; 2203 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto != 2204 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m, 2205 off, pd->hdr.tcp), r->os_fingerprint))) 2206 r = TAILQ_NEXT(r, entries); 2207 else if (r->anchorname[0] && r->anchor == NULL) 2208 r = TAILQ_NEXT(r, entries); 2209 else if (r->anchor == NULL) 2210 rm = r; 2211 else 2212 PF_STEP_INTO_ANCHOR(r, anchorrule, ruleset, rs_num); 2213 if (r == NULL && anchorrule != NULL) 2214 PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset, 2215 rs_num); 2216 } 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, |
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, |
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, |
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, |
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, |
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;
|
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, |
2254 daddr, dport, naddr, nport, r->rpool.proxy_port[0],
|
2067 r->rpool.proxy_port[1])) {
|
2255 r->rpool.proxy_port[1], sn)) { |
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 |
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 |
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)) |
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] - 2336 r->rpool.proxy_port[0] + 1)) + 2337 r->rpool.proxy_port[0]; 2338 2339 /* wrap around if necessary */ 2340 if (tmp_nport > 65535) 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;
|
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) |
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) { |
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 2378 break; 2379 case IPPROTO_UDP: 2380 sport = pd->hdr.udp->uh_sport; 2381 dport = pd->hdr.udp->uh_dport; 2382#ifdef __FreeBSD__ 2383 pi = &udbinfo; 2384#else 2385 tb = &udbtable; 2386#endif 2387 break; 2388 default: 2389 return (0); 2390 } 2391 if (direction == PF_IN) { 2392 saddr = pd->src; 2393 daddr = pd->dst; 2394 } else { 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) { |
2404 case AF_INET: 2405#ifdef __FreeBSD__
|
2183#if (__FreeBSD_version >= 500043)
|
2406 INP_INFO_RLOCK(pi); /* XXX LOR */
|
2185#endif
|
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)
|
2413 INP_INFO_RUNLOCK(pi);
|
2194#endif
|
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); |
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)
|
2429 INP_INFO_RLOCK(pi);
|
2213#endif
|
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)
|
2436 INP_INFO_RUNLOCK(pi);
|
2222#endif
|
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); |
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)
|
2456 INP_LOCK(inp);
|
2245#endif
|
2457 *uid = inp->inp_socket->so_cred->cr_uid; 2458 *gid = inp->inp_socket->so_cred->cr_groups[0];
|
2248#if (__FreeBSD_version >= 500043)
|
2459 INP_UNLOCK(inp); 2460 INP_INFO_RUNLOCK(pi);
|
2251#endif
|
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 2469pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 2470{ 2471 int hlen; 2472 u_int8_t hdr[60]; 2473 u_int8_t *opt, optlen; 2474 u_int8_t wscale = 0; 2475 2476 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 2477 if (hlen <= sizeof(struct tcphdr)) 2478 return (0); 2479 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 2480 return (0); 2481 opt = hdr + sizeof(struct tcphdr); 2482 hlen -= sizeof(struct tcphdr); 2483 while (hlen >= 3) { 2484 switch (*opt) { 2485 case TCPOPT_EOL: 2486 case TCPOPT_NOP: 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 */ |
2496 default: 2497 optlen = opt[1]; 2498 if (optlen < 2) 2499 optlen = 2; 2500 hlen -= optlen; 2501 opt += optlen;
|
2502 break; |
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{ 2511 int hlen; 2512 u_int8_t hdr[60]; 2513 u_int8_t *opt, optlen; 2514 u_int16_t mss = tcp_mssdflt; 2515 2516 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 2517 if (hlen <= sizeof(struct tcphdr)) 2518 return (0); 2519 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 2520 return (0); 2521 opt = hdr + sizeof(struct tcphdr); 2522 hlen -= sizeof(struct tcphdr); 2523 while (hlen >= TCPOLEN_MAXSEG) { 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 */ |
2533 default: 2534 optlen = opt[1]; 2535 if (optlen < 2) 2536 optlen = 2; 2537 hlen -= optlen; 2538 opt += optlen;
|
2539 break; |
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{ 2548#ifdef INET 2549 struct sockaddr_in *dst; 2550 struct route ro; 2551#endif /* INET */ 2552#ifdef INET6 2553 struct sockaddr_in6 *dst6; 2554 struct route_in6 ro6; 2555#endif /* INET6 */ 2556 struct rtentry *rt = NULL; 2557 int hlen = 0; /* make the compiler happy */ 2558 u_int16_t mss = tcp_mssdflt; 2559 2560 switch (af) { 2561#ifdef INET 2562 case AF_INET: 2563 hlen = sizeof(struct ip); 2564 bzero(&ro, sizeof(ro)); 2565 dst = (struct sockaddr_in *)&ro.ro_dst; 2566 dst->sin_family = AF_INET; 2567 dst->sin_len = sizeof(*dst); 2568 dst->sin_addr = addr->v4; 2569#ifdef __FreeBSD__ 2570#ifdef RTF_PRCLONING 2571 rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING)); 2572#else /* !RTF_PRCLONING */ 2573 rtalloc_ign(&ro, RTF_CLONING); 2574#endif 2575#else /* ! __FreeBSD__ */ 2576 rtalloc_noclone(&ro, NO_CLONING); 2577#endif 2578 rt = ro.ro_rt; 2579 break; 2580#endif /* INET */ 2581#ifdef INET6 2582 case AF_INET6: 2583 hlen = sizeof(struct ip6_hdr); 2584 bzero(&ro6, sizeof(ro6)); 2585 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst; 2586 dst6->sin6_family = AF_INET6; 2587 dst6->sin6_len = sizeof(*dst6); 2588 dst6->sin6_addr = addr->v6; 2589#ifdef __FreeBSD__ 2590#ifdef RTF_PRCLONING 2591 rtalloc_ign((struct route *)&ro6, 2592 (RTF_CLONING | RTF_PRCLONING)); 2593#else /* !RTF_PRCLONING */ 2594 rtalloc_ign((struct route *)&ro6, RTF_CLONING); 2595#endif 2596#else /* ! __FreeBSD__ */ 2597 rtalloc_noclone((struct route *)&ro6, NO_CLONING); 2598#endif 2599 rt = ro6.ro_rt; 2600 break; 2601#endif /* INET6 */ 2602 } 2603 2604 if (rt && rt->rt_ifp) { 2605 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr); 2606 mss = max(tcp_mssdflt, mss); 2607 RTFREE(rt); 2608 } 2609 mss = min(mss, offer); 2610 mss = max(mss, 64); /* sanity - at least max opt space */ 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; |
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; |
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; |
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, |
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; |
2646 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
|
2436 struct pf_addr baddr, naddr;
|
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; |
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, |
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); |
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); |
2673 rewrite++;
|
2463 if (nat->natpass)
|
2674 if (nr->natpass) |
2675 r = NULL;
|
2676 pd->nat_rule = nr; |
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); |
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); |
2687 rewrite++;
|
2476 if (rdr->natpass)
|
2688 if (nr->natpass) |
2689 r = NULL;
|
2690 pd->nat_rule = nr; |
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) |
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)) 2706 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 2707 else if (r->src.port_op && !pf_match_port(r->src.port_op, 2708 r->src.port[0], r->src.port[1], th->th_sport)) 2709 r = r->skip[PF_SKIP_SRC_PORT].ptr; 2710 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) 2711 r = r->skip[PF_SKIP_DST_ADDR].ptr; 2712 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 2713 r->dst.port[0], r->dst.port[1], th->th_dport)) 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)) && |
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)) && |
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)) |
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) 2740 tag = r->tag; 2741 if (r->anchor == NULL) { 2742 *rm = r; 2743 *am = a; 2744 *rsm = ruleset; 2745 if ((*rm)->quick) 2746 break; 2747 r = TAILQ_NEXT(r, entries); 2748 } else 2749 PF_STEP_INTO_ANCHOR(r, a, ruleset, 2750 PF_RULESET_FILTER); 2751 } 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 }
|
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); |
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 } |
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++; 2791 if (th->th_flags & TH_FIN) 2792 ack++; 2793 pf_send_tcp(r, af, pd->dst, 2794 pd->src, th->th_dport, th->th_sport, 2795 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0, 2796 r->return_ttl); 2797 } else if ((af == AF_INET) && r->return_icmp) 2798 pf_send_icmp(m, r->return_icmp >> 8, 2799 r->return_icmp & 255, af, r); 2800 else if ((af == AF_INET6) && r->return_icmp6) 2801 pf_send_icmp(m, r->return_icmp6 >> 8, 2802 r->return_icmp6 & 255, af, r); 2803 } 2804 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 || |
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; |
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); |
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 } |
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; |
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); |
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); |
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); 2896 s->src.seqhi = s->src.seqlo + len + 1; 2897 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 2898 r->keep_state == PF_STATE_MODULATE) { 2899 /* Generate sequence number modulator */ 2900 while ((s->src.seqdiff = arc4random()) == 0) 2901 ; 2902 pf_change_a(&th->th_seq, &th->th_sum, 2903 htonl(s->src.seqlo + s->src.seqdiff), 0); 2904 rewrite = 1; 2905 } else 2906 s->src.seqdiff = 0; 2907 if (th->th_flags & TH_SYN) { 2908 s->src.seqhi++; 2909 s->src.wscale = pf_get_wscale(m, off, th->th_off, af); 2910 } 2911 s->src.max_win = MAX(ntohs(th->th_win), 1); 2912 if (s->src.wscale & PF_WSCALE_MASK) { 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 */
|
2921 s->dst.seqhi = 1; 2922 s->dst.max_win = 1;
|
2692 s->dst.seqdiff = 0; /* Defer random generation */
|
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;
|
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 } |
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); |
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); |
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)) { |
2959 pf_normalize_tcp_cleanup(s); 2960 REASON_SET(&reason, PFRES_MEMORY);
|
2961 pf_src_tree_remove_state(s); |
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 } |
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); |
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, |
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; |
3006 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
|
2765 struct pf_addr baddr, naddr;
|
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; |
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, |
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); |
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); |
3032 rewrite++;
|
2791 if (nat->natpass)
|
3033 if (nr->natpass) |
3034 r = NULL;
|
3035 pd->nat_rule = nr; |
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); |
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); |
3046 rewrite++;
|
2804 if (rdr->natpass)
|
3047 if (nr->natpass) |
3048 r = NULL;
|
3049 pd->nat_rule = nr; |
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) |
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)) 3065 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3066 else if (r->src.port_op && !pf_match_port(r->src.port_op, 3067 r->src.port[0], r->src.port[1], uh->uh_sport)) 3068 r = r->skip[PF_SKIP_SRC_PORT].ptr; 3069 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.not)) 3070 r = r->skip[PF_SKIP_DST_ADDR].ptr; 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)) && |
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)) && |
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)) |
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; 3097 if (r->anchor == NULL) { 3098 *rm = r; 3099 *am = a; 3100 *rsm = ruleset; 3101 if ((*rm)->quick) 3102 break; 3103 r = TAILQ_NEXT(r, entries); 3104 } else 3105 PF_STEP_INTO_ANCHOR(r, a, ruleset, 3106 PF_RULESET_FILTER); 3107 } 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 }
|
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); |
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 } |
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) { |
3156 /* create new state */ 3157 struct pf_state *s = NULL;
|
3158 struct pf_src_node *sn = NULL; |
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); |
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 } |
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; |
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); |
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); |
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;
|
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;
|
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;
|
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)) { |
3253 REASON_SET(&reason, PFRES_MEMORY);
|
3254 pf_src_tree_remove_state(s); |
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, |
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; |
3274 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
|
3013 struct pf_addr baddr, naddr;
|
3275 struct pf_rule *r, *a = NULL; 3276 struct pf_ruleset *ruleset = NULL;
|
3277 struct pf_src_node *nsn = NULL; |
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; 3286#ifdef INET6 3287 int rewrite = 0; 3288#endif /* INET6 */ 3289 3290 switch (pd->proto) { 3291#ifdef INET 3292 case IPPROTO_ICMP: 3293 icmptype = pd->hdr.icmp->icmp_type; 3294 icmpcode = pd->hdr.icmp->icmp_code; 3295 icmpid = pd->hdr.icmp->icmp_id; 3296 3297 if (icmptype == ICMP_UNREACH || 3298 icmptype == ICMP_SOURCEQUENCH || 3299 icmptype == ICMP_REDIRECT || 3300 icmptype == ICMP_TIMXCEED || 3301 icmptype == ICMP_PARAMPROB) 3302 state_icmp++; 3303 break; 3304#endif /* INET */ 3305#ifdef INET6 3306 case IPPROTO_ICMPV6: 3307 icmptype = pd->hdr.icmp6->icmp6_type; 3308 icmpcode = pd->hdr.icmp6->icmp6_code; 3309 icmpid = pd->hdr.icmp6->icmp6_id; 3310 3311 if (icmptype == ICMP6_DST_UNREACH || 3312 icmptype == ICMP6_PACKET_TOO_BIG || 3313 icmptype == ICMP6_TIME_EXCEEDED || 3314 icmptype == ICMP6_PARAM_PROB) 3315 state_icmp++; 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); |
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); |
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); |
3338 rewrite++; 3339 break; 3340#endif /* INET6 */ 3341 }
|
3080 if (nat->natpass)
|
3342 if (nr->natpass) |
3343 r = NULL;
|
3344 pd->nat_rule = nr; |
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); |
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); |
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); |
3362 rewrite++; 3363 break; 3364#endif /* INET6 */ 3365 }
|
3103 if (rdr->natpass)
|
3366 if (nr->natpass) |
3367 r = NULL;
|
3368 pd->nat_rule = nr; |
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) |
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)) |
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; 3404 if (r->anchor == NULL) { 3405 *rm = r; 3406 *am = a; 3407 *rsm = ruleset; 3408 if ((*rm)->quick) 3409 break; 3410 r = TAILQ_NEXT(r, entries); 3411 } else 3412 PF_STEP_INTO_ANCHOR(r, a, ruleset, 3413 PF_RULESET_FILTER); 3414 } 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 }
|
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); |
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)) { |
3443 /* create new state */ 3444 struct pf_state *s = NULL;
|
3445 struct pf_src_node *sn = NULL; |
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); |
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 } |
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; |
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); |
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); |
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;
|
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;
|
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)) { |
3534 REASON_SET(&reason, PFRES_MEMORY);
|
3535 pf_src_tree_remove_state(s); |
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, |
3555 struct pf_rule **am, struct pf_ruleset **rsm) 3556{
|
3279 struct pf_rule *nat = NULL, *rdr = NULL;
|
3557 struct pf_rule *nr = NULL; |
3558 struct pf_rule *r, *a = NULL; 3559 struct pf_ruleset *ruleset = NULL;
|
3560 struct pf_src_node *nsn = NULL; |
3561 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
|
3283 struct pf_addr baddr, naddr;
|
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); |
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); |
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); |
3584 break; 3585#endif /* INET6 */ 3586 }
|
3309 if (nat->natpass)
|
3587 if (nr->natpass) |
3588 r = NULL;
|
3589 pd->nat_rule = nr; |
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); |
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); |
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); |
3606 break; 3607#endif /* INET6 */ 3608 }
|
3330 if (rdr->natpass)
|
3609 if (nr->natpass) |
3610 r = NULL;
|
3611 pd->nat_rule = nr; |
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) |
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)) |
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; 3643 if (r->anchor == NULL) { 3644 *rm = r; 3645 *am = a; 3646 *rsm = ruleset; 3647 if ((*rm)->quick) 3648 break; 3649 r = TAILQ_NEXT(r, entries); 3650 } else 3651 PF_STEP_INTO_ANCHOR(r, a, ruleset, 3652 PF_RULESET_FILTER); 3653 } 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 }
|
3662 REASON_SET(&reason, PFRES_MATCH);
|
3663 |
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); |
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 } |
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); |
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); |
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) 3697 pf_send_icmp(m, r->return_icmp6 >> 8, 3698 r->return_icmp6 & 255, af, r); 3699 } 3700 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) { |
3710 /* create new state */ 3711 struct pf_state *s = NULL;
|
3712 struct pf_src_node *sn = NULL; |
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); |
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 } |
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; |
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;
|
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); |
3766 else 3767 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
|
3469 s->lan.port = 0;
|
3768 } else { 3769 PF_ACPY(&s->lan.addr, daddr, af);
|
3472 s->lan.port = 0;
|
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); |
3773 else 3774 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
|
3479 s->gwy.port = 0;
|
3775 }
|
3481 s->src.seqlo = 0;
3482 s->src.seqhi = 0;
3483 s->src.seqdiff = 0;
3484 s->src.max_win = 0;
|
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;
|
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;
|
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)) { |
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); |
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, |
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) |
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)) |
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; 3851 if ((*rm)->quick) 3852 break; 3853 r = TAILQ_NEXT(r, entries); 3854 } else 3855 PF_STEP_INTO_ANCHOR(r, a, ruleset, 3856 PF_RULESET_FILTER); 3857 } 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 }
|
3866 REASON_SET(&reason, PFRES_MATCH);
|
3867 |
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); |
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, |
3885 u_short *reason) 3886{
|
3601 struct pf_tree_node key;
|
3887 struct pf_state key; |
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; |
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 } |
3909 3910 STATE_LOOKUP(); 3911 3912 if (direction == (*state)->direction) { 3913 src = &(*state)->src; 3914 dst = &(*state)->dst;
|
3622 dirndx = 0;
|
3915 } else { 3916 src = &(*state)->dst; 3917 dst = &(*state)->src;
|
3626 dirndx = 1;
|
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); 3926 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 3927 pd->src, th->th_dport, th->th_sport, 3928 (*state)->src.seqhi, ntohl(th->th_seq) + 1, 3929 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0); 3930 return (PF_SYNPROXY_DROP); 3931 } else if (!(th->th_flags & TH_ACK) || 3932 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 3933 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) 3934 return (PF_DROP); 3935 else 3936 (*state)->src.state = PF_TCPS_PROXY_DST; 3937 } 3938 if ((*state)->src.state == PF_TCPS_PROXY_DST) { 3939 struct pf_state_host *src, *dst; 3940 3941 if (direction == PF_OUT) { 3942 src = &(*state)->gwy; 3943 dst = &(*state)->ext; 3944 } else { 3945 src = &(*state)->ext; 3946 dst = &(*state)->lan; 3947 } 3948 if (direction == (*state)->direction) { 3949 if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) || 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); |
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); 3968 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 3969 pd->src, th->th_dport, th->th_sport, 3970 ntohl(th->th_ack), ntohl(th->th_seq) + 1, 3971 TH_ACK, (*state)->src.max_win, 0, 0); 3972 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr, 3973 &dst->addr, src->port, dst->port, 3974 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1, 3975 TH_ACK, (*state)->dst.max_win, 0, 0); 3976 (*state)->src.seqdiff = (*state)->dst.seqhi - 3977 (*state)->src.seqlo; 3978 (*state)->dst.seqdiff = (*state)->src.seqhi - 3979 (*state)->dst.seqlo; 3980 (*state)->src.seqhi = (*state)->src.seqlo + 3981 (*state)->src.max_win; 3982 (*state)->dst.seqhi = (*state)->dst.seqlo + 3983 (*state)->dst.max_win; 3984 (*state)->src.wscale = (*state)->dst.wscale = 0; 3985 (*state)->src.state = (*state)->dst.state = 3986 TCPS_ESTABLISHED; 3987 return (PF_SYNPROXY_DROP); 3988 } 3989 } 3990 3991 if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) { 3992 sws = src->wscale & PF_WSCALE_MASK; 3993 dws = dst->wscale & PF_WSCALE_MASK; 3994 } else 3995 sws = dws = 0; 3996 3997 /* 3998 * Sequence tracking algorithm from Guido van Rooij's paper: 3999 * http://www.madison-gurkha.com/publications/tcp_filtering/ 4000 * tcp_filtering.ps 4001 */ 4002 4003 seq = ntohl(th->th_seq); 4004 if (src->seqlo == 0) { 4005 /* First packet from this end. Set its state */ 4006 4007 if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) && 4008 src->scrub == NULL) { 4009 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) { 4010 REASON_SET(reason, PFRES_MEMORY); 4011 return (PF_DROP); 4012 } 4013 } 4014 4015 /* Deferred generation of sequence number modulator */ 4016 if (dst->seqdiff && !src->seqdiff) { 4017 while ((src->seqdiff = arc4random()) == 0) 4018 ; 4019 ack = ntohl(th->th_ack) - dst->seqdiff; 4020 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4021 src->seqdiff), 0); 4022 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4023 copyback = 1; 4024 } else { 4025 ack = ntohl(th->th_ack); 4026 } 4027 4028 end = seq + pd->p_len; 4029 if (th->th_flags & TH_SYN) { 4030 end++; 4031 if (dst->wscale & PF_WSCALE_FLAG) { 4032 src->wscale = pf_get_wscale(m, off, th->th_off, 4033 pd->af); 4034 if (src->wscale & PF_WSCALE_FLAG) { 4035 /* Remove scale factor from initial 4036 * window */ 4037 sws = src->wscale & PF_WSCALE_MASK; 4038 win = ((u_int32_t)win + (1 << sws) - 1) 4039 >> sws; 4040 dws = dst->wscale & PF_WSCALE_MASK; 4041 } else { 4042 /* fixup other window */ 4043 dst->max_win <<= dst->wscale & 4044 PF_WSCALE_MASK; 4045 /* in case of a retrans SYN|ACK */ 4046 dst->wscale = 0; 4047 } 4048 } 4049 } 4050 if (th->th_flags & TH_FIN) 4051 end++; 4052 4053 src->seqlo = seq; 4054 if (src->state < TCPS_SYN_SENT) 4055 src->state = TCPS_SYN_SENT; 4056 4057 /* 4058 * May need to slide the window (seqhi may have been set by 4059 * the crappy stack check or if we picked up the connection 4060 * after establishment) 4061 */ 4062 if (src->seqhi == 1 || 4063 SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi)) 4064 src->seqhi = end + MAX(1, dst->max_win << dws); 4065 if (win > src->max_win) 4066 src->max_win = win; 4067 4068 } else { 4069 ack = ntohl(th->th_ack) - dst->seqdiff; 4070 if (src->seqdiff) { 4071 /* Modulate sequence numbers */ 4072 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4073 src->seqdiff), 0); 4074 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4075 copyback = 1; 4076 } 4077 end = seq + pd->p_len; 4078 if (th->th_flags & TH_SYN) 4079 end++; 4080 if (th->th_flags & TH_FIN) 4081 end++; 4082 } 4083 4084 if ((th->th_flags & TH_ACK) == 0) { 4085 /* Let it pass through the ack skew check */ 4086 ack = dst->seqlo; 4087 } else if ((ack == 0 && 4088 (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) || 4089 /* broken tcp stacks do not set ack */ 4090 (dst->state < TCPS_SYN_SENT)) { 4091 /* 4092 * Many stacks (ours included) will set the ACK number in an 4093 * FIN|ACK if the SYN times out -- no sequence to ACK. 4094 */ 4095 ack = dst->seqlo; 4096 } 4097 4098 if (seq == end) { 4099 /* Ease sequencing restrictions on no data packets */ 4100 seq = src->seqlo; 4101 end = seq; 4102 } 4103 4104 ackskew = dst->seqlo - ack; 4105 4106#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */ 4107 if (SEQ_GEQ(src->seqhi, end) && 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
|
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)) 4124 dst->seqhi = ack + MAX((win << sws), 1); 4125 4126 4127 /* update states */ 4128 if (th->th_flags & TH_SYN) 4129 if (src->state < TCPS_SYN_SENT) 4130 src->state = TCPS_SYN_SENT; 4131 if (th->th_flags & TH_FIN) 4132 if (src->state < TCPS_CLOSING) 4133 src->state = TCPS_CLOSING; 4134 if (th->th_flags & TH_ACK) { 4135 if (dst->state == TCPS_SYN_SENT) 4136 dst->state = TCPS_ESTABLISHED; 4137 else if (dst->state == TCPS_CLOSING) 4138 dst->state = TCPS_FIN_WAIT_2; 4139 } 4140 if (th->th_flags & TH_RST) 4141 src->state = dst->state = TCPS_TIME_WAIT; 4142 4143 /* update expire time */ 4144#ifdef __FreeBSD__ 4145 (*state)->expire = time_second; 4146#else 4147 (*state)->expire = time.tv_sec; 4148#endif 4149 if (src->state >= TCPS_FIN_WAIT_2 && 4150 dst->state >= TCPS_FIN_WAIT_2) 4151 (*state)->timeout = PFTM_TCP_CLOSED; 4152 else if (src->state >= TCPS_FIN_WAIT_2 || 4153 dst->state >= TCPS_FIN_WAIT_2) 4154 (*state)->timeout = PFTM_TCP_FIN_WAIT; 4155 else if (src->state < TCPS_ESTABLISHED || 4156 dst->state < TCPS_ESTABLISHED) 4157 (*state)->timeout = PFTM_TCP_OPENING; 4158 else if (src->state >= TCPS_CLOSING || 4159 dst->state >= TCPS_CLOSING) 4160 (*state)->timeout = PFTM_TCP_CLOSING; 4161 else 4162 (*state)->timeout = PFTM_TCP_ESTABLISHED; 4163 4164 /* Fall through to PASS packet */ 4165 4166 } else if ((dst->state < TCPS_SYN_SENT || 4167 dst->state >= TCPS_FIN_WAIT_2 || 4168 src->state >= TCPS_FIN_WAIT_2) && 4169 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) && 4170 /* Within a window forward of the originating packet */ 4171 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) { 4172 /* Within a window backward of the originating packet */ 4173 4174 /* 4175 * This currently handles three situations: 4176 * 1) Stupid stacks will shotgun SYNs before their peer 4177 * replies. 4178 * 2) When PF catches an already established stream (the 4179 * firewall rebooted, the state table was flushed, routes 4180 * changed...) 4181 * 3) Packets get funky immediately after the connection 4182 * closes (this should catch Solaris spurious ACK|FINs 4183 * that web servers like to spew after a close) 4184 * 4185 * This must be a little more careful than the above code 4186 * since packet floods will also be caught here. We don't 4187 * update the TTL here to mitigate the damage of a packet 4188 * flood and so the same code can handle awkward establishment 4189 * and a loosened connection close. 4190 * In the establishment case, a correct peer response will 4191 * validate the connection, go through the normal state code 4192 * and keep updating the state TTL. 4193 */ 4194 4195 if (pf_status.debug >= PF_DEBUG_MISC) { 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
|
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)) 4212 dst->seqhi = ack + MAX((win << sws), 1); 4213 4214 /* 4215 * Cannot set dst->seqhi here since this could be a shotgunned 4216 * SYN and not an already established connection. 4217 */ 4218 4219 if (th->th_flags & TH_FIN) 4220 if (src->state < TCPS_CLOSING) 4221 src->state = TCPS_CLOSING; 4222 if (th->th_flags & TH_RST) 4223 src->state = dst->state = TCPS_TIME_WAIT; 4224 4225 /* Fall through to PASS packet */ 4226 4227 } else { 4228 if ((*state)->dst.state == TCPS_SYN_SENT && 4229 (*state)->src.state == TCPS_SYN_SENT) { 4230 /* Send RST for state mismatches during handshake */ 4231 if (!(th->th_flags & TH_RST)) { 4232 u_int32_t ack = ntohl(th->th_seq) + pd->p_len; 4233 4234 if (th->th_flags & TH_SYN) 4235 ack++; 4236 if (th->th_flags & TH_FIN) 4237 ack++; 4238 pf_send_tcp((*state)->rule.ptr, pd->af, 4239 pd->dst, pd->src, th->th_dport, 4240 th->th_sport, ntohl(th->th_ack), ack, 4241 TH_RST|TH_ACK, 0, 0, 4242 (*state)->rule.ptr->return_ttl); 4243 } 4244 src->seqlo = 0; 4245 src->seqhi = 1; 4246 src->max_win = 1; 4247 } else if (pf_status.debug >= PF_DEBUG_MISC) { 4248 printf("pf: BAD state: "); 4249 pf_print_state(*state); 4250 pf_print_flags(th->th_flags); 4251 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d " 4252 "dir=%s,%s\n", seq, ack, pd->p_len, ackskew, 4253 (*state)->packets[0], (*state)->packets[1], 4254 direction == PF_IN ? "in" : "out", 4255 direction == (*state)->direction ? "fwd" : "rev"); 4256 printf("pf: State failure on: %c %c %c %c | %c %c\n", 4257 SEQ_GEQ(src->seqhi, end) ? ' ' : '1', 4258 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ? 4259 ' ': '2', 4260 (ackskew >= -MAXACKWINDOW) ? ' ' : '3', 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)) |
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) 4279 pf_change_ap(pd->src, &th->th_sport, pd->ip_sum, 4280 &th->th_sum, &(*state)->gwy.addr, 4281 (*state)->gwy.port, 0, pd->af); 4282 else 4283 pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, 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 }
|
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) |
4298{ 4299 struct pf_state_peer *src, *dst;
|
4024 struct pf_tree_node key;
|
4300 struct pf_state key; |
4301 struct udphdr *uh = pd->hdr.udp;
|
4026 int dirndx;
|
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 } |
4316 4317 STATE_LOOKUP(); 4318 4319 if (direction == (*state)->direction) { 4320 src = &(*state)->src; 4321 dst = &(*state)->dst;
|
4040 dirndx = 0;
|
4322 } else { 4323 src = &(*state)->dst; 4324 dst = &(*state)->src;
|
4044 dirndx = 1;
|
4325 } 4326
|
4047 (*state)->packets[dirndx]++;
4048 (*state)->bytes[dirndx] += pd->tot_len;
4049
|
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__ 4335 (*state)->expire = time_second; 4336#else 4337 (*state)->expire = time.tv_sec; 4338#endif 4339 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE) 4340 (*state)->timeout = PFTM_UDP_MULTIPLE; 4341 else 4342 (*state)->timeout = PFTM_UDP_SINGLE; 4343 4344 /* translate source/destination address, if necessary */ 4345 if (STATE_TRANSLATE(*state)) { 4346 if (direction == PF_OUT) 4347 pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum, 4348 &uh->uh_sum, &(*state)->gwy.addr, 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 }
|
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) |
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; |
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 4377 if (icmptype == ICMP_UNREACH || 4378 icmptype == ICMP_SOURCEQUENCH || 4379 icmptype == ICMP_REDIRECT || 4380 icmptype == ICMP_TIMXCEED || 4381 icmptype == ICMP_PARAMPROB) 4382 state_icmp++; 4383 break; 4384#endif /* INET */ 4385#ifdef INET6 4386 case IPPROTO_ICMPV6: 4387 icmptype = pd->hdr.icmp6->icmp6_type; 4388 icmpid = pd->hdr.icmp6->icmp6_id; 4389 icmpsum = &pd->hdr.icmp6->icmp6_cksum; 4390 4391 if (icmptype == ICMP6_DST_UNREACH || 4392 icmptype == ICMP6_PACKET_TOO_BIG || 4393 icmptype == ICMP6_TIME_EXCEEDED || 4394 icmptype == ICMP6_PARAM_PROB) 4395 state_icmp++; 4396 break; 4397#endif /* INET6 */ 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; |
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 } |
4421 4422 STATE_LOOKUP(); 4423
|
4150 dirndx = (direction == (*state)->direction) ? 0 : 1;
4151 (*state)->packets[dirndx]++;
4152 (*state)->bytes[dirndx] += pd->tot_len;
|
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 */ 4432 if (PF_ANEQ(&(*state)->lan.addr, &(*state)->gwy.addr, pd->af)) { 4433 if (direction == PF_OUT) { 4434 switch (pd->af) { 4435#ifdef INET 4436 case AF_INET: 4437 pf_change_a(&saddr->v4.s_addr, 4438 pd->ip_sum, 4439 (*state)->gwy.addr.v4.s_addr, 0); 4440 break; 4441#endif /* INET */ 4442#ifdef INET6 4443 case AF_INET6: 4444 pf_change_a6(saddr, 4445 &pd->hdr.icmp6->icmp6_cksum, 4446 &(*state)->gwy.addr, 0); 4447 m_copyback(m, off, 4448 sizeof(struct icmp6_hdr), 4449 (caddr_t)pd->hdr.icmp6); 4450 break; 4451#endif /* INET6 */ 4452 } 4453 } else { 4454 switch (pd->af) { 4455#ifdef INET 4456 case AF_INET: 4457 pf_change_a(&daddr->v4.s_addr, 4458 pd->ip_sum, 4459 (*state)->lan.addr.v4.s_addr, 0); 4460 break; 4461#endif /* INET */ 4462#ifdef INET6 4463 case AF_INET6: 4464 pf_change_a6(daddr, 4465 &pd->hdr.icmp6->icmp6_cksum, 4466 &(*state)->lan.addr, 0); 4467 m_copyback(m, off, 4468 sizeof(struct icmp6_hdr), 4469 (caddr_t)pd->hdr.icmp6); 4470 break; 4471#endif /* INET6 */ 4472 } 4473 } 4474 } 4475 4476 return (PF_PASS); 4477 4478 } else { 4479 /* 4480 * ICMP error message in response to a TCP/UDP packet. 4481 * Extract the inner TCP/UDP header and search for that state. 4482 */ 4483 4484 struct pf_pdesc pd2; 4485#ifdef INET 4486 struct ip h2; 4487#endif /* INET */ 4488#ifdef INET6 4489 struct ip6_hdr h2_6; 4490 int terminal = 0; 4491#endif /* INET6 */ 4492 int ipoff2 = 0; /* make the compiler happy */ 4493 int off2 = 0; /* make the compiler happy */ 4494 4495 pd2.af = pd->af; 4496 switch (pd->af) { 4497#ifdef INET 4498 case AF_INET: 4499 /* offset of h2 in mbuf chain */ 4500 ipoff2 = off + ICMP_MINLEN; 4501 4502 if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2), 4503 NULL, NULL, pd2.af)) { 4504 DPFPRINTF(PF_DEBUG_MISC, 4505 ("pf: ICMP error message too short " 4506 "(ip)\n")); 4507 return (PF_DROP); 4508 } 4509 /* 4510 * ICMP error messages don't refer to non-first 4511 * fragments 4512 */ 4513 if (h2.ip_off & htons(IP_OFFMASK)) 4514 return (PF_DROP); 4515 4516 /* offset of protocol header that follows h2 */ 4517 off2 = ipoff2 + (h2.ip_hl << 2); 4518 4519 pd2.proto = h2.ip_p; 4520 pd2.src = (struct pf_addr *)&h2.ip_src; 4521 pd2.dst = (struct pf_addr *)&h2.ip_dst; 4522 pd2.ip_sum = &h2.ip_sum; 4523 break; 4524#endif /* INET */ 4525#ifdef INET6 4526 case AF_INET6: 4527 ipoff2 = off + sizeof(struct icmp6_hdr); 4528 4529 if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6), 4530 NULL, NULL, pd2.af)) { 4531 DPFPRINTF(PF_DEBUG_MISC, 4532 ("pf: ICMP error message too short " 4533 "(ip6)\n")); 4534 return (PF_DROP); 4535 } 4536 pd2.proto = h2_6.ip6_nxt; 4537 pd2.src = (struct pf_addr *)&h2_6.ip6_src; 4538 pd2.dst = (struct pf_addr *)&h2_6.ip6_dst; 4539 pd2.ip_sum = NULL; 4540 off2 = ipoff2 + sizeof(h2_6); 4541 do { 4542 switch (pd2.proto) { 4543 case IPPROTO_FRAGMENT: 4544 /* 4545 * ICMPv6 error messages for 4546 * non-first fragments 4547 */ 4548 return (PF_DROP); 4549 case IPPROTO_AH: 4550 case IPPROTO_HOPOPTS: 4551 case IPPROTO_ROUTING: 4552 case IPPROTO_DSTOPTS: { 4553 /* get next header and header length */ 4554 struct ip6_ext opt6; 4555 4556 if (!pf_pull_hdr(m, off2, &opt6, 4557 sizeof(opt6), NULL, NULL, pd2.af)) { 4558 DPFPRINTF(PF_DEBUG_MISC, 4559 ("pf: ICMPv6 short opt\n")); 4560 return (PF_DROP); 4561 } 4562 if (pd2.proto == IPPROTO_AH) 4563 off2 += (opt6.ip6e_len + 2) * 4; 4564 else 4565 off2 += (opt6.ip6e_len + 1) * 8; 4566 pd2.proto = opt6.ip6e_nxt; 4567 /* goto the next header */ 4568 break; 4569 } 4570 default: 4571 terminal++; 4572 break; 4573 } 4574 } while (!terminal); 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; |
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 } |
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)) |
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, 4634 htonl(seq), 0); 4635 copyback = 1; 4636 } 4637 4638 if (!SEQ_GEQ(src->seqhi, seq) || 4639 !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws))) { 4640 if (pf_status.debug >= PF_DEBUG_MISC) { 4641 printf("pf: BAD ICMP %d:%d ", 4642 icmptype, pd->hdr.icmp->icmp_code); 4643 pf_print_host(pd->src, 0, pd->af); 4644 printf(" -> "); 4645 pf_print_host(pd->dst, 0, pd->af); 4646 printf(" state: "); 4647 pf_print_state(*state); 4648 printf(" seq=%u\n", seq); 4649 } 4650 return (PF_DROP); 4651 } 4652 4653 if (STATE_TRANSLATE(*state)) { 4654 if (direction == PF_IN) { 4655 pf_change_icmp(pd2.src, &th.th_sport, 4656 daddr, &(*state)->lan.addr, 4657 (*state)->lan.port, NULL, 4658 pd2.ip_sum, icmpsum, 4659 pd->ip_sum, 0, pd2.af); 4660 } else { 4661 pf_change_icmp(pd2.dst, &th.th_dport, 4662 saddr, &(*state)->gwy.addr, 4663 (*state)->gwy.port, NULL, 4664 pd2.ip_sum, icmpsum, 4665 pd->ip_sum, 0, pd2.af); 4666 } 4667 copyback = 1; 4668 } 4669 4670 if (copyback) { 4671 switch (pd2.af) { 4672#ifdef INET 4673 case AF_INET: 4674 m_copyback(m, off, ICMP_MINLEN, 4675 (caddr_t)pd->hdr.icmp); 4676 m_copyback(m, ipoff2, sizeof(h2), 4677 (caddr_t)&h2); 4678 break; 4679#endif /* INET */ 4680#ifdef INET6 4681 case AF_INET6: 4682 m_copyback(m, off, 4683 sizeof(struct icmp6_hdr), 4684 (caddr_t)pd->hdr.icmp6); 4685 m_copyback(m, ipoff2, sizeof(h2_6), 4686 (caddr_t)&h2_6); 4687 break; 4688#endif /* INET6 */ 4689 } 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; |
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 } |
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, 4729 pd2.ip_sum, icmpsum, 4730 pd->ip_sum, 1, pd2.af); 4731 } else { 4732 pf_change_icmp(pd2.dst, &uh.uh_dport, 4733 saddr, &(*state)->gwy.addr, 4734 (*state)->gwy.port, &uh.uh_sum, 4735 pd2.ip_sum, icmpsum, 4736 pd->ip_sum, 1, pd2.af); 4737 } 4738 switch (pd2.af) { 4739#ifdef INET 4740 case AF_INET: 4741 m_copyback(m, off, ICMP_MINLEN, 4742 (caddr_t)pd->hdr.icmp); 4743 m_copyback(m, ipoff2, sizeof(h2), 4744 (caddr_t)&h2); 4745 break; 4746#endif /* INET */ 4747#ifdef INET6 4748 case AF_INET6: 4749 m_copyback(m, off, 4750 sizeof(struct icmp6_hdr), 4751 (caddr_t)pd->hdr.icmp6); 4752 m_copyback(m, ipoff2, sizeof(h2_6), 4753 (caddr_t)&h2_6); 4754 break; 4755#endif /* INET6 */ 4756 } 4757 m_copyback(m, off2, sizeof(uh), 4758 (caddr_t)&uh); 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; |
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 } |
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, 4798 pd2.ip_sum, icmpsum, 4799 pd->ip_sum, 0, AF_INET); 4800 } else { 4801 pf_change_icmp(pd2.dst, &iih.icmp_id, 4802 saddr, &(*state)->gwy.addr, 4803 (*state)->gwy.port, NULL, 4804 pd2.ip_sum, icmpsum, 4805 pd->ip_sum, 0, AF_INET); 4806 } 4807 m_copyback(m, off, ICMP_MINLEN, 4808 (caddr_t)pd->hdr.icmp); 4809 m_copyback(m, ipoff2, sizeof(h2), 4810 (caddr_t)&h2); 4811 m_copyback(m, off2, ICMP_MINLEN, 4812 (caddr_t)&iih); 4813 } 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; |
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 } |
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, 4853 pd2.ip_sum, icmpsum, 4854 pd->ip_sum, 0, AF_INET6); 4855 } else { 4856 pf_change_icmp(pd2.dst, &iih.icmp6_id, 4857 saddr, &(*state)->gwy.addr, 4858 (*state)->gwy.port, NULL, 4859 pd2.ip_sum, icmpsum, 4860 pd->ip_sum, 0, AF_INET6); 4861 } 4862 m_copyback(m, off, sizeof(struct icmp6_hdr), 4863 (caddr_t)pd->hdr.icmp6); 4864 m_copyback(m, ipoff2, sizeof(h2_6), 4865 (caddr_t)&h2_6); 4866 m_copyback(m, off2, sizeof(struct icmp6_hdr), 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; |
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 } |
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, 4898 pd2.ip_sum, icmpsum, 4899 pd->ip_sum, 0, pd2.af); 4900 } else { 4901 pf_change_icmp(pd2.dst, NULL, 4902 saddr, &(*state)->gwy.addr, 4903 0, NULL, 4904 pd2.ip_sum, icmpsum, 4905 pd->ip_sum, 0, pd2.af); 4906 } 4907 switch (pd2.af) { 4908#ifdef INET 4909 case AF_INET: 4910 m_copyback(m, off, ICMP_MINLEN, 4911 (caddr_t)pd->hdr.icmp); 4912 m_copyback(m, ipoff2, sizeof(h2), 4913 (caddr_t)&h2); 4914 break; 4915#endif /* INET */ 4916#ifdef INET6 4917 case AF_INET6: 4918 m_copyback(m, off, 4919 sizeof(struct icmp6_hdr), 4920 (caddr_t)pd->hdr.icmp6); 4921 m_copyback(m, ipoff2, sizeof(h2_6), 4922 (caddr_t)&h2_6); 4923 break; 4924#endif /* INET6 */ 4925 } 4926 } 4927 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, |
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; |
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 } |
4955 4956 STATE_LOOKUP(); 4957 4958 if (direction == (*state)->direction) { 4959 src = &(*state)->src; 4960 dst = &(*state)->dst;
|
4648 dirndx = 0;
|
4961 } else { 4962 src = &(*state)->dst; 4963 dst = &(*state)->src;
|
4652 dirndx = 1;
|
4964 } 4965
|
4655 (*state)->packets[dirndx]++;
4656 (*state)->bytes[dirndx] += pd->tot_len;
4657
|
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__ 4974 (*state)->expire = time_second; 4975#else 4976 (*state)->expire = time.tv_sec; 4977#endif 4978 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE) 4979 (*state)->timeout = PFTM_OTHER_MULTIPLE; 4980 else 4981 (*state)->timeout = PFTM_OTHER_SINGLE; 4982 4983 /* translate source/destination address, if necessary */ 4984 if (STATE_TRANSLATE(*state)) { 4985 if (direction == PF_OUT) 4986 switch (pd->af) { 4987#ifdef INET 4988 case AF_INET: 4989 pf_change_a(&pd->src->v4.s_addr, 4990 pd->ip_sum, (*state)->gwy.addr.v4.s_addr, 4991 0); 4992 break; 4993#endif /* INET */ 4994#ifdef INET6 4995 case AF_INET6: 4996 PF_ACPY(pd->src, &(*state)->gwy.addr, pd->af); 4997 break; 4998#endif /* INET6 */ 4999 } 5000 else 5001 switch (pd->af) { 5002#ifdef INET 5003 case AF_INET: 5004 pf_change_a(&pd->dst->v4.s_addr, 5005 pd->ip_sum, (*state)->lan.addr.v4.s_addr, 5006 0); 5007 break; 5008#endif /* INET */ 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 }
|
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 * 5025pf_pull_hdr(struct mbuf *m, int off, void *p, int len, 5026 u_short *actionp, u_short *reasonp, sa_family_t af) 5027{ 5028 switch (af) { 5029#ifdef INET 5030 case AF_INET: { 5031 struct ip *h = mtod(m, struct ip *); 5032 u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3; 5033 5034 if (fragoff) { 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) { |
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 5053 case AF_INET6: { 5054 struct ip6_hdr *h = mtod(m, struct ip6_hdr *); 5055 5056 if (m->m_pkthdr.len < off + len || 5057 (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) < 5058 (unsigned)(off + len)) { 5059 ACTION_SET(actionp, PF_DROP); 5060 REASON_SET(reasonp, PFRES_SHORT); 5061 return (NULL); 5062 } 5063 break; 5064 } 5065#endif /* INET6 */ 5066 } 5067 m_copydata(m, off, len, p); 5068 return (p); 5069} 5070 5071int 5072pf_routable(struct pf_addr *addr, sa_family_t af) 5073{ 5074 struct sockaddr_in *dst; 5075 struct route ro; 5076 int ret = 0; 5077 5078 bzero(&ro, sizeof(ro)); 5079 dst = satosin(&ro.ro_dst); 5080 dst->sin_family = af; 5081 dst->sin_len = sizeof(*dst); 5082 dst->sin_addr = addr->v4; 5083#ifdef __FreeBSD__ 5084#ifdef RTF_PRCLONING 5085 rtalloc_ign(&ro, (RTF_CLONING|RTF_PRCLONING)); 5086#else /* !RTF_PRCLONING */ 5087 rtalloc_ign(&ro, RTF_CLONING); 5088#endif 5089#else /* ! __FreeBSD__ */ 5090 rtalloc_noclone(&ro, NO_CLONING); 5091#endif 5092 5093 if (ro.ro_rt != NULL) { 5094 ret = 1; 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
|
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; |
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"); 5124 5125 if (r->rt == PF_DUPTO) { 5126 m0 = *m; 5127 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 5128 if (mtag == NULL) { 5129 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 5130 if (mtag == NULL) 5131 goto bad; 5132 m_tag_prepend(m0, mtag); 5133 } 5134#ifdef __FreeBSD__ 5135 m0 = m_dup(*m, M_DONTWAIT); 5136#else 5137 m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT); 5138#endif 5139 if (m0 == NULL) 5140 return; 5141 } else { 5142 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 5143 return; 5144 m0 = *m; 5145 } 5146 5147 if (m0->m_len < sizeof(struct ip)) 5148 panic("pf_route: m0->m_len < sizeof(struct ip)"); 5149 ip = mtod(m0, struct ip *); 5150 5151 ro = &iproute; 5152 bzero((caddr_t)ro, sizeof(*ro)); 5153 dst = satosin(&ro->ro_dst); 5154 dst->sin_family = AF_INET; 5155 dst->sin_len = sizeof(*dst); 5156 dst->sin_addr = ip->ip_dst; 5157 5158 if (r->rt == PF_FASTROUTE) { 5159 rtalloc(ro); 5160 if (ro->ro_rt == 0) { 5161 ipstat.ips_noroute++; 5162 goto bad; 5163 } 5164 5165 ifp = ro->ro_rt->rt_ifp; 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); |
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; |
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; |
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; |
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) { |
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; 5210 } 5211 PF_LOCK(); 5212#else 5213 if (pf_test(PF_OUT, ifp, &m0) != PF_PASS) 5214 goto bad; 5215 else if (m0 == NULL) 5216 goto done; 5217#endif 5218 if (m0->m_len < sizeof(struct ip)) 5219 panic("pf_route: m0->m_len < sizeof(struct ip)"); 5220 ip = mtod(m0, struct ip *); 5221 } 5222 5223#ifdef __FreeBSD__ 5224 /* Copied from FreeBSD 5.1-CURRENT ip_output. */ 5225 m0->m_pkthdr.csum_flags |= CSUM_IP; 5226 sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist; 5227 if (sw_csum & CSUM_DELAY_DATA) { 5228 /* 5229 * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least) 5230 */ 5231 NTOHS(ip->ip_len); 5232 NTOHS(ip->ip_off); /* XXX: needed? */ 5233 in_delayed_cksum(m0); 5234 HTONS(ip->ip_len); 5235 HTONS(ip->ip_off); 5236 sw_csum &= ~CSUM_DELAY_DATA; 5237 } 5238 m0->m_pkthdr.csum_flags &= ifp->if_hwassist; 5239 5240 if (ntohs(ip->ip_len) <= ifp->if_mtu || 5241 (ifp->if_hwassist & CSUM_FRAGMENT && 5242 ((ip->ip_off & htons(IP_DF)) == 0))) { 5243 /* 5244 * ip->ip_len = htons(ip->ip_len); 5245 * ip->ip_off = htons(ip->ip_off); 5246 */ 5247 ip->ip_sum = 0; 5248 if (sw_csum & CSUM_DELAY_IP) { 5249 /* From KAME */ 5250 if (ip->ip_v == IPVERSION && 5251 (ip->ip_hl << 2) == sizeof(*ip)) { 5252 ip->ip_sum = in_cksum_hdr(ip); 5253 } else { 5254 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 5255 } 5256 } 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 |
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); 5301 } 5302 /* Update relevant hardware checksum stats for TCP/UDP */ 5303 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) 5304 tcpstat.tcps_outhwcsum++; 5305 else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) 5306 udpstat.udps_outhwcsum++; 5307 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); 5308 goto done; 5309 } 5310#endif 5311 /* 5312 * Too large for interface; fragment if possible. 5313 * Must be able to put at least 8 bytes per fragment. 5314 */ 5315 if (ip->ip_off & htons(IP_DF)) { 5316 ipstat.ips_cantfrag++; 5317 if (r->rt != PF_DUPTO) { 5318#ifdef __FreeBSD__ 5319 /* icmp_error() expects host byte ordering */ 5320 NTOHS(ip->ip_len); 5321 NTOHS(ip->ip_off); 5322 PF_UNLOCK(); 5323#endif 5324 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 5325 ifp); 5326#ifdef __FreeBSD__ 5327 PF_LOCK(); 5328#endif 5329 goto done; 5330 } else 5331 goto bad; 5332 } 5333 5334 m1 = m0; 5335#ifdef __FreeBSD__ 5336 /* 5337 * XXX: is cheaper + less error prone than own function 5338 */ 5339 NTOHS(ip->ip_len); 5340 NTOHS(ip->ip_off); 5341 error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum); 5342#else 5343 error = ip_fragment(m0, ifp, ifp->if_mtu); 5344#endif 5345 if (error) { 5346#ifndef __FreeBSD__ /* ip_fragment does not do m_freem() on FreeBSD */ 5347 m0 = NULL; 5348#endif 5349 goto bad; 5350 } 5351 5352 for (m0 = m1; m0; m0 = m1) { 5353 m1 = m0->m_nextpkt; 5354 m0->m_nextpkt = 0; 5355#ifdef __FreeBSD__ 5356 if (error == 0) { 5357 PF_UNLOCK(); 5358 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 5359 NULL); 5360 PF_LOCK(); 5361 } else 5362#else 5363 if (error == 0) 5364 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 5365 NULL); 5366 else 5367#endif 5368 m_freem(m0); 5369 } 5370 5371 if (error == 0) 5372 ipstat.ips_fragmented++; 5373 5374done: 5375 if (r->rt != PF_DUPTO) 5376 *m = NULL; 5377 if (ro == &iproute && ro->ro_rt) 5378 RTFREE(ro->ro_rt); 5379 return; 5380 5381bad: 5382 m_freem(m0); 5383 goto done; 5384} 5385#endif /* INET */ 5386 5387#ifdef INET6 5388void 5389pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 5390 struct pf_state *s) 5391{ 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; |
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; 5409 mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL); 5410 if (mtag == NULL) { 5411 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 5412 if (mtag == NULL) 5413 goto bad; 5414 m_tag_prepend(m0, mtag); 5415 } 5416#ifdef __FreeBSD__ 5417 m0 = m_dup(*m, M_DONTWAIT); 5418#else 5419 m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT); 5420#endif 5421 if (m0 == NULL) 5422 return; 5423 } else { 5424 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 5425 return; 5426 m0 = *m; 5427 } 5428 5429 if (m0->m_len < sizeof(struct ip6_hdr)) 5430 panic("pf_route6: m0->m_len < sizeof(struct ip6_hdr)"); 5431 ip6 = mtod(m0, struct ip6_hdr *); 5432 5433 ro = &ip6route; 5434 bzero((caddr_t)ro, sizeof(*ro)); 5435 dst = (struct sockaddr_in6 *)&ro->ro_dst; 5436 dst->sin6_family = AF_INET6; 5437 dst->sin6_len = sizeof(*dst); 5438 dst->sin6_addr = ip6->ip6_dst; 5439 5440 /* Cheat. */ 5441 if (r->rt == PF_FASTROUTE) { 5442 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); 5443 if (mtag == NULL) 5444 goto bad; 5445 m_tag_prepend(m0, mtag); 5446#ifdef __FreeBSD__ 5447 PF_UNLOCK(); 5448 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 5449 PF_LOCK(); 5450#else 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); |
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; |
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; |
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) { 5478 mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT); 5479 if (mtag == NULL) 5480 goto bad; 5481 m_tag_prepend(m0, mtag); 5482#ifdef __FreeBSD__ 5483 PF_UNLOCK(); 5484 if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS) { 5485 PF_LOCK(); 5486 goto bad; 5487 } else if (m0 == NULL) { 5488 PF_LOCK(); 5489 goto done; 5490 } 5491 PF_LOCK(); 5492#else 5493 if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS) 5494 goto bad; 5495 else if (m0 == NULL) 5496 goto done; 5497#endif 5498 } 5499 } 5500 5501 /* 5502 * If the packet is too large for the outgoing interface, 5503 * send back an icmp6 error. 5504 */ 5505 if (IN6_IS_ADDR_LINKLOCAL(&dst->sin6_addr)) 5506 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); 5507 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { 5508#ifdef __FreeBSD__ 5509 PF_UNLOCK(); 5510#endif 5511 error = nd6_output(ifp, ifp, m0, dst, NULL); 5512#ifdef __FreeBSD__ 5513 PF_LOCK(); 5514#endif 5515 } else { 5516 in6_ifstat_inc(ifp, ifs6_in_toobig); 5517#ifdef __FreeBSD__ 5518 if (r->rt != PF_DUPTO) { 5519 PF_UNLOCK(); 5520 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 5521 PF_LOCK(); 5522 } else 5523#else 5524 if (r->rt != PF_DUPTO) 5525 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 5526 else 5527#endif 5528 goto bad; 5529 } 5530 5531done: 5532 if (r->rt != PF_DUPTO) 5533 *m = NULL; 5534 return; 5535 5536bad: 5537 m_freem(m0); 5538 goto done; 5539} 5540#endif /* INET6 */ 5541 5542 5543#ifdef __FreeBSD__ 5544/* 5545 * XXX 5546 * FreeBSD supports cksum offload for the following drivers. 5547 * em(4), gx(4), lge(4), nge(4), ti(4), xl(4) 5548 * If we can make full use of it we would outperform ipfw/ipfilter in 5549 * very heavy traffic. 5550 * I have not tested 'cause I don't have NICs that supports cksum offload. 5551 * (There might be problems. Typical phenomena would be 5552 * 1. No route message for UDP packet. 5553 * 2. No connection acceptance from external hosts regardless of rule set.) 5554 */ 5555int 5556pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) 5557{ 5558 u_int16_t sum = 0; 5559 int hw_assist = 0; 5560 struct ip *ip; 5561 5562 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 5563 return (1); 5564 if (m->m_pkthdr.len < off + len) 5565 return (1); 5566 5567 switch (p) { 5568 case IPPROTO_TCP: 5569 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 5570 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 5571 sum = m->m_pkthdr.csum_data; 5572 } else { 5573 ip = mtod(m, struct ip *); 5574 sum = in_pseudo(ip->ip_src.s_addr, 5575 ip->ip_dst.s_addr, 5576 htonl(m->m_pkthdr.csum_data + 5577 IPPROTO_TCP) + ip->ip_len); 5578 } 5579 sum ^= 0xffff; 5580 ++hw_assist; 5581 } 5582 break; 5583 case IPPROTO_UDP: 5584 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 5585 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 5586 sum = m->m_pkthdr.csum_data; 5587 } else { 5588 ip = mtod(m, struct ip *); 5589 sum = in_pseudo(ip->ip_src.s_addr, 5590 ip->ip_dst.s_addr, htonl((u_short)len + 5591 m->m_pkthdr.csum_data + IPPROTO_UDP)); 5592 } 5593 sum ^= 0xffff; 5594 ++hw_assist; 5595 } 5596 break; 5597 case IPPROTO_ICMP: 5598#ifdef INET6 5599 case IPPROTO_ICMPV6: 5600#endif /* INET6 */ 5601 break; 5602 default: 5603 return (1); 5604 } 5605 5606 if (!hw_assist) { 5607 switch (af) { 5608 case AF_INET: 5609 if (p == IPPROTO_ICMP) { 5610 if (m->m_len < off) 5611 return (1); 5612 m->m_data += off; 5613 m->m_len -= off; 5614 sum = in_cksum(m, len); 5615 m->m_data -= off; 5616 m->m_len += off; 5617 } else { 5618 if (m->m_len < sizeof(struct ip)) 5619 return (1); 5620 sum = in4_cksum(m, p, off, len); 5621 if (sum == 0) { 5622 m->m_pkthdr.csum_flags |= 5623 (CSUM_DATA_VALID | 5624 CSUM_PSEUDO_HDR); 5625 m->m_pkthdr.csum_data = 0xffff; 5626 } 5627 } 5628 break; 5629#ifdef INET6 5630 case AF_INET6: 5631 if (m->m_len < sizeof(struct ip6_hdr)) 5632 return (1); 5633 sum = in6_cksum(m, p, off, len); 5634 /* 5635 * XXX 5636 * IPv6 H/W cksum off-load not supported yet! 5637 * 5638 * if (sum == 0) { 5639 * m->m_pkthdr.csum_flags |= 5640 * (CSUM_DATA_VALID|CSUM_PSEUDO_HDR); 5641 * m->m_pkthdr.csum_data = 0xffff; 5642 *} 5643 */ 5644 break; 5645#endif /* INET6 */ 5646 default: 5647 return (1); 5648 } 5649 } 5650 if (sum) { 5651 switch (p) { 5652 case IPPROTO_TCP: 5653 tcpstat.tcps_rcvbadsum++; 5654 break; 5655 case IPPROTO_UDP: 5656 udpstat.udps_badsum++; 5657 break; 5658 case IPPROTO_ICMP: 5659 icmpstat.icps_checksum++; 5660 break; 5661#ifdef INET6 5662 case IPPROTO_ICMPV6: 5663 icmp6stat.icp6s_checksum++; 5664 break; 5665#endif /* INET6 */ 5666 } 5667 return (1); 5668 } 5669 return (0); 5670} 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) |
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; 5689 break; 5690 case IPPROTO_UDP: 5691 flag_ok = M_UDP_CSUM_IN_OK; 5692 flag_bad = M_UDP_CSUM_IN_BAD; 5693 break; 5694 case IPPROTO_ICMP: 5695#ifdef INET6 5696 case IPPROTO_ICMPV6: 5697#endif /* INET6 */ 5698 flag_ok = flag_bad = 0; 5699 break; 5700 default: 5701 return (1); 5702 } 5703 if (m->m_pkthdr.csum & flag_ok) 5704 return (0); 5705 if (m->m_pkthdr.csum & flag_bad) 5706 return (1); 5707 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 5708 return (1); 5709 if (m->m_pkthdr.len < off + len) 5710 return (1); 5711 switch (af) { 5712 case AF_INET: 5713 if (p == IPPROTO_ICMP) { 5714 if (m->m_len < off) 5715 return (1); 5716 m->m_data += off; 5717 m->m_len -= off; 5718 sum = in_cksum(m, len); 5719 m->m_data -= off; 5720 m->m_len += off; 5721 } else { 5722 if (m->m_len < sizeof(struct ip)) 5723 return (1); 5724 sum = in4_cksum(m, p, off, len); 5725 } 5726 break; 5727#ifdef INET6 5728 case AF_INET6: 5729 if (m->m_len < sizeof(struct ip6_hdr)) 5730 return (1); 5731 sum = in6_cksum(m, p, off, len); 5732 break; 5733#endif /* INET6 */ 5734 default: 5735 return (1); 5736 } 5737 if (sum) { 5738 m->m_pkthdr.csum |= flag_bad; 5739 switch (p) { 5740 case IPPROTO_TCP: 5741 tcpstat.tcps_rcvbadsum++; 5742 break; 5743 case IPPROTO_UDP: 5744 udpstat.udps_badsum++; 5745 break; 5746 case IPPROTO_ICMP: 5747 icmpstat.icps_checksum++; 5748 break; 5749#ifdef INET6 5750 case IPPROTO_ICMPV6: 5751 icmp6stat.icp6s_checksum++; 5752 break; 5753#endif /* INET6 */ 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 |
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; |
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__ |
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)); |
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) { |
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));
|
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); |
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, |
5854 &pd, &a, &ruleset); 5855 goto done; 5856 } 5857 5858 switch (h->ip_p) { 5859 5860 case IPPROTO_TCP: { 5861 struct tcphdr th; 5862 5863 pd.hdr.tcp = &th; 5864 if (!pf_pull_hdr(m, off, &th, sizeof(th), 5865 &action, &reason, AF_INET)) { 5866 log = action != PF_PASS; 5867 goto done; 5868 } 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); |
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, |
5881 &reason); 5882 if (action == PF_PASS) {
|
5883#if NPFSYNC 5884 pfsync_update_state(s); 5885#endif |
5886 r = s->rule.ptr;
|
5887 a = s->anchor.ptr; |
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); |
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); |
5916 if (action == PF_PASS) {
|
5917#if NPFSYNC 5918 pfsync_update_state(s); 5919#endif |
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); |
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); |
5944 if (action == PF_PASS) {
|
5945#if NPFSYNC 5946 pfsync_update_state(s); 5947#endif |
5948 r = s->rule.ptr;
|
5738 r->packets++;
5739 r->bytes += ntohs(h->ip_len);
|
5949 a = s->anchor.ptr;
|
5741 if (a != NULL) {
5742 a->packets++;
5743 a->bytes += ntohs(h->ip_len);
5744 }
|
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); |
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); |
5959 if (action == PF_PASS) {
|
5960#if NPFSYNC 5961 pfsync_update_state(s); 5962#endif |
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, |
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
|
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
|
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 } 5981 5982#ifdef ALTQ 5983 if (action == PF_PASS && r->qid) { 5984 struct m_tag *mtag; 5985 struct altq_tag *atag; 5986 5987 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT); 5988 if (mtag != NULL) { 5989 atag = (struct altq_tag *)(mtag + 1); 5990 if (pqid || pd.tos == IPTOS_LOWDELAY) 5991 atag->qid = r->pqid; 5992 else 5993 atag->qid = r->qid; 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 |
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); |
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 |
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 6092#ifdef __FreeBSD__ 6093 PF_UNLOCK(); 6094#endif 6095 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; |
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__ |
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)); |
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) { |
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));
|
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); |
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, |
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: { 6181 /* get next header and header length */ 6182 struct ip6_ext opt6; 6183 6184 if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6), 6185 NULL, NULL, pd.af)) { 6186 DPFPRINTF(PF_DEBUG_MISC, 6187 ("pf: IPv6 short opt\n")); 6188 action = PF_DROP; 6189 REASON_SET(&reason, PFRES_SHORT); 6190 log = 1; 6191 goto done; 6192 } 6193 if (pd.proto == IPPROTO_AH) 6194 off += (opt6.ip6e_len + 2) * 4; 6195 else 6196 off += (opt6.ip6e_len + 1) * 8; 6197 pd.proto = opt6.ip6e_nxt; 6198 /* goto the next header */ 6199 break; 6200 } 6201 default: 6202 terminal++; 6203 break; 6204 } 6205 } while (!terminal); 6206 6207 switch (pd.proto) { 6208 6209 case IPPROTO_TCP: { 6210 struct tcphdr th; 6211 6212 pd.hdr.tcp = &th; 6213 if (!pf_pull_hdr(m, off, &th, sizeof(th), 6214 &action, &reason, AF_INET6)) { 6215 log = action != PF_PASS; 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); |
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, |
6228 &reason); 6229 if (action == PF_PASS) {
|
6230#if NPFSYNC 6231 pfsync_update_state(s); 6232#endif |
6233 r = s->rule.ptr;
|
6234 a = s->anchor.ptr; |
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); |
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); |
6263 if (action == PF_PASS) {
|
6264#if NPFSYNC 6265 pfsync_update_state(s); 6266#endif |
6267 r = s->rule.ptr;
|
6268 a = s->anchor.ptr; |
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); |
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); |
6292 if (action == PF_PASS) {
|
6293#if NPFSYNC 6294 pfsync_update_state(s); 6295#endif |
6296 r = s->rule.ptr;
|
6002 r->packets++;
6003 r->bytes += h->ip6_plen;
|
6297 a = s->anchor.ptr; |
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); |
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); |
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
|
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
|
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); 6326 if (mtag != NULL) { 6327 atag = (struct altq_tag *)(mtag + 1); 6328 if (pd.tos == IPTOS_LOWDELAY) 6329 atag->qid = r->pqid; 6330 else 6331 atag->qid = r->qid; 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 |
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); |
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 |
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 */
|