Deleted Added
full compact
pf.c (169843) pf.c (171168)
1/* $FreeBSD: head/sys/contrib/pf/net/pf.c 169843 2007-05-21 20:08:59Z dhartmei $ */
2/* $OpenBSD: pf.c,v 1.483 2005/03/15 17:38:43 dhartmei Exp $ */
1/* $OpenBSD: pf.c,v 1.527 2007/02/22 15:23:23 pyr 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

--- 23 unchanged lines hidden (view full) ---

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"
2
3/*
4 * Copyright (c) 2001 Daniel Hartmeier
5 * Copyright (c) 2002,2003 Henning Brauer
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions

--- 23 unchanged lines hidden (view full) ---

33 * Agency (DARPA) and Air Force Research Laboratory, Air Force
34 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
35 *
36 */
37
38#ifdef __FreeBSD__
39#include "opt_inet.h"
40#include "opt_inet6.h"
41
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf.c 171168 2007-07-03 12:16:07Z mlaier $");
42#endif
43
44#ifdef __FreeBSD__
45#include "opt_mac.h"
46#include "opt_bpf.h"
47#include "opt_pf.h"
48
49#ifdef DEV_BPF

--- 29 unchanged lines hidden (view full) ---

79#include <sys/kernel.h>
80#include <sys/time.h>
81#ifdef __FreeBSD__
82#include <sys/sysctl.h>
83#include <sys/endian.h>
84#else
85#include <sys/pool.h>
86#endif
44#endif
45
46#ifdef __FreeBSD__
47#include "opt_mac.h"
48#include "opt_bpf.h"
49#include "opt_pf.h"
50
51#ifdef DEV_BPF

--- 29 unchanged lines hidden (view full) ---

81#include <sys/kernel.h>
82#include <sys/time.h>
83#ifdef __FreeBSD__
84#include <sys/sysctl.h>
85#include <sys/endian.h>
86#else
87#include <sys/pool.h>
88#endif
89#include <sys/proc.h>
90#ifdef __FreeBSD__
91#include <sys/kthread.h>
92#include <sys/lock.h>
93#include <sys/sx.h>
94#else
95#include <sys/rwlock.h>
96#endif
87
88#include <net/if.h>
89#include <net/if_types.h>
90#include <net/bpf.h>
91#include <net/route.h>
97
98#include <net/if.h>
99#include <net/if_types.h>
100#include <net/bpf.h>
101#include <net/route.h>
102#ifndef __FreeBSD__
103#include <net/radix_mpath.h>
104#endif
92
93#include <netinet/in.h>
94#include <netinet/in_var.h>
95#include <netinet/in_systm.h>
96#include <netinet/ip.h>
97#include <netinet/ip_var.h>
98#include <netinet/tcp.h>
99#include <netinet/tcp_seq.h>

--- 29 unchanged lines hidden (view full) ---

129
130#ifdef __FreeBSD__
131#include <machine/in_cksum.h>
132#include <sys/limits.h>
133#include <sys/ucred.h>
134#include <security/mac/mac_framework.h>
135
136extern int ip_optcopy(struct ip *, struct ip *);
105
106#include <netinet/in.h>
107#include <netinet/in_var.h>
108#include <netinet/in_systm.h>
109#include <netinet/ip.h>
110#include <netinet/ip_var.h>
111#include <netinet/tcp.h>
112#include <netinet/tcp_seq.h>

--- 29 unchanged lines hidden (view full) ---

142
143#ifdef __FreeBSD__
144#include <machine/in_cksum.h>
145#include <sys/limits.h>
146#include <sys/ucred.h>
147#include <security/mac/mac_framework.h>
148
149extern int ip_optcopy(struct ip *, struct ip *);
150extern int debug_pfugidhack;
137#endif
138
139#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
140
141/*
142 * Global variables
143 */
144
151#endif
152
153#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
154
155/*
156 * Global variables
157 */
158
145struct pf_anchor_global pf_anchors;
146struct pf_ruleset pf_main_ruleset;
147struct pf_altqqueue pf_altqs[2];
148struct pf_palist pf_pabuf;
149struct pf_altqqueue *pf_altqs_active;
150struct pf_altqqueue *pf_altqs_inactive;
151struct pf_status pf_status;
152
153u_int32_t ticket_altqs_active;
154u_int32_t ticket_altqs_inactive;
155int altqs_inactive_open;
156u_int32_t ticket_pabuf;
157
159struct pf_altqqueue pf_altqs[2];
160struct pf_palist pf_pabuf;
161struct pf_altqqueue *pf_altqs_active;
162struct pf_altqqueue *pf_altqs_inactive;
163struct pf_status pf_status;
164
165u_int32_t ticket_altqs_active;
166u_int32_t ticket_altqs_inactive;
167int altqs_inactive_open;
168u_int32_t ticket_pabuf;
169
158#ifdef __FreeBSD__
159struct callout pf_expire_to; /* expire timeout */
160#else
161struct timeout pf_expire_to; /* expire timeout */
162#endif
163
164struct pf_anchor_stackframe {
165 struct pf_ruleset *rs;
166 struct pf_rule *r;
167 struct pf_anchor_node *parent;
168 struct pf_anchor *child;
169} pf_anchor_stack[64];
170
171#ifdef __FreeBSD__

--- 9 unchanged lines hidden (view full) ---

181void pf_init_threshold(struct pf_threshold *, u_int32_t,
182 u_int32_t);
183void pf_add_threshold(struct pf_threshold *);
184int pf_check_threshold(struct pf_threshold *);
185
186void pf_change_ap(struct pf_addr *, u_int16_t *,
187 u_int16_t *, u_int16_t *, struct pf_addr *,
188 u_int16_t, u_int8_t, sa_family_t);
170struct pf_anchor_stackframe {
171 struct pf_ruleset *rs;
172 struct pf_rule *r;
173 struct pf_anchor_node *parent;
174 struct pf_anchor *child;
175} pf_anchor_stack[64];
176
177#ifdef __FreeBSD__

--- 9 unchanged lines hidden (view full) ---

187void pf_init_threshold(struct pf_threshold *, u_int32_t,
188 u_int32_t);
189void pf_add_threshold(struct pf_threshold *);
190int pf_check_threshold(struct pf_threshold *);
191
192void pf_change_ap(struct pf_addr *, u_int16_t *,
193 u_int16_t *, u_int16_t *, struct pf_addr *,
194 u_int16_t, u_int8_t, sa_family_t);
195int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *,
196 struct tcphdr *, struct pf_state_peer *);
189#ifdef INET6
190void pf_change_a6(struct pf_addr *, u_int16_t *,
191 struct pf_addr *, u_int8_t);
192#endif /* INET6 */
193void pf_change_icmp(struct pf_addr *, u_int16_t *,
194 struct pf_addr *, struct pf_addr *, u_int16_t,
195 u_int16_t *, u_int16_t *, u_int16_t *,
196 u_int16_t *, u_int8_t, sa_family_t);
197#ifdef __FreeBSD__
198void pf_send_tcp(struct mbuf *,
199 const struct pf_rule *, sa_family_t,
200#else
201void pf_send_tcp(const struct pf_rule *, sa_family_t,
202#endif
203 const struct pf_addr *, const struct pf_addr *,
204 u_int16_t, u_int16_t, u_int32_t, u_int32_t,
205 u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
197#ifdef INET6
198void pf_change_a6(struct pf_addr *, u_int16_t *,
199 struct pf_addr *, u_int8_t);
200#endif /* INET6 */
201void pf_change_icmp(struct pf_addr *, u_int16_t *,
202 struct pf_addr *, struct pf_addr *, u_int16_t,
203 u_int16_t *, u_int16_t *, u_int16_t *,
204 u_int16_t *, u_int8_t, sa_family_t);
205#ifdef __FreeBSD__
206void pf_send_tcp(struct mbuf *,
207 const struct pf_rule *, sa_family_t,
208#else
209void pf_send_tcp(const struct pf_rule *, sa_family_t,
210#endif
211 const struct pf_addr *, const struct pf_addr *,
212 u_int16_t, u_int16_t, u_int32_t, u_int32_t,
213 u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
206 struct ether_header *, struct ifnet *);
214 u_int16_t, struct ether_header *, struct ifnet *);
207void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
208 sa_family_t, struct pf_rule *);
209struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
210 int, int, struct pfi_kif *,
211 struct pf_addr *, u_int16_t, struct pf_addr *,
212 u_int16_t, int);
213struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
214 int, int, struct pfi_kif *, struct pf_src_node **,

--- 36 unchanged lines hidden (view full) ---

251int pf_test_state_udp(struct pf_state **, int,
252 struct pfi_kif *, struct mbuf *, int,
253 void *, struct pf_pdesc *);
254int pf_test_state_icmp(struct pf_state **, int,
255 struct pfi_kif *, struct mbuf *, int,
256 void *, struct pf_pdesc *, u_short *);
257int pf_test_state_other(struct pf_state **, int,
258 struct pfi_kif *, struct pf_pdesc *);
215void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
216 sa_family_t, struct pf_rule *);
217struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
218 int, int, struct pfi_kif *,
219 struct pf_addr *, u_int16_t, struct pf_addr *,
220 u_int16_t, int);
221struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
222 int, int, struct pfi_kif *, struct pf_src_node **,

--- 36 unchanged lines hidden (view full) ---

259int pf_test_state_udp(struct pf_state **, int,
260 struct pfi_kif *, struct mbuf *, int,
261 void *, struct pf_pdesc *);
262int pf_test_state_icmp(struct pf_state **, int,
263 struct pfi_kif *, struct mbuf *, int,
264 void *, struct pf_pdesc *, u_short *);
265int pf_test_state_other(struct pf_state **, int,
266 struct pfi_kif *, struct pf_pdesc *);
259struct pf_tag *pf_get_tag(struct mbuf *);
260int pf_match_tag(struct mbuf *, struct pf_rule *,
267int pf_match_tag(struct mbuf *, struct pf_rule *,
261 struct pf_tag **, int *);
268 struct pf_mtag *, int *);
269int pf_step_out_of_anchor(int *, struct pf_ruleset **,
270 int, struct pf_rule **, struct pf_rule **,
271 int *);
262void pf_hash(struct pf_addr *, struct pf_addr *,
263 struct pf_poolhashkey *, sa_family_t);
264int pf_map_addr(u_int8_t, struct pf_rule *,
265 struct pf_addr *, struct pf_addr *,
266 struct pf_addr *, struct pf_src_node **);
267int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
268 struct pf_addr *, struct pf_addr *, u_int16_t,
269 struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
270 struct pf_src_node **);
271void pf_route(struct mbuf **, struct pf_rule *, int,
272void pf_hash(struct pf_addr *, struct pf_addr *,
273 struct pf_poolhashkey *, sa_family_t);
274int pf_map_addr(u_int8_t, struct pf_rule *,
275 struct pf_addr *, struct pf_addr *,
276 struct pf_addr *, struct pf_src_node **);
277int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
278 struct pf_addr *, struct pf_addr *, u_int16_t,
279 struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
280 struct pf_src_node **);
281void pf_route(struct mbuf **, struct pf_rule *, int,
272 struct ifnet *, struct pf_state *);
282 struct ifnet *, struct pf_state *,
283 struct pf_pdesc *);
273void pf_route6(struct mbuf **, struct pf_rule *, int,
284void pf_route6(struct mbuf **, struct pf_rule *, int,
274 struct ifnet *, struct pf_state *);
285 struct ifnet *, struct pf_state *,
286 struct pf_pdesc *);
275#ifdef __FreeBSD__
287#ifdef __FreeBSD__
276int pf_socket_lookup(uid_t *, gid_t *,
277 int, struct pf_pdesc *, struct inpcb *);
288/* XXX: import */
278#else
289#else
279int pf_socket_lookup(uid_t *, gid_t *,
280 int, struct pf_pdesc *);
290int pf_socket_lookup(int, struct pf_pdesc *);
281#endif
282u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t,
283 sa_family_t);
284u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
285 sa_family_t);
286u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t,
287 u_int16_t);
288void pf_set_rt_ifp(struct pf_state *,
289 struct pf_addr *);
290int pf_check_proto_cksum(struct mbuf *, int, int,
291 u_int8_t, sa_family_t);
292int pf_addr_wrap_neq(struct pf_addr_wrap *,
293 struct pf_addr_wrap *);
291#endif
292u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t,
293 sa_family_t);
294u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
295 sa_family_t);
296u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t,
297 u_int16_t);
298void pf_set_rt_ifp(struct pf_state *,
299 struct pf_addr *);
300int pf_check_proto_cksum(struct mbuf *, int, int,
301 u_int8_t, sa_family_t);
302int pf_addr_wrap_neq(struct pf_addr_wrap *,
303 struct pf_addr_wrap *);
294static int pf_add_mbuf_tag(struct mbuf *, u_int);
295struct pf_state *pf_find_state_recurse(struct pfi_kif *,
304struct pf_state *pf_find_state_recurse(struct pfi_kif *,
296 struct pf_state *, u_int8_t);
305 struct pf_state_cmp *, u_int8_t);
297int pf_src_connlimit(struct pf_state **);
298int pf_check_congestion(struct ifqueue *);
299
300#ifdef __FreeBSD__
301int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len);
302
306int pf_src_connlimit(struct pf_state **);
307int pf_check_congestion(struct ifqueue *);
308
309#ifdef __FreeBSD__
310int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len);
311
303struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX];
312extern int pf_end_threads;
304
313
314struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX];
305#else
315#else
316extern struct pool pfr_ktable_pl;
317extern struct pool pfr_kentry_pl;
318
306struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
307 { &pf_state_pl, PFSTATE_HIWAT },
308 { &pf_src_tree_pl, PFSNODE_HIWAT },
319struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
320 { &pf_state_pl, PFSTATE_HIWAT },
321 { &pf_src_tree_pl, PFSNODE_HIWAT },
309 { &pf_frent_pl, PFFRAG_FRENT_HIWAT }
322 { &pf_frent_pl, PFFRAG_FRENT_HIWAT },
323 { &pfr_ktable_pl, PFR_KTABLE_HIWAT },
324 { &pfr_kentry_pl, PFR_KENTRY_HIWAT }
310};
311#endif
312
313#define STATE_LOOKUP() \
314 do { \
315 if (direction == PF_IN) \
316 *state = pf_find_state_recurse( \
317 kif, &key, PF_EXT_GWY); \

--- 15 unchanged lines hidden (view full) ---

333#define STATE_TRANSLATE(s) \
334 (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \
335 ((s)->af == AF_INET6 && \
336 ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \
337 (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \
338 (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \
339 (s)->lan.port != (s)->gwy.port
340
325};
326#endif
327
328#define STATE_LOOKUP() \
329 do { \
330 if (direction == PF_IN) \
331 *state = pf_find_state_recurse( \
332 kif, &key, PF_EXT_GWY); \

--- 15 unchanged lines hidden (view full) ---

348#define STATE_TRANSLATE(s) \
349 (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \
350 ((s)->af == AF_INET6 && \
351 ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \
352 (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \
353 (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \
354 (s)->lan.port != (s)->gwy.port
355
341#define BOUND_IFACE(r, k) (((r)->rule_flag & PFRULE_IFBOUND) ? (k) : \
342 ((r)->rule_flag & PFRULE_GRBOUND) ? (k)->pfik_parent : \
343 (k)->pfik_parent->pfik_parent)
356#define BOUND_IFACE(r, k) \
357 ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all
344
345#define STATE_INC_COUNTERS(s) \
346 do { \
347 s->rule.ptr->states++; \
348 if (s->anchor.ptr != NULL) \
349 s->anchor.ptr->states++; \
350 if (s->nat_rule.ptr != NULL) \
351 s->nat_rule.ptr->states++; \
352 } while (0)
353
354#define STATE_DEC_COUNTERS(s) \
355 do { \
356 if (s->nat_rule.ptr != NULL) \
357 s->nat_rule.ptr->states--; \
358 if (s->anchor.ptr != NULL) \
359 s->anchor.ptr->states--; \
360 s->rule.ptr->states--; \
361 } while (0)
362
358
359#define STATE_INC_COUNTERS(s) \
360 do { \
361 s->rule.ptr->states++; \
362 if (s->anchor.ptr != NULL) \
363 s->anchor.ptr->states++; \
364 if (s->nat_rule.ptr != NULL) \
365 s->nat_rule.ptr->states++; \
366 } while (0)
367
368#define STATE_DEC_COUNTERS(s) \
369 do { \
370 if (s->nat_rule.ptr != NULL) \
371 s->nat_rule.ptr->states--; \
372 if (s->anchor.ptr != NULL) \
373 s->anchor.ptr->states--; \
374 s->rule.ptr->states--; \
375 } while (0)
376
363#ifndef __FreeBSD__
364static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
365static __inline int pf_state_compare_lan_ext(struct pf_state *,
366 struct pf_state *);
367static __inline int pf_state_compare_ext_gwy(struct pf_state *,
368 struct pf_state *);
369static __inline int pf_state_compare_id(struct pf_state *,
370 struct pf_state *);
371static __inline int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
372#else
373static int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
374static int pf_state_compare_lan_ext(struct pf_state *,
375 struct pf_state *);
376static int pf_state_compare_ext_gwy(struct pf_state *,
377 struct pf_state *);
378static int pf_state_compare_id(struct pf_state *,
379 struct pf_state *);
380static int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
381#endif
382
383struct pf_src_tree tree_src_tracking;
384
385struct pf_state_tree_id tree_id;
377struct pf_src_tree tree_src_tracking;
378
379struct pf_state_tree_id tree_id;
386struct pf_state_queue state_updates;
380struct pf_state_queue state_list;
387
381
382#ifdef __FreeBSD__
383static int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
384static int pf_state_compare_lan_ext(struct pf_state *, struct pf_state *);
385static int pf_state_compare_ext_gwy(struct pf_state *, struct pf_state *);
386static int pf_state_compare_id(struct pf_state *, struct pf_state *);
387#endif
388
388RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
389RB_GENERATE(pf_state_tree_lan_ext, pf_state,
390 u.s.entry_lan_ext, pf_state_compare_lan_ext);
391RB_GENERATE(pf_state_tree_ext_gwy, pf_state,
392 u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
393RB_GENERATE(pf_state_tree_id, pf_state,
394 u.s.entry_id, pf_state_compare_id);
389RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
390RB_GENERATE(pf_state_tree_lan_ext, pf_state,
391 u.s.entry_lan_ext, pf_state_compare_lan_ext);
392RB_GENERATE(pf_state_tree_ext_gwy, pf_state,
393 u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
394RB_GENERATE(pf_state_tree_id, pf_state,
395 u.s.entry_id, pf_state_compare_id);
395RB_GENERATE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
396RB_GENERATE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
397
398#ifdef __FreeBSD__
399static int
400#else
401static __inline int
402#endif
403pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
404{

--- 196 unchanged lines hidden (view full) ---

601 if (a->creatorid > b->creatorid)
602 return (1);
603 if (a->creatorid < b->creatorid)
604 return (-1);
605
606 return (0);
607}
608
396
397#ifdef __FreeBSD__
398static int
399#else
400static __inline int
401#endif
402pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
403{

--- 196 unchanged lines hidden (view full) ---

600 if (a->creatorid > b->creatorid)
601 return (1);
602 if (a->creatorid < b->creatorid)
603 return (-1);
604
605 return (0);
606}
607
609#ifdef __FreeBSD__
610static int
611#else
612static __inline int
613#endif
614pf_anchor_compare(struct pf_anchor *a, struct pf_anchor *b)
615{
616 int c = strcmp(a->path, b->path);
617
618 return (c ? (c < 0 ? -1 : 1) : 0);
619}
620
621#ifdef INET6
622void
623pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
624{
625 switch (af) {
626#ifdef INET
627 case AF_INET:
628 dst->addr32[0] = src->addr32[0];

--- 5 unchanged lines hidden (view full) ---

634 dst->addr32[2] = src->addr32[2];
635 dst->addr32[3] = src->addr32[3];
636 break;
637 }
638}
639#endif /* INET6 */
640
641struct pf_state *
608#ifdef INET6
609void
610pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
611{
612 switch (af) {
613#ifdef INET
614 case AF_INET:
615 dst->addr32[0] = src->addr32[0];

--- 5 unchanged lines hidden (view full) ---

621 dst->addr32[2] = src->addr32[2];
622 dst->addr32[3] = src->addr32[3];
623 break;
624 }
625}
626#endif /* INET6 */
627
628struct pf_state *
642pf_find_state_byid(struct pf_state *key)
629pf_find_state_byid(struct pf_state_cmp *key)
643{
644 pf_status.fcounters[FCNT_STATE_SEARCH]++;
630{
631 pf_status.fcounters[FCNT_STATE_SEARCH]++;
645 return (RB_FIND(pf_state_tree_id, &tree_id, key));
632 return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key));
646}
647
648struct pf_state *
633}
634
635struct pf_state *
649pf_find_state_recurse(struct pfi_kif *kif, struct pf_state *key, u_int8_t tree)
636pf_find_state_recurse(struct pfi_kif *kif, struct pf_state_cmp *key, u_int8_t tree)
650{
651 struct pf_state *s;
652
653 pf_status.fcounters[FCNT_STATE_SEARCH]++;
654
655 switch (tree) {
656 case PF_LAN_EXT:
637{
638 struct pf_state *s;
639
640 pf_status.fcounters[FCNT_STATE_SEARCH]++;
641
642 switch (tree) {
643 case PF_LAN_EXT:
657 for (; kif != NULL; kif = kif->pfik_parent) {
658 s = RB_FIND(pf_state_tree_lan_ext,
659 &kif->pfik_lan_ext, key);
660 if (s != NULL)
661 return (s);
662 }
644 if ((s = RB_FIND(pf_state_tree_lan_ext, &kif->pfik_lan_ext,
645 (struct pf_state *)key)) != NULL)
646 return (s);
647 if ((s = RB_FIND(pf_state_tree_lan_ext, &pfi_all->pfik_lan_ext,
648 (struct pf_state *)key)) != NULL)
649 return (s);
663 return (NULL);
664 case PF_EXT_GWY:
650 return (NULL);
651 case PF_EXT_GWY:
665 for (; kif != NULL; kif = kif->pfik_parent) {
666 s = RB_FIND(pf_state_tree_ext_gwy,
667 &kif->pfik_ext_gwy, key);
668 if (s != NULL)
669 return (s);
670 }
652 if ((s = RB_FIND(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy,
653 (struct pf_state *)key)) != NULL)
654 return (s);
655 if ((s = RB_FIND(pf_state_tree_ext_gwy, &pfi_all->pfik_ext_gwy,
656 (struct pf_state *)key)) != NULL)
657 return (s);
671 return (NULL);
672 default:
673 panic("pf_find_state_recurse");
674 }
675}
676
677struct pf_state *
658 return (NULL);
659 default:
660 panic("pf_find_state_recurse");
661 }
662}
663
664struct pf_state *
678pf_find_state_all(struct pf_state *key, u_int8_t tree, int *more)
665pf_find_state_all(struct pf_state_cmp *key, u_int8_t tree, int *more)
679{
680 struct pf_state *s, *ss = NULL;
681 struct pfi_kif *kif;
682
683 pf_status.fcounters[FCNT_STATE_SEARCH]++;
684
685 switch (tree) {
686 case PF_LAN_EXT:
687 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
688 s = RB_FIND(pf_state_tree_lan_ext,
666{
667 struct pf_state *s, *ss = NULL;
668 struct pfi_kif *kif;
669
670 pf_status.fcounters[FCNT_STATE_SEARCH]++;
671
672 switch (tree) {
673 case PF_LAN_EXT:
674 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
675 s = RB_FIND(pf_state_tree_lan_ext,
689 &kif->pfik_lan_ext, key);
676 &kif->pfik_lan_ext, (struct pf_state *)key);
690 if (s == NULL)
691 continue;
692 if (more == NULL)
693 return (s);
694 ss = s;
695 (*more)++;
696 }
697 return (ss);
698 case PF_EXT_GWY:
699 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
700 s = RB_FIND(pf_state_tree_ext_gwy,
677 if (s == NULL)
678 continue;
679 if (more == NULL)
680 return (s);
681 ss = s;
682 (*more)++;
683 }
684 return (ss);
685 case PF_EXT_GWY:
686 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
687 s = RB_FIND(pf_state_tree_ext_gwy,
701 &kif->pfik_ext_gwy, key);
688 &kif->pfik_ext_gwy, (struct pf_state *)key);
702 if (s == NULL)
703 continue;
704 if (more == NULL)
705 return (s);
706 ss = s;
707 (*more)++;
708 }
709 return (ss);

--- 34 unchanged lines hidden (view full) ---

744
745int
746pf_src_connlimit(struct pf_state **state)
747{
748 struct pf_state *s;
749 int bad = 0;
750
751 (*state)->src_node->conn++;
689 if (s == NULL)
690 continue;
691 if (more == NULL)
692 return (s);
693 ss = s;
694 (*more)++;
695 }
696 return (ss);

--- 34 unchanged lines hidden (view full) ---

731
732int
733pf_src_connlimit(struct pf_state **state)
734{
735 struct pf_state *s;
736 int bad = 0;
737
738 (*state)->src_node->conn++;
752#ifdef __FreeBSD__
753 (*state)->local_flags |= PFSTATE_SRC_CONN;
754#endif
739 (*state)->src.tcp_est = 1;
755 pf_add_threshold(&(*state)->src_node->conn_rate);
756
757 if ((*state)->rule.ptr->max_src_conn &&
758 (*state)->rule.ptr->max_src_conn <
759 (*state)->src_node->conn) {
760 pf_status.lcounters[LCNT_SRCCONN]++;
761 bad++;
762 }

--- 204 unchanged lines hidden (view full) ---

967 if (state->sync_flags & PFSTATE_FROMSYNC)
968 printf(" (from sync)");
969 printf("\n");
970 }
971 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
972 RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state);
973 return (-1);
974 }
740 pf_add_threshold(&(*state)->src_node->conn_rate);
741
742 if ((*state)->rule.ptr->max_src_conn &&
743 (*state)->rule.ptr->max_src_conn <
744 (*state)->src_node->conn) {
745 pf_status.lcounters[LCNT_SRCCONN]++;
746 bad++;
747 }

--- 204 unchanged lines hidden (view full) ---

952 if (state->sync_flags & PFSTATE_FROMSYNC)
953 printf(" (from sync)");
954 printf("\n");
955 }
956 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
957 RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state);
958 return (-1);
959 }
975 TAILQ_INSERT_HEAD(&state_updates, state, u.s.entry_updates);
976
960 TAILQ_INSERT_TAIL(&state_list, state, u.s.entry_list);
977 pf_status.fcounters[FCNT_STATE_INSERT]++;
978 pf_status.states++;
961 pf_status.fcounters[FCNT_STATE_INSERT]++;
962 pf_status.states++;
979 pfi_attach_state(kif);
963 pfi_kif_ref(kif, PFI_KIF_REF_STATE);
980#if NPFSYNC
981 pfsync_insert_state(state);
982#endif
983 return (0);
984}
985
986void
964#if NPFSYNC
965 pfsync_insert_state(state);
966#endif
967 return (0);
968}
969
970void
987pf_purge_timeout(void *arg)
971pf_purge_thread(void *v)
988{
972{
989#ifdef __FreeBSD__
990 struct callout *to = arg;
991#else
992 struct timeout *to = arg;
993#endif
994 int s;
973 int nloops = 0, s;
995
974
975 for (;;) {
976 tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz);
977
996#ifdef __FreeBSD__
978#ifdef __FreeBSD__
997 PF_LOCK();
979 sx_slock(&pf_consistency_lock);
980 PF_LOCK();
981
982 if (pf_end_threads) {
983 pf_purge_expired_states(pf_status.states);
984 pf_purge_expired_fragments();
985 pf_purge_expired_src_nodes(0);
986 pf_end_threads++;
987
988 sx_sunlock(&pf_consistency_lock);
989 PF_UNLOCK();
990 wakeup(pf_purge_thread);
991 kthread_exit(0);
992 }
998#endif
993#endif
999 s = splsoftnet();
1000 pf_purge_expired_states();
1001 pf_purge_expired_fragments();
1002 pf_purge_expired_src_nodes();
1003 splx(s);
1004#ifdef __FreeBSD__
1005 PF_UNLOCK();
1006#endif
994 s = splsoftnet();
1007
995
996 /* process a fraction of the state table every second */
997 pf_purge_expired_states(1 + (pf_status.states
998 / pf_default_rule.timeout[PFTM_INTERVAL]));
999
1000 /* purge other expired types every PFTM_INTERVAL seconds */
1001 if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) {
1002 pf_purge_expired_fragments();
1003 pf_purge_expired_src_nodes(0);
1004 nloops = 0;
1005 }
1006
1007 splx(s);
1008#ifdef __FreeBSD__
1008#ifdef __FreeBSD__
1009 callout_reset(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz,
1010 pf_purge_timeout, to);
1011#else
1012 timeout_add(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz);
1009 PF_UNLOCK();
1010 sx_sunlock(&pf_consistency_lock);
1013#endif
1011#endif
1012 }
1014}
1015
1016u_int32_t
1017pf_state_expires(const struct pf_state *state)
1018{
1019 u_int32_t timeout;
1020 u_int32_t start;
1021 u_int32_t end;
1022 u_int32_t states;
1023
1024 /* handle all PFTM_* > PFTM_MAX here */
1025 if (state->timeout == PFTM_PURGE)
1026 return (time_second);
1027 if (state->timeout == PFTM_UNTIL_PACKET)
1028 return (0);
1029#ifdef __FreeBSD__
1013}
1014
1015u_int32_t
1016pf_state_expires(const struct pf_state *state)
1017{
1018 u_int32_t timeout;
1019 u_int32_t start;
1020 u_int32_t end;
1021 u_int32_t states;
1022
1023 /* handle all PFTM_* > PFTM_MAX here */
1024 if (state->timeout == PFTM_PURGE)
1025 return (time_second);
1026 if (state->timeout == PFTM_UNTIL_PACKET)
1027 return (0);
1028#ifdef __FreeBSD__
1029 KASSERT(state->timeout != PFTM_UNLINKED,
1030 ("pf_state_expires: timeout == PFTM_UNLINKED"));
1030 KASSERT((state->timeout < PFTM_MAX),
1031 ("pf_state_expires: timeout > PFTM_MAX"));
1032#else
1031 KASSERT((state->timeout < PFTM_MAX),
1032 ("pf_state_expires: timeout > PFTM_MAX"));
1033#else
1034 KASSERT(state->timeout != PFTM_UNLINKED);
1033 KASSERT(state->timeout < PFTM_MAX);
1034#endif
1035 timeout = state->rule.ptr->timeout[state->timeout];
1036 if (!timeout)
1037 timeout = pf_default_rule.timeout[state->timeout];
1038 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
1039 if (start) {
1040 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];

--- 9 unchanged lines hidden (view full) ---

1050 (end - start));
1051 else
1052 return (time_second);
1053 }
1054 return (state->expire + timeout);
1055}
1056
1057void
1035 KASSERT(state->timeout < PFTM_MAX);
1036#endif
1037 timeout = state->rule.ptr->timeout[state->timeout];
1038 if (!timeout)
1039 timeout = pf_default_rule.timeout[state->timeout];
1040 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
1041 if (start) {
1042 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];

--- 9 unchanged lines hidden (view full) ---

1052 (end - start));
1053 else
1054 return (time_second);
1055 }
1056 return (state->expire + timeout);
1057}
1058
1059void
1058pf_purge_expired_src_nodes(void)
1060pf_purge_expired_src_nodes(int waslocked)
1059{
1060 struct pf_src_node *cur, *next;
1061{
1062 struct pf_src_node *cur, *next;
1063 int locked = waslocked;
1061
1062 for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
1063 next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
1064
1065 if (cur->states <= 0 && cur->expire <= time_second) {
1064
1065 for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
1066 next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
1067
1068 if (cur->states <= 0 && cur->expire <= time_second) {
1069 if (! locked) {
1070#ifdef __FreeBSD__
1071 if (!sx_try_upgrade(&pf_consistency_lock)) {
1072 PF_UNLOCK();
1073 sx_sunlock(&pf_consistency_lock);
1074 sx_xlock(&pf_consistency_lock);
1075 PF_LOCK();
1076 }
1077#else
1078 rw_enter_write(&pf_consistency_lock);
1079#endif
1080 next = RB_NEXT(pf_src_tree,
1081 &tree_src_tracking, cur);
1082 locked = 1;
1083 }
1066 if (cur->rule.ptr != NULL) {
1067 cur->rule.ptr->src_nodes--;
1068 if (cur->rule.ptr->states <= 0 &&
1069 cur->rule.ptr->max_src_nodes <= 0)
1070 pf_rm_rule(NULL, cur->rule.ptr);
1071 }
1072 RB_REMOVE(pf_src_tree, &tree_src_tracking, cur);
1073 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
1074 pf_status.src_nodes--;
1075 pool_put(&pf_src_tree_pl, cur);
1076 }
1077 }
1084 if (cur->rule.ptr != NULL) {
1085 cur->rule.ptr->src_nodes--;
1086 if (cur->rule.ptr->states <= 0 &&
1087 cur->rule.ptr->max_src_nodes <= 0)
1088 pf_rm_rule(NULL, cur->rule.ptr);
1089 }
1090 RB_REMOVE(pf_src_tree, &tree_src_tracking, cur);
1091 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
1092 pf_status.src_nodes--;
1093 pool_put(&pf_src_tree_pl, cur);
1094 }
1095 }
1096
1097 if (locked && !waslocked)
1098#ifdef __FreeBSD__
1099 sx_downgrade(&pf_consistency_lock);
1100#else
1101 rw_exit_write(&pf_consistency_lock);
1102#endif
1078}
1079
1080void
1081pf_src_tree_remove_state(struct pf_state *s)
1082{
1083 u_int32_t timeout;
1084
1085 if (s->src_node != NULL) {
1086 if (s->proto == IPPROTO_TCP) {
1103}
1104
1105void
1106pf_src_tree_remove_state(struct pf_state *s)
1107{
1108 u_int32_t timeout;
1109
1110 if (s->src_node != NULL) {
1111 if (s->proto == IPPROTO_TCP) {
1087#ifdef __FreeBSD__
1088 if (s->local_flags & PFSTATE_SRC_CONN)
1089#else
1090 if (s->src.state == PF_TCPS_PROXY_DST ||
1091 s->timeout >= PFTM_TCP_ESTABLISHED)
1092#endif
1112 if (s->src.tcp_est)
1093 --s->src_node->conn;
1094 }
1095 if (--s->src_node->states <= 0) {
1096 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1097 if (!timeout)
1098 timeout =
1099 pf_default_rule.timeout[PFTM_SRC_NODE];
1100 s->src_node->expire = time_second + timeout;

--- 6 unchanged lines hidden (view full) ---

1107 timeout =
1108 pf_default_rule.timeout[PFTM_SRC_NODE];
1109 s->nat_src_node->expire = time_second + timeout;
1110 }
1111 }
1112 s->src_node = s->nat_src_node = NULL;
1113}
1114
1113 --s->src_node->conn;
1114 }
1115 if (--s->src_node->states <= 0) {
1116 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1117 if (!timeout)
1118 timeout =
1119 pf_default_rule.timeout[PFTM_SRC_NODE];
1120 s->src_node->expire = time_second + timeout;

--- 6 unchanged lines hidden (view full) ---

1127 timeout =
1128 pf_default_rule.timeout[PFTM_SRC_NODE];
1129 s->nat_src_node->expire = time_second + timeout;
1130 }
1131 }
1132 s->src_node = s->nat_src_node = NULL;
1133}
1134
1135/* callers should be at splsoftnet */
1115void
1136void
1116pf_purge_expired_state(struct pf_state *cur)
1137pf_unlink_state(struct pf_state *cur)
1117{
1118#ifdef __FreeBSD__
1119 if (cur->local_flags & PFSTATE_EXPIRING)
1120 return;
1121 cur->local_flags |= PFSTATE_EXPIRING;
1122#endif
1138{
1139#ifdef __FreeBSD__
1140 if (cur->local_flags & PFSTATE_EXPIRING)
1141 return;
1142 cur->local_flags |= PFSTATE_EXPIRING;
1143#endif
1123 if (cur->src.state == PF_TCPS_PROXY_DST)
1144 if (cur->src.state == PF_TCPS_PROXY_DST) {
1124#ifdef __FreeBSD__
1125 pf_send_tcp(NULL, cur->rule.ptr, cur->af,
1126#else
1127 pf_send_tcp(cur->rule.ptr, cur->af,
1128#endif
1129 &cur->ext.addr, &cur->lan.addr,
1130 cur->ext.port, cur->lan.port,
1131 cur->src.seqhi, cur->src.seqlo + 1,
1145#ifdef __FreeBSD__
1146 pf_send_tcp(NULL, cur->rule.ptr, cur->af,
1147#else
1148 pf_send_tcp(cur->rule.ptr, cur->af,
1149#endif
1150 &cur->ext.addr, &cur->lan.addr,
1151 cur->ext.port, cur->lan.port,
1152 cur->src.seqhi, cur->src.seqlo + 1,
1132 TH_RST|TH_ACK, 0, 0, 0, 1, NULL, NULL);
1153 TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL);
1154 }
1133 RB_REMOVE(pf_state_tree_ext_gwy,
1134 &cur->u.s.kif->pfik_ext_gwy, cur);
1135 RB_REMOVE(pf_state_tree_lan_ext,
1136 &cur->u.s.kif->pfik_lan_ext, cur);
1137 RB_REMOVE(pf_state_tree_id, &tree_id, cur);
1138#if NPFSYNC
1155 RB_REMOVE(pf_state_tree_ext_gwy,
1156 &cur->u.s.kif->pfik_ext_gwy, cur);
1157 RB_REMOVE(pf_state_tree_lan_ext,
1158 &cur->u.s.kif->pfik_lan_ext, cur);
1159 RB_REMOVE(pf_state_tree_id, &tree_id, cur);
1160#if NPFSYNC
1139 pfsync_delete_state(cur);
1161 if (cur->creatorid == pf_status.hostid)
1162 pfsync_delete_state(cur);
1140#endif
1163#endif
1164 cur->timeout = PFTM_UNLINKED;
1141 pf_src_tree_remove_state(cur);
1165 pf_src_tree_remove_state(cur);
1166}
1167
1168/* callers should be at splsoftnet and hold the
1169 * write_lock on pf_consistency_lock */
1170void
1171pf_free_state(struct pf_state *cur)
1172{
1173#if NPFSYNC
1174 if (pfsyncif != NULL &&
1175 (pfsyncif->sc_bulk_send_next == cur ||
1176 pfsyncif->sc_bulk_terminator == cur))
1177 return;
1178#endif
1179#ifdef __FreeBSD__
1180 KASSERT(cur->timeout == PFTM_UNLINKED,
1181 ("pf_free_state: cur->timeout != PFTM_UNLINKED"));
1182#else
1183 KASSERT(cur->timeout == PFTM_UNLINKED);
1184#endif
1142 if (--cur->rule.ptr->states <= 0 &&
1143 cur->rule.ptr->src_nodes <= 0)
1144 pf_rm_rule(NULL, cur->rule.ptr);
1145 if (cur->nat_rule.ptr != NULL)
1146 if (--cur->nat_rule.ptr->states <= 0 &&
1147 cur->nat_rule.ptr->src_nodes <= 0)
1148 pf_rm_rule(NULL, cur->nat_rule.ptr);
1149 if (cur->anchor.ptr != NULL)
1150 if (--cur->anchor.ptr->states <= 0)
1151 pf_rm_rule(NULL, cur->anchor.ptr);
1152 pf_normalize_tcp_cleanup(cur);
1185 if (--cur->rule.ptr->states <= 0 &&
1186 cur->rule.ptr->src_nodes <= 0)
1187 pf_rm_rule(NULL, cur->rule.ptr);
1188 if (cur->nat_rule.ptr != NULL)
1189 if (--cur->nat_rule.ptr->states <= 0 &&
1190 cur->nat_rule.ptr->src_nodes <= 0)
1191 pf_rm_rule(NULL, cur->nat_rule.ptr);
1192 if (cur->anchor.ptr != NULL)
1193 if (--cur->anchor.ptr->states <= 0)
1194 pf_rm_rule(NULL, cur->anchor.ptr);
1195 pf_normalize_tcp_cleanup(cur);
1153 pfi_detach_state(cur->u.s.kif);
1154 TAILQ_REMOVE(&state_updates, cur, u.s.entry_updates);
1196 pfi_kif_unref(cur->u.s.kif, PFI_KIF_REF_STATE);
1197 TAILQ_REMOVE(&state_list, cur, u.s.entry_list);
1155 if (cur->tag)
1156 pf_tag_unref(cur->tag);
1157 pool_put(&pf_state_pl, cur);
1158 pf_status.fcounters[FCNT_STATE_REMOVALS]++;
1159 pf_status.states--;
1160}
1161
1162void
1198 if (cur->tag)
1199 pf_tag_unref(cur->tag);
1200 pool_put(&pf_state_pl, cur);
1201 pf_status.fcounters[FCNT_STATE_REMOVALS]++;
1202 pf_status.states--;
1203}
1204
1205void
1163pf_purge_expired_states(void)
1206pf_purge_expired_states(u_int32_t maxcheck)
1164{
1207{
1165 struct pf_state *cur, *next;
1208 static struct pf_state *cur = NULL;
1209 struct pf_state *next;
1210 int locked = 0;
1166
1211
1167 for (cur = RB_MIN(pf_state_tree_id, &tree_id);
1168 cur; cur = next) {
1169 next = RB_NEXT(pf_state_tree_id, &tree_id, cur);
1170 if (pf_state_expires(cur) <= time_second)
1171 pf_purge_expired_state(cur);
1212 while (maxcheck--) {
1213 /* wrap to start of list when we hit the end */
1214 if (cur == NULL) {
1215 cur = TAILQ_FIRST(&state_list);
1216 if (cur == NULL)
1217 break; /* list empty */
1218 }
1219
1220 /* get next state, as cur may get deleted */
1221 next = TAILQ_NEXT(cur, u.s.entry_list);
1222
1223 if (cur->timeout == PFTM_UNLINKED) {
1224 /* free unlinked state */
1225 if (! locked) {
1226#ifdef __FreeBSD__
1227 if (!sx_try_upgrade(&pf_consistency_lock)) {
1228 PF_UNLOCK();
1229 sx_sunlock(&pf_consistency_lock);
1230 sx_xlock(&pf_consistency_lock);
1231 PF_LOCK();
1232 }
1233#else
1234 rw_enter_write(&pf_consistency_lock);
1235#endif
1236 locked = 1;
1237 }
1238 pf_free_state(cur);
1239 } else if (pf_state_expires(cur) <= time_second) {
1240 /* unlink and free expired state */
1241 pf_unlink_state(cur);
1242 if (! locked) {
1243#ifdef __FreeBSD__
1244 if (!sx_try_upgrade(&pf_consistency_lock)) {
1245 PF_UNLOCK();
1246 sx_sunlock(&pf_consistency_lock);
1247 sx_xlock(&pf_consistency_lock);
1248 PF_LOCK();
1249 }
1250#else
1251 rw_enter_write(&pf_consistency_lock);
1252#endif
1253 locked = 1;
1254 }
1255 pf_free_state(cur);
1256 }
1257 cur = next;
1172 }
1258 }
1259
1260 if (locked)
1261#ifdef __FreeBSD__
1262 sx_downgrade(&pf_consistency_lock);
1263#else
1264 rw_exit_write(&pf_consistency_lock);
1265#endif
1173}
1174
1175int
1176pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
1177{
1178 if (aw->type != PF_ADDR_TABLE)
1179 return (0);
1180 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)

--- 209 unchanged lines hidden (view full) ---

1390 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
1391 return (1);
1392 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
1393 return (1);
1394 return (0);
1395 case PF_ADDR_DYNIFTL:
1396 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
1397 case PF_ADDR_NOROUTE:
1266}
1267
1268int
1269pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
1270{
1271 if (aw->type != PF_ADDR_TABLE)
1272 return (0);
1273 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)

--- 209 unchanged lines hidden (view full) ---

1483 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
1484 return (1);
1485 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
1486 return (1);
1487 return (0);
1488 case PF_ADDR_DYNIFTL:
1489 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
1490 case PF_ADDR_NOROUTE:
1491 case PF_ADDR_URPFFAILED:
1398 return (0);
1399 case PF_ADDR_TABLE:
1400 return (aw1->p.tbl != aw2->p.tbl);
1492 return (0);
1493 case PF_ADDR_TABLE:
1494 return (aw1->p.tbl != aw2->p.tbl);
1495 case PF_ADDR_RTLABEL:
1496 return (aw1->v.rtlabel != aw2->v.rtlabel);
1401 default:
1402 printf("invalid address type: %d\n", aw1->type);
1403 return (1);
1404 }
1405}
1406
1407u_int16_t
1408pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp)

--- 170 unchanged lines hidden (view full) ---

1579 ooa.addr16[5], oa->addr16[5], u),
1580 ooa.addr16[6], oa->addr16[6], u),
1581 ooa.addr16[7], oa->addr16[7], u);
1582 break;
1583#endif /* INET6 */
1584 }
1585}
1586
1497 default:
1498 printf("invalid address type: %d\n", aw1->type);
1499 return (1);
1500 }
1501}
1502
1503u_int16_t
1504pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp)

--- 170 unchanged lines hidden (view full) ---

1675 ooa.addr16[5], oa->addr16[5], u),
1676 ooa.addr16[6], oa->addr16[6], u),
1677 ooa.addr16[7], oa->addr16[7], u);
1678 break;
1679#endif /* INET6 */
1680 }
1681}
1682
1683
1684/*
1685 * Need to modulate the sequence numbers in the TCP SACK option
1686 * (credits to Krzysztof Pfaff for report and patch)
1687 */
1688int
1689pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd,
1690 struct tcphdr *th, struct pf_state_peer *dst)
1691{
1692 int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen;
1693#ifdef __FreeBSD__
1694 u_int8_t opts[TCP_MAXOLEN], *opt = opts;
1695#else
1696 u_int8_t opts[MAX_TCPOPTLEN], *opt = opts;
1697#endif
1698 int copyback = 0, i, olen;
1699 struct sackblk sack;
1700
1701#define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2)
1702 if (hlen < TCPOLEN_SACKLEN ||
1703 !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af))
1704 return 0;
1705
1706 while (hlen >= TCPOLEN_SACKLEN) {
1707 olen = opt[1];
1708 switch (*opt) {
1709 case TCPOPT_EOL: /* FALLTHROUGH */
1710 case TCPOPT_NOP:
1711 opt++;
1712 hlen--;
1713 break;
1714 case TCPOPT_SACK:
1715 if (olen > hlen)
1716 olen = hlen;
1717 if (olen >= TCPOLEN_SACKLEN) {
1718 for (i = 2; i + TCPOLEN_SACK <= olen;
1719 i += TCPOLEN_SACK) {
1720 memcpy(&sack, &opt[i], sizeof(sack));
1721 pf_change_a(&sack.start, &th->th_sum,
1722 htonl(ntohl(sack.start) -
1723 dst->seqdiff), 0);
1724 pf_change_a(&sack.end, &th->th_sum,
1725 htonl(ntohl(sack.end) -
1726 dst->seqdiff), 0);
1727 memcpy(&opt[i], &sack, sizeof(sack));
1728 }
1729 copyback = 1;
1730 }
1731 /* FALLTHROUGH */
1732 default:
1733 if (olen < 2)
1734 olen = 2;
1735 hlen -= olen;
1736 opt += olen;
1737 }
1738 }
1739
1740 if (copyback)
1741#ifdef __FreeBSD__
1742 m_copyback(m, off + sizeof(*th), thoptlen, (caddr_t)opts);
1743#else
1744 m_copyback(m, off + sizeof(*th), thoptlen, opts);
1745#endif
1746 return (copyback);
1747}
1748
1587void
1588#ifdef __FreeBSD__
1589pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af,
1590#else
1591pf_send_tcp(const struct pf_rule *r, sa_family_t af,
1592#endif
1593 const struct pf_addr *saddr, const struct pf_addr *daddr,
1594 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
1595 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
1749void
1750#ifdef __FreeBSD__
1751pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af,
1752#else
1753pf_send_tcp(const struct pf_rule *r, sa_family_t af,
1754#endif
1755 const struct pf_addr *saddr, const struct pf_addr *daddr,
1756 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
1757 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
1596 struct ether_header *eh, struct ifnet *ifp)
1758 u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp)
1597{
1598 struct mbuf *m;
1759{
1760 struct mbuf *m;
1599 int len = 0, tlen; /* make the compiler happy */
1761 int len, tlen;
1600#ifdef INET
1762#ifdef INET
1601 struct ip *h = NULL; /* make the compiler happy */
1763 struct ip *h;
1602#endif /* INET */
1603#ifdef INET6
1764#endif /* INET */
1765#ifdef INET6
1604 struct ip6_hdr *h6 = NULL; /* make the compiler happy */
1766 struct ip6_hdr *h6;
1605#endif /* INET6 */
1767#endif /* INET6 */
1606 struct tcphdr *th = NULL; /* make the compiler happy */
1607 char *opt;
1768 struct tcphdr *th;
1769 char *opt;
1770 struct pf_mtag *pf_mtag;
1608
1771
1772#ifdef __FreeBSD__
1773 KASSERT(
1774#ifdef INET
1775 af == AF_INET
1776#else
1777 0
1778#endif
1779 ||
1780#ifdef INET6
1781 af == AF_INET6
1782#else
1783 0
1784#endif
1785 , ("Unsupported AF %d", af));
1786 len = 0;
1787 th = NULL;
1788#ifdef INET
1789 h = NULL;
1790#endif
1791#ifdef INET6
1792 h6 = NULL;
1793#endif
1794#endif
1795
1609 /* maximum segment size tcp option */
1610 tlen = sizeof(struct tcphdr);
1611 if (mss)
1612 tlen += 4;
1613
1614 switch (af) {
1615#ifdef INET
1616 case AF_INET:

--- 16 unchanged lines hidden (view full) ---

1633 if (replyto)
1634 mac_create_mbuf_netlayer(replyto, m);
1635 else
1636 mac_create_mbuf_from_firewall(m);
1637#else
1638 (void)replyto;
1639#endif
1640#endif
1796 /* maximum segment size tcp option */
1797 tlen = sizeof(struct tcphdr);
1798 if (mss)
1799 tlen += 4;
1800
1801 switch (af) {
1802#ifdef INET
1803 case AF_INET:

--- 16 unchanged lines hidden (view full) ---

1820 if (replyto)
1821 mac_create_mbuf_netlayer(replyto, m);
1822 else
1823 mac_create_mbuf_from_firewall(m);
1824#else
1825 (void)replyto;
1826#endif
1827#endif
1641 if (tag) {
1828 if ((pf_mtag = pf_get_mtag(m)) == NULL) {
1829 m_freem(m);
1830 return;
1831 }
1832 if (tag)
1642#ifdef __FreeBSD__
1643 m->m_flags |= M_SKIP_FIREWALL;
1644#else
1833#ifdef __FreeBSD__
1834 m->m_flags |= M_SKIP_FIREWALL;
1835#else
1645 struct m_tag *mtag;
1646
1647 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
1648 if (mtag == NULL) {
1649 m_freem(m);
1650 return;
1651 }
1652 m_tag_prepend(m, mtag);
1836 pf_mtag->flags |= PF_TAG_GENERATED;
1653#endif
1837#endif
1654 }
1838
1839 pf_mtag->tag = rtag;
1840
1841 if (r != NULL && r->rtableid >= 0)
1842 pf_mtag->rtableid = r->rtableid;
1655#ifdef ALTQ
1656 if (r != NULL && r->qid) {
1843#ifdef ALTQ
1844 if (r != NULL && r->qid) {
1657 struct m_tag *mtag;
1658 struct altq_tag *atag;
1659
1660 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
1661 if (mtag != NULL) {
1662 atag = (struct altq_tag *)(mtag + 1);
1663 atag->qid = r->qid;
1664 /* add hints for ecn */
1665 atag->af = af;
1666 atag->hdr = mtod(m, struct ip *);
1667 m_tag_prepend(m, mtag);
1668 }
1845 pf_mtag->qid = r->qid;
1846 /* add hints for ecn */
1847 pf_mtag->af = af;
1848 pf_mtag->hdr = mtod(m, struct ip *);
1669 }
1670#endif /* ALTQ */
1671 m->m_data += max_linkhdr;
1672 m->m_pkthdr.len = m->m_len = len;
1673 m->m_pkthdr.rcvif = NULL;
1674 bzero(m->m_data, len);
1675 switch (af) {
1676#ifdef INET

--- 119 unchanged lines hidden (view full) ---

1796#endif /* INET6 */
1797 }
1798}
1799
1800void
1801pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
1802 struct pf_rule *r)
1803{
1849 }
1850#endif /* ALTQ */
1851 m->m_data += max_linkhdr;
1852 m->m_pkthdr.len = m->m_len = len;
1853 m->m_pkthdr.rcvif = NULL;
1854 bzero(m->m_data, len);
1855 switch (af) {
1856#ifdef INET

--- 119 unchanged lines hidden (view full) ---

1976#endif /* INET6 */
1977 }
1978}
1979
1980void
1981pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
1982 struct pf_rule *r)
1983{
1804#ifdef ALTQ
1805 struct m_tag *mtag;
1806#endif
1984 struct pf_mtag *pf_mtag;
1807 struct mbuf *m0;
1808#ifdef __FreeBSD__
1809 struct ip *ip;
1810#endif
1811
1812#ifdef __FreeBSD__
1813 m0 = m_copypacket(m, M_DONTWAIT);
1814 if (m0 == NULL)
1815 return;
1985 struct mbuf *m0;
1986#ifdef __FreeBSD__
1987 struct ip *ip;
1988#endif
1989
1990#ifdef __FreeBSD__
1991 m0 = m_copypacket(m, M_DONTWAIT);
1992 if (m0 == NULL)
1993 return;
1816 m0->m_flags |= M_SKIP_FIREWALL;
1817#else
1994#else
1818 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
1819 if (mtag == NULL)
1820 return;
1821 m0 = m_copy(m, 0, M_COPYALL);
1995 m0 = m_copy(m, 0, M_COPYALL);
1822 if (m0 == NULL) {
1823 m_tag_free(mtag);
1996#endif
1997 if ((pf_mtag = pf_get_mtag(m0)) == NULL)
1824 return;
1998 return;
1825 }
1826 m_tag_prepend(m0, mtag);
1999#ifdef __FreeBSD__
2000 /* XXX: revisit */
2001 m0->m_flags |= M_SKIP_FIREWALL;
2002#else
2003 pf_mtag->flags |= PF_TAG_GENERATED;
1827#endif
1828
2004#endif
2005
2006 if (r->rtableid >= 0)
2007 pf_mtag->rtableid = r->rtableid;
2008
1829#ifdef ALTQ
1830 if (r->qid) {
2009#ifdef ALTQ
2010 if (r->qid) {
1831 struct altq_tag *atag;
1832
1833 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
1834 if (mtag != NULL) {
1835 atag = (struct altq_tag *)(mtag + 1);
1836 atag->qid = r->qid;
1837 /* add hints for ecn */
1838 atag->af = af;
1839 atag->hdr = mtod(m0, struct ip *);
1840 m_tag_prepend(m0, mtag);
1841 }
2011 pf_mtag->qid = r->qid;
2012 /* add hints for ecn */
2013 pf_mtag->af = af;
2014 pf_mtag->hdr = mtod(m0, struct ip *);
1842 }
1843#endif /* ALTQ */
1844
1845 switch (af) {
1846#ifdef INET
1847 case AF_INET:
1848#ifdef __FreeBSD__
1849 /* icmp_error() expects host byte ordering */
1850 ip = mtod(m0, struct ip *);
1851 NTOHS(ip->ip_len);
1852 NTOHS(ip->ip_off);
1853 PF_UNLOCK();
1854 icmp_error(m0, type, code, 0, 0);
1855 PF_LOCK();
1856#else
2015 }
2016#endif /* ALTQ */
2017
2018 switch (af) {
2019#ifdef INET
2020 case AF_INET:
2021#ifdef __FreeBSD__
2022 /* icmp_error() expects host byte ordering */
2023 ip = mtod(m0, struct ip *);
2024 NTOHS(ip->ip_len);
2025 NTOHS(ip->ip_off);
2026 PF_UNLOCK();
2027 icmp_error(m0, type, code, 0, 0);
2028 PF_LOCK();
2029#else
1857 icmp_error(m0, type, code, 0, (void *)NULL);
2030 icmp_error(m0, type, code, 0, 0);
1858#endif
1859 break;
1860#endif /* INET */
1861#ifdef INET6
1862 case AF_INET6:
1863#ifdef __FreeBSD__
1864 PF_UNLOCK();
1865#endif

--- 98 unchanged lines hidden (view full) ---

1964int
1965pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
1966{
1967 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
1968 return (0);
1969 return (pf_match(op, a1, a2, g));
1970}
1971
2031#endif
2032 break;
2033#endif /* INET */
2034#ifdef INET6
2035 case AF_INET6:
2036#ifdef __FreeBSD__
2037 PF_UNLOCK();
2038#endif

--- 98 unchanged lines hidden (view full) ---

2137int
2138pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
2139{
2140 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
2141 return (0);
2142 return (pf_match(op, a1, a2, g));
2143}
2144
1972struct pf_tag *
1973pf_get_tag(struct mbuf *m)
2145#ifndef __FreeBSD__
2146struct pf_mtag *
2147pf_find_mtag(struct mbuf *m)
1974{
1975 struct m_tag *mtag;
1976
2148{
2149 struct m_tag *mtag;
2150
1977 if ((mtag = m_tag_find(m, PACKET_TAG_PF_TAG, NULL)) != NULL)
1978 return ((struct pf_tag *)(mtag + 1));
1979 else
2151 if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL)
1980 return (NULL);
2152 return (NULL);
2153
2154 return ((struct pf_mtag *)(mtag + 1));
1981}
1982
2155}
2156
1983int
1984pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_tag **pftag, int *tag)
2157struct pf_mtag *
2158pf_get_mtag(struct mbuf *m)
1985{
2159{
1986 if (*tag == -1) { /* find mbuf tag */
1987 *pftag = pf_get_tag(m);
1988 if (*pftag != NULL)
1989 *tag = (*pftag)->tag;
1990 else
1991 *tag = 0;
2160 struct m_tag *mtag;
2161
2162 if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) {
2163 mtag = m_tag_get(PACKET_TAG_PF, sizeof(struct pf_mtag),
2164 M_NOWAIT);
2165 if (mtag == NULL)
2166 return (NULL);
2167 bzero(mtag + 1, sizeof(struct pf_mtag));
2168 m_tag_prepend(m, mtag);
1992 }
1993
2169 }
2170
2171 return ((struct pf_mtag *)(mtag + 1));
2172}
2173#endif
2174
2175int
2176pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_mtag *pf_mtag,
2177 int *tag)
2178{
2179 if (*tag == -1)
2180 *tag = pf_mtag->tag;
2181
1994 return ((!r->match_tag_not && r->match_tag == *tag) ||
1995 (r->match_tag_not && r->match_tag != *tag));
1996}
1997
1998int
2182 return ((!r->match_tag_not && r->match_tag == *tag) ||
2183 (r->match_tag_not && r->match_tag != *tag));
2184}
2185
2186int
1999pf_tag_packet(struct mbuf *m, struct pf_tag *pftag, int tag)
2187pf_tag_packet(struct mbuf *m, struct pf_mtag *pf_mtag, int tag, int rtableid)
2000{
2188{
2001 struct m_tag *mtag;
2002
2003 if (tag <= 0)
2189 if (tag <= 0 && rtableid < 0)
2004 return (0);
2005
2190 return (0);
2191
2006 if (pftag == NULL) {
2007 mtag = m_tag_get(PACKET_TAG_PF_TAG, sizeof(*pftag), M_NOWAIT);
2008 if (mtag == NULL)
2192 if (pf_mtag == NULL)
2193 if ((pf_mtag = pf_get_mtag(m)) == NULL)
2009 return (1);
2194 return (1);
2010 ((struct pf_tag *)(mtag + 1))->tag = tag;
2011 m_tag_prepend(m, mtag);
2012 } else
2013 pftag->tag = tag;
2195 if (tag > 0)
2196 pf_mtag->tag = tag;
2197 if (rtableid >= 0)
2198 pf_mtag->rtableid = rtableid;
2014
2015 return (0);
2016}
2017
2018static void
2019pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n,
2199
2200 return (0);
2201}
2202
2203static void
2204pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n,
2020 struct pf_rule **r, struct pf_rule **a)
2205 struct pf_rule **r, struct pf_rule **a, int *match)
2021{
2022 struct pf_anchor_stackframe *f;
2023
2206{
2207 struct pf_anchor_stackframe *f;
2208
2209 (*r)->anchor->match = 0;
2210 if (match)
2211 *match = 0;
2024 if (*depth >= sizeof(pf_anchor_stack) /
2025 sizeof(pf_anchor_stack[0])) {
2026 printf("pf_step_into_anchor: stack overflow\n");
2027 *r = TAILQ_NEXT(*r, entries);
2028 return;
2029 } else if (*depth == 0 && a != NULL)
2030 *a = *r;
2031 f = pf_anchor_stack + (*depth)++;

--- 10 unchanged lines hidden (view full) ---

2042 } else {
2043 f->parent = NULL;
2044 f->child = NULL;
2045 *rs = &(*r)->anchor->ruleset;
2046 }
2047 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2048}
2049
2212 if (*depth >= sizeof(pf_anchor_stack) /
2213 sizeof(pf_anchor_stack[0])) {
2214 printf("pf_step_into_anchor: stack overflow\n");
2215 *r = TAILQ_NEXT(*r, entries);
2216 return;
2217 } else if (*depth == 0 && a != NULL)
2218 *a = *r;
2219 f = pf_anchor_stack + (*depth)++;

--- 10 unchanged lines hidden (view full) ---

2230 } else {
2231 f->parent = NULL;
2232 f->child = NULL;
2233 *rs = &(*r)->anchor->ruleset;
2234 }
2235 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2236}
2237
2050static void
2238int
2051pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n,
2239pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n,
2052 struct pf_rule **r, struct pf_rule **a)
2240 struct pf_rule **r, struct pf_rule **a, int *match)
2053{
2054 struct pf_anchor_stackframe *f;
2241{
2242 struct pf_anchor_stackframe *f;
2243 int quick = 0;
2055
2056 do {
2057 if (*depth <= 0)
2058 break;
2059 f = pf_anchor_stack + *depth - 1;
2060 if (f->parent != NULL && f->child != NULL) {
2244
2245 do {
2246 if (*depth <= 0)
2247 break;
2248 f = pf_anchor_stack + *depth - 1;
2249 if (f->parent != NULL && f->child != NULL) {
2250 if (f->child->match ||
2251 (match != NULL && *match)) {
2252 f->r->anchor->match = 1;
2253 *match = 0;
2254 }
2061 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child);
2062 if (f->child != NULL) {
2063 *rs = &f->child->ruleset;
2064 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2065 if (*r == NULL)
2066 continue;
2067 else
2068 break;
2069 }
2070 }
2071 (*depth)--;
2072 if (*depth == 0 && a != NULL)
2073 *a = NULL;
2074 *rs = f->rs;
2255 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child);
2256 if (f->child != NULL) {
2257 *rs = &f->child->ruleset;
2258 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2259 if (*r == NULL)
2260 continue;
2261 else
2262 break;
2263 }
2264 }
2265 (*depth)--;
2266 if (*depth == 0 && a != NULL)
2267 *a = NULL;
2268 *rs = f->rs;
2269 if (f->r->anchor->match || (match != NULL && *match))
2270 quick = f->r->quick;
2075 *r = TAILQ_NEXT(f->r, entries);
2076 } while (*r == NULL);
2271 *r = TAILQ_NEXT(f->r, entries);
2272 } while (*r == NULL);
2273
2274 return (quick);
2077}
2078
2079#ifdef INET6
2080void
2081pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
2082 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af)
2083{
2084 switch (af) {

--- 287 unchanged lines hidden (view full) ---

2372}
2373
2374int
2375pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
2376 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
2377 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
2378 struct pf_src_node **sn)
2379{
2275}
2276
2277#ifdef INET6
2278void
2279pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
2280 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af)
2281{
2282 switch (af) {

--- 287 unchanged lines hidden (view full) ---

2570}
2571
2572int
2573pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
2574 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
2575 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
2576 struct pf_src_node **sn)
2577{
2380 struct pf_state key;
2578 struct pf_state_cmp key;
2381 struct pf_addr init_addr;
2382 u_int16_t cut;
2383
2384 bzero(&init_addr, sizeof(init_addr));
2385 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
2386 return (1);
2387
2388 if (proto == IPPROTO_ICMP) {

--- 75 unchanged lines hidden (view full) ---

2464
2465struct pf_rule *
2466pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
2467 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
2468 struct pf_addr *daddr, u_int16_t dport, int rs_num)
2469{
2470 struct pf_rule *r, *rm = NULL;
2471 struct pf_ruleset *ruleset = NULL;
2579 struct pf_addr init_addr;
2580 u_int16_t cut;
2581
2582 bzero(&init_addr, sizeof(init_addr));
2583 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
2584 return (1);
2585
2586 if (proto == IPPROTO_ICMP) {

--- 75 unchanged lines hidden (view full) ---

2662
2663struct pf_rule *
2664pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
2665 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
2666 struct pf_addr *daddr, u_int16_t dport, int rs_num)
2667{
2668 struct pf_rule *r, *rm = NULL;
2669 struct pf_ruleset *ruleset = NULL;
2472 struct pf_tag *pftag = NULL;
2473 int tag = -1;
2670 int tag = -1;
2671 int rtableid = -1;
2474 int asd = 0;
2475
2476 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
2477 while (r && rm == NULL) {
2478 struct pf_rule_addr *src = NULL, *dst = NULL;
2479 struct pf_addr_wrap *xdst = NULL;
2480
2481 if (r->action == PF_BINAT && direction == PF_IN) {
2482 src = &r->dst;
2483 if (r->rpool.cur != NULL)
2484 xdst = &r->rpool.cur->addr;
2485 } else {
2486 src = &r->src;
2487 dst = &r->dst;
2488 }
2489
2490 r->evaluations++;
2672 int asd = 0;
2673
2674 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
2675 while (r && rm == NULL) {
2676 struct pf_rule_addr *src = NULL, *dst = NULL;
2677 struct pf_addr_wrap *xdst = NULL;
2678
2679 if (r->action == PF_BINAT && direction == PF_IN) {
2680 src = &r->dst;
2681 if (r->rpool.cur != NULL)
2682 xdst = &r->rpool.cur->addr;
2683 } else {
2684 src = &r->src;
2685 dst = &r->dst;
2686 }
2687
2688 r->evaluations++;
2491 if (r->kif != NULL &&
2492 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
2689 if (pfi_kif_match(r->kif, kif) == r->ifnot)
2493 r = r->skip[PF_SKIP_IFP].ptr;
2494 else if (r->direction && r->direction != direction)
2495 r = r->skip[PF_SKIP_DIR].ptr;
2496 else if (r->af && r->af != pd->af)
2497 r = r->skip[PF_SKIP_AF].ptr;
2498 else if (r->proto && r->proto != pd->proto)
2499 r = r->skip[PF_SKIP_PROTO].ptr;
2690 r = r->skip[PF_SKIP_IFP].ptr;
2691 else if (r->direction && r->direction != direction)
2692 r = r->skip[PF_SKIP_DIR].ptr;
2693 else if (r->af && r->af != pd->af)
2694 r = r->skip[PF_SKIP_AF].ptr;
2695 else if (r->proto && r->proto != pd->proto)
2696 r = r->skip[PF_SKIP_PROTO].ptr;
2500 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, src->neg))
2697 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af,
2698 src->neg, kif))
2501 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR :
2502 PF_SKIP_DST_ADDR].ptr;
2503 else if (src->port_op && !pf_match_port(src->port_op,
2504 src->port[0], src->port[1], sport))
2505 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
2506 PF_SKIP_DST_PORT].ptr;
2507 else if (dst != NULL &&
2699 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR :
2700 PF_SKIP_DST_ADDR].ptr;
2701 else if (src->port_op && !pf_match_port(src->port_op,
2702 src->port[0], src->port[1], sport))
2703 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
2704 PF_SKIP_DST_PORT].ptr;
2705 else if (dst != NULL &&
2508 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg))
2706 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL))
2509 r = r->skip[PF_SKIP_DST_ADDR].ptr;
2707 r = r->skip[PF_SKIP_DST_ADDR].ptr;
2510 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, 0))
2708 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af,
2709 0, NULL))
2511 r = TAILQ_NEXT(r, entries);
2512 else if (dst != NULL && dst->port_op &&
2513 !pf_match_port(dst->port_op, dst->port[0],
2514 dst->port[1], dport))
2515 r = r->skip[PF_SKIP_DST_PORT].ptr;
2710 r = TAILQ_NEXT(r, entries);
2711 else if (dst != NULL && dst->port_op &&
2712 !pf_match_port(dst->port_op, dst->port[0],
2713 dst->port[1], dport))
2714 r = r->skip[PF_SKIP_DST_PORT].ptr;
2516 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
2715 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
2517 r = TAILQ_NEXT(r, entries);
2518 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
2519 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
2520 off, pd->hdr.tcp), r->os_fingerprint)))
2521 r = TAILQ_NEXT(r, entries);
2522 else {
2523 if (r->tag)
2524 tag = r->tag;
2716 r = TAILQ_NEXT(r, entries);
2717 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
2718 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
2719 off, pd->hdr.tcp), r->os_fingerprint)))
2720 r = TAILQ_NEXT(r, entries);
2721 else {
2722 if (r->tag)
2723 tag = r->tag;
2724 if (r->rtableid >= 0)
2725 rtableid = r->rtableid;
2525 if (r->anchor == NULL) {
2526 rm = r;
2527 } else
2726 if (r->anchor == NULL) {
2727 rm = r;
2728 } else
2528 pf_step_into_anchor(&asd, &ruleset, rs_num, &r, NULL);
2729 pf_step_into_anchor(&asd, &ruleset, rs_num,
2730 &r, NULL, NULL);
2529 }
2530 if (r == NULL)
2731 }
2732 if (r == NULL)
2531 pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r, NULL);
2733 pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r,
2734 NULL, NULL);
2532 }
2735 }
2533 if (pf_tag_packet(m, pftag, tag))
2736 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid))
2534 return (NULL);
2535 if (rm != NULL && (rm->action == PF_NONAT ||
2536 rm->action == PF_NORDR || rm->action == PF_NOBINAT))
2537 return (NULL);
2538 return (rm);
2539}
2540
2541struct pf_rule *

--- 144 unchanged lines hidden (view full) ---

2686 }
2687 }
2688
2689 return (r);
2690}
2691
2692int
2693#ifdef __FreeBSD__
2737 return (NULL);
2738 if (rm != NULL && (rm->action == PF_NONAT ||
2739 rm->action == PF_NORDR || rm->action == PF_NOBINAT))
2740 return (NULL);
2741 return (rm);
2742}
2743
2744struct pf_rule *

--- 144 unchanged lines hidden (view full) ---

2889 }
2890 }
2891
2892 return (r);
2893}
2894
2895int
2896#ifdef __FreeBSD__
2694pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd,
2695 struct inpcb *inp_arg)
2897pf_socket_lookup(int direction, struct pf_pdesc *pd, struct inpcb *inp_arg)
2696#else
2898#else
2697pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd)
2899pf_socket_lookup(int direction, struct pf_pdesc *pd)
2698#endif
2699{
2700 struct pf_addr *saddr, *daddr;
2701 u_int16_t sport, dport;
2702#ifdef __FreeBSD__
2703 struct inpcbinfo *pi;
2704#else
2705 struct inpcbtable *tb;
2706#endif
2707 struct inpcb *inp;
2708
2900#endif
2901{
2902 struct pf_addr *saddr, *daddr;
2903 u_int16_t sport, dport;
2904#ifdef __FreeBSD__
2905 struct inpcbinfo *pi;
2906#else
2907 struct inpcbtable *tb;
2908#endif
2909 struct inpcb *inp;
2910
2709 *uid = UID_MAX;
2710 *gid = GID_MAX;
2911 if (pd == NULL)
2912 return (-1);
2913 pd->lookup.uid = UID_MAX;
2914 pd->lookup.gid = GID_MAX;
2915 pd->lookup.pid = NO_PID; /* XXX: revisit */
2711#ifdef __FreeBSD__
2712 if (inp_arg != NULL) {
2713 INP_LOCK_ASSERT(inp_arg);
2714 if (inp_arg->inp_socket) {
2916#ifdef __FreeBSD__
2917 if (inp_arg != NULL) {
2918 INP_LOCK_ASSERT(inp_arg);
2919 if (inp_arg->inp_socket) {
2715 *uid = inp_arg->inp_socket->so_cred->cr_uid;
2716 *gid = inp_arg->inp_socket->so_cred->cr_groups[0];
2920 pd->lookup.uid = inp_arg->inp_socket->so_cred->cr_uid;
2921 pd->lookup.gid =
2922 inp_arg->inp_socket->so_cred->cr_groups[0];
2717 return (1);
2718 } else
2923 return (1);
2924 } else
2719 return (0);
2925 return (-1);
2720 }
2721#endif
2722 switch (pd->proto) {
2723 case IPPROTO_TCP:
2926 }
2927#endif
2928 switch (pd->proto) {
2929 case IPPROTO_TCP:
2930 if (pd->hdr.tcp == NULL)
2931 return (-1);
2724 sport = pd->hdr.tcp->th_sport;
2725 dport = pd->hdr.tcp->th_dport;
2726#ifdef __FreeBSD__
2727 pi = &tcbinfo;
2728#else
2729 tb = &tcbtable;
2730#endif
2731 break;
2732 case IPPROTO_UDP:
2932 sport = pd->hdr.tcp->th_sport;
2933 dport = pd->hdr.tcp->th_dport;
2934#ifdef __FreeBSD__
2935 pi = &tcbinfo;
2936#else
2937 tb = &tcbtable;
2938#endif
2939 break;
2940 case IPPROTO_UDP:
2941 if (pd->hdr.udp == NULL)
2942 return (-1);
2733 sport = pd->hdr.udp->uh_sport;
2734 dport = pd->hdr.udp->uh_dport;
2735#ifdef __FreeBSD__
2736 pi = &udbinfo;
2737#else
2738 tb = &udbtable;
2739#endif
2740 break;
2741 default:
2943 sport = pd->hdr.udp->uh_sport;
2944 dport = pd->hdr.udp->uh_dport;
2945#ifdef __FreeBSD__
2946 pi = &udbinfo;
2947#else
2948 tb = &udbtable;
2949#endif
2950 break;
2951 default:
2742 return (0);
2952 return (-1);
2743 }
2744 if (direction == PF_IN) {
2745 saddr = pd->src;
2746 daddr = pd->dst;
2747 } else {
2748 u_int16_t p;
2749
2750 p = sport;

--- 9 unchanged lines hidden (view full) ---

2760 INP_INFO_RLOCK(pi); /* XXX LOR */
2761 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4,
2762 dport, 0, NULL);
2763 if (inp == NULL) {
2764 inp = in_pcblookup_hash(pi, saddr->v4, sport,
2765 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL);
2766 if(inp == NULL) {
2767 INP_INFO_RUNLOCK(pi);
2953 }
2954 if (direction == PF_IN) {
2955 saddr = pd->src;
2956 daddr = pd->dst;
2957 } else {
2958 u_int16_t p;
2959
2960 p = sport;

--- 9 unchanged lines hidden (view full) ---

2970 INP_INFO_RLOCK(pi); /* XXX LOR */
2971 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4,
2972 dport, 0, NULL);
2973 if (inp == NULL) {
2974 inp = in_pcblookup_hash(pi, saddr->v4, sport,
2975 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL);
2976 if(inp == NULL) {
2977 INP_INFO_RUNLOCK(pi);
2768 return (0);
2978 return (-1);
2769 }
2770 }
2771#else
2772 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport);
2773 if (inp == NULL) {
2774 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0);
2775 if (inp == NULL)
2979 }
2980 }
2981#else
2982 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport);
2983 if (inp == NULL) {
2984 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0);
2985 if (inp == NULL)
2776 return (0);
2986 return (-1);
2777 }
2778#endif
2779 break;
2780#endif /* INET */
2781#ifdef INET6
2782 case AF_INET6:
2783#ifdef __FreeBSD__
2784 INP_INFO_RLOCK(pi);
2785 inp = in6_pcblookup_hash(pi, &saddr->v6, sport,
2786 &daddr->v6, dport, 0, NULL);
2787 if (inp == NULL) {
2788 inp = in6_pcblookup_hash(pi, &saddr->v6, sport,
2789 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL);
2790 if (inp == NULL) {
2791 INP_INFO_RUNLOCK(pi);
2987 }
2988#endif
2989 break;
2990#endif /* INET */
2991#ifdef INET6
2992 case AF_INET6:
2993#ifdef __FreeBSD__
2994 INP_INFO_RLOCK(pi);
2995 inp = in6_pcblookup_hash(pi, &saddr->v6, sport,
2996 &daddr->v6, dport, 0, NULL);
2997 if (inp == NULL) {
2998 inp = in6_pcblookup_hash(pi, &saddr->v6, sport,
2999 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL);
3000 if (inp == NULL) {
3001 INP_INFO_RUNLOCK(pi);
2792 return (0);
3002 return (-1);
2793 }
2794 }
2795#else
2796 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6,
2797 dport);
2798 if (inp == NULL) {
2799 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0);
2800 if (inp == NULL)
3003 }
3004 }
3005#else
3006 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6,
3007 dport);
3008 if (inp == NULL) {
3009 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0);
3010 if (inp == NULL)
2801 return (0);
3011 return (-1);
2802 }
2803#endif
2804 break;
2805#endif /* INET6 */
2806
2807 default:
3012 }
3013#endif
3014 break;
3015#endif /* INET6 */
3016
3017 default:
2808 return (0);
3018 return (-1);
2809 }
2810#ifdef __FreeBSD__
2811 INP_LOCK(inp);
2812 if ((inp->inp_socket == NULL) || (inp->inp_socket->so_cred == NULL)) {
2813 INP_UNLOCK(inp);
2814 INP_INFO_RUNLOCK(pi);
3019 }
3020#ifdef __FreeBSD__
3021 INP_LOCK(inp);
3022 if ((inp->inp_socket == NULL) || (inp->inp_socket->so_cred == NULL)) {
3023 INP_UNLOCK(inp);
3024 INP_INFO_RUNLOCK(pi);
2815 return (0);
3025 return (-1);
2816 }
3026 }
2817 *uid = inp->inp_socket->so_cred->cr_uid;
2818 *gid = inp->inp_socket->so_cred->cr_groups[0];
3027 pd->lookup.uid = inp->inp_socket->so_cred->cr_uid;
3028 pd->lookup.gid = inp->inp_socket->so_cred->cr_groups[0];
2819 INP_UNLOCK(inp);
2820 INP_INFO_RUNLOCK(pi);
2821#else
3029 INP_UNLOCK(inp);
3030 INP_INFO_RUNLOCK(pi);
3031#else
2822 *uid = inp->inp_socket->so_euid;
2823 *gid = inp->inp_socket->so_egid;
3032 pd->lookup.uid = inp->inp_socket->so_euid;
3033 pd->lookup.gid = inp->inp_socket->so_egid;
3034 pd->lookup.pid = inp->inp_socket->so_cpid;
2824#endif
2825 return (1);
2826}
2827
2828u_int8_t
2829pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
2830{
2831 int hlen;

--- 177 unchanged lines hidden (view full) ---

3009 struct ifqueue *ifq)
3010#endif
3011{
3012 struct pf_rule *nr = NULL;
3013 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3014 struct tcphdr *th = pd->hdr.tcp;
3015 u_int16_t bport, nport = 0;
3016 sa_family_t af = pd->af;
3035#endif
3036 return (1);
3037}
3038
3039u_int8_t
3040pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
3041{
3042 int hlen;

--- 177 unchanged lines hidden (view full) ---

3220 struct ifqueue *ifq)
3221#endif
3222{
3223 struct pf_rule *nr = NULL;
3224 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3225 struct tcphdr *th = pd->hdr.tcp;
3226 u_int16_t bport, nport = 0;
3227 sa_family_t af = pd->af;
3017 int lookup = -1;
3018 uid_t uid;
3019 gid_t gid;
3020 struct pf_rule *r, *a = NULL;
3021 struct pf_ruleset *ruleset = NULL;
3022 struct pf_src_node *nsn = NULL;
3023 u_short reason;
3024 int rewrite = 0;
3228 struct pf_rule *r, *a = NULL;
3229 struct pf_ruleset *ruleset = NULL;
3230 struct pf_src_node *nsn = NULL;
3231 u_short reason;
3232 int rewrite = 0;
3025 struct pf_tag *pftag = NULL;
3026 int tag = -1;
3233 int tag = -1, rtableid = -1;
3027 u_int16_t mss = tcp_mssdflt;
3028 int asd = 0;
3234 u_int16_t mss = tcp_mssdflt;
3235 int asd = 0;
3236 int match = 0;
3029
3030 if (pf_check_congestion(ifq)) {
3031 REASON_SET(&reason, PFRES_CONGEST);
3032 return (PF_DROP);
3033 }
3034
3237
3238 if (pf_check_congestion(ifq)) {
3239 REASON_SET(&reason, PFRES_CONGEST);
3240 return (PF_DROP);
3241 }
3242
3035#if defined(__FreeBSD__) && defined(PF_MPSAFE_UGID)
3036 PF_UNLOCK();
3037 lookup = pf_socket_lookup(&uid, &gid, direction, pd, inp);
3038 PF_LOCK();
3243#ifdef __FreeBSD__
3244 if (inp != NULL)
3245 pd->lookup.done = pf_socket_lookup(direction, pd, inp);
3246 else if (debug_pfugidhack) {
3247 PF_UNLOCK();
3248 DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n"));
3249 pd->lookup.done = pf_socket_lookup(direction, pd, inp);
3250 PF_LOCK();
3251 }
3039#endif
3040
3041 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3042
3043 if (direction == PF_OUT) {
3044 bport = nport = th->th_sport;
3045 /* check outgoing packet for BINAT/NAT */
3046 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,

--- 20 unchanged lines hidden (view full) ---

3067 if (nr->natpass)
3068 r = NULL;
3069 pd->nat_rule = nr;
3070 }
3071 }
3072
3073 while (r != NULL) {
3074 r->evaluations++;
3252#endif
3253
3254 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3255
3256 if (direction == PF_OUT) {
3257 bport = nport = th->th_sport;
3258 /* check outgoing packet for BINAT/NAT */
3259 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,

--- 20 unchanged lines hidden (view full) ---

3280 if (nr->natpass)
3281 r = NULL;
3282 pd->nat_rule = nr;
3283 }
3284 }
3285
3286 while (r != NULL) {
3287 r->evaluations++;
3075 if (r->kif != NULL &&
3076 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
3288 if (pfi_kif_match(r->kif, kif) == r->ifnot)
3077 r = r->skip[PF_SKIP_IFP].ptr;
3078 else if (r->direction && r->direction != direction)
3079 r = r->skip[PF_SKIP_DIR].ptr;
3080 else if (r->af && r->af != af)
3081 r = r->skip[PF_SKIP_AF].ptr;
3082 else if (r->proto && r->proto != IPPROTO_TCP)
3083 r = r->skip[PF_SKIP_PROTO].ptr;
3289 r = r->skip[PF_SKIP_IFP].ptr;
3290 else if (r->direction && r->direction != direction)
3291 r = r->skip[PF_SKIP_DIR].ptr;
3292 else if (r->af && r->af != af)
3293 r = r->skip[PF_SKIP_AF].ptr;
3294 else if (r->proto && r->proto != IPPROTO_TCP)
3295 r = r->skip[PF_SKIP_PROTO].ptr;
3084 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg))
3296 else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
3297 r->src.neg, kif))
3085 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3086 else if (r->src.port_op && !pf_match_port(r->src.port_op,
3087 r->src.port[0], r->src.port[1], th->th_sport))
3088 r = r->skip[PF_SKIP_SRC_PORT].ptr;
3298 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3299 else if (r->src.port_op && !pf_match_port(r->src.port_op,
3300 r->src.port[0], r->src.port[1], th->th_sport))
3301 r = r->skip[PF_SKIP_SRC_PORT].ptr;
3089 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg))
3302 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
3303 r->dst.neg, NULL))
3090 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3091 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
3092 r->dst.port[0], r->dst.port[1], th->th_dport))
3093 r = r->skip[PF_SKIP_DST_PORT].ptr;
3304 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3305 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
3306 r->dst.port[0], r->dst.port[1], th->th_dport))
3307 r = r->skip[PF_SKIP_DST_PORT].ptr;
3094 else if (r->tos && !(r->tos & pd->tos))
3308 else if (r->tos && !(r->tos == pd->tos))
3095 r = TAILQ_NEXT(r, entries);
3096 else if (r->rule_flag & PFRULE_FRAGMENT)
3097 r = TAILQ_NEXT(r, entries);
3098 else if ((r->flagset & th->th_flags) != r->flags)
3099 r = TAILQ_NEXT(r, entries);
3309 r = TAILQ_NEXT(r, entries);
3310 else if (r->rule_flag & PFRULE_FRAGMENT)
3311 r = TAILQ_NEXT(r, entries);
3312 else if ((r->flagset & th->th_flags) != r->flags)
3313 r = TAILQ_NEXT(r, entries);
3100 else if (r->uid.op && (lookup != -1 || (lookup =
3314 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done =
3101#ifdef __FreeBSD__
3315#ifdef __FreeBSD__
3102 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
3316 pf_socket_lookup(direction, pd, inp), 1)) &&
3103#else
3317#else
3104 pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
3318 pf_socket_lookup(direction, pd), 1)) &&
3105#endif
3106 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
3319#endif
3320 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
3107 uid))
3321 pd->lookup.uid))
3108 r = TAILQ_NEXT(r, entries);
3322 r = TAILQ_NEXT(r, entries);
3109 else if (r->gid.op && (lookup != -1 || (lookup =
3323 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done =
3110#ifdef __FreeBSD__
3324#ifdef __FreeBSD__
3111 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
3325 pf_socket_lookup(direction, pd, inp), 1)) &&
3112#else
3326#else
3113 pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
3327 pf_socket_lookup(direction, pd), 1)) &&
3114#endif
3115 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
3328#endif
3329 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
3116 gid))
3330 pd->lookup.gid))
3117 r = TAILQ_NEXT(r, entries);
3118 else if (r->prob && r->prob <= arc4random())
3119 r = TAILQ_NEXT(r, entries);
3331 r = TAILQ_NEXT(r, entries);
3332 else if (r->prob && r->prob <= arc4random())
3333 r = TAILQ_NEXT(r, entries);
3120 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
3334 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
3121 r = TAILQ_NEXT(r, entries);
3122 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
3123 pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint))
3124 r = TAILQ_NEXT(r, entries);
3125 else {
3126 if (r->tag)
3127 tag = r->tag;
3335 r = TAILQ_NEXT(r, entries);
3336 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
3337 pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint))
3338 r = TAILQ_NEXT(r, entries);
3339 else {
3340 if (r->tag)
3341 tag = r->tag;
3342 if (r->rtableid >= 0)
3343 rtableid = r->rtableid;
3128 if (r->anchor == NULL) {
3344 if (r->anchor == NULL) {
3345 match = 1;
3129 *rm = r;
3130 *am = a;
3131 *rsm = ruleset;
3132 if ((*rm)->quick)
3133 break;
3134 r = TAILQ_NEXT(r, entries);
3135 } else
3136 pf_step_into_anchor(&asd, &ruleset,
3346 *rm = r;
3347 *am = a;
3348 *rsm = ruleset;
3349 if ((*rm)->quick)
3350 break;
3351 r = TAILQ_NEXT(r, entries);
3352 } else
3353 pf_step_into_anchor(&asd, &ruleset,
3137 PF_RULESET_FILTER, &r, &a);
3354 PF_RULESET_FILTER, &r, &a, &match);
3138 }
3355 }
3139 if (r == NULL)
3140 pf_step_out_of_anchor(&asd, &ruleset,
3141 PF_RULESET_FILTER, &r, &a);
3356 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
3357 PF_RULESET_FILTER, &r, &a, &match))
3358 break;
3142 }
3143 r = *rm;
3144 a = *am;
3145 ruleset = *rsm;
3146
3147 REASON_SET(&reason, PFRES_MATCH);
3148
3359 }
3360 r = *rm;
3361 a = *am;
3362 ruleset = *rsm;
3363
3364 REASON_SET(&reason, PFRES_MATCH);
3365
3149 if (r->log) {
3366 if (r->log || (nr != NULL && nr->natpass && nr->log)) {
3150 if (rewrite)
3367 if (rewrite)
3368#ifdef __FreeBSD__
3151 m_copyback(m, off, sizeof(*th), (caddr_t)th);
3369 m_copyback(m, off, sizeof(*th), (caddr_t)th);
3152 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
3370#else
3371 m_copyback(m, off, sizeof(*th), th);
3372#endif
3373 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr,
3374 a, ruleset, pd);
3153 }
3154
3155 if ((r->action == PF_DROP) &&
3156 ((r->rule_flag & PFRULE_RETURNRST) ||
3157 (r->rule_flag & PFRULE_RETURNICMP) ||
3158 (r->rule_flag & PFRULE_RETURN))) {
3159 /* undo NAT changes, if they have taken place */
3160 if (nr != NULL) {

--- 18 unchanged lines hidden (view full) ---

3179 ack++;
3180#ifdef __FreeBSD__
3181 pf_send_tcp(m, r, af, pd->dst,
3182#else
3183 pf_send_tcp(r, af, pd->dst,
3184#endif
3185 pd->src, th->th_dport, th->th_sport,
3186 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
3375 }
3376
3377 if ((r->action == PF_DROP) &&
3378 ((r->rule_flag & PFRULE_RETURNRST) ||
3379 (r->rule_flag & PFRULE_RETURNICMP) ||
3380 (r->rule_flag & PFRULE_RETURN))) {
3381 /* undo NAT changes, if they have taken place */
3382 if (nr != NULL) {

--- 18 unchanged lines hidden (view full) ---

3401 ack++;
3402#ifdef __FreeBSD__
3403 pf_send_tcp(m, r, af, pd->dst,
3404#else
3405 pf_send_tcp(r, af, pd->dst,
3406#endif
3407 pd->src, th->th_dport, th->th_sport,
3408 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
3187 r->return_ttl, 1, pd->eh, kif->pfik_ifp);
3409 r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp);
3188 } else if ((af == AF_INET) && r->return_icmp)
3189 pf_send_icmp(m, r->return_icmp >> 8,
3190 r->return_icmp & 255, af, r);
3191 else if ((af == AF_INET6) && r->return_icmp6)
3192 pf_send_icmp(m, r->return_icmp6 >> 8,
3193 r->return_icmp6 & 255, af, r);
3194 }
3195
3196 if (r->action == PF_DROP)
3197 return (PF_DROP);
3198
3410 } else if ((af == AF_INET) && r->return_icmp)
3411 pf_send_icmp(m, r->return_icmp >> 8,
3412 r->return_icmp & 255, af, r);
3413 else if ((af == AF_INET6) && r->return_icmp6)
3414 pf_send_icmp(m, r->return_icmp6 >> 8,
3415 r->return_icmp6 & 255, af, r);
3416 }
3417
3418 if (r->action == PF_DROP)
3419 return (PF_DROP);
3420
3199 if (pf_tag_packet(m, pftag, tag)) {
3421 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) {
3200 REASON_SET(&reason, PFRES_MEMORY);
3201 return (PF_DROP);
3202 }
3203
3204 if (r->keep_state || nr != NULL ||
3205 (pd->flags & PFDESC_TCP_NORM)) {
3206 /* create new state */
3207 u_int16_t len;
3208 struct pf_state *s = NULL;
3209 struct pf_src_node *sn = NULL;
3210
3211 len = pd->tot_len - off - (th->th_off << 2);
3212
3213 /* check maximums */
3214 if (r->max_states && (r->states >= r->max_states)) {
3215 pf_status.lcounters[LCNT_STATES]++;
3216 REASON_SET(&reason, PFRES_MAXSTATES);
3217 goto cleanup;
3218 }
3422 REASON_SET(&reason, PFRES_MEMORY);
3423 return (PF_DROP);
3424 }
3425
3426 if (r->keep_state || nr != NULL ||
3427 (pd->flags & PFDESC_TCP_NORM)) {
3428 /* create new state */
3429 u_int16_t len;
3430 struct pf_state *s = NULL;
3431 struct pf_src_node *sn = NULL;
3432
3433 len = pd->tot_len - off - (th->th_off << 2);
3434
3435 /* check maximums */
3436 if (r->max_states && (r->states >= r->max_states)) {
3437 pf_status.lcounters[LCNT_STATES]++;
3438 REASON_SET(&reason, PFRES_MAXSTATES);
3439 goto cleanup;
3440 }
3219 /* src node for flter rule */
3441 /* src node for filter rule */
3220 if ((r->rule_flag & PFRULE_SRCTRACK ||
3221 r->rpool.opts & PF_POOL_STICKYADDR) &&
3222 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3223 REASON_SET(&reason, PFRES_SRCLIMIT);
3224 goto cleanup;
3225 }
3226 /* src node for translation rule */
3227 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&

--- 23 unchanged lines hidden (view full) ---

3251 return (PF_DROP);
3252 }
3253 bzero(s, sizeof(*s));
3254 s->rule.ptr = r;
3255 s->nat_rule.ptr = nr;
3256 s->anchor.ptr = a;
3257 STATE_INC_COUNTERS(s);
3258 s->allow_opts = r->allow_opts;
3442 if ((r->rule_flag & PFRULE_SRCTRACK ||
3443 r->rpool.opts & PF_POOL_STICKYADDR) &&
3444 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3445 REASON_SET(&reason, PFRES_SRCLIMIT);
3446 goto cleanup;
3447 }
3448 /* src node for translation rule */
3449 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&

--- 23 unchanged lines hidden (view full) ---

3473 return (PF_DROP);
3474 }
3475 bzero(s, sizeof(*s));
3476 s->rule.ptr = r;
3477 s->nat_rule.ptr = nr;
3478 s->anchor.ptr = a;
3479 STATE_INC_COUNTERS(s);
3480 s->allow_opts = r->allow_opts;
3259 s->log = r->log & 2;
3481 s->log = r->log & PF_LOG_ALL;
3482 if (nr != NULL)
3483 s->log |= nr->log & PF_LOG_ALL;
3260 s->proto = IPPROTO_TCP;
3261 s->direction = direction;
3262 s->af = af;
3263 if (direction == PF_OUT) {
3264 PF_ACPY(&s->gwy.addr, saddr, af);
3265 s->gwy.port = th->th_sport; /* sport */
3266 PF_ACPY(&s->ext.addr, daddr, af);
3267 s->ext.port = th->th_dport;

--- 18 unchanged lines hidden (view full) ---

3286 }
3287 }
3288
3289 s->src.seqlo = ntohl(th->th_seq);
3290 s->src.seqhi = s->src.seqlo + len + 1;
3291 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
3292 r->keep_state == PF_STATE_MODULATE) {
3293 /* Generate sequence number modulator */
3484 s->proto = IPPROTO_TCP;
3485 s->direction = direction;
3486 s->af = af;
3487 if (direction == PF_OUT) {
3488 PF_ACPY(&s->gwy.addr, saddr, af);
3489 s->gwy.port = th->th_sport; /* sport */
3490 PF_ACPY(&s->ext.addr, daddr, af);
3491 s->ext.port = th->th_dport;

--- 18 unchanged lines hidden (view full) ---

3510 }
3511 }
3512
3513 s->src.seqlo = ntohl(th->th_seq);
3514 s->src.seqhi = s->src.seqlo + len + 1;
3515 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
3516 r->keep_state == PF_STATE_MODULATE) {
3517 /* Generate sequence number modulator */
3294 while ((s->src.seqdiff = htonl(arc4random())) == 0)
3518#ifdef __FreeBSD__
3519 while ((s->src.seqdiff =
3520 pf_new_isn(s) - s->src.seqlo) == 0)
3521 ;
3522#else
3523 while ((s->src.seqdiff =
3524 tcp_rndiss_next() - s->src.seqlo) == 0)
3295 ;
3525 ;
3526#endif
3296 pf_change_a(&th->th_seq, &th->th_sum,
3297 htonl(s->src.seqlo + s->src.seqdiff), 0);
3298 rewrite = 1;
3299 } else
3300 s->src.seqdiff = 0;
3301 if (th->th_flags & TH_SYN) {
3302 s->src.seqhi++;
3303 s->src.wscale = pf_get_wscale(m, off, th->th_off, af);

--- 79 unchanged lines hidden (view full) ---

3383 mss = pf_calc_mss(daddr, af, mss);
3384 s->src.mss = mss;
3385#ifdef __FreeBSD__
3386 pf_send_tcp(NULL, r, af, daddr, saddr, th->th_dport,
3387#else
3388 pf_send_tcp(r, af, daddr, saddr, th->th_dport,
3389#endif
3390 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
3527 pf_change_a(&th->th_seq, &th->th_sum,
3528 htonl(s->src.seqlo + s->src.seqdiff), 0);
3529 rewrite = 1;
3530 } else
3531 s->src.seqdiff = 0;
3532 if (th->th_flags & TH_SYN) {
3533 s->src.seqhi++;
3534 s->src.wscale = pf_get_wscale(m, off, th->th_off, af);

--- 79 unchanged lines hidden (view full) ---

3614 mss = pf_calc_mss(daddr, af, mss);
3615 s->src.mss = mss;
3616#ifdef __FreeBSD__
3617 pf_send_tcp(NULL, r, af, daddr, saddr, th->th_dport,
3618#else
3619 pf_send_tcp(r, af, daddr, saddr, th->th_dport,
3620#endif
3621 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
3391 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, NULL, NULL);
3622 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL);
3392 REASON_SET(&reason, PFRES_SYNPROXY);
3393 return (PF_SYNPROXY_DROP);
3394 }
3395 }
3396
3397 /* copy back packet headers if we performed NAT operations */
3398 if (rewrite)
3399 m_copyback(m, off, sizeof(*th), (caddr_t)th);

--- 12 unchanged lines hidden (view full) ---

3412 struct ifqueue *ifq)
3413#endif
3414{
3415 struct pf_rule *nr = NULL;
3416 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3417 struct udphdr *uh = pd->hdr.udp;
3418 u_int16_t bport, nport = 0;
3419 sa_family_t af = pd->af;
3623 REASON_SET(&reason, PFRES_SYNPROXY);
3624 return (PF_SYNPROXY_DROP);
3625 }
3626 }
3627
3628 /* copy back packet headers if we performed NAT operations */
3629 if (rewrite)
3630 m_copyback(m, off, sizeof(*th), (caddr_t)th);

--- 12 unchanged lines hidden (view full) ---

3643 struct ifqueue *ifq)
3644#endif
3645{
3646 struct pf_rule *nr = NULL;
3647 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3648 struct udphdr *uh = pd->hdr.udp;
3649 u_int16_t bport, nport = 0;
3650 sa_family_t af = pd->af;
3420 int lookup = -1;
3421 uid_t uid;
3422 gid_t gid;
3423 struct pf_rule *r, *a = NULL;
3424 struct pf_ruleset *ruleset = NULL;
3425 struct pf_src_node *nsn = NULL;
3426 u_short reason;
3427 int rewrite = 0;
3651 struct pf_rule *r, *a = NULL;
3652 struct pf_ruleset *ruleset = NULL;
3653 struct pf_src_node *nsn = NULL;
3654 u_short reason;
3655 int rewrite = 0;
3428 struct pf_tag *pftag = NULL;
3429 int tag = -1;
3656 int tag = -1, rtableid = -1;
3430 int asd = 0;
3657 int asd = 0;
3658 int match = 0;
3431
3432 if (pf_check_congestion(ifq)) {
3433 REASON_SET(&reason, PFRES_CONGEST);
3434 return (PF_DROP);
3435 }
3436
3659
3660 if (pf_check_congestion(ifq)) {
3661 REASON_SET(&reason, PFRES_CONGEST);
3662 return (PF_DROP);
3663 }
3664
3437#if defined(__FreeBSD__) && defined(PF_MPSAFE_UGID)
3438 PF_UNLOCK();
3439 lookup = pf_socket_lookup(&uid, &gid, direction, pd, inp);
3440 PF_LOCK();
3665#ifdef __FreeBSD__
3666 if (inp != NULL)
3667 pd->lookup.done = pf_socket_lookup(direction, pd, inp);
3668 else if (debug_pfugidhack) {
3669 PF_UNLOCK();
3670 DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n"));
3671 pd->lookup.done = pf_socket_lookup(direction, pd, inp);
3672 PF_LOCK();
3673 }
3441#endif
3442
3443 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3444
3445 if (direction == PF_OUT) {
3446 bport = nport = uh->uh_sport;
3447 /* check outgoing packet for BINAT/NAT */
3448 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,

--- 20 unchanged lines hidden (view full) ---

3469 if (nr->natpass)
3470 r = NULL;
3471 pd->nat_rule = nr;
3472 }
3473 }
3474
3475 while (r != NULL) {
3476 r->evaluations++;
3674#endif
3675
3676 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3677
3678 if (direction == PF_OUT) {
3679 bport = nport = uh->uh_sport;
3680 /* check outgoing packet for BINAT/NAT */
3681 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,

--- 20 unchanged lines hidden (view full) ---

3702 if (nr->natpass)
3703 r = NULL;
3704 pd->nat_rule = nr;
3705 }
3706 }
3707
3708 while (r != NULL) {
3709 r->evaluations++;
3477 if (r->kif != NULL &&
3478 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
3710 if (pfi_kif_match(r->kif, kif) == r->ifnot)
3479 r = r->skip[PF_SKIP_IFP].ptr;
3480 else if (r->direction && r->direction != direction)
3481 r = r->skip[PF_SKIP_DIR].ptr;
3482 else if (r->af && r->af != af)
3483 r = r->skip[PF_SKIP_AF].ptr;
3484 else if (r->proto && r->proto != IPPROTO_UDP)
3485 r = r->skip[PF_SKIP_PROTO].ptr;
3711 r = r->skip[PF_SKIP_IFP].ptr;
3712 else if (r->direction && r->direction != direction)
3713 r = r->skip[PF_SKIP_DIR].ptr;
3714 else if (r->af && r->af != af)
3715 r = r->skip[PF_SKIP_AF].ptr;
3716 else if (r->proto && r->proto != IPPROTO_UDP)
3717 r = r->skip[PF_SKIP_PROTO].ptr;
3486 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg))
3718 else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
3719 r->src.neg, kif))
3487 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3488 else if (r->src.port_op && !pf_match_port(r->src.port_op,
3489 r->src.port[0], r->src.port[1], uh->uh_sport))
3490 r = r->skip[PF_SKIP_SRC_PORT].ptr;
3720 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3721 else if (r->src.port_op && !pf_match_port(r->src.port_op,
3722 r->src.port[0], r->src.port[1], uh->uh_sport))
3723 r = r->skip[PF_SKIP_SRC_PORT].ptr;
3491 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg))
3724 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
3725 r->dst.neg, NULL))
3492 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3493 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
3494 r->dst.port[0], r->dst.port[1], uh->uh_dport))
3495 r = r->skip[PF_SKIP_DST_PORT].ptr;
3726 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3727 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
3728 r->dst.port[0], r->dst.port[1], uh->uh_dport))
3729 r = r->skip[PF_SKIP_DST_PORT].ptr;
3496 else if (r->tos && !(r->tos & pd->tos))
3730 else if (r->tos && !(r->tos == pd->tos))
3497 r = TAILQ_NEXT(r, entries);
3498 else if (r->rule_flag & PFRULE_FRAGMENT)
3499 r = TAILQ_NEXT(r, entries);
3731 r = TAILQ_NEXT(r, entries);
3732 else if (r->rule_flag & PFRULE_FRAGMENT)
3733 r = TAILQ_NEXT(r, entries);
3500 else if (r->uid.op && (lookup != -1 || (lookup =
3734 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done =
3501#ifdef __FreeBSD__
3735#ifdef __FreeBSD__
3502 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
3736 pf_socket_lookup(direction, pd, inp), 1)) &&
3503#else
3737#else
3504 pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
3738 pf_socket_lookup(direction, pd), 1)) &&
3505#endif
3506 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
3739#endif
3740 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
3507 uid))
3741 pd->lookup.uid))
3508 r = TAILQ_NEXT(r, entries);
3742 r = TAILQ_NEXT(r, entries);
3509 else if (r->gid.op && (lookup != -1 || (lookup =
3743 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done =
3510#ifdef __FreeBSD__
3744#ifdef __FreeBSD__
3511 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
3745 pf_socket_lookup(direction, pd, inp), 1)) &&
3512#else
3746#else
3513 pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
3747 pf_socket_lookup(direction, pd), 1)) &&
3514#endif
3515 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
3748#endif
3749 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
3516 gid))
3750 pd->lookup.gid))
3517 r = TAILQ_NEXT(r, entries);
3518 else if (r->prob && r->prob <= arc4random())
3519 r = TAILQ_NEXT(r, entries);
3751 r = TAILQ_NEXT(r, entries);
3752 else if (r->prob && r->prob <= arc4random())
3753 r = TAILQ_NEXT(r, entries);
3520 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
3754 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
3521 r = TAILQ_NEXT(r, entries);
3522 else if (r->os_fingerprint != PF_OSFP_ANY)
3523 r = TAILQ_NEXT(r, entries);
3524 else {
3525 if (r->tag)
3526 tag = r->tag;
3755 r = TAILQ_NEXT(r, entries);
3756 else if (r->os_fingerprint != PF_OSFP_ANY)
3757 r = TAILQ_NEXT(r, entries);
3758 else {
3759 if (r->tag)
3760 tag = r->tag;
3761 if (r->rtableid >= 0)
3762 rtableid = r->rtableid;
3527 if (r->anchor == NULL) {
3763 if (r->anchor == NULL) {
3764 match = 1;
3528 *rm = r;
3529 *am = a;
3530 *rsm = ruleset;
3531 if ((*rm)->quick)
3532 break;
3533 r = TAILQ_NEXT(r, entries);
3534 } else
3535 pf_step_into_anchor(&asd, &ruleset,
3765 *rm = r;
3766 *am = a;
3767 *rsm = ruleset;
3768 if ((*rm)->quick)
3769 break;
3770 r = TAILQ_NEXT(r, entries);
3771 } else
3772 pf_step_into_anchor(&asd, &ruleset,
3536 PF_RULESET_FILTER, &r, &a);
3773 PF_RULESET_FILTER, &r, &a, &match);
3537 }
3774 }
3538 if (r == NULL)
3539 pf_step_out_of_anchor(&asd, &ruleset,
3540 PF_RULESET_FILTER, &r, &a);
3775 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
3776 PF_RULESET_FILTER, &r, &a, &match))
3777 break;
3541 }
3542 r = *rm;
3543 a = *am;
3544 ruleset = *rsm;
3545
3546 REASON_SET(&reason, PFRES_MATCH);
3547
3778 }
3779 r = *rm;
3780 a = *am;
3781 ruleset = *rsm;
3782
3783 REASON_SET(&reason, PFRES_MATCH);
3784
3548 if (r->log) {
3785 if (r->log || (nr != NULL && nr->natpass && nr->log)) {
3549 if (rewrite)
3786 if (rewrite)
3787#ifdef __FreeBSD__
3550 m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
3788 m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
3551 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
3789#else
3790 m_copyback(m, off, sizeof(*uh), uh);
3791#endif
3792 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr,
3793 a, ruleset, pd);
3552 }
3553
3554 if ((r->action == PF_DROP) &&
3555 ((r->rule_flag & PFRULE_RETURNICMP) ||
3556 (r->rule_flag & PFRULE_RETURN))) {
3557 /* undo NAT changes, if they have taken place */
3558 if (nr != NULL) {
3559 if (direction == PF_OUT) {

--- 12 unchanged lines hidden (view full) ---

3572 else if ((af == AF_INET6) && r->return_icmp6)
3573 pf_send_icmp(m, r->return_icmp6 >> 8,
3574 r->return_icmp6 & 255, af, r);
3575 }
3576
3577 if (r->action == PF_DROP)
3578 return (PF_DROP);
3579
3794 }
3795
3796 if ((r->action == PF_DROP) &&
3797 ((r->rule_flag & PFRULE_RETURNICMP) ||
3798 (r->rule_flag & PFRULE_RETURN))) {
3799 /* undo NAT changes, if they have taken place */
3800 if (nr != NULL) {
3801 if (direction == PF_OUT) {

--- 12 unchanged lines hidden (view full) ---

3814 else if ((af == AF_INET6) && r->return_icmp6)
3815 pf_send_icmp(m, r->return_icmp6 >> 8,
3816 r->return_icmp6 & 255, af, r);
3817 }
3818
3819 if (r->action == PF_DROP)
3820 return (PF_DROP);
3821
3580 if (pf_tag_packet(m, pftag, tag)) {
3822 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) {
3581 REASON_SET(&reason, PFRES_MEMORY);
3582 return (PF_DROP);
3583 }
3584
3585 if (r->keep_state || nr != NULL) {
3586 /* create new state */
3587 struct pf_state *s = NULL;
3588 struct pf_src_node *sn = NULL;
3589
3590 /* check maximums */
3591 if (r->max_states && (r->states >= r->max_states)) {
3592 pf_status.lcounters[LCNT_STATES]++;
3593 REASON_SET(&reason, PFRES_MAXSTATES);
3594 goto cleanup;
3595 }
3823 REASON_SET(&reason, PFRES_MEMORY);
3824 return (PF_DROP);
3825 }
3826
3827 if (r->keep_state || nr != NULL) {
3828 /* create new state */
3829 struct pf_state *s = NULL;
3830 struct pf_src_node *sn = NULL;
3831
3832 /* check maximums */
3833 if (r->max_states && (r->states >= r->max_states)) {
3834 pf_status.lcounters[LCNT_STATES]++;
3835 REASON_SET(&reason, PFRES_MAXSTATES);
3836 goto cleanup;
3837 }
3596 /* src node for flter rule */
3838 /* src node for filter rule */
3597 if ((r->rule_flag & PFRULE_SRCTRACK ||
3598 r->rpool.opts & PF_POOL_STICKYADDR) &&
3599 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3600 REASON_SET(&reason, PFRES_SRCLIMIT);
3601 goto cleanup;
3602 }
3603 /* src node for translation rule */
3604 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&

--- 23 unchanged lines hidden (view full) ---

3628 return (PF_DROP);
3629 }
3630 bzero(s, sizeof(*s));
3631 s->rule.ptr = r;
3632 s->nat_rule.ptr = nr;
3633 s->anchor.ptr = a;
3634 STATE_INC_COUNTERS(s);
3635 s->allow_opts = r->allow_opts;
3839 if ((r->rule_flag & PFRULE_SRCTRACK ||
3840 r->rpool.opts & PF_POOL_STICKYADDR) &&
3841 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3842 REASON_SET(&reason, PFRES_SRCLIMIT);
3843 goto cleanup;
3844 }
3845 /* src node for translation rule */
3846 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&

--- 23 unchanged lines hidden (view full) ---

3870 return (PF_DROP);
3871 }
3872 bzero(s, sizeof(*s));
3873 s->rule.ptr = r;
3874 s->nat_rule.ptr = nr;
3875 s->anchor.ptr = a;
3876 STATE_INC_COUNTERS(s);
3877 s->allow_opts = r->allow_opts;
3636 s->log = r->log & 2;
3878 s->log = r->log & PF_LOG_ALL;
3879 if (nr != NULL)
3880 s->log |= nr->log & PF_LOG_ALL;
3637 s->proto = IPPROTO_UDP;
3638 s->direction = direction;
3639 s->af = af;
3640 if (direction == PF_OUT) {
3641 PF_ACPY(&s->gwy.addr, saddr, af);
3642 s->gwy.port = uh->uh_sport;
3643 PF_ACPY(&s->ext.addr, daddr, af);
3644 s->ext.port = uh->uh_dport;

--- 65 unchanged lines hidden (view full) ---

3710 struct pf_ruleset *ruleset = NULL;
3711 struct pf_src_node *nsn = NULL;
3712 u_short reason;
3713 u_int16_t icmpid = 0, bport, nport = 0;
3714 sa_family_t af = pd->af;
3715 u_int8_t icmptype = 0; /* make the compiler happy */
3716 u_int8_t icmpcode = 0; /* make the compiler happy */
3717 int state_icmp = 0;
3881 s->proto = IPPROTO_UDP;
3882 s->direction = direction;
3883 s->af = af;
3884 if (direction == PF_OUT) {
3885 PF_ACPY(&s->gwy.addr, saddr, af);
3886 s->gwy.port = uh->uh_sport;
3887 PF_ACPY(&s->ext.addr, daddr, af);
3888 s->ext.port = uh->uh_dport;

--- 65 unchanged lines hidden (view full) ---

3954 struct pf_ruleset *ruleset = NULL;
3955 struct pf_src_node *nsn = NULL;
3956 u_short reason;
3957 u_int16_t icmpid = 0, bport, nport = 0;
3958 sa_family_t af = pd->af;
3959 u_int8_t icmptype = 0; /* make the compiler happy */
3960 u_int8_t icmpcode = 0; /* make the compiler happy */
3961 int state_icmp = 0;
3718 struct pf_tag *pftag = NULL;
3719 int tag = -1;
3962 int tag = -1, rtableid = -1;
3720#ifdef INET6
3721 int rewrite = 0;
3722#endif /* INET6 */
3723 int asd = 0;
3963#ifdef INET6
3964 int rewrite = 0;
3965#endif /* INET6 */
3966 int asd = 0;
3967 int match = 0;
3724
3725 if (pf_check_congestion(ifq)) {
3726 REASON_SET(&reason, PFRES_CONGEST);
3727 return (PF_DROP);
3728 }
3729
3730 switch (pd->proto) {
3731#ifdef INET

--- 83 unchanged lines hidden (view full) ---

3815 if (nr->natpass)
3816 r = NULL;
3817 pd->nat_rule = nr;
3818 }
3819 }
3820
3821 while (r != NULL) {
3822 r->evaluations++;
3968
3969 if (pf_check_congestion(ifq)) {
3970 REASON_SET(&reason, PFRES_CONGEST);
3971 return (PF_DROP);
3972 }
3973
3974 switch (pd->proto) {
3975#ifdef INET

--- 83 unchanged lines hidden (view full) ---

4059 if (nr->natpass)
4060 r = NULL;
4061 pd->nat_rule = nr;
4062 }
4063 }
4064
4065 while (r != NULL) {
4066 r->evaluations++;
3823 if (r->kif != NULL &&
3824 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
4067 if (pfi_kif_match(r->kif, kif) == 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;
4068 r = r->skip[PF_SKIP_IFP].ptr;
4069 else if (r->direction && r->direction != direction)
4070 r = r->skip[PF_SKIP_DIR].ptr;
4071 else if (r->af && r->af != af)
4072 r = r->skip[PF_SKIP_AF].ptr;
4073 else if (r->proto && r->proto != pd->proto)
4074 r = r->skip[PF_SKIP_PROTO].ptr;
3832 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg))
4075 else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
4076 r->src.neg, kif))
3833 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
4077 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3834 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg))
4078 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
4079 r->dst.neg, NULL))
3835 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3836 else if (r->type && r->type != icmptype + 1)
3837 r = TAILQ_NEXT(r, entries);
3838 else if (r->code && r->code != icmpcode + 1)
3839 r = TAILQ_NEXT(r, entries);
4080 r = r->skip[PF_SKIP_DST_ADDR].ptr;
4081 else if (r->type && r->type != icmptype + 1)
4082 r = TAILQ_NEXT(r, entries);
4083 else if (r->code && r->code != icmpcode + 1)
4084 r = TAILQ_NEXT(r, entries);
3840 else if (r->tos && !(r->tos & pd->tos))
4085 else if (r->tos && !(r->tos == pd->tos))
3841 r = TAILQ_NEXT(r, entries);
3842 else if (r->rule_flag & PFRULE_FRAGMENT)
3843 r = TAILQ_NEXT(r, entries);
3844 else if (r->prob && r->prob <= arc4random())
3845 r = TAILQ_NEXT(r, entries);
4086 r = TAILQ_NEXT(r, entries);
4087 else if (r->rule_flag & PFRULE_FRAGMENT)
4088 r = TAILQ_NEXT(r, entries);
4089 else if (r->prob && r->prob <= arc4random())
4090 r = TAILQ_NEXT(r, entries);
3846 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
4091 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
3847 r = TAILQ_NEXT(r, entries);
3848 else if (r->os_fingerprint != PF_OSFP_ANY)
3849 r = TAILQ_NEXT(r, entries);
3850 else {
3851 if (r->tag)
3852 tag = r->tag;
4092 r = TAILQ_NEXT(r, entries);
4093 else if (r->os_fingerprint != PF_OSFP_ANY)
4094 r = TAILQ_NEXT(r, entries);
4095 else {
4096 if (r->tag)
4097 tag = r->tag;
4098 if (r->rtableid >= 0)
4099 rtableid = r->rtableid;
3853 if (r->anchor == NULL) {
4100 if (r->anchor == NULL) {
4101 match = 1;
3854 *rm = r;
3855 *am = a;
3856 *rsm = ruleset;
3857 if ((*rm)->quick)
3858 break;
3859 r = TAILQ_NEXT(r, entries);
3860 } else
3861 pf_step_into_anchor(&asd, &ruleset,
4102 *rm = r;
4103 *am = a;
4104 *rsm = ruleset;
4105 if ((*rm)->quick)
4106 break;
4107 r = TAILQ_NEXT(r, entries);
4108 } else
4109 pf_step_into_anchor(&asd, &ruleset,
3862 PF_RULESET_FILTER, &r, &a);
4110 PF_RULESET_FILTER, &r, &a, &match);
3863 }
4111 }
3864 if (r == NULL)
3865 pf_step_out_of_anchor(&asd, &ruleset,
3866 PF_RULESET_FILTER, &r, &a);
4112 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
4113 PF_RULESET_FILTER, &r, &a, &match))
4114 break;
3867 }
3868 r = *rm;
3869 a = *am;
3870 ruleset = *rsm;
3871
3872 REASON_SET(&reason, PFRES_MATCH);
3873
4115 }
4116 r = *rm;
4117 a = *am;
4118 ruleset = *rsm;
4119
4120 REASON_SET(&reason, PFRES_MATCH);
4121
3874 if (r->log) {
4122 if (r->log || (nr != NULL && nr->natpass && nr->log)) {
3875#ifdef INET6
3876 if (rewrite)
3877 m_copyback(m, off, sizeof(struct icmp6_hdr),
3878 (caddr_t)pd->hdr.icmp6);
3879#endif /* INET6 */
4123#ifdef INET6
4124 if (rewrite)
4125 m_copyback(m, off, sizeof(struct icmp6_hdr),
4126 (caddr_t)pd->hdr.icmp6);
4127#endif /* INET6 */
3880 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
4128 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr,
4129 a, ruleset, pd);
3881 }
3882
3883 if (r->action != PF_PASS)
3884 return (PF_DROP);
3885
4130 }
4131
4132 if (r->action != PF_PASS)
4133 return (PF_DROP);
4134
3886 if (pf_tag_packet(m, pftag, tag)) {
4135 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) {
3887 REASON_SET(&reason, PFRES_MEMORY);
3888 return (PF_DROP);
3889 }
3890
3891 if (!state_icmp && (r->keep_state || nr != NULL)) {
3892 /* create new state */
3893 struct pf_state *s = NULL;
3894 struct pf_src_node *sn = NULL;
3895
3896 /* check maximums */
3897 if (r->max_states && (r->states >= r->max_states)) {
3898 pf_status.lcounters[LCNT_STATES]++;
3899 REASON_SET(&reason, PFRES_MAXSTATES);
3900 goto cleanup;
3901 }
4136 REASON_SET(&reason, PFRES_MEMORY);
4137 return (PF_DROP);
4138 }
4139
4140 if (!state_icmp && (r->keep_state || nr != NULL)) {
4141 /* create new state */
4142 struct pf_state *s = NULL;
4143 struct pf_src_node *sn = NULL;
4144
4145 /* check maximums */
4146 if (r->max_states && (r->states >= r->max_states)) {
4147 pf_status.lcounters[LCNT_STATES]++;
4148 REASON_SET(&reason, PFRES_MAXSTATES);
4149 goto cleanup;
4150 }
3902 /* src node for flter rule */
4151 /* src node for filter rule */
3903 if ((r->rule_flag & PFRULE_SRCTRACK ||
3904 r->rpool.opts & PF_POOL_STICKYADDR) &&
3905 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3906 REASON_SET(&reason, PFRES_SRCLIMIT);
3907 goto cleanup;
3908 }
3909 /* src node for translation rule */
3910 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&

--- 23 unchanged lines hidden (view full) ---

3934 return (PF_DROP);
3935 }
3936 bzero(s, sizeof(*s));
3937 s->rule.ptr = r;
3938 s->nat_rule.ptr = nr;
3939 s->anchor.ptr = a;
3940 STATE_INC_COUNTERS(s);
3941 s->allow_opts = r->allow_opts;
4152 if ((r->rule_flag & PFRULE_SRCTRACK ||
4153 r->rpool.opts & PF_POOL_STICKYADDR) &&
4154 pf_insert_src_node(&sn, r, saddr, af) != 0) {
4155 REASON_SET(&reason, PFRES_SRCLIMIT);
4156 goto cleanup;
4157 }
4158 /* src node for translation rule */
4159 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&

--- 23 unchanged lines hidden (view full) ---

4183 return (PF_DROP);
4184 }
4185 bzero(s, sizeof(*s));
4186 s->rule.ptr = r;
4187 s->nat_rule.ptr = nr;
4188 s->anchor.ptr = a;
4189 STATE_INC_COUNTERS(s);
4190 s->allow_opts = r->allow_opts;
3942 s->log = r->log & 2;
4191 s->log = r->log & PF_LOG_ALL;
4192 if (nr != NULL)
4193 s->log |= nr->log & PF_LOG_ALL;
3943 s->proto = pd->proto;
3944 s->direction = direction;
3945 s->af = af;
3946 if (direction == PF_OUT) {
3947 PF_ACPY(&s->gwy.addr, saddr, af);
3948 s->gwy.port = nport;
3949 PF_ACPY(&s->ext.addr, daddr, af);
3950 s->ext.port = 0;

--- 61 unchanged lines hidden (view full) ---

4012{
4013 struct pf_rule *nr = NULL;
4014 struct pf_rule *r, *a = NULL;
4015 struct pf_ruleset *ruleset = NULL;
4016 struct pf_src_node *nsn = NULL;
4017 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
4018 sa_family_t af = pd->af;
4019 u_short reason;
4194 s->proto = pd->proto;
4195 s->direction = direction;
4196 s->af = af;
4197 if (direction == PF_OUT) {
4198 PF_ACPY(&s->gwy.addr, saddr, af);
4199 s->gwy.port = nport;
4200 PF_ACPY(&s->ext.addr, daddr, af);
4201 s->ext.port = 0;

--- 61 unchanged lines hidden (view full) ---

4263{
4264 struct pf_rule *nr = NULL;
4265 struct pf_rule *r, *a = NULL;
4266 struct pf_ruleset *ruleset = NULL;
4267 struct pf_src_node *nsn = NULL;
4268 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
4269 sa_family_t af = pd->af;
4270 u_short reason;
4020 struct pf_tag *pftag = NULL;
4021 int tag = -1;
4271 int tag = -1, rtableid = -1;
4022 int asd = 0;
4272 int asd = 0;
4273 int match = 0;
4023
4024 if (pf_check_congestion(ifq)) {
4025 REASON_SET(&reason, PFRES_CONGEST);
4026 return (PF_DROP);
4027 }
4028
4029 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
4030

--- 40 unchanged lines hidden (view full) ---

4071 if (nr->natpass)
4072 r = NULL;
4073 pd->nat_rule = nr;
4074 }
4075 }
4076
4077 while (r != NULL) {
4078 r->evaluations++;
4274
4275 if (pf_check_congestion(ifq)) {
4276 REASON_SET(&reason, PFRES_CONGEST);
4277 return (PF_DROP);
4278 }
4279
4280 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
4281

--- 40 unchanged lines hidden (view full) ---

4322 if (nr->natpass)
4323 r = NULL;
4324 pd->nat_rule = nr;
4325 }
4326 }
4327
4328 while (r != NULL) {
4329 r->evaluations++;
4079 if (r->kif != NULL &&
4080 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
4330 if (pfi_kif_match(r->kif, kif) == r->ifnot)
4081 r = r->skip[PF_SKIP_IFP].ptr;
4082 else if (r->direction && r->direction != direction)
4083 r = r->skip[PF_SKIP_DIR].ptr;
4084 else if (r->af && r->af != af)
4085 r = r->skip[PF_SKIP_AF].ptr;
4086 else if (r->proto && r->proto != pd->proto)
4087 r = r->skip[PF_SKIP_PROTO].ptr;
4331 r = r->skip[PF_SKIP_IFP].ptr;
4332 else if (r->direction && r->direction != direction)
4333 r = r->skip[PF_SKIP_DIR].ptr;
4334 else if (r->af && r->af != af)
4335 r = r->skip[PF_SKIP_AF].ptr;
4336 else if (r->proto && r->proto != pd->proto)
4337 r = r->skip[PF_SKIP_PROTO].ptr;
4088 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.neg))
4338 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
4339 r->src.neg, kif))
4089 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
4340 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
4090 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.neg))
4341 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
4342 r->dst.neg, NULL))
4091 r = r->skip[PF_SKIP_DST_ADDR].ptr;
4343 r = r->skip[PF_SKIP_DST_ADDR].ptr;
4092 else if (r->tos && !(r->tos & pd->tos))
4344 else if (r->tos && !(r->tos == pd->tos))
4093 r = TAILQ_NEXT(r, entries);
4094 else if (r->rule_flag & PFRULE_FRAGMENT)
4095 r = TAILQ_NEXT(r, entries);
4096 else if (r->prob && r->prob <= arc4random())
4097 r = TAILQ_NEXT(r, entries);
4345 r = TAILQ_NEXT(r, entries);
4346 else if (r->rule_flag & PFRULE_FRAGMENT)
4347 r = TAILQ_NEXT(r, entries);
4348 else if (r->prob && r->prob <= arc4random())
4349 r = TAILQ_NEXT(r, entries);
4098 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
4350 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
4099 r = TAILQ_NEXT(r, entries);
4100 else if (r->os_fingerprint != PF_OSFP_ANY)
4101 r = TAILQ_NEXT(r, entries);
4102 else {
4103 if (r->tag)
4104 tag = r->tag;
4351 r = TAILQ_NEXT(r, entries);
4352 else if (r->os_fingerprint != PF_OSFP_ANY)
4353 r = TAILQ_NEXT(r, entries);
4354 else {
4355 if (r->tag)
4356 tag = r->tag;
4357 if (r->rtableid >= 0)
4358 rtableid = r->rtableid;
4105 if (r->anchor == NULL) {
4359 if (r->anchor == NULL) {
4360 match = 1;
4106 *rm = r;
4107 *am = a;
4108 *rsm = ruleset;
4109 if ((*rm)->quick)
4110 break;
4111 r = TAILQ_NEXT(r, entries);
4112 } else
4113 pf_step_into_anchor(&asd, &ruleset,
4361 *rm = r;
4362 *am = a;
4363 *rsm = ruleset;
4364 if ((*rm)->quick)
4365 break;
4366 r = TAILQ_NEXT(r, entries);
4367 } else
4368 pf_step_into_anchor(&asd, &ruleset,
4114 PF_RULESET_FILTER, &r, &a);
4369 PF_RULESET_FILTER, &r, &a, &match);
4115 }
4370 }
4116 if (r == NULL)
4117 pf_step_out_of_anchor(&asd, &ruleset,
4118 PF_RULESET_FILTER, &r, &a);
4371 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
4372 PF_RULESET_FILTER, &r, &a, &match))
4373 break;
4119 }
4120 r = *rm;
4121 a = *am;
4122 ruleset = *rsm;
4123
4124 REASON_SET(&reason, PFRES_MATCH);
4125
4374 }
4375 r = *rm;
4376 a = *am;
4377 ruleset = *rsm;
4378
4379 REASON_SET(&reason, PFRES_MATCH);
4380
4126 if (r->log)
4127 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
4381 if (r->log || (nr != NULL && nr->natpass && nr->log))
4382 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr,
4383 a, ruleset, pd);
4128
4129 if ((r->action == PF_DROP) &&
4130 ((r->rule_flag & PFRULE_RETURNICMP) ||
4131 (r->rule_flag & PFRULE_RETURN))) {
4132 struct pf_addr *a = NULL;
4133
4134 if (nr != NULL) {
4135 if (direction == PF_OUT)

--- 22 unchanged lines hidden (view full) ---

4158 else if ((af == AF_INET6) && r->return_icmp6)
4159 pf_send_icmp(m, r->return_icmp6 >> 8,
4160 r->return_icmp6 & 255, af, r);
4161 }
4162
4163 if (r->action != PF_PASS)
4164 return (PF_DROP);
4165
4384
4385 if ((r->action == PF_DROP) &&
4386 ((r->rule_flag & PFRULE_RETURNICMP) ||
4387 (r->rule_flag & PFRULE_RETURN))) {
4388 struct pf_addr *a = NULL;
4389
4390 if (nr != NULL) {
4391 if (direction == PF_OUT)

--- 22 unchanged lines hidden (view full) ---

4414 else if ((af == AF_INET6) && r->return_icmp6)
4415 pf_send_icmp(m, r->return_icmp6 >> 8,
4416 r->return_icmp6 & 255, af, r);
4417 }
4418
4419 if (r->action != PF_PASS)
4420 return (PF_DROP);
4421
4166 if (pf_tag_packet(m, pftag, tag)) {
4422 if (pf_tag_packet(m, pd->pf_mtag, tag, rtableid)) {
4167 REASON_SET(&reason, PFRES_MEMORY);
4168 return (PF_DROP);
4169 }
4170
4171 if (r->keep_state || nr != NULL) {
4172 /* create new state */
4173 struct pf_state *s = NULL;
4174 struct pf_src_node *sn = NULL;
4175
4176 /* check maximums */
4177 if (r->max_states && (r->states >= r->max_states)) {
4178 pf_status.lcounters[LCNT_STATES]++;
4179 REASON_SET(&reason, PFRES_MAXSTATES);
4180 goto cleanup;
4181 }
4423 REASON_SET(&reason, PFRES_MEMORY);
4424 return (PF_DROP);
4425 }
4426
4427 if (r->keep_state || nr != NULL) {
4428 /* create new state */
4429 struct pf_state *s = NULL;
4430 struct pf_src_node *sn = NULL;
4431
4432 /* check maximums */
4433 if (r->max_states && (r->states >= r->max_states)) {
4434 pf_status.lcounters[LCNT_STATES]++;
4435 REASON_SET(&reason, PFRES_MAXSTATES);
4436 goto cleanup;
4437 }
4182 /* src node for flter rule */
4438 /* src node for filter rule */
4183 if ((r->rule_flag & PFRULE_SRCTRACK ||
4184 r->rpool.opts & PF_POOL_STICKYADDR) &&
4185 pf_insert_src_node(&sn, r, saddr, af) != 0) {
4186 REASON_SET(&reason, PFRES_SRCLIMIT);
4187 goto cleanup;
4188 }
4189 /* src node for translation rule */
4190 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&

--- 23 unchanged lines hidden (view full) ---

4214 return (PF_DROP);
4215 }
4216 bzero(s, sizeof(*s));
4217 s->rule.ptr = r;
4218 s->nat_rule.ptr = nr;
4219 s->anchor.ptr = a;
4220 STATE_INC_COUNTERS(s);
4221 s->allow_opts = r->allow_opts;
4439 if ((r->rule_flag & PFRULE_SRCTRACK ||
4440 r->rpool.opts & PF_POOL_STICKYADDR) &&
4441 pf_insert_src_node(&sn, r, saddr, af) != 0) {
4442 REASON_SET(&reason, PFRES_SRCLIMIT);
4443 goto cleanup;
4444 }
4445 /* src node for translation rule */
4446 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&

--- 23 unchanged lines hidden (view full) ---

4470 return (PF_DROP);
4471 }
4472 bzero(s, sizeof(*s));
4473 s->rule.ptr = r;
4474 s->nat_rule.ptr = nr;
4475 s->anchor.ptr = a;
4476 STATE_INC_COUNTERS(s);
4477 s->allow_opts = r->allow_opts;
4222 s->log = r->log & 2;
4478 s->log = r->log & PF_LOG_ALL;
4479 if (nr != NULL)
4480 s->log |= nr->log & PF_LOG_ALL;
4223 s->proto = pd->proto;
4224 s->direction = direction;
4225 s->af = af;
4226 if (direction == PF_OUT) {
4227 PF_ACPY(&s->gwy.addr, saddr, af);
4228 PF_ACPY(&s->ext.addr, daddr, af);
4229 if (nr != NULL)
4230 PF_ACPY(&s->lan.addr, &pd->baddr, af);

--- 43 unchanged lines hidden (view full) ---

4274pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
4275 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am,
4276 struct pf_ruleset **rsm)
4277{
4278 struct pf_rule *r, *a = NULL;
4279 struct pf_ruleset *ruleset = NULL;
4280 sa_family_t af = pd->af;
4281 u_short reason;
4481 s->proto = pd->proto;
4482 s->direction = direction;
4483 s->af = af;
4484 if (direction == PF_OUT) {
4485 PF_ACPY(&s->gwy.addr, saddr, af);
4486 PF_ACPY(&s->ext.addr, daddr, af);
4487 if (nr != NULL)
4488 PF_ACPY(&s->lan.addr, &pd->baddr, af);

--- 43 unchanged lines hidden (view full) ---

4532pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
4533 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am,
4534 struct pf_ruleset **rsm)
4535{
4536 struct pf_rule *r, *a = NULL;
4537 struct pf_ruleset *ruleset = NULL;
4538 sa_family_t af = pd->af;
4539 u_short reason;
4282 struct pf_tag *pftag = NULL;
4283 int tag = -1;
4284 int asd = 0;
4540 int tag = -1;
4541 int asd = 0;
4542 int match = 0;
4285
4286 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
4287 while (r != NULL) {
4288 r->evaluations++;
4543
4544 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
4545 while (r != NULL) {
4546 r->evaluations++;
4289 if (r->kif != NULL &&
4290 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
4547 if (pfi_kif_match(r->kif, kif) == r->ifnot)
4291 r = r->skip[PF_SKIP_IFP].ptr;
4292 else if (r->direction && r->direction != direction)
4293 r = r->skip[PF_SKIP_DIR].ptr;
4294 else if (r->af && r->af != af)
4295 r = r->skip[PF_SKIP_AF].ptr;
4296 else if (r->proto && r->proto != pd->proto)
4297 r = r->skip[PF_SKIP_PROTO].ptr;
4548 r = r->skip[PF_SKIP_IFP].ptr;
4549 else if (r->direction && r->direction != direction)
4550 r = r->skip[PF_SKIP_DIR].ptr;
4551 else if (r->af && r->af != af)
4552 r = r->skip[PF_SKIP_AF].ptr;
4553 else if (r->proto && r->proto != pd->proto)
4554 r = r->skip[PF_SKIP_PROTO].ptr;
4298 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.neg))
4555 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
4556 r->src.neg, kif))
4299 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
4557 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
4300 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.neg))
4558 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
4559 r->dst.neg, NULL))
4301 r = r->skip[PF_SKIP_DST_ADDR].ptr;
4560 r = r->skip[PF_SKIP_DST_ADDR].ptr;
4302 else if (r->tos && !(r->tos & pd->tos))
4561 else if (r->tos && !(r->tos == pd->tos))
4303 r = TAILQ_NEXT(r, entries);
4304 else if (r->src.port_op || r->dst.port_op ||
4305 r->flagset || r->type || r->code ||
4306 r->os_fingerprint != PF_OSFP_ANY)
4307 r = TAILQ_NEXT(r, entries);
4308 else if (r->prob && r->prob <= arc4random())
4309 r = TAILQ_NEXT(r, entries);
4562 r = TAILQ_NEXT(r, entries);
4563 else if (r->src.port_op || r->dst.port_op ||
4564 r->flagset || r->type || r->code ||
4565 r->os_fingerprint != PF_OSFP_ANY)
4566 r = TAILQ_NEXT(r, entries);
4567 else if (r->prob && r->prob <= arc4random())
4568 r = TAILQ_NEXT(r, entries);
4310 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
4569 else if (r->match_tag && !pf_match_tag(m, r, pd->pf_mtag, &tag))
4311 r = TAILQ_NEXT(r, entries);
4312 else {
4313 if (r->anchor == NULL) {
4570 r = TAILQ_NEXT(r, entries);
4571 else {
4572 if (r->anchor == NULL) {
4573 match = 1;
4314 *rm = r;
4315 *am = a;
4316 *rsm = ruleset;
4317 if ((*rm)->quick)
4318 break;
4319 r = TAILQ_NEXT(r, entries);
4320 } else
4321 pf_step_into_anchor(&asd, &ruleset,
4574 *rm = r;
4575 *am = a;
4576 *rsm = ruleset;
4577 if ((*rm)->quick)
4578 break;
4579 r = TAILQ_NEXT(r, entries);
4580 } else
4581 pf_step_into_anchor(&asd, &ruleset,
4322 PF_RULESET_FILTER, &r, &a);
4582 PF_RULESET_FILTER, &r, &a, &match);
4323 }
4583 }
4324 if (r == NULL)
4325 pf_step_out_of_anchor(&asd, &ruleset,
4326 PF_RULESET_FILTER, &r, &a);
4584 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
4585 PF_RULESET_FILTER, &r, &a, &match))
4586 break;
4327 }
4328 r = *rm;
4329 a = *am;
4330 ruleset = *rsm;
4331
4332 REASON_SET(&reason, PFRES_MATCH);
4333
4334 if (r->log)
4587 }
4588 r = *rm;
4589 a = *am;
4590 ruleset = *rsm;
4591
4592 REASON_SET(&reason, PFRES_MATCH);
4593
4594 if (r->log)
4335 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
4595 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset,
4596 pd);
4336
4337 if (r->action != PF_PASS)
4338 return (PF_DROP);
4339
4597
4598 if (r->action != PF_PASS)
4599 return (PF_DROP);
4600
4340 if (pf_tag_packet(m, pftag, tag)) {
4601 if (pf_tag_packet(m, pd->pf_mtag, tag, -1)) {
4341 REASON_SET(&reason, PFRES_MEMORY);
4342 return (PF_DROP);
4343 }
4344
4345 return (PF_PASS);
4346}
4347
4348int
4349pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
4350 struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
4351 u_short *reason)
4352{
4602 REASON_SET(&reason, PFRES_MEMORY);
4603 return (PF_DROP);
4604 }
4605
4606 return (PF_PASS);
4607}
4608
4609int
4610pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
4611 struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
4612 u_short *reason)
4613{
4353 struct pf_state key;
4614 struct pf_state_cmp key;
4354 struct tcphdr *th = pd->hdr.tcp;
4355 u_int16_t win = ntohs(th->th_win);
4356 u_int32_t ack, end, seq, orig_seq;
4357 u_int8_t sws, dws;
4358 int ackskew;
4359 int copyback = 0;
4360 struct pf_state_peer *src, *dst;
4361

--- 34 unchanged lines hidden (view full) ---

4396#ifdef __FreeBSD__
4397 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst,
4398#else
4399 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
4400#endif
4401 pd->src, th->th_dport, th->th_sport,
4402 (*state)->src.seqhi, ntohl(th->th_seq) + 1,
4403 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1,
4615 struct tcphdr *th = pd->hdr.tcp;
4616 u_int16_t win = ntohs(th->th_win);
4617 u_int32_t ack, end, seq, orig_seq;
4618 u_int8_t sws, dws;
4619 int ackskew;
4620 int copyback = 0;
4621 struct pf_state_peer *src, *dst;
4622

--- 34 unchanged lines hidden (view full) ---

4657#ifdef __FreeBSD__
4658 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst,
4659#else
4660 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
4661#endif
4662 pd->src, th->th_dport, th->th_sport,
4663 (*state)->src.seqhi, ntohl(th->th_seq) + 1,
4664 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1,
4404 NULL, NULL);
4665 0, NULL, NULL);
4405 REASON_SET(reason, PFRES_SYNPROXY);
4406 return (PF_SYNPROXY_DROP);
4407 } else if (!(th->th_flags & TH_ACK) ||
4408 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
4409 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
4410 REASON_SET(reason, PFRES_SYNPROXY);
4411 return (PF_DROP);
4412 } else if ((*state)->src_node != NULL &&

--- 26 unchanged lines hidden (view full) ---

4439#ifdef __FreeBSD__
4440 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af,
4441 &src->addr,
4442#else
4443 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
4444#endif
4445 &dst->addr, src->port, dst->port,
4446 (*state)->dst.seqhi, 0, TH_SYN, 0,
4666 REASON_SET(reason, PFRES_SYNPROXY);
4667 return (PF_SYNPROXY_DROP);
4668 } else if (!(th->th_flags & TH_ACK) ||
4669 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
4670 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
4671 REASON_SET(reason, PFRES_SYNPROXY);
4672 return (PF_DROP);
4673 } else if ((*state)->src_node != NULL &&

--- 26 unchanged lines hidden (view full) ---

4700#ifdef __FreeBSD__
4701 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af,
4702 &src->addr,
4703#else
4704 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
4705#endif
4706 &dst->addr, src->port, dst->port,
4707 (*state)->dst.seqhi, 0, TH_SYN, 0,
4447 (*state)->src.mss, 0, 0, NULL, NULL);
4708 (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL);
4448 REASON_SET(reason, PFRES_SYNPROXY);
4449 return (PF_SYNPROXY_DROP);
4450 } else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
4451 (TH_SYN|TH_ACK)) ||
4452 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) {
4453 REASON_SET(reason, PFRES_SYNPROXY);
4454 return (PF_DROP);
4455 } else {
4456 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1);
4457 (*state)->dst.seqlo = ntohl(th->th_seq);
4458#ifdef __FreeBSD__
4459 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst,
4460#else
4461 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
4462#endif
4463 pd->src, th->th_dport, th->th_sport,
4464 ntohl(th->th_ack), ntohl(th->th_seq) + 1,
4465 TH_ACK, (*state)->src.max_win, 0, 0, 0,
4709 REASON_SET(reason, PFRES_SYNPROXY);
4710 return (PF_SYNPROXY_DROP);
4711 } else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
4712 (TH_SYN|TH_ACK)) ||
4713 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) {
4714 REASON_SET(reason, PFRES_SYNPROXY);
4715 return (PF_DROP);
4716 } else {
4717 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1);
4718 (*state)->dst.seqlo = ntohl(th->th_seq);
4719#ifdef __FreeBSD__
4720 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst,
4721#else
4722 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
4723#endif
4724 pd->src, th->th_dport, th->th_sport,
4725 ntohl(th->th_ack), ntohl(th->th_seq) + 1,
4726 TH_ACK, (*state)->src.max_win, 0, 0, 0,
4466 NULL, NULL);
4727 (*state)->tag, NULL, NULL);
4467#ifdef __FreeBSD__
4468 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af,
4469 &src->addr,
4470#else
4471 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
4472#endif
4473 &dst->addr, src->port, dst->port,
4474 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
4475 TH_ACK, (*state)->dst.max_win, 0, 0, 1,
4728#ifdef __FreeBSD__
4729 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af,
4730 &src->addr,
4731#else
4732 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
4733#endif
4734 &dst->addr, src->port, dst->port,
4735 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
4736 TH_ACK, (*state)->dst.max_win, 0, 0, 1,
4476 NULL, NULL);
4737 0, NULL, NULL);
4477 (*state)->src.seqdiff = (*state)->dst.seqhi -
4478 (*state)->src.seqlo;
4479 (*state)->dst.seqdiff = (*state)->src.seqhi -
4480 (*state)->dst.seqlo;
4481 (*state)->src.seqhi = (*state)->src.seqlo +
4482 (*state)->dst.max_win;
4483 (*state)->dst.seqhi = (*state)->dst.seqlo +
4484 (*state)->src.max_win;

--- 26 unchanged lines hidden (view full) ---

4511 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) {
4512 REASON_SET(reason, PFRES_MEMORY);
4513 return (PF_DROP);
4514 }
4515 }
4516
4517 /* Deferred generation of sequence number modulator */
4518 if (dst->seqdiff && !src->seqdiff) {
4738 (*state)->src.seqdiff = (*state)->dst.seqhi -
4739 (*state)->src.seqlo;
4740 (*state)->dst.seqdiff = (*state)->src.seqhi -
4741 (*state)->dst.seqlo;
4742 (*state)->src.seqhi = (*state)->src.seqlo +
4743 (*state)->dst.max_win;
4744 (*state)->dst.seqhi = (*state)->dst.seqlo +
4745 (*state)->src.max_win;

--- 26 unchanged lines hidden (view full) ---

4772 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) {
4773 REASON_SET(reason, PFRES_MEMORY);
4774 return (PF_DROP);
4775 }
4776 }
4777
4778 /* Deferred generation of sequence number modulator */
4779 if (dst->seqdiff && !src->seqdiff) {
4519 while ((src->seqdiff = htonl(arc4random())) == 0)
4780#ifdef __FreeBSD__
4781 while ((src->seqdiff = pf_new_isn(*state) - seq) == 0)
4520 ;
4782 ;
4783#else
4784 while ((src->seqdiff = tcp_rndiss_next() - seq) == 0)
4785 ;
4786#endif
4521 ack = ntohl(th->th_ack) - dst->seqdiff;
4522 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
4523 src->seqdiff), 0);
4524 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
4525 copyback = 1;
4526 } else {
4527 ack = ntohl(th->th_ack);
4528 }

--- 71 unchanged lines hidden (view full) ---

4600 if (seq == end) {
4601 /* Ease sequencing restrictions on no data packets */
4602 seq = src->seqlo;
4603 end = seq;
4604 }
4605
4606 ackskew = dst->seqlo - ack;
4607
4787 ack = ntohl(th->th_ack) - dst->seqdiff;
4788 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
4789 src->seqdiff), 0);
4790 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
4791 copyback = 1;
4792 } else {
4793 ack = ntohl(th->th_ack);
4794 }

--- 71 unchanged lines hidden (view full) ---

4866 if (seq == end) {
4867 /* Ease sequencing restrictions on no data packets */
4868 seq = src->seqlo;
4869 end = seq;
4870 }
4871
4872 ackskew = dst->seqlo - ack;
4873
4874
4875 /*
4876 * Need to demodulate the sequence numbers in any TCP SACK options
4877 * (Selective ACK). We could optionally validate the SACK values
4878 * against the current ACK window, either forwards or backwards, but
4879 * I'm not confident that SACK has been implemented properly
4880 * everywhere. It wouldn't surprise me if several stacks accidently
4881 * SACK too far backwards of previously ACKed data. There really aren't
4882 * any security implications of bad SACKing unless the target stack
4883 * doesn't validate the option length correctly. Someone trying to
4884 * spoof into a TCP connection won't bother blindly sending SACK
4885 * options anyway.
4886 */
4887 if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) {
4888 if (pf_modulate_sack(m, off, pd, th, dst))
4889 copyback = 1;
4890 }
4891
4892
4608#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */
4609 if (SEQ_GEQ(src->seqhi, end) &&
4610 /* Last octet inside other's window space */
4611 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
4612 /* Retrans: not more than one window back */
4613 (ackskew >= -MAXACKWINDOW) &&
4614 /* Acking not more than one reassembled fragment backwards */
4615 (ackskew <= (MAXACKWINDOW << sws)) &&
4616 /* Acking not more than one window forward */
4617 ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
4893#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */
4894 if (SEQ_GEQ(src->seqhi, end) &&
4895 /* Last octet inside other's window space */
4896 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
4897 /* Retrans: not more than one window back */
4898 (ackskew >= -MAXACKWINDOW) &&
4899 /* Acking not more than one reassembled fragment backwards */
4900 (ackskew <= (MAXACKWINDOW << sws)) &&
4901 /* Acking not more than one window forward */
4902 ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
4618 (pd->flags & PFDESC_IP_REAS) == 0)) {
4619 /* Require an exact sequence match on resets when possible */
4903 (orig_seq == src->seqlo + 1) || (pd->flags & PFDESC_IP_REAS) == 0)) {
4904 /* Require an exact/+1 sequence match on resets when possible */
4620
4621 if (dst->scrub || src->scrub) {
4622 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
4623 *state, src, dst, &copyback))
4624 return (PF_DROP);
4625 }
4626
4627 /* update max window */

--- 29 unchanged lines hidden (view full) ---

4657 if (th->th_flags & TH_RST)
4658 src->state = dst->state = TCPS_TIME_WAIT;
4659
4660 /* update expire time */
4661 (*state)->expire = time_second;
4662 if (src->state >= TCPS_FIN_WAIT_2 &&
4663 dst->state >= TCPS_FIN_WAIT_2)
4664 (*state)->timeout = PFTM_TCP_CLOSED;
4905
4906 if (dst->scrub || src->scrub) {
4907 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
4908 *state, src, dst, &copyback))
4909 return (PF_DROP);
4910 }
4911
4912 /* update max window */

--- 29 unchanged lines hidden (view full) ---

4942 if (th->th_flags & TH_RST)
4943 src->state = dst->state = TCPS_TIME_WAIT;
4944
4945 /* update expire time */
4946 (*state)->expire = time_second;
4947 if (src->state >= TCPS_FIN_WAIT_2 &&
4948 dst->state >= TCPS_FIN_WAIT_2)
4949 (*state)->timeout = PFTM_TCP_CLOSED;
4665 else if (src->state >= TCPS_FIN_WAIT_2 ||
4666 dst->state >= TCPS_FIN_WAIT_2)
4950 else if (src->state >= TCPS_CLOSING &&
4951 dst->state >= TCPS_CLOSING)
4667 (*state)->timeout = PFTM_TCP_FIN_WAIT;
4668 else if (src->state < TCPS_ESTABLISHED ||
4669 dst->state < TCPS_ESTABLISHED)
4670 (*state)->timeout = PFTM_TCP_OPENING;
4671 else if (src->state >= TCPS_CLOSING ||
4672 dst->state >= TCPS_CLOSING)
4673 (*state)->timeout = PFTM_TCP_CLOSING;
4674 else

--- 29 unchanged lines hidden (view full) ---

4704 * validate the connection, go through the normal state code
4705 * and keep updating the state TTL.
4706 */
4707
4708 if (pf_status.debug >= PF_DEBUG_MISC) {
4709 printf("pf: loose state match: ");
4710 pf_print_state(*state);
4711 pf_print_flags(th->th_flags);
4952 (*state)->timeout = PFTM_TCP_FIN_WAIT;
4953 else if (src->state < TCPS_ESTABLISHED ||
4954 dst->state < TCPS_ESTABLISHED)
4955 (*state)->timeout = PFTM_TCP_OPENING;
4956 else if (src->state >= TCPS_CLOSING ||
4957 dst->state >= TCPS_CLOSING)
4958 (*state)->timeout = PFTM_TCP_CLOSING;
4959 else

--- 29 unchanged lines hidden (view full) ---

4989 * validate the connection, go through the normal state code
4990 * and keep updating the state TTL.
4991 */
4992
4993 if (pf_status.debug >= PF_DEBUG_MISC) {
4994 printf("pf: loose state match: ");
4995 pf_print_state(*state);
4996 pf_print_flags(th->th_flags);
4712 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d\n",
4713 seq, ack, pd->p_len, ackskew,
4714 (*state)->packets[0], (*state)->packets[1]);
4997 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
4998 "pkts=%llu:%llu\n", seq, orig_seq, ack, pd->p_len,
4999#ifdef __FreeBSD__
5000 ackskew, (unsigned long long)(*state)->packets[0],
5001 (unsigned long long)(*state)->packets[1]);
5002#else
5003 ackskew, (*state)->packets[0],
5004 (*state)->packets[1]);
5005#endif
4715 }
4716
4717 if (dst->scrub || src->scrub) {
4718 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
4719 *state, src, dst, &copyback))
4720 return (PF_DROP);
4721 }
4722

--- 28 unchanged lines hidden (view full) ---

4751#ifdef __FreeBSD__
4752 pf_send_tcp(m, (*state)->rule.ptr, pd->af,
4753#else
4754 pf_send_tcp((*state)->rule.ptr, pd->af,
4755#endif
4756 pd->dst, pd->src, th->th_dport,
4757 th->th_sport, ntohl(th->th_ack), 0,
4758 TH_RST, 0, 0,
5006 }
5007
5008 if (dst->scrub || src->scrub) {
5009 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
5010 *state, src, dst, &copyback))
5011 return (PF_DROP);
5012 }
5013

--- 28 unchanged lines hidden (view full) ---

5042#ifdef __FreeBSD__
5043 pf_send_tcp(m, (*state)->rule.ptr, pd->af,
5044#else
5045 pf_send_tcp((*state)->rule.ptr, pd->af,
5046#endif
5047 pd->dst, pd->src, th->th_dport,
5048 th->th_sport, ntohl(th->th_ack), 0,
5049 TH_RST, 0, 0,
4759 (*state)->rule.ptr->return_ttl, 1,
5050 (*state)->rule.ptr->return_ttl, 1, 0,
4760 pd->eh, kif->pfik_ifp);
4761 src->seqlo = 0;
4762 src->seqhi = 1;
4763 src->max_win = 1;
4764 } else if (pf_status.debug >= PF_DEBUG_MISC) {
4765 printf("pf: BAD state: ");
4766 pf_print_state(*state);
4767 pf_print_flags(th->th_flags);
5051 pd->eh, kif->pfik_ifp);
5052 src->seqlo = 0;
5053 src->seqhi = 1;
5054 src->max_win = 1;
5055 } else if (pf_status.debug >= PF_DEBUG_MISC) {
5056 printf("pf: BAD state: ");
5057 pf_print_state(*state);
5058 pf_print_flags(th->th_flags);
4768 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d "
4769 "dir=%s,%s\n", seq, ack, pd->p_len, ackskew,
5059 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
5060 "pkts=%llu:%llu dir=%s,%s\n",
5061 seq, orig_seq, ack, pd->p_len, ackskew,
5062#ifdef __FreeBSD__
5063 (unsigned long long)(*state)->packets[0],
5064 (unsigned long long)(*state)->packets[1],
5065#else
4770 (*state)->packets[0], (*state)->packets[1],
5066 (*state)->packets[0], (*state)->packets[1],
5067#endif
4771 direction == PF_IN ? "in" : "out",
4772 direction == (*state)->direction ? "fwd" : "rev");
4773 printf("pf: State failure on: %c %c %c %c | %c %c\n",
4774 SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
4775 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
4776 ' ': '2',
4777 (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
4778 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',

--- 25 unchanged lines hidden (view full) ---

4804 return (PF_PASS);
4805}
4806
4807int
4808pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
4809 struct mbuf *m, int off, void *h, struct pf_pdesc *pd)
4810{
4811 struct pf_state_peer *src, *dst;
5068 direction == PF_IN ? "in" : "out",
5069 direction == (*state)->direction ? "fwd" : "rev");
5070 printf("pf: State failure on: %c %c %c %c | %c %c\n",
5071 SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
5072 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
5073 ' ': '2',
5074 (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
5075 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',

--- 25 unchanged lines hidden (view full) ---

5101 return (PF_PASS);
5102}
5103
5104int
5105pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
5106 struct mbuf *m, int off, void *h, struct pf_pdesc *pd)
5107{
5108 struct pf_state_peer *src, *dst;
4812 struct pf_state key;
5109 struct pf_state_cmp key;
4813 struct udphdr *uh = pd->hdr.udp;
4814
4815 key.af = pd->af;
4816 key.proto = IPPROTO_UDP;
4817 if (direction == PF_IN) {
4818 PF_ACPY(&key.ext.addr, pd->src, key.af);
4819 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4820 key.ext.port = uh->uh_sport;

--- 48 unchanged lines hidden (view full) ---

4869pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
4870 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason)
4871{
4872 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
4873 u_int16_t icmpid = 0; /* make the compiler happy */
4874 u_int16_t *icmpsum = NULL; /* make the compiler happy */
4875 u_int8_t icmptype = 0; /* make the compiler happy */
4876 int state_icmp = 0;
5110 struct udphdr *uh = pd->hdr.udp;
5111
5112 key.af = pd->af;
5113 key.proto = IPPROTO_UDP;
5114 if (direction == PF_IN) {
5115 PF_ACPY(&key.ext.addr, pd->src, key.af);
5116 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
5117 key.ext.port = uh->uh_sport;

--- 48 unchanged lines hidden (view full) ---

5166pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
5167 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason)
5168{
5169 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
5170 u_int16_t icmpid = 0; /* make the compiler happy */
5171 u_int16_t *icmpsum = NULL; /* make the compiler happy */
5172 u_int8_t icmptype = 0; /* make the compiler happy */
5173 int state_icmp = 0;
5174 struct pf_state_cmp key;
4877
4878 switch (pd->proto) {
4879#ifdef INET
4880 case IPPROTO_ICMP:
4881 icmptype = pd->hdr.icmp->icmp_type;
4882 icmpid = pd->hdr.icmp->icmp_id;
4883 icmpsum = &pd->hdr.icmp->icmp_cksum;
4884

--- 21 unchanged lines hidden (view full) ---

4906 }
4907
4908 if (!state_icmp) {
4909
4910 /*
4911 * ICMP query/reply message not related to a TCP/UDP packet.
4912 * Search for an ICMP state.
4913 */
5175
5176 switch (pd->proto) {
5177#ifdef INET
5178 case IPPROTO_ICMP:
5179 icmptype = pd->hdr.icmp->icmp_type;
5180 icmpid = pd->hdr.icmp->icmp_id;
5181 icmpsum = &pd->hdr.icmp->icmp_cksum;
5182

--- 21 unchanged lines hidden (view full) ---

5204 }
5205
5206 if (!state_icmp) {
5207
5208 /*
5209 * ICMP query/reply message not related to a TCP/UDP packet.
5210 * Search for an ICMP state.
5211 */
4914 struct pf_state key;
4915
4916 key.af = pd->af;
4917 key.proto = pd->proto;
4918 if (direction == PF_IN) {
4919 PF_ACPY(&key.ext.addr, pd->src, key.af);
4920 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4921 key.ext.port = 0;
4922 key.gwy.port = icmpid;
4923 } else {

--- 169 unchanged lines hidden (view full) ---

5093 }
5094 default:
5095 terminal++;
5096 break;
5097 }
5098 } while (!terminal);
5099 break;
5100#endif /* INET6 */
5212 key.af = pd->af;
5213 key.proto = pd->proto;
5214 if (direction == PF_IN) {
5215 PF_ACPY(&key.ext.addr, pd->src, key.af);
5216 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
5217 key.ext.port = 0;
5218 key.gwy.port = icmpid;
5219 } else {

--- 169 unchanged lines hidden (view full) ---

5389 }
5390 default:
5391 terminal++;
5392 break;
5393 }
5394 } while (!terminal);
5395 break;
5396#endif /* INET6 */
5397#ifdef __FreeBSD__
5398 default:
5399 panic("AF not supported: %d", pd->af);
5400#endif
5101 }
5102
5103 switch (pd2.proto) {
5104 case IPPROTO_TCP: {
5105 struct tcphdr th;
5106 u_int32_t seq;
5401 }
5402
5403 switch (pd2.proto) {
5404 case IPPROTO_TCP: {
5405 struct tcphdr th;
5406 u_int32_t seq;
5107 struct pf_state key;
5108 struct pf_state_peer *src, *dst;
5109 u_int8_t dws;
5110 int copyback = 0;
5111
5112 /*
5113 * Only the first 8 bytes of the TCP header can be
5114 * expected. Don't access any TCP header fields after
5115 * th_seq, an ackskew test is not possible.

--- 100 unchanged lines hidden (view full) ---

5216 m_copyback(m, off2, 8, (caddr_t)&th);
5217 }
5218
5219 return (PF_PASS);
5220 break;
5221 }
5222 case IPPROTO_UDP: {
5223 struct udphdr uh;
5407 struct pf_state_peer *src, *dst;
5408 u_int8_t dws;
5409 int copyback = 0;
5410
5411 /*
5412 * Only the first 8 bytes of the TCP header can be
5413 * expected. Don't access any TCP header fields after
5414 * th_seq, an ackskew test is not possible.

--- 100 unchanged lines hidden (view full) ---

5515 m_copyback(m, off2, 8, (caddr_t)&th);
5516 }
5517
5518 return (PF_PASS);
5519 break;
5520 }
5521 case IPPROTO_UDP: {
5522 struct udphdr uh;
5224 struct pf_state key;
5225
5226 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh),
5227 NULL, reason, pd2.af)) {
5228 DPFPRINTF(PF_DEBUG_MISC,
5229 ("pf: ICMP error message too short "
5230 "(udp)\n"));
5231 return (PF_DROP);
5232 }

--- 52 unchanged lines hidden (view full) ---

5285 }
5286
5287 return (PF_PASS);
5288 break;
5289 }
5290#ifdef INET
5291 case IPPROTO_ICMP: {
5292 struct icmp iih;
5523
5524 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh),
5525 NULL, reason, pd2.af)) {
5526 DPFPRINTF(PF_DEBUG_MISC,
5527 ("pf: ICMP error message too short "
5528 "(udp)\n"));
5529 return (PF_DROP);
5530 }

--- 52 unchanged lines hidden (view full) ---

5583 }
5584
5585 return (PF_PASS);
5586 break;
5587 }
5588#ifdef INET
5589 case IPPROTO_ICMP: {
5590 struct icmp iih;
5293 struct pf_state key;
5294
5295 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN,
5296 NULL, reason, pd2.af)) {
5297 DPFPRINTF(PF_DEBUG_MISC,
5298 ("pf: ICMP error message too short i"
5299 "(icmp)\n"));
5300 return (PF_DROP);
5301 }

--- 38 unchanged lines hidden (view full) ---

5340
5341 return (PF_PASS);
5342 break;
5343 }
5344#endif /* INET */
5345#ifdef INET6
5346 case IPPROTO_ICMPV6: {
5347 struct icmp6_hdr iih;
5591
5592 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN,
5593 NULL, reason, pd2.af)) {
5594 DPFPRINTF(PF_DEBUG_MISC,
5595 ("pf: ICMP error message too short i"
5596 "(icmp)\n"));
5597 return (PF_DROP);
5598 }

--- 38 unchanged lines hidden (view full) ---

5637
5638 return (PF_PASS);
5639 break;
5640 }
5641#endif /* INET */
5642#ifdef INET6
5643 case IPPROTO_ICMPV6: {
5644 struct icmp6_hdr iih;
5348 struct pf_state key;
5349
5350 if (!pf_pull_hdr(m, off2, &iih,
5351 sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
5352 DPFPRINTF(PF_DEBUG_MISC,
5353 ("pf: ICMP error message too short "
5354 "(icmp6)\n"));
5355 return (PF_DROP);
5356 }

--- 36 unchanged lines hidden (view full) ---

5393 (caddr_t)&iih);
5394 }
5395
5396 return (PF_PASS);
5397 break;
5398 }
5399#endif /* INET6 */
5400 default: {
5645
5646 if (!pf_pull_hdr(m, off2, &iih,
5647 sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
5648 DPFPRINTF(PF_DEBUG_MISC,
5649 ("pf: ICMP error message too short "
5650 "(icmp6)\n"));
5651 return (PF_DROP);
5652 }

--- 36 unchanged lines hidden (view full) ---

5689 (caddr_t)&iih);
5690 }
5691
5692 return (PF_PASS);
5693 break;
5694 }
5695#endif /* INET6 */
5696 default: {
5401 struct pf_state key;
5402
5403 key.af = pd2.af;
5404 key.proto = pd2.proto;
5405 if (direction == PF_IN) {
5406 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
5407 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
5408 key.ext.port = 0;
5409 key.gwy.port = 0;
5410 } else {

--- 47 unchanged lines hidden (view full) ---

5458 }
5459}
5460
5461int
5462pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
5463 struct pf_pdesc *pd)
5464{
5465 struct pf_state_peer *src, *dst;
5697 key.af = pd2.af;
5698 key.proto = pd2.proto;
5699 if (direction == PF_IN) {
5700 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
5701 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
5702 key.ext.port = 0;
5703 key.gwy.port = 0;
5704 } else {

--- 47 unchanged lines hidden (view full) ---

5752 }
5753}
5754
5755int
5756pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
5757 struct pf_pdesc *pd)
5758{
5759 struct pf_state_peer *src, *dst;
5466 struct pf_state key;
5760 struct pf_state_cmp key;
5467
5468 key.af = pd->af;
5469 key.proto = pd->proto;
5470 if (direction == PF_IN) {
5471 PF_ACPY(&key.ext.addr, pd->src, key.af);
5472 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
5473 key.ext.port = 0;
5474 key.gwy.port = 0;

--- 111 unchanged lines hidden (view full) ---

5586 }
5587#endif /* INET6 */
5588 }
5589 m_copydata(m, off, len, p);
5590 return (p);
5591}
5592
5593int
5761
5762 key.af = pd->af;
5763 key.proto = pd->proto;
5764 if (direction == PF_IN) {
5765 PF_ACPY(&key.ext.addr, pd->src, key.af);
5766 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
5767 key.ext.port = 0;
5768 key.gwy.port = 0;

--- 111 unchanged lines hidden (view full) ---

5880 }
5881#endif /* INET6 */
5882 }
5883 m_copydata(m, off, len, p);
5884 return (p);
5885}
5886
5887int
5594pf_routable(struct pf_addr *addr, sa_family_t af)
5888pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif)
5595{
5596 struct sockaddr_in *dst;
5889{
5890 struct sockaddr_in *dst;
5891 int ret = 1;
5892 int check_mpath;
5893#ifndef __FreeBSD__
5894 extern int ipmultipath;
5895#endif
5597#ifdef INET6
5896#ifdef INET6
5897#ifndef __FreeBSD__
5898 extern int ip6_multipath;
5899#endif
5598 struct sockaddr_in6 *dst6;
5599 struct route_in6 ro;
5600#else
5601 struct route ro;
5602#endif
5900 struct sockaddr_in6 *dst6;
5901 struct route_in6 ro;
5902#else
5903 struct route ro;
5904#endif
5905 struct radix_node *rn;
5906 struct rtentry *rt;
5907 struct ifnet *ifp;
5603
5908
5909 check_mpath = 0;
5604 bzero(&ro, sizeof(ro));
5605 switch (af) {
5606 case AF_INET:
5607 dst = satosin(&ro.ro_dst);
5608 dst->sin_family = AF_INET;
5609 dst->sin_len = sizeof(*dst);
5610 dst->sin_addr = addr->v4;
5910 bzero(&ro, sizeof(ro));
5911 switch (af) {
5912 case AF_INET:
5913 dst = satosin(&ro.ro_dst);
5914 dst->sin_family = AF_INET;
5915 dst->sin_len = sizeof(*dst);
5916 dst->sin_addr = addr->v4;
5917#ifndef __FreeBSD__ /* MULTIPATH_ROUTING */
5918 if (ipmultipath)
5919 check_mpath = 1;
5920#endif
5611 break;
5612#ifdef INET6
5613 case AF_INET6:
5614 dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
5615 dst6->sin6_family = AF_INET6;
5616 dst6->sin6_len = sizeof(*dst6);
5617 dst6->sin6_addr = addr->v6;
5921 break;
5922#ifdef INET6
5923 case AF_INET6:
5924 dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
5925 dst6->sin6_family = AF_INET6;
5926 dst6->sin6_len = sizeof(*dst6);
5927 dst6->sin6_addr = addr->v6;
5928#ifndef __FreeBSD__ /* MULTIPATH_ROUTING */
5929 if (ip6_multipath)
5930 check_mpath = 1;
5931#endif
5618 break;
5619#endif /* INET6 */
5620 default:
5621 return (0);
5622 }
5623
5932 break;
5933#endif /* INET6 */
5934 default:
5935 return (0);
5936 }
5937
5938 /* Skip checks for ipsec interfaces */
5939 if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC)
5940 goto out;
5941
5624#ifdef __FreeBSD__
5942#ifdef __FreeBSD__
5625#ifdef RTF_PRCLONING
5626 rtalloc_ign((struct route *)&ro, (RTF_CLONING | RTF_PRCLONING));
5627#else /* !RTF_PRCLONING */
5628 rtalloc_ign((struct route *)&ro, RTF_CLONING);
5943 rtalloc_ign((struct route *)&ro, RTF_CLONING);
5629#endif
5630#else /* ! __FreeBSD__ */
5631 rtalloc_noclone((struct route *)&ro, NO_CLONING);
5632#endif
5633
5634 if (ro.ro_rt != NULL) {
5944#else /* ! __FreeBSD__ */
5945 rtalloc_noclone((struct route *)&ro, NO_CLONING);
5946#endif
5947
5948 if (ro.ro_rt != NULL) {
5635 RTFREE(ro.ro_rt);
5636 return (1);
5637 }
5949 /* No interface given, this is a no-route check */
5950 if (kif == NULL)
5951 goto out;
5638
5952
5639 return (0);
5953 if (kif->pfik_ifp == NULL) {
5954 ret = 0;
5955 goto out;
5956 }
5957
5958 /* Perform uRPF check if passed input interface */
5959 ret = 0;
5960 rn = (struct radix_node *)ro.ro_rt;
5961 do {
5962 rt = (struct rtentry *)rn;
5963#ifndef __FreeBSD__ /* CARPDEV */
5964 if (rt->rt_ifp->if_type == IFT_CARP)
5965 ifp = rt->rt_ifp->if_carpdev;
5966 else
5967#endif
5968 ifp = rt->rt_ifp;
5969
5970 if (kif->pfik_ifp == ifp)
5971 ret = 1;
5972#ifdef __FreeBSD__ /* MULTIPATH_ROUTING */
5973 rn = NULL;
5974#else
5975 rn = rn_mpath_next(rn);
5976#endif
5977 } while (check_mpath == 1 && rn != NULL && ret == 0);
5978 } else
5979 ret = 0;
5980out:
5981 if (ro.ro_rt != NULL)
5982 RTFREE(ro.ro_rt);
5983 return (ret);
5640}
5641
5642int
5643pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw)
5644{
5645 struct sockaddr_in *dst;
5646#ifdef INET6
5647 struct sockaddr_in6 *dst6;

--- 45 unchanged lines hidden (view full) ---

5693
5694 return (ret);
5695}
5696
5697#ifdef INET
5698
5699void
5700pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
5984}
5985
5986int
5987pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw)
5988{
5989 struct sockaddr_in *dst;
5990#ifdef INET6
5991 struct sockaddr_in6 *dst6;

--- 45 unchanged lines hidden (view full) ---

6037
6038 return (ret);
6039}
6040
6041#ifdef INET
6042
6043void
6044pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
5701 struct pf_state *s)
6045 struct pf_state *s, struct pf_pdesc *pd)
5702{
5703 struct mbuf *m0, *m1;
6046{
6047 struct mbuf *m0, *m1;
5704 struct m_tag *mtag;
5705 struct route iproute;
6048 struct route iproute;
5706 struct route *ro = NULL; /* XXX: was uninitialized */
6049 struct route *ro = NULL;
5707 struct sockaddr_in *dst;
5708 struct ip *ip;
5709 struct ifnet *ifp = NULL;
5710 struct pf_addr naddr;
5711 struct pf_src_node *sn = NULL;
5712 int error = 0;
5713#ifdef __FreeBSD__
5714 int sw_csum;
5715#endif
6050 struct sockaddr_in *dst;
6051 struct ip *ip;
6052 struct ifnet *ifp = NULL;
6053 struct pf_addr naddr;
6054 struct pf_src_node *sn = NULL;
6055 int error = 0;
6056#ifdef __FreeBSD__
6057 int sw_csum;
6058#endif
6059#ifdef IPSEC
6060 struct m_tag *mtag;
6061#endif /* IPSEC */
5716
5717 if (m == NULL || *m == NULL || r == NULL ||
5718 (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
5719 panic("pf_route: invalid parameters");
5720
6062
6063 if (m == NULL || *m == NULL || r == NULL ||
6064 (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
6065 panic("pf_route: invalid parameters");
6066
5721 if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) {
5722 if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) ==
5723 NULL) {
5724 m0 = *m;
5725 *m = NULL;
5726 goto bad;
5727 }
5728 *(char *)(mtag + 1) = 1;
5729 m_tag_prepend(*m, mtag);
5730 } else {
5731 if (*(char *)(mtag + 1) > 3) {
5732 m0 = *m;
5733 *m = NULL;
5734 goto bad;
5735 }
5736 (*(char *)(mtag + 1))++;
6067 if (pd->pf_mtag->routed++ > 3) {
6068 m0 = *m;
6069 *m = NULL;
6070 goto bad;
5737 }
5738
5739 if (r->rt == PF_DUPTO) {
5740#ifdef __FreeBSD__
5741 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
5742#else
5743 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
5744#endif

--- 130 unchanged lines hidden (view full) ---

5875 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) {
5876 /* Notify IPsec to do its own crypto. */
5877 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
5878 goto bad;
5879 }
5880#endif /* IPSEC */
5881
5882 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */
6071 }
6072
6073 if (r->rt == PF_DUPTO) {
6074#ifdef __FreeBSD__
6075 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
6076#else
6077 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
6078#endif

--- 130 unchanged lines hidden (view full) ---

6209 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) {
6210 /* Notify IPsec to do its own crypto. */
6211 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
6212 goto bad;
6213 }
6214#endif /* IPSEC */
6215
6216 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */
5883 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) {
6217 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) {
5884 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) ||
5885 ifp->if_bridge != NULL) {
5886 in_delayed_cksum(m0);
6218 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) ||
6219 ifp->if_bridge != NULL) {
6220 in_delayed_cksum(m0);
5887 m0->m_pkthdr.csum &= ~M_TCPV4_CSUM_OUT; /* Clear */
6221 m0->m_pkthdr.csum_flags &= ~M_TCPV4_CSUM_OUT; /* Clear */
5888 }
6222 }
5889 } else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) {
6223 } else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) {
5890 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) ||
5891 ifp->if_bridge != NULL) {
5892 in_delayed_cksum(m0);
6224 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) ||
6225 ifp->if_bridge != NULL) {
6226 in_delayed_cksum(m0);
5893 m0->m_pkthdr.csum &= ~M_UDPV4_CSUM_OUT; /* Clear */
6227 m0->m_pkthdr.csum_flags &= ~M_UDPV4_CSUM_OUT; /* Clear */
5894 }
5895 }
5896
5897 if (ntohs(ip->ip_len) <= ifp->if_mtu) {
5898 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
5899 ifp->if_bridge == NULL) {
6228 }
6229 }
6230
6231 if (ntohs(ip->ip_len) <= ifp->if_mtu) {
6232 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
6233 ifp->if_bridge == NULL) {
5900 m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT;
6234 m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
5901 ipstat.ips_outhwcsum++;
5902 } else {
5903 ip->ip_sum = 0;
5904 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
5905 }
5906 /* Update relevant hardware checksum stats for TCP/UDP */
6235 ipstat.ips_outhwcsum++;
6236 } else {
6237 ip->ip_sum = 0;
6238 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
6239 }
6240 /* Update relevant hardware checksum stats for TCP/UDP */
5907 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT)
6241 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT)
5908 tcpstat.tcps_outhwcsum++;
6242 tcpstat.tcps_outhwcsum++;
5909 else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT)
6243 else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT)
5910 udpstat.udps_outhwcsum++;
5911 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL);
5912 goto done;
5913 }
5914#endif
5915 /*
5916 * Too large for interface; fragment if possible.
5917 * Must be able to put at least 8 bytes per fragment.

--- 6 unchanged lines hidden (view full) ---

5924 NTOHS(ip->ip_len);
5925 NTOHS(ip->ip_off);
5926 PF_UNLOCK();
5927 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
5928 ifp->if_mtu);
5929 PF_LOCK();
5930#else
5931 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
6244 udpstat.udps_outhwcsum++;
6245 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL);
6246 goto done;
6247 }
6248#endif
6249 /*
6250 * Too large for interface; fragment if possible.
6251 * Must be able to put at least 8 bytes per fragment.

--- 6 unchanged lines hidden (view full) ---

6258 NTOHS(ip->ip_len);
6259 NTOHS(ip->ip_off);
6260 PF_UNLOCK();
6261 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
6262 ifp->if_mtu);
6263 PF_LOCK();
6264#else
6265 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
5932 ifp);
6266 ifp->if_mtu);
5933#endif
5934 goto done;
5935 } else
5936 goto bad;
5937 }
5938
5939 m1 = m0;
5940#ifdef __FreeBSD__

--- 46 unchanged lines hidden (view full) ---

5987 m_freem(m0);
5988 goto done;
5989}
5990#endif /* INET */
5991
5992#ifdef INET6
5993void
5994pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
6267#endif
6268 goto done;
6269 } else
6270 goto bad;
6271 }
6272
6273 m1 = m0;
6274#ifdef __FreeBSD__

--- 46 unchanged lines hidden (view full) ---

6321 m_freem(m0);
6322 goto done;
6323}
6324#endif /* INET */
6325
6326#ifdef INET6
6327void
6328pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
5995 struct pf_state *s)
6329 struct pf_state *s, struct pf_pdesc *pd)
5996{
5997 struct mbuf *m0;
6330{
6331 struct mbuf *m0;
5998 struct m_tag *mtag;
5999 struct route_in6 ip6route;
6000 struct route_in6 *ro;
6001 struct sockaddr_in6 *dst;
6002 struct ip6_hdr *ip6;
6003 struct ifnet *ifp = NULL;
6004 struct pf_addr naddr;
6005 struct pf_src_node *sn = NULL;
6006 int error = 0;
6007
6008 if (m == NULL || *m == NULL || r == NULL ||
6009 (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
6010 panic("pf_route6: invalid parameters");
6011
6332 struct route_in6 ip6route;
6333 struct route_in6 *ro;
6334 struct sockaddr_in6 *dst;
6335 struct ip6_hdr *ip6;
6336 struct ifnet *ifp = NULL;
6337 struct pf_addr naddr;
6338 struct pf_src_node *sn = NULL;
6339 int error = 0;
6340
6341 if (m == NULL || *m == NULL || r == NULL ||
6342 (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
6343 panic("pf_route6: invalid parameters");
6344
6012 if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) {
6013 if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) ==
6014 NULL) {
6015 m0 = *m;
6016 *m = NULL;
6017 goto bad;
6018 }
6019 *(char *)(mtag + 1) = 1;
6020 m_tag_prepend(*m, mtag);
6021 } else {
6022 if (*(char *)(mtag + 1) > 3) {
6023 m0 = *m;
6024 *m = NULL;
6025 goto bad;
6026 }
6027 (*(char *)(mtag + 1))++;
6345 if (pd->pf_mtag->routed++ > 3) {
6346 m0 = *m;
6347 *m = NULL;
6348 goto bad;
6028 }
6029
6030 if (r->rt == PF_DUPTO) {
6031#ifdef __FreeBSD__
6032 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
6033#else
6034 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
6035#endif

--- 13 unchanged lines hidden (view full) ---

6049
6050 ro = &ip6route;
6051 bzero((caddr_t)ro, sizeof(*ro));
6052 dst = (struct sockaddr_in6 *)&ro->ro_dst;
6053 dst->sin6_family = AF_INET6;
6054 dst->sin6_len = sizeof(*dst);
6055 dst->sin6_addr = ip6->ip6_dst;
6056
6349 }
6350
6351 if (r->rt == PF_DUPTO) {
6352#ifdef __FreeBSD__
6353 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
6354#else
6355 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
6356#endif

--- 13 unchanged lines hidden (view full) ---

6370
6371 ro = &ip6route;
6372 bzero((caddr_t)ro, sizeof(*ro));
6373 dst = (struct sockaddr_in6 *)&ro->ro_dst;
6374 dst->sin6_family = AF_INET6;
6375 dst->sin6_len = sizeof(*dst);
6376 dst->sin6_addr = ip6->ip6_dst;
6377
6057 /* Cheat. */
6378 /* Cheat. XXX why only in the v6 case??? */
6058 if (r->rt == PF_FASTROUTE) {
6059#ifdef __FreeBSD__
6060 m0->m_flags |= M_SKIP_FIREWALL;
6061 PF_UNLOCK();
6062 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
6063 PF_LOCK();
6064#else
6065 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
6066 if (mtag == NULL)
6067 goto bad;
6068 m_tag_prepend(m0, mtag);
6379 if (r->rt == PF_FASTROUTE) {
6380#ifdef __FreeBSD__
6381 m0->m_flags |= M_SKIP_FIREWALL;
6382 PF_UNLOCK();
6383 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
6384 PF_LOCK();
6385#else
6386 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
6387 if (mtag == NULL)
6388 goto bad;
6389 m_tag_prepend(m0, mtag);
6390 pd->pf_mtag->flags |= PF_TAG_GENERATED;
6069 ip6_output(m0, NULL, NULL, 0, NULL, NULL);
6070#endif
6071 return;
6072 }
6073
6074 if (TAILQ_EMPTY(&r->rpool.list)) {
6075 DPFPRINTF(PF_DEBUG_URGENT,
6076 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n"));

--- 39 unchanged lines hidden (view full) ---

6116 }
6117 ip6 = mtod(m0, struct ip6_hdr *);
6118 }
6119
6120 /*
6121 * If the packet is too large for the outgoing interface,
6122 * send back an icmp6 error.
6123 */
6391 ip6_output(m0, NULL, NULL, 0, NULL, NULL);
6392#endif
6393 return;
6394 }
6395
6396 if (TAILQ_EMPTY(&r->rpool.list)) {
6397 DPFPRINTF(PF_DEBUG_URGENT,
6398 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n"));

--- 39 unchanged lines hidden (view full) ---

6438 }
6439 ip6 = mtod(m0, struct ip6_hdr *);
6440 }
6441
6442 /*
6443 * If the packet is too large for the outgoing interface,
6444 * send back an icmp6 error.
6445 */
6124 if (IN6_IS_ADDR_LINKLOCAL(&dst->sin6_addr))
6446 if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr))
6125 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
6126 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
6127#ifdef __FreeBSD__
6128 PF_UNLOCK();
6129#endif
6130 error = nd6_output(ifp, ifp, m0, dst, NULL);
6131#ifdef __FreeBSD__
6132 PF_LOCK();

--- 145 unchanged lines hidden (view full) ---

6278 if (p == IPPROTO_TCP || p == IPPROTO_UDP) {
6279 m->m_pkthdr.csum_flags |=
6280 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
6281 m->m_pkthdr.csum_data = 0xffff;
6282 }
6283 }
6284 return (0);
6285}
6447 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
6448 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
6449#ifdef __FreeBSD__
6450 PF_UNLOCK();
6451#endif
6452 error = nd6_output(ifp, ifp, m0, dst, NULL);
6453#ifdef __FreeBSD__
6454 PF_LOCK();

--- 145 unchanged lines hidden (view full) ---

6600 if (p == IPPROTO_TCP || p == IPPROTO_UDP) {
6601 m->m_pkthdr.csum_flags |=
6602 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
6603 m->m_pkthdr.csum_data = 0xffff;
6604 }
6605 }
6606 return (0);
6607}
6286#else
6608#else /* !__FreeBSD__ */
6287/*
6288 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag
6289 * off is the offset where the protocol header starts
6290 * len is the total length of protocol header plus payload
6291 * returns 0 when the checksum is valid, otherwise returns 1.
6292 */
6293int
6294pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,

--- 15 unchanged lines hidden (view full) ---

6310#ifdef INET6
6311 case IPPROTO_ICMPV6:
6312#endif /* INET6 */
6313 flag_ok = flag_bad = 0;
6314 break;
6315 default:
6316 return (1);
6317 }
6609/*
6610 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag
6611 * off is the offset where the protocol header starts
6612 * len is the total length of protocol header plus payload
6613 * returns 0 when the checksum is valid, otherwise returns 1.
6614 */
6615int
6616pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,

--- 15 unchanged lines hidden (view full) ---

6632#ifdef INET6
6633 case IPPROTO_ICMPV6:
6634#endif /* INET6 */
6635 flag_ok = flag_bad = 0;
6636 break;
6637 default:
6638 return (1);
6639 }
6318 if (m->m_pkthdr.csum & flag_ok)
6640 if (m->m_pkthdr.csum_flags & flag_ok)
6319 return (0);
6641 return (0);
6320 if (m->m_pkthdr.csum & flag_bad)
6642 if (m->m_pkthdr.csum_flags & flag_bad)
6321 return (1);
6322 if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
6323 return (1);
6324 if (m->m_pkthdr.len < off + len)
6325 return (1);
6326 switch (af) {
6327#ifdef INET
6328 case AF_INET:

--- 18 unchanged lines hidden (view full) ---

6347 return (1);
6348 sum = in6_cksum(m, p, off, len);
6349 break;
6350#endif /* INET6 */
6351 default:
6352 return (1);
6353 }
6354 if (sum) {
6643 return (1);
6644 if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
6645 return (1);
6646 if (m->m_pkthdr.len < off + len)
6647 return (1);
6648 switch (af) {
6649#ifdef INET
6650 case AF_INET:

--- 18 unchanged lines hidden (view full) ---

6669 return (1);
6670 sum = in6_cksum(m, p, off, len);
6671 break;
6672#endif /* INET6 */
6673 default:
6674 return (1);
6675 }
6676 if (sum) {
6355 m->m_pkthdr.csum |= flag_bad;
6677 m->m_pkthdr.csum_flags |= flag_bad;
6356 switch (p) {
6357 case IPPROTO_TCP:
6358 tcpstat.tcps_rcvbadsum++;
6359 break;
6360 case IPPROTO_UDP:
6361 udpstat.udps_badsum++;
6362 break;
6363 case IPPROTO_ICMP:
6364 icmpstat.icps_checksum++;
6365 break;
6366#ifdef INET6
6367 case IPPROTO_ICMPV6:
6368 icmp6stat.icp6s_checksum++;
6369 break;
6370#endif /* INET6 */
6371 }
6372 return (1);
6373 }
6678 switch (p) {
6679 case IPPROTO_TCP:
6680 tcpstat.tcps_rcvbadsum++;
6681 break;
6682 case IPPROTO_UDP:
6683 udpstat.udps_badsum++;
6684 break;
6685 case IPPROTO_ICMP:
6686 icmpstat.icps_checksum++;
6687 break;
6688#ifdef INET6
6689 case IPPROTO_ICMPV6:
6690 icmp6stat.icp6s_checksum++;
6691 break;
6692#endif /* INET6 */
6693 }
6694 return (1);
6695 }
6374 m->m_pkthdr.csum |= flag_ok;
6696 m->m_pkthdr.csum_flags |= flag_ok;
6375 return (0);
6376}
6697 return (0);
6698}
6377#endif
6699#endif /* __FreeBSD__ */
6378
6700
6379static int
6380pf_add_mbuf_tag(struct mbuf *m, u_int tag)
6381{
6382 struct m_tag *mtag;
6383
6384 if (m_tag_find(m, tag, NULL) != NULL)
6385 return (0);
6386 mtag = m_tag_get(tag, 0, M_NOWAIT);
6387 if (mtag == NULL)
6388 return (1);
6389 m_tag_prepend(m, mtag);
6390 return (0);
6391}
6392
6393#ifdef INET
6394int
6395#ifdef __FreeBSD__
6396pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
6397 struct ether_header *eh, struct inpcb *inp)
6398#else
6399pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
6400 struct ether_header *eh)

--- 7 unchanged lines hidden (view full) ---

6408 struct pf_state *s = NULL;
6409 struct pf_ruleset *ruleset = NULL;
6410 struct pf_pdesc pd;
6411 int off, dirndx, pqid = 0;
6412
6413#ifdef __FreeBSD__
6414 PF_LOCK();
6415#endif
6701#ifdef INET
6702int
6703#ifdef __FreeBSD__
6704pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
6705 struct ether_header *eh, struct inpcb *inp)
6706#else
6707pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
6708 struct ether_header *eh)

--- 7 unchanged lines hidden (view full) ---

6716 struct pf_state *s = NULL;
6717 struct pf_ruleset *ruleset = NULL;
6718 struct pf_pdesc pd;
6719 int off, dirndx, pqid = 0;
6720
6721#ifdef __FreeBSD__
6722 PF_LOCK();
6723#endif
6416 if (!pf_status.running ||
6724 if (!pf_status.running)
6417#ifdef __FreeBSD__
6725#ifdef __FreeBSD__
6418 (m->m_flags & M_SKIP_FIREWALL)) {
6726 {
6419 PF_UNLOCK();
6727 PF_UNLOCK();
6420#else
6421 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) {
6422#endif
6728#endif
6423 return (PF_PASS);
6729 return (PF_PASS);
6730#ifdef __FreeBSD__
6424 }
6731 }
6732#endif
6425
6733
6734 memset(&pd, 0, sizeof(pd));
6735 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) {
6426#ifdef __FreeBSD__
6736#ifdef __FreeBSD__
6737 PF_UNLOCK();
6738#endif
6739 DPFPRINTF(PF_DEBUG_URGENT,
6740 ("pf_test: pf_get_mtag returned NULL\n"));
6741 return (PF_DROP);
6742 }
6743#ifdef __FreeBSD__
6744 if (m->m_flags & M_SKIP_FIREWALL) {
6745 PF_UNLOCK();
6746 return (PF_PASS);
6747 }
6748#else
6749 if (pd.pf_mtag->flags & PF_TAG_GENERATED)
6750 return (PF_PASS);
6751#endif
6752
6753#ifdef __FreeBSD__
6427 /* XXX_IMPORT: later */
6428#else
6429 if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
6430 ifp = ifp->if_carpdev;
6431#endif
6432
6754 /* XXX_IMPORT: later */
6755#else
6756 if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
6757 ifp = ifp->if_carpdev;
6758#endif
6759
6433 kif = pfi_index2kif[ifp->if_index];
6760 kif = (struct pfi_kif *)ifp->if_pf_kif;
6434 if (kif == NULL) {
6435#ifdef __FreeBSD__
6436 PF_UNLOCK();
6437#endif
6438 DPFPRINTF(PF_DEBUG_URGENT,
6439 ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname));
6440 return (PF_DROP);
6441 }

--- 8 unchanged lines hidden (view full) ---

6450 M_ASSERTPKTHDR(m);
6451#else
6452#ifdef DIAGNOSTIC
6453 if ((m->m_flags & M_PKTHDR) == 0)
6454 panic("non-M_PKTHDR is passed to pf_test");
6455#endif /* DIAGNOSTIC */
6456#endif /* __FreeBSD__ */
6457
6761 if (kif == NULL) {
6762#ifdef __FreeBSD__
6763 PF_UNLOCK();
6764#endif
6765 DPFPRINTF(PF_DEBUG_URGENT,
6766 ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname));
6767 return (PF_DROP);
6768 }

--- 8 unchanged lines hidden (view full) ---

6777 M_ASSERTPKTHDR(m);
6778#else
6779#ifdef DIAGNOSTIC
6780 if ((m->m_flags & M_PKTHDR) == 0)
6781 panic("non-M_PKTHDR is passed to pf_test");
6782#endif /* DIAGNOSTIC */
6783#endif /* __FreeBSD__ */
6784
6458 memset(&pd, 0, sizeof(pd));
6459 if (m->m_pkthdr.len < (int)sizeof(*h)) {
6460 action = PF_DROP;
6461 REASON_SET(&reason, PFRES_SHORT);
6462 log = 1;
6463 goto done;
6464 }
6465
6466 /* We do IP header normalization and packet reassembly here */

--- 37 unchanged lines hidden (view full) ---

6504 pd.hdr.tcp = &th;
6505 if (!pf_pull_hdr(m, off, &th, sizeof(th),
6506 &action, &reason, AF_INET)) {
6507 log = action != PF_PASS;
6508 goto done;
6509 }
6510 if (dir == PF_IN && pf_check_proto_cksum(m, off,
6511 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) {
6785 if (m->m_pkthdr.len < (int)sizeof(*h)) {
6786 action = PF_DROP;
6787 REASON_SET(&reason, PFRES_SHORT);
6788 log = 1;
6789 goto done;
6790 }
6791
6792 /* We do IP header normalization and packet reassembly here */

--- 37 unchanged lines hidden (view full) ---

6830 pd.hdr.tcp = &th;
6831 if (!pf_pull_hdr(m, off, &th, sizeof(th),
6832 &action, &reason, AF_INET)) {
6833 log = action != PF_PASS;
6834 goto done;
6835 }
6836 if (dir == PF_IN && pf_check_proto_cksum(m, off,
6837 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) {
6838 REASON_SET(&reason, PFRES_PROTCKSUM);
6512 action = PF_DROP;
6513 goto done;
6514 }
6515 pd.p_len = pd.tot_len - off - (th.th_off << 2);
6516 if ((th.th_flags & TH_ACK) && pd.p_len == 0)
6517 pqid = 1;
6518 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
6519 if (action == PF_DROP)

--- 25 unchanged lines hidden (view full) ---

6545 if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
6546 &action, &reason, AF_INET)) {
6547 log = action != PF_PASS;
6548 goto done;
6549 }
6550 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m,
6551 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) {
6552 action = PF_DROP;
6839 action = PF_DROP;
6840 goto done;
6841 }
6842 pd.p_len = pd.tot_len - off - (th.th_off << 2);
6843 if ((th.th_flags & TH_ACK) && pd.p_len == 0)
6844 pqid = 1;
6845 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
6846 if (action == PF_DROP)

--- 25 unchanged lines hidden (view full) ---

6872 if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
6873 &action, &reason, AF_INET)) {
6874 log = action != PF_PASS;
6875 goto done;
6876 }
6877 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m,
6878 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) {
6879 action = PF_DROP;
6880 REASON_SET(&reason, PFRES_PROTCKSUM);
6553 goto done;
6554 }
6555 if (uh.uh_dport == 0 ||
6556 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
6557 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
6558 action = PF_DROP;
6881 goto done;
6882 }
6883 if (uh.uh_dport == 0 ||
6884 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
6885 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
6886 action = PF_DROP;
6887 REASON_SET(&reason, PFRES_SHORT);
6559 goto done;
6560 }
6561 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
6562 if (action == PF_PASS) {
6563#if NPFSYNC
6564 pfsync_update_state(s);
6565#endif /* NPFSYNC */
6566 r = s->rule.ptr;

--- 17 unchanged lines hidden (view full) ---

6584 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN,
6585 &action, &reason, AF_INET)) {
6586 log = action != PF_PASS;
6587 goto done;
6588 }
6589 if (dir == PF_IN && pf_check_proto_cksum(m, off,
6590 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) {
6591 action = PF_DROP;
6888 goto done;
6889 }
6890 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
6891 if (action == PF_PASS) {
6892#if NPFSYNC
6893 pfsync_update_state(s);
6894#endif /* NPFSYNC */
6895 r = s->rule.ptr;

--- 17 unchanged lines hidden (view full) ---

6913 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN,
6914 &action, &reason, AF_INET)) {
6915 log = action != PF_PASS;
6916 goto done;
6917 }
6918 if (dir == PF_IN && pf_check_proto_cksum(m, off,
6919 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) {
6920 action = PF_DROP;
6921 REASON_SET(&reason, PFRES_PROTCKSUM);
6592 goto done;
6593 }
6594 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd,
6595 &reason);
6596 if (action == PF_PASS) {
6597#if NPFSYNC
6598 pfsync_update_state(s);
6599#endif /* NPFSYNC */

--- 36 unchanged lines hidden (view full) ---

6636 !((s && s->allow_opts) || r->allow_opts)) {
6637 action = PF_DROP;
6638 REASON_SET(&reason, PFRES_IPOPTIONS);
6639 log = 1;
6640 DPFPRINTF(PF_DEBUG_MISC,
6641 ("pf: dropping packet with ip options\n"));
6642 }
6643
6922 goto done;
6923 }
6924 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd,
6925 &reason);
6926 if (action == PF_PASS) {
6927#if NPFSYNC
6928 pfsync_update_state(s);
6929#endif /* NPFSYNC */

--- 36 unchanged lines hidden (view full) ---

6966 !((s && s->allow_opts) || r->allow_opts)) {
6967 action = PF_DROP;
6968 REASON_SET(&reason, PFRES_IPOPTIONS);
6969 log = 1;
6970 DPFPRINTF(PF_DEBUG_MISC,
6971 ("pf: dropping packet with ip options\n"));
6972 }
6973
6644 if (s && s->tag)
6645 pf_tag_packet(m, pf_get_tag(m), s->tag);
6974 if ((s && s->tag) || r->rtableid)
6975 pf_tag_packet(m, pd.pf_mtag, s ? s->tag : 0, r->rtableid);
6646
6647#ifdef ALTQ
6648 if (action == PF_PASS && r->qid) {
6976
6977#ifdef ALTQ
6978 if (action == PF_PASS && r->qid) {
6649 struct m_tag *mtag;
6650 struct altq_tag *atag;
6651
6652 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
6653 if (mtag != NULL) {
6654 atag = (struct altq_tag *)(mtag + 1);
6655 if (pqid || pd.tos == IPTOS_LOWDELAY)
6656 atag->qid = r->pqid;
6657 else
6658 atag->qid = r->qid;
6659 /* add hints for ecn */
6660 atag->af = AF_INET;
6661 atag->hdr = h;
6662 m_tag_prepend(m, mtag);
6663 }
6979 if (pqid || (pd.tos & IPTOS_LOWDELAY))
6980 pd.pf_mtag->qid = r->pqid;
6981 else
6982 pd.pf_mtag->qid = r->qid;
6983 /* add hints for ecn */
6984 pd.pf_mtag->af = AF_INET;
6985 pd.pf_mtag->hdr = h;
6664 }
6665#endif /* ALTQ */
6666
6667 /*
6668 * connections redirected to loopback should not match sockets
6669 * bound specifically to loopback due to security implications,
6670 * see tcp_input() and in_pcblookup_listen().
6671 */
6672 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
6673 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
6674 (s->nat_rule.ptr->action == PF_RDR ||
6675 s->nat_rule.ptr->action == PF_BINAT) &&
6986 }
6987#endif /* ALTQ */
6988
6989 /*
6990 * connections redirected to loopback should not match sockets
6991 * bound specifically to loopback due to security implications,
6992 * see tcp_input() and in_pcblookup_listen().
6993 */
6994 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
6995 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
6996 (s->nat_rule.ptr->action == PF_RDR ||
6997 s->nat_rule.ptr->action == PF_BINAT) &&
6676 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET &&
6677 pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) {
6678 action = PF_DROP;
6679 REASON_SET(&reason, PFRES_MEMORY);
6680 }
6998 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
6999 pd.pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST;
6681
7000
6682 if (log)
6683 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, a, ruleset);
7001 if (log) {
7002 struct pf_rule *lr;
6684
7003
7004 if (s != NULL && s->nat_rule.ptr != NULL &&
7005 s->nat_rule.ptr->log & PF_LOG_ALL)
7006 lr = s->nat_rule.ptr;
7007 else
7008 lr = r;
7009 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, lr, a, ruleset,
7010 &pd);
7011 }
7012
6685 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
6686 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++;
6687
6688 if (action == PF_PASS || r->action == PF_DROP) {
7013 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
7014 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++;
7015
7016 if (action == PF_PASS || r->action == PF_DROP) {
6689 r->packets++;
6690 r->bytes += pd.tot_len;
7017 dirndx = (dir == PF_OUT);
7018 r->packets[dirndx]++;
7019 r->bytes[dirndx] += pd.tot_len;
6691 if (a != NULL) {
7020 if (a != NULL) {
6692 a->packets++;
6693 a->bytes += pd.tot_len;
7021 a->packets[dirndx]++;
7022 a->bytes[dirndx] += pd.tot_len;
6694 }
6695 if (s != NULL) {
7023 }
7024 if (s != NULL) {
6696 dirndx = (dir == s->direction) ? 0 : 1;
6697 s->packets[dirndx]++;
6698 s->bytes[dirndx] += pd.tot_len;
6699 if (s->nat_rule.ptr != NULL) {
7025 if (s->nat_rule.ptr != NULL) {
6700 s->nat_rule.ptr->packets++;
6701 s->nat_rule.ptr->bytes += pd.tot_len;
7026 s->nat_rule.ptr->packets[dirndx]++;
7027 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
6702 }
6703 if (s->src_node != NULL) {
7028 }
7029 if (s->src_node != NULL) {
6704 s->src_node->packets++;
6705 s->src_node->bytes += pd.tot_len;
7030 s->src_node->packets[dirndx]++;
7031 s->src_node->bytes[dirndx] += pd.tot_len;
6706 }
6707 if (s->nat_src_node != NULL) {
7032 }
7033 if (s->nat_src_node != NULL) {
6708 s->nat_src_node->packets++;
6709 s->nat_src_node->bytes += pd.tot_len;
7034 s->nat_src_node->packets[dirndx]++;
7035 s->nat_src_node->bytes[dirndx] += pd.tot_len;
6710 }
7036 }
7037 dirndx = (dir == s->direction) ? 0 : 1;
7038 s->packets[dirndx]++;
7039 s->bytes[dirndx] += pd.tot_len;
6711 }
6712 tr = r;
6713 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
6714 if (nr != NULL) {
6715 struct pf_addr *x;
6716 /*
6717 * XXX: we need to make sure that the addresses
6718 * passed to pfr_update_stats() are the same than

--- 28 unchanged lines hidden (view full) ---

6747
6748
6749 if (action == PF_SYNPROXY_DROP) {
6750 m_freem(*m0);
6751 *m0 = NULL;
6752 action = PF_PASS;
6753 } else if (r->rt)
6754 /* pf_route can free the mbuf causing *m0 to become NULL */
7040 }
7041 tr = r;
7042 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
7043 if (nr != NULL) {
7044 struct pf_addr *x;
7045 /*
7046 * XXX: we need to make sure that the addresses
7047 * passed to pfr_update_stats() are the same than

--- 28 unchanged lines hidden (view full) ---

7076
7077
7078 if (action == PF_SYNPROXY_DROP) {
7079 m_freem(*m0);
7080 *m0 = NULL;
7081 action = PF_PASS;
7082 } else if (r->rt)
7083 /* pf_route can free the mbuf causing *m0 to become NULL */
6755 pf_route(m0, r, dir, ifp, s);
7084 pf_route(m0, r, dir, ifp, s, &pd);
6756
6757#ifdef __FreeBSD__
6758 PF_UNLOCK();
6759#endif
6760
6761 return (action);
6762}
6763#endif /* INET */

--- 5 unchanged lines hidden (view full) ---

6769 struct ether_header *eh, struct inpcb *inp)
6770#else
6771pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
6772 struct ether_header *eh)
6773#endif
6774{
6775 struct pfi_kif *kif;
6776 u_short action, reason = 0, log = 0;
7085
7086#ifdef __FreeBSD__
7087 PF_UNLOCK();
7088#endif
7089
7090 return (action);
7091}
7092#endif /* INET */

--- 5 unchanged lines hidden (view full) ---

7098 struct ether_header *eh, struct inpcb *inp)
7099#else
7100pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
7101 struct ether_header *eh)
7102#endif
7103{
7104 struct pfi_kif *kif;
7105 u_short action, reason = 0, log = 0;
6777 struct mbuf *m = *m0;
6778 struct ip6_hdr *h = NULL; /* make the compiler happy */
7106 struct mbuf *m = *m0, *n = NULL;
7107 struct ip6_hdr *h;
6779 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
6780 struct pf_state *s = NULL;
6781 struct pf_ruleset *ruleset = NULL;
6782 struct pf_pdesc pd;
6783 int off, terminal = 0, dirndx, rh_cnt = 0;
6784
6785#ifdef __FreeBSD__
6786 PF_LOCK();
6787#endif
6788
7108 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
7109 struct pf_state *s = NULL;
7110 struct pf_ruleset *ruleset = NULL;
7111 struct pf_pdesc pd;
7112 int off, terminal = 0, dirndx, rh_cnt = 0;
7113
7114#ifdef __FreeBSD__
7115 PF_LOCK();
7116#endif
7117
6789 if (!pf_status.running ||
7118 if (!pf_status.running)
6790#ifdef __FreeBSD__
7119#ifdef __FreeBSD__
6791 (m->m_flags & M_SKIP_FIREWALL)) {
7120 {
6792 PF_UNLOCK();
7121 PF_UNLOCK();
6793#else
6794 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) {
6795#endif
6796 return (PF_PASS);
7122#endif
7123 return (PF_PASS);
7124#ifdef __FreeBSD__
6797 }
7125 }
7126#endif
6798
7127
7128 memset(&pd, 0, sizeof(pd));
7129 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) {
6799#ifdef __FreeBSD__
7130#ifdef __FreeBSD__
7131 PF_UNLOCK();
7132#endif
7133 DPFPRINTF(PF_DEBUG_URGENT,
7134 ("pf_test6: pf_get_mtag returned NULL\n"));
7135 return (PF_DROP);
7136 }
7137 if (pd.pf_mtag->flags & PF_TAG_GENERATED)
7138 return (PF_PASS);
7139
7140#ifdef __FreeBSD__
6800 /* XXX_IMPORT: later */
6801#else
6802 if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
6803 ifp = ifp->if_carpdev;
6804#endif
6805
7141 /* XXX_IMPORT: later */
7142#else
7143 if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
7144 ifp = ifp->if_carpdev;
7145#endif
7146
6806 kif = pfi_index2kif[ifp->if_index];
7147 kif = (struct pfi_kif *)ifp->if_pf_kif;
6807 if (kif == NULL) {
6808#ifdef __FreeBSD__
6809 PF_UNLOCK();
6810#endif
6811 DPFPRINTF(PF_DEBUG_URGENT,
6812 ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname));
6813 return (PF_DROP);
6814 }

--- 8 unchanged lines hidden (view full) ---

6823 M_ASSERTPKTHDR(m);
6824#else
6825#ifdef DIAGNOSTIC
6826 if ((m->m_flags & M_PKTHDR) == 0)
6827 panic("non-M_PKTHDR is passed to pf_test6");
6828#endif /* DIAGNOSTIC */
6829#endif
6830
7148 if (kif == NULL) {
7149#ifdef __FreeBSD__
7150 PF_UNLOCK();
7151#endif
7152 DPFPRINTF(PF_DEBUG_URGENT,
7153 ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname));
7154 return (PF_DROP);
7155 }

--- 8 unchanged lines hidden (view full) ---

7164 M_ASSERTPKTHDR(m);
7165#else
7166#ifdef DIAGNOSTIC
7167 if ((m->m_flags & M_PKTHDR) == 0)
7168 panic("non-M_PKTHDR is passed to pf_test6");
7169#endif /* DIAGNOSTIC */
7170#endif
7171
6831 memset(&pd, 0, sizeof(pd));
7172#ifdef __FreeBSD__
7173 h = NULL; /* make the compiler happy */
7174#endif
7175
6832 if (m->m_pkthdr.len < (int)sizeof(*h)) {
6833 action = PF_DROP;
6834 REASON_SET(&reason, PFRES_SHORT);
6835 log = 1;
6836 goto done;
6837 }
6838
6839 /* We do IP header normalization and packet reassembly here */

--- 88 unchanged lines hidden (view full) ---

6928 break;
6929 }
6930 default:
6931 terminal++;
6932 break;
6933 }
6934 } while (!terminal);
6935
7176 if (m->m_pkthdr.len < (int)sizeof(*h)) {
7177 action = PF_DROP;
7178 REASON_SET(&reason, PFRES_SHORT);
7179 log = 1;
7180 goto done;
7181 }
7182
7183 /* We do IP header normalization and packet reassembly here */

--- 88 unchanged lines hidden (view full) ---

7272 break;
7273 }
7274 default:
7275 terminal++;
7276 break;
7277 }
7278 } while (!terminal);
7279
7280 /* if there's no routing header, use unmodified mbuf for checksumming */
7281 if (!n)
7282 n = m;
7283
6936 switch (pd.proto) {
6937
6938 case IPPROTO_TCP: {
6939 struct tcphdr th;
6940
6941 pd.hdr.tcp = &th;
6942 if (!pf_pull_hdr(m, off, &th, sizeof(th),
6943 &action, &reason, AF_INET6)) {
6944 log = action != PF_PASS;
6945 goto done;
6946 }
7284 switch (pd.proto) {
7285
7286 case IPPROTO_TCP: {
7287 struct tcphdr th;
7288
7289 pd.hdr.tcp = &th;
7290 if (!pf_pull_hdr(m, off, &th, sizeof(th),
7291 &action, &reason, AF_INET6)) {
7292 log = action != PF_PASS;
7293 goto done;
7294 }
6947 if (dir == PF_IN && pf_check_proto_cksum(m, off,
7295 if (dir == PF_IN && pf_check_proto_cksum(n, off,
6948 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
6949 IPPROTO_TCP, AF_INET6)) {
6950 action = PF_DROP;
6951 REASON_SET(&reason, PFRES_PROTCKSUM);
6952 goto done;
6953 }
6954 pd.p_len = pd.tot_len - off - (th.th_off << 2);
6955 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);

--- 23 unchanged lines hidden (view full) ---

6979 struct udphdr uh;
6980
6981 pd.hdr.udp = &uh;
6982 if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
6983 &action, &reason, AF_INET6)) {
6984 log = action != PF_PASS;
6985 goto done;
6986 }
7296 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
7297 IPPROTO_TCP, AF_INET6)) {
7298 action = PF_DROP;
7299 REASON_SET(&reason, PFRES_PROTCKSUM);
7300 goto done;
7301 }
7302 pd.p_len = pd.tot_len - off - (th.th_off << 2);
7303 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);

--- 23 unchanged lines hidden (view full) ---

7327 struct udphdr uh;
7328
7329 pd.hdr.udp = &uh;
7330 if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
7331 &action, &reason, AF_INET6)) {
7332 log = action != PF_PASS;
7333 goto done;
7334 }
6987 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m,
7335 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(n,
6988 off, ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
6989 IPPROTO_UDP, AF_INET6)) {
6990 action = PF_DROP;
6991 REASON_SET(&reason, PFRES_PROTCKSUM);
6992 goto done;
6993 }
6994 if (uh.uh_dport == 0 ||
6995 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
6996 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
6997 action = PF_DROP;
7336 off, ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
7337 IPPROTO_UDP, AF_INET6)) {
7338 action = PF_DROP;
7339 REASON_SET(&reason, PFRES_PROTCKSUM);
7340 goto done;
7341 }
7342 if (uh.uh_dport == 0 ||
7343 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
7344 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
7345 action = PF_DROP;
7346 REASON_SET(&reason, PFRES_SHORT);
6998 goto done;
6999 }
7000 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
7001 if (action == PF_PASS) {
7002#if NPFSYNC
7003 pfsync_update_state(s);
7004#endif /* NPFSYNC */
7005 r = s->rule.ptr;

--- 14 unchanged lines hidden (view full) ---

7020 struct icmp6_hdr ih;
7021
7022 pd.hdr.icmp6 = &ih;
7023 if (!pf_pull_hdr(m, off, &ih, sizeof(ih),
7024 &action, &reason, AF_INET6)) {
7025 log = action != PF_PASS;
7026 goto done;
7027 }
7347 goto done;
7348 }
7349 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
7350 if (action == PF_PASS) {
7351#if NPFSYNC
7352 pfsync_update_state(s);
7353#endif /* NPFSYNC */
7354 r = s->rule.ptr;

--- 14 unchanged lines hidden (view full) ---

7369 struct icmp6_hdr ih;
7370
7371 pd.hdr.icmp6 = &ih;
7372 if (!pf_pull_hdr(m, off, &ih, sizeof(ih),
7373 &action, &reason, AF_INET6)) {
7374 log = action != PF_PASS;
7375 goto done;
7376 }
7028 if (dir == PF_IN && pf_check_proto_cksum(m, off,
7377 if (dir == PF_IN && pf_check_proto_cksum(n, off,
7029 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
7030 IPPROTO_ICMPV6, AF_INET6)) {
7031 action = PF_DROP;
7032 REASON_SET(&reason, PFRES_PROTCKSUM);
7033 goto done;
7034 }
7035 action = pf_test_state_icmp(&s, dir, kif,
7036 m, off, h, &pd, &reason);

--- 41 unchanged lines hidden (view full) ---

7078 !((s && s->allow_opts) || r->allow_opts)) {
7079 action = PF_DROP;
7080 REASON_SET(&reason, PFRES_IPOPTIONS);
7081 log = 1;
7082 DPFPRINTF(PF_DEBUG_MISC,
7083 ("pf: dropping packet with dangerous v6 headers\n"));
7084 }
7085
7378 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
7379 IPPROTO_ICMPV6, AF_INET6)) {
7380 action = PF_DROP;
7381 REASON_SET(&reason, PFRES_PROTCKSUM);
7382 goto done;
7383 }
7384 action = pf_test_state_icmp(&s, dir, kif,
7385 m, off, h, &pd, &reason);

--- 41 unchanged lines hidden (view full) ---

7427 !((s && s->allow_opts) || r->allow_opts)) {
7428 action = PF_DROP;
7429 REASON_SET(&reason, PFRES_IPOPTIONS);
7430 log = 1;
7431 DPFPRINTF(PF_DEBUG_MISC,
7432 ("pf: dropping packet with dangerous v6 headers\n"));
7433 }
7434
7086 if (s && s->tag)
7087 pf_tag_packet(m, pf_get_tag(m), s->tag);
7435 if ((s && s->tag) || r->rtableid)
7436 pf_tag_packet(m, pd.pf_mtag, s ? s->tag : 0, r->rtableid);
7088
7089#ifdef ALTQ
7090 if (action == PF_PASS && r->qid) {
7437
7438#ifdef ALTQ
7439 if (action == PF_PASS && r->qid) {
7091 struct m_tag *mtag;
7092 struct altq_tag *atag;
7093
7094 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
7095 if (mtag != NULL) {
7096 atag = (struct altq_tag *)(mtag + 1);
7097 if (pd.tos == IPTOS_LOWDELAY)
7098 atag->qid = r->pqid;
7099 else
7100 atag->qid = r->qid;
7101 /* add hints for ecn */
7102 atag->af = AF_INET6;
7103 atag->hdr = h;
7104 m_tag_prepend(m, mtag);
7105 }
7440 if (pd.tos & IPTOS_LOWDELAY)
7441 pd.pf_mtag->qid = r->pqid;
7442 else
7443 pd.pf_mtag->qid = r->qid;
7444 /* add hints for ecn */
7445 pd.pf_mtag->af = AF_INET6;
7446 pd.pf_mtag->hdr = h;
7106 }
7107#endif /* ALTQ */
7108
7109 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
7110 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
7111 (s->nat_rule.ptr->action == PF_RDR ||
7112 s->nat_rule.ptr->action == PF_BINAT) &&
7447 }
7448#endif /* ALTQ */
7449
7450 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
7451 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
7452 (s->nat_rule.ptr->action == PF_RDR ||
7453 s->nat_rule.ptr->action == PF_BINAT) &&
7113 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6) &&
7114 pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) {
7115 action = PF_DROP;
7116 REASON_SET(&reason, PFRES_MEMORY);
7117 }
7454 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6))
7455 pd.pf_mtag->flags |= PF_TAG_TRANSLATE_LOCALHOST;
7118
7456
7119 if (log)
7120 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, r, a, ruleset);
7457 if (log) {
7458 struct pf_rule *lr;
7121
7459
7460 if (s != NULL && s->nat_rule.ptr != NULL &&
7461 s->nat_rule.ptr->log & PF_LOG_ALL)
7462 lr = s->nat_rule.ptr;
7463 else
7464 lr = r;
7465 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, lr, a, ruleset,
7466 &pd);
7467 }
7468
7122 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
7123 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++;
7124
7125 if (action == PF_PASS || r->action == PF_DROP) {
7469 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
7470 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++;
7471
7472 if (action == PF_PASS || r->action == PF_DROP) {
7126 r->packets++;
7127 r->bytes += pd.tot_len;
7473 dirndx = (dir == PF_OUT);
7474 r->packets[dirndx]++;
7475 r->bytes[dirndx] += pd.tot_len;
7128 if (a != NULL) {
7476 if (a != NULL) {
7129 a->packets++;
7130 a->bytes += pd.tot_len;
7477 a->packets[dirndx]++;
7478 a->bytes[dirndx] += pd.tot_len;
7131 }
7132 if (s != NULL) {
7479 }
7480 if (s != NULL) {
7133 dirndx = (dir == s->direction) ? 0 : 1;
7134 s->packets[dirndx]++;
7135 s->bytes[dirndx] += pd.tot_len;
7136 if (s->nat_rule.ptr != NULL) {
7481 if (s->nat_rule.ptr != NULL) {
7137 s->nat_rule.ptr->packets++;
7138 s->nat_rule.ptr->bytes += pd.tot_len;
7482 s->nat_rule.ptr->packets[dirndx]++;
7483 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
7139 }
7140 if (s->src_node != NULL) {
7484 }
7485 if (s->src_node != NULL) {
7141 s->src_node->packets++;
7142 s->src_node->bytes += pd.tot_len;
7486 s->src_node->packets[dirndx]++;
7487 s->src_node->bytes[dirndx] += pd.tot_len;
7143 }
7144 if (s->nat_src_node != NULL) {
7488 }
7489 if (s->nat_src_node != NULL) {
7145 s->nat_src_node->packets++;
7146 s->nat_src_node->bytes += pd.tot_len;
7490 s->nat_src_node->packets[dirndx]++;
7491 s->nat_src_node->bytes[dirndx] += pd.tot_len;
7147 }
7492 }
7493 dirndx = (dir == s->direction) ? 0 : 1;
7494 s->packets[dirndx]++;
7495 s->bytes[dirndx] += pd.tot_len;
7148 }
7149 tr = r;
7150 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
7151 if (nr != NULL) {
7152 struct pf_addr *x;
7153 /*
7154 * XXX: we need to make sure that the addresses
7155 * passed to pfr_update_stats() are the same than

--- 28 unchanged lines hidden (view full) ---

7184
7185
7186 if (action == PF_SYNPROXY_DROP) {
7187 m_freem(*m0);
7188 *m0 = NULL;
7189 action = PF_PASS;
7190 } else if (r->rt)
7191 /* pf_route6 can free the mbuf causing *m0 to become NULL */
7496 }
7497 tr = r;
7498 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
7499 if (nr != NULL) {
7500 struct pf_addr *x;
7501 /*
7502 * XXX: we need to make sure that the addresses
7503 * passed to pfr_update_stats() are the same than

--- 28 unchanged lines hidden (view full) ---

7532
7533
7534 if (action == PF_SYNPROXY_DROP) {
7535 m_freem(*m0);
7536 *m0 = NULL;
7537 action = PF_PASS;
7538 } else if (r->rt)
7539 /* pf_route6 can free the mbuf causing *m0 to become NULL */
7192 pf_route6(m0, r, dir, ifp, s);
7540 pf_route6(m0, r, dir, ifp, s, &pd);
7193
7194#ifdef __FreeBSD__
7195 PF_UNLOCK();
7196#endif
7197 return (action);
7198}
7199#endif /* INET6 */
7200

--- 13 unchanged lines hidden ---
7541
7542#ifdef __FreeBSD__
7543 PF_UNLOCK();
7544#endif
7545 return (action);
7546}
7547#endif /* INET6 */
7548

--- 13 unchanged lines hidden ---