Deleted Added
full compact
pf.c (153110) pf.c (153545)
1/* $FreeBSD: head/sys/contrib/pf/net/pf.c 153110 2005-12-05 11:58:35Z ru $ */
1/* $FreeBSD: head/sys/contrib/pf/net/pf.c 153545 2005-12-20 00:33:33Z mlaier $ */
2/* $OpenBSD: pf.c,v 1.483 2005/03/15 17:38:43 dhartmei Exp $ */
3
4/*
5 * Copyright (c) 2001 Daniel Hartmeier
6 * Copyright (c) 2002,2003 Henning Brauer
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * - Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Effort sponsored in part by the Defense Advanced Research Projects
34 * Agency (DARPA) and Air Force Research Laboratory, Air Force
35 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
36 *
37 */
38
39#ifdef __FreeBSD__
40#include "opt_inet.h"
41#include "opt_inet6.h"
42#endif
43
44#ifdef __FreeBSD__
45#include "opt_bpf.h"
46#include "opt_pf.h"
47
48#ifdef DEV_BPF
49#define NBPFILTER DEV_BPF
50#else
51#define NBPFILTER 0
52#endif
53
54#ifdef DEV_PFLOG
55#define NPFLOG DEV_PFLOG
56#else
57#define NPFLOG 0
58#endif
59
60#ifdef DEV_PFSYNC
61#define NPFSYNC DEV_PFSYNC
62#else
63#define NPFSYNC 0
64#endif
65
66#else
67#include "bpfilter.h"
68#include "pflog.h"
69#include "pfsync.h"
70#endif
71
72#include <sys/param.h>
73#include <sys/systm.h>
74#include <sys/mbuf.h>
75#include <sys/filio.h>
76#include <sys/socket.h>
77#include <sys/socketvar.h>
78#include <sys/kernel.h>
79#include <sys/time.h>
80#ifdef __FreeBSD__
81#include <sys/sysctl.h>
82#include <sys/endian.h>
83#else
84#include <sys/pool.h>
85#endif
86
87#include <net/if.h>
88#include <net/if_types.h>
89#include <net/bpf.h>
90#include <net/route.h>
91
92#include <netinet/in.h>
93#include <netinet/in_var.h>
94#include <netinet/in_systm.h>
95#include <netinet/ip.h>
96#include <netinet/ip_var.h>
97#include <netinet/tcp.h>
98#include <netinet/tcp_seq.h>
99#include <netinet/udp.h>
100#include <netinet/ip_icmp.h>
101#include <netinet/in_pcb.h>
102#include <netinet/tcp_timer.h>
103#include <netinet/tcp_var.h>
104#include <netinet/udp_var.h>
105#include <netinet/icmp_var.h>
106#include <netinet/if_ether.h>
107
108#ifndef __FreeBSD__
109#include <dev/rndvar.h>
110#endif
111#include <net/pfvar.h>
112#include <net/if_pflog.h>
113
114#if NPFSYNC > 0
115#include <net/if_pfsync.h>
116#endif /* NPFSYNC > 0 */
117
118#ifdef INET6
119#include <netinet/ip6.h>
120#include <netinet/in_pcb.h>
121#include <netinet/icmp6.h>
122#include <netinet6/nd6.h>
123#ifdef __FreeBSD__
124#include <netinet6/ip6_var.h>
125#include <netinet6/in6_pcb.h>
126#endif
127#endif /* INET6 */
128
129#ifdef __FreeBSD__
130#include <machine/in_cksum.h>
131#include <sys/limits.h>
132#include <sys/ucred.h>
133
134extern int ip_optcopy(struct ip *, struct ip *);
135#endif
136
137#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
138
139/*
140 * Global variables
141 */
142
143struct pf_anchor_global pf_anchors;
144struct pf_ruleset pf_main_ruleset;
145struct pf_altqqueue pf_altqs[2];
146struct pf_palist pf_pabuf;
147struct pf_altqqueue *pf_altqs_active;
148struct pf_altqqueue *pf_altqs_inactive;
149struct pf_status pf_status;
150
151u_int32_t ticket_altqs_active;
152u_int32_t ticket_altqs_inactive;
153int altqs_inactive_open;
154u_int32_t ticket_pabuf;
155
156#ifdef __FreeBSD__
157struct callout pf_expire_to; /* expire timeout */
158#else
159struct timeout pf_expire_to; /* expire timeout */
160#endif
161
162struct pf_anchor_stackframe {
163 struct pf_ruleset *rs;
164 struct pf_rule *r;
165 struct pf_anchor_node *parent;
166 struct pf_anchor *child;
167} pf_anchor_stack[64];
168
169#ifdef __FreeBSD__
170uma_zone_t pf_src_tree_pl, pf_rule_pl;
171uma_zone_t pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
172#else
173struct pool pf_src_tree_pl, pf_rule_pl;
174struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
175#endif
176
177void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
178
179void pf_init_threshold(struct pf_threshold *, u_int32_t,
180 u_int32_t);
181void pf_add_threshold(struct pf_threshold *);
182int pf_check_threshold(struct pf_threshold *);
183
184void pf_change_ap(struct pf_addr *, u_int16_t *,
185 u_int16_t *, u_int16_t *, struct pf_addr *,
186 u_int16_t, u_int8_t, sa_family_t);
187#ifdef INET6
188void pf_change_a6(struct pf_addr *, u_int16_t *,
189 struct pf_addr *, u_int8_t);
190#endif /* INET6 */
191void pf_change_icmp(struct pf_addr *, u_int16_t *,
192 struct pf_addr *, struct pf_addr *, u_int16_t,
193 u_int16_t *, u_int16_t *, u_int16_t *,
194 u_int16_t *, u_int8_t, sa_family_t);
195void pf_send_tcp(const struct pf_rule *, sa_family_t,
196 const struct pf_addr *, const struct pf_addr *,
197 u_int16_t, u_int16_t, u_int32_t, u_int32_t,
198 u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
199 struct ether_header *, struct ifnet *);
200void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
201 sa_family_t, struct pf_rule *);
202struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
203 int, int, struct pfi_kif *,
204 struct pf_addr *, u_int16_t, struct pf_addr *,
205 u_int16_t, int);
206struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
207 int, int, struct pfi_kif *, struct pf_src_node **,
208 struct pf_addr *, u_int16_t,
209 struct pf_addr *, u_int16_t,
210 struct pf_addr *, u_int16_t *);
211int pf_test_tcp(struct pf_rule **, struct pf_state **,
212 int, struct pfi_kif *, struct mbuf *, int,
213 void *, struct pf_pdesc *, struct pf_rule **,
214#ifdef __FreeBSD__
215 struct pf_ruleset **, struct ifqueue *,
216 struct inpcb *);
217#else
218 struct pf_ruleset **, struct ifqueue *);
219#endif
220int pf_test_udp(struct pf_rule **, struct pf_state **,
221 int, struct pfi_kif *, struct mbuf *, int,
222 void *, struct pf_pdesc *, struct pf_rule **,
223#ifdef __FreeBSD__
224 struct pf_ruleset **, struct ifqueue *,
225 struct inpcb *);
226#else
227 struct pf_ruleset **, struct ifqueue *);
228#endif
229int pf_test_icmp(struct pf_rule **, struct pf_state **,
230 int, struct pfi_kif *, struct mbuf *, int,
231 void *, struct pf_pdesc *, struct pf_rule **,
232 struct pf_ruleset **, struct ifqueue *);
233int pf_test_other(struct pf_rule **, struct pf_state **,
234 int, struct pfi_kif *, struct mbuf *, int, void *,
235 struct pf_pdesc *, struct pf_rule **,
236 struct pf_ruleset **, struct ifqueue *);
237int pf_test_fragment(struct pf_rule **, int,
238 struct pfi_kif *, struct mbuf *, void *,
239 struct pf_pdesc *, struct pf_rule **,
240 struct pf_ruleset **);
241int pf_test_state_tcp(struct pf_state **, int,
242 struct pfi_kif *, struct mbuf *, int,
243 void *, struct pf_pdesc *, u_short *);
244int pf_test_state_udp(struct pf_state **, int,
245 struct pfi_kif *, struct mbuf *, int,
246 void *, struct pf_pdesc *);
247int pf_test_state_icmp(struct pf_state **, int,
248 struct pfi_kif *, struct mbuf *, int,
249 void *, struct pf_pdesc *, u_short *);
250int pf_test_state_other(struct pf_state **, int,
251 struct pfi_kif *, struct pf_pdesc *);
252struct pf_tag *pf_get_tag(struct mbuf *);
253int pf_match_tag(struct mbuf *, struct pf_rule *,
254 struct pf_tag **, int *);
255void pf_hash(struct pf_addr *, struct pf_addr *,
256 struct pf_poolhashkey *, sa_family_t);
257int pf_map_addr(u_int8_t, struct pf_rule *,
258 struct pf_addr *, struct pf_addr *,
259 struct pf_addr *, struct pf_src_node **);
260int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
261 struct pf_addr *, struct pf_addr *, u_int16_t,
262 struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
263 struct pf_src_node **);
264void pf_route(struct mbuf **, struct pf_rule *, int,
265 struct ifnet *, struct pf_state *);
266void pf_route6(struct mbuf **, struct pf_rule *, int,
267 struct ifnet *, struct pf_state *);
268#ifdef __FreeBSD__
269int pf_socket_lookup(uid_t *, gid_t *,
270 int, struct pf_pdesc *, struct inpcb *);
271#else
272int pf_socket_lookup(uid_t *, gid_t *,
273 int, struct pf_pdesc *);
274#endif
275u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t,
276 sa_family_t);
277u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
278 sa_family_t);
279u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t,
280 u_int16_t);
281void pf_set_rt_ifp(struct pf_state *,
282 struct pf_addr *);
283int pf_check_proto_cksum(struct mbuf *, int, int,
284 u_int8_t, sa_family_t);
285int pf_addr_wrap_neq(struct pf_addr_wrap *,
286 struct pf_addr_wrap *);
287static int pf_add_mbuf_tag(struct mbuf *, u_int);
288struct pf_state *pf_find_state_recurse(struct pfi_kif *,
289 struct pf_state *, u_int8_t);
290int pf_src_connlimit(struct pf_state **);
291int pf_check_congestion(struct ifqueue *);
292
293#ifdef __FreeBSD__
294int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len);
295
296struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX];
297
298#else
299struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
300 { &pf_state_pl, PFSTATE_HIWAT },
301 { &pf_src_tree_pl, PFSNODE_HIWAT },
302 { &pf_frent_pl, PFFRAG_FRENT_HIWAT }
303};
304#endif
305
306#define STATE_LOOKUP() \
307 do { \
308 if (direction == PF_IN) \
309 *state = pf_find_state_recurse( \
310 kif, &key, PF_EXT_GWY); \
311 else \
312 *state = pf_find_state_recurse( \
313 kif, &key, PF_LAN_EXT); \
314 if (*state == NULL || (*state)->timeout == PFTM_PURGE) \
315 return (PF_DROP); \
316 if (direction == PF_OUT && \
317 (((*state)->rule.ptr->rt == PF_ROUTETO && \
318 (*state)->rule.ptr->direction == PF_OUT) || \
319 ((*state)->rule.ptr->rt == PF_REPLYTO && \
320 (*state)->rule.ptr->direction == PF_IN)) && \
321 (*state)->rt_kif != NULL && \
322 (*state)->rt_kif != kif) \
323 return (PF_PASS); \
324 } while (0)
325
326#define STATE_TRANSLATE(s) \
327 (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \
328 ((s)->af == AF_INET6 && \
329 ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \
330 (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \
331 (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \
332 (s)->lan.port != (s)->gwy.port
333
334#define BOUND_IFACE(r, k) (((r)->rule_flag & PFRULE_IFBOUND) ? (k) : \
335 ((r)->rule_flag & PFRULE_GRBOUND) ? (k)->pfik_parent : \
336 (k)->pfik_parent->pfik_parent)
337
338#define STATE_INC_COUNTERS(s) \
339 do { \
340 s->rule.ptr->states++; \
341 if (s->anchor.ptr != NULL) \
342 s->anchor.ptr->states++; \
343 if (s->nat_rule.ptr != NULL) \
344 s->nat_rule.ptr->states++; \
345 } while (0)
346
347#define STATE_DEC_COUNTERS(s) \
348 do { \
349 if (s->nat_rule.ptr != NULL) \
350 s->nat_rule.ptr->states--; \
351 if (s->anchor.ptr != NULL) \
352 s->anchor.ptr->states--; \
353 s->rule.ptr->states--; \
354 } while (0)
355
356#ifndef __FreeBSD__
357static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
358static __inline int pf_state_compare_lan_ext(struct pf_state *,
359 struct pf_state *);
360static __inline int pf_state_compare_ext_gwy(struct pf_state *,
361 struct pf_state *);
362static __inline int pf_state_compare_id(struct pf_state *,
363 struct pf_state *);
364static __inline int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
365#else
366static int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
367static int pf_state_compare_lan_ext(struct pf_state *,
368 struct pf_state *);
369static int pf_state_compare_ext_gwy(struct pf_state *,
370 struct pf_state *);
371static int pf_state_compare_id(struct pf_state *,
372 struct pf_state *);
373static int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
374#endif
375
376struct pf_src_tree tree_src_tracking;
377
378struct pf_state_tree_id tree_id;
379struct pf_state_queue state_updates;
380
381RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
382RB_GENERATE(pf_state_tree_lan_ext, pf_state,
383 u.s.entry_lan_ext, pf_state_compare_lan_ext);
384RB_GENERATE(pf_state_tree_ext_gwy, pf_state,
385 u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
386RB_GENERATE(pf_state_tree_id, pf_state,
387 u.s.entry_id, pf_state_compare_id);
388RB_GENERATE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
389RB_GENERATE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
390
391#ifdef __FreeBSD__
392static int
393#else
394static __inline int
395#endif
396pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
397{
398 int diff;
399
400 if (a->rule.ptr > b->rule.ptr)
401 return (1);
402 if (a->rule.ptr < b->rule.ptr)
403 return (-1);
404 if ((diff = a->af - b->af) != 0)
405 return (diff);
406 switch (a->af) {
407#ifdef INET
408 case AF_INET:
409 if (a->addr.addr32[0] > b->addr.addr32[0])
410 return (1);
411 if (a->addr.addr32[0] < b->addr.addr32[0])
412 return (-1);
413 break;
414#endif /* INET */
415#ifdef INET6
416 case AF_INET6:
417 if (a->addr.addr32[3] > b->addr.addr32[3])
418 return (1);
419 if (a->addr.addr32[3] < b->addr.addr32[3])
420 return (-1);
421 if (a->addr.addr32[2] > b->addr.addr32[2])
422 return (1);
423 if (a->addr.addr32[2] < b->addr.addr32[2])
424 return (-1);
425 if (a->addr.addr32[1] > b->addr.addr32[1])
426 return (1);
427 if (a->addr.addr32[1] < b->addr.addr32[1])
428 return (-1);
429 if (a->addr.addr32[0] > b->addr.addr32[0])
430 return (1);
431 if (a->addr.addr32[0] < b->addr.addr32[0])
432 return (-1);
433 break;
434#endif /* INET6 */
435 }
436 return (0);
437}
438
439#ifdef __FreeBSD__
440static int
441#else
442static __inline int
443#endif
444pf_state_compare_lan_ext(struct pf_state *a, struct pf_state *b)
445{
446 int diff;
447
448 if ((diff = a->proto - b->proto) != 0)
449 return (diff);
450 if ((diff = a->af - b->af) != 0)
451 return (diff);
452 switch (a->af) {
453#ifdef INET
454 case AF_INET:
455 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
456 return (1);
457 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
458 return (-1);
459 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
460 return (1);
461 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
462 return (-1);
463 break;
464#endif /* INET */
465#ifdef INET6
466 case AF_INET6:
467 if (a->lan.addr.addr32[3] > b->lan.addr.addr32[3])
468 return (1);
469 if (a->lan.addr.addr32[3] < b->lan.addr.addr32[3])
470 return (-1);
471 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
472 return (1);
473 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
474 return (-1);
475 if (a->lan.addr.addr32[2] > b->lan.addr.addr32[2])
476 return (1);
477 if (a->lan.addr.addr32[2] < b->lan.addr.addr32[2])
478 return (-1);
479 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
480 return (1);
481 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
482 return (-1);
483 if (a->lan.addr.addr32[1] > b->lan.addr.addr32[1])
484 return (1);
485 if (a->lan.addr.addr32[1] < b->lan.addr.addr32[1])
486 return (-1);
487 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
488 return (1);
489 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
490 return (-1);
491 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
492 return (1);
493 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
494 return (-1);
495 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
496 return (1);
497 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
498 return (-1);
499 break;
500#endif /* INET6 */
501 }
502
503 if ((diff = a->lan.port - b->lan.port) != 0)
504 return (diff);
505 if ((diff = a->ext.port - b->ext.port) != 0)
506 return (diff);
507
508 return (0);
509}
510
511#ifdef __FreeBSD__
512static int
513#else
514static __inline int
515#endif
516pf_state_compare_ext_gwy(struct pf_state *a, struct pf_state *b)
517{
518 int diff;
519
520 if ((diff = a->proto - b->proto) != 0)
521 return (diff);
522 if ((diff = a->af - b->af) != 0)
523 return (diff);
524 switch (a->af) {
525#ifdef INET
526 case AF_INET:
527 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
528 return (1);
529 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
530 return (-1);
531 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
532 return (1);
533 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
534 return (-1);
535 break;
536#endif /* INET */
537#ifdef INET6
538 case AF_INET6:
539 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
540 return (1);
541 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
542 return (-1);
543 if (a->gwy.addr.addr32[3] > b->gwy.addr.addr32[3])
544 return (1);
545 if (a->gwy.addr.addr32[3] < b->gwy.addr.addr32[3])
546 return (-1);
547 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
548 return (1);
549 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
550 return (-1);
551 if (a->gwy.addr.addr32[2] > b->gwy.addr.addr32[2])
552 return (1);
553 if (a->gwy.addr.addr32[2] < b->gwy.addr.addr32[2])
554 return (-1);
555 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
556 return (1);
557 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
558 return (-1);
559 if (a->gwy.addr.addr32[1] > b->gwy.addr.addr32[1])
560 return (1);
561 if (a->gwy.addr.addr32[1] < b->gwy.addr.addr32[1])
562 return (-1);
563 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
564 return (1);
565 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
566 return (-1);
567 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
568 return (1);
569 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
570 return (-1);
571 break;
572#endif /* INET6 */
573 }
574
575 if ((diff = a->ext.port - b->ext.port) != 0)
576 return (diff);
577 if ((diff = a->gwy.port - b->gwy.port) != 0)
578 return (diff);
579
580 return (0);
581}
582
583#ifdef __FreeBSD__
584static int
585#else
586static __inline int
587#endif
588pf_state_compare_id(struct pf_state *a, struct pf_state *b)
589{
590 if (a->id > b->id)
591 return (1);
592 if (a->id < b->id)
593 return (-1);
594 if (a->creatorid > b->creatorid)
595 return (1);
596 if (a->creatorid < b->creatorid)
597 return (-1);
598
599 return (0);
600}
601
602#ifdef __FreeBSD__
603static int
604#else
605static __inline int
606#endif
607pf_anchor_compare(struct pf_anchor *a, struct pf_anchor *b)
608{
609 int c = strcmp(a->path, b->path);
610
611 return (c ? (c < 0 ? -1 : 1) : 0);
612}
613
614#ifdef INET6
615void
616pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
617{
618 switch (af) {
619#ifdef INET
620 case AF_INET:
621 dst->addr32[0] = src->addr32[0];
622 break;
623#endif /* INET */
624 case AF_INET6:
625 dst->addr32[0] = src->addr32[0];
626 dst->addr32[1] = src->addr32[1];
627 dst->addr32[2] = src->addr32[2];
628 dst->addr32[3] = src->addr32[3];
629 break;
630 }
631}
632#endif /* INET6 */
633
634struct pf_state *
635pf_find_state_byid(struct pf_state *key)
636{
637 pf_status.fcounters[FCNT_STATE_SEARCH]++;
638 return (RB_FIND(pf_state_tree_id, &tree_id, key));
639}
640
641struct pf_state *
642pf_find_state_recurse(struct pfi_kif *kif, struct pf_state *key, u_int8_t tree)
643{
644 struct pf_state *s;
645
646 pf_status.fcounters[FCNT_STATE_SEARCH]++;
647
648 switch (tree) {
649 case PF_LAN_EXT:
650 for (; kif != NULL; kif = kif->pfik_parent) {
651 s = RB_FIND(pf_state_tree_lan_ext,
652 &kif->pfik_lan_ext, key);
653 if (s != NULL)
654 return (s);
655 }
656 return (NULL);
657 case PF_EXT_GWY:
658 for (; kif != NULL; kif = kif->pfik_parent) {
659 s = RB_FIND(pf_state_tree_ext_gwy,
660 &kif->pfik_ext_gwy, key);
661 if (s != NULL)
662 return (s);
663 }
664 return (NULL);
665 default:
666 panic("pf_find_state_recurse");
667 }
668}
669
670struct pf_state *
671pf_find_state_all(struct pf_state *key, u_int8_t tree, int *more)
672{
673 struct pf_state *s, *ss = NULL;
674 struct pfi_kif *kif;
675
676 pf_status.fcounters[FCNT_STATE_SEARCH]++;
677
678 switch (tree) {
679 case PF_LAN_EXT:
680 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
681 s = RB_FIND(pf_state_tree_lan_ext,
682 &kif->pfik_lan_ext, key);
683 if (s == NULL)
684 continue;
685 if (more == NULL)
686 return (s);
687 ss = s;
688 (*more)++;
689 }
690 return (ss);
691 case PF_EXT_GWY:
692 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
693 s = RB_FIND(pf_state_tree_ext_gwy,
694 &kif->pfik_ext_gwy, key);
695 if (s == NULL)
696 continue;
697 if (more == NULL)
698 return (s);
699 ss = s;
700 (*more)++;
701 }
702 return (ss);
703 default:
704 panic("pf_find_state_all");
705 }
706}
707
708void
709pf_init_threshold(struct pf_threshold *threshold,
710 u_int32_t limit, u_int32_t seconds)
711{
712 threshold->limit = limit * PF_THRESHOLD_MULT;
713 threshold->seconds = seconds;
714 threshold->count = 0;
715 threshold->last = time_second;
716}
717
718void
719pf_add_threshold(struct pf_threshold *threshold)
720{
721 u_int32_t t = time_second, diff = t - threshold->last;
722
723 if (diff >= threshold->seconds)
724 threshold->count = 0;
725 else
726 threshold->count -= threshold->count * diff /
727 threshold->seconds;
728 threshold->count += PF_THRESHOLD_MULT;
729 threshold->last = t;
730}
731
732int
733pf_check_threshold(struct pf_threshold *threshold)
734{
735 return (threshold->count > threshold->limit);
736}
737
738int
739pf_src_connlimit(struct pf_state **state)
740{
741 struct pf_state *s;
742 int bad = 0;
743
744 (*state)->src_node->conn++;
745 pf_add_threshold(&(*state)->src_node->conn_rate);
746
747 if ((*state)->rule.ptr->max_src_conn &&
748 (*state)->rule.ptr->max_src_conn <
749 (*state)->src_node->conn) {
750 pf_status.lcounters[LCNT_SRCCONN]++;
751 bad++;
752 }
753
754 if ((*state)->rule.ptr->max_src_conn_rate.limit &&
755 pf_check_threshold(&(*state)->src_node->conn_rate)) {
756 pf_status.lcounters[LCNT_SRCCONNRATE]++;
757 bad++;
758 }
759
760 if (!bad)
761 return (0);
762
763 if ((*state)->rule.ptr->overload_tbl) {
764 struct pfr_addr p;
765 u_int32_t killed = 0;
766
767 pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
768 if (pf_status.debug >= PF_DEBUG_MISC) {
769 printf("pf_src_connlimit: blocking address ");
770 pf_print_host(&(*state)->src_node->addr, 0,
771 (*state)->af);
772 }
773
774 bzero(&p, sizeof(p));
775 p.pfra_af = (*state)->af;
776 switch ((*state)->af) {
777#ifdef INET
778 case AF_INET:
779 p.pfra_net = 32;
780 p.pfra_ip4addr = (*state)->src_node->addr.v4;
781 break;
782#endif /* INET */
783#ifdef INET6
784 case AF_INET6:
785 p.pfra_net = 128;
786 p.pfra_ip6addr = (*state)->src_node->addr.v6;
787 break;
788#endif /* INET6 */
789 }
790
791 pfr_insert_kentry((*state)->rule.ptr->overload_tbl,
792 &p, time_second);
793
794 /* kill existing states if that's required. */
795 if ((*state)->rule.ptr->flush) {
796 pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
797
798 RB_FOREACH(s, pf_state_tree_id, &tree_id) {
799 /*
800 * Kill states from this source. (Only those
801 * from the same rule if PF_FLUSH_GLOBAL is not
802 * set)
803 */
804 if (s->af == (*state)->af &&
805 (((*state)->direction == PF_OUT &&
806 PF_AEQ(&(*state)->src_node->addr,
807 &s->lan.addr, s->af)) ||
808 ((*state)->direction == PF_IN &&
809 PF_AEQ(&(*state)->src_node->addr,
810 &s->ext.addr, s->af))) &&
811 ((*state)->rule.ptr->flush &
812 PF_FLUSH_GLOBAL ||
813 (*state)->rule.ptr == s->rule.ptr)) {
814 s->timeout = PFTM_PURGE;
815 s->src.state = s->dst.state =
816 TCPS_CLOSED;
817 killed++;
818 }
819 }
820 if (pf_status.debug >= PF_DEBUG_MISC)
821 printf(", %u states killed", killed);
822 }
823 if (pf_status.debug >= PF_DEBUG_MISC)
824 printf("\n");
825 }
826
827 /* kill this state */
828 (*state)->timeout = PFTM_PURGE;
829 (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
830 return (1);
831}
832
833int
834pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
835 struct pf_addr *src, sa_family_t af)
836{
837 struct pf_src_node k;
838
839 if (*sn == NULL) {
840 k.af = af;
841 PF_ACPY(&k.addr, src, af);
842 if (rule->rule_flag & PFRULE_RULESRCTRACK ||
843 rule->rpool.opts & PF_POOL_STICKYADDR)
844 k.rule.ptr = rule;
845 else
846 k.rule.ptr = NULL;
847 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
848 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
849 }
850 if (*sn == NULL) {
851 if (!rule->max_src_nodes ||
852 rule->src_nodes < rule->max_src_nodes)
853 (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT);
854 else
855 pf_status.lcounters[LCNT_SRCNODES]++;
856 if ((*sn) == NULL)
857 return (-1);
858 bzero(*sn, sizeof(struct pf_src_node));
859
860 pf_init_threshold(&(*sn)->conn_rate,
861 rule->max_src_conn_rate.limit,
862 rule->max_src_conn_rate.seconds);
863
864 (*sn)->af = af;
865 if (rule->rule_flag & PFRULE_RULESRCTRACK ||
866 rule->rpool.opts & PF_POOL_STICKYADDR)
867 (*sn)->rule.ptr = rule;
868 else
869 (*sn)->rule.ptr = NULL;
870 PF_ACPY(&(*sn)->addr, src, af);
871 if (RB_INSERT(pf_src_tree,
872 &tree_src_tracking, *sn) != NULL) {
873 if (pf_status.debug >= PF_DEBUG_MISC) {
874 printf("pf: src_tree insert failed: ");
875 pf_print_host(&(*sn)->addr, 0, af);
876 printf("\n");
877 }
878 pool_put(&pf_src_tree_pl, *sn);
879 return (-1);
880 }
881 (*sn)->creation = time_second;
882 (*sn)->ruletype = rule->action;
883 if ((*sn)->rule.ptr != NULL)
884 (*sn)->rule.ptr->src_nodes++;
885 pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
886 pf_status.src_nodes++;
887 } else {
888 if (rule->max_src_states &&
889 (*sn)->states >= rule->max_src_states) {
890 pf_status.lcounters[LCNT_SRCSTATES]++;
891 return (-1);
892 }
893 }
894 return (0);
895}
896
897int
898pf_insert_state(struct pfi_kif *kif, struct pf_state *state)
899{
900 /* Thou MUST NOT insert multiple duplicate keys */
901 state->u.s.kif = kif;
902 if (RB_INSERT(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state)) {
903 if (pf_status.debug >= PF_DEBUG_MISC) {
904 printf("pf: state insert failed: tree_lan_ext");
905 printf(" lan: ");
906 pf_print_host(&state->lan.addr, state->lan.port,
907 state->af);
908 printf(" gwy: ");
909 pf_print_host(&state->gwy.addr, state->gwy.port,
910 state->af);
911 printf(" ext: ");
912 pf_print_host(&state->ext.addr, state->ext.port,
913 state->af);
914 if (state->sync_flags & PFSTATE_FROMSYNC)
915 printf(" (from sync)");
916 printf("\n");
917 }
918 return (-1);
919 }
920
921 if (RB_INSERT(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state)) {
922 if (pf_status.debug >= PF_DEBUG_MISC) {
923 printf("pf: state insert failed: tree_ext_gwy");
924 printf(" lan: ");
925 pf_print_host(&state->lan.addr, state->lan.port,
926 state->af);
927 printf(" gwy: ");
928 pf_print_host(&state->gwy.addr, state->gwy.port,
929 state->af);
930 printf(" ext: ");
931 pf_print_host(&state->ext.addr, state->ext.port,
932 state->af);
933 if (state->sync_flags & PFSTATE_FROMSYNC)
934 printf(" (from sync)");
935 printf("\n");
936 }
937 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
938 return (-1);
939 }
940
941 if (state->id == 0 && state->creatorid == 0) {
942 state->id = htobe64(pf_status.stateid++);
943 state->creatorid = pf_status.hostid;
944 }
945 if (RB_INSERT(pf_state_tree_id, &tree_id, state) != NULL) {
946 if (pf_status.debug >= PF_DEBUG_MISC) {
947#ifdef __FreeBSD__
948 printf("pf: state insert failed: "
949 "id: %016llx creatorid: %08x",
950 (long long)be64toh(state->id),
951 ntohl(state->creatorid));
952#else
953 printf("pf: state insert failed: "
954 "id: %016llx creatorid: %08x",
955 betoh64(state->id), ntohl(state->creatorid));
956#endif
957 if (state->sync_flags & PFSTATE_FROMSYNC)
958 printf(" (from sync)");
959 printf("\n");
960 }
961 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
962 RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state);
963 return (-1);
964 }
965 TAILQ_INSERT_HEAD(&state_updates, state, u.s.entry_updates);
966
967 pf_status.fcounters[FCNT_STATE_INSERT]++;
968 pf_status.states++;
969 pfi_attach_state(kif);
970#if NPFSYNC
971 pfsync_insert_state(state);
972#endif
973 return (0);
974}
975
976void
977pf_purge_timeout(void *arg)
978{
979#ifdef __FreeBSD__
980 struct callout *to = arg;
981#else
982 struct timeout *to = arg;
983#endif
984 int s;
985
986#ifdef __FreeBSD__
987 PF_LOCK();
988#endif
989 s = splsoftnet();
990 pf_purge_expired_states();
991 pf_purge_expired_fragments();
992 pf_purge_expired_src_nodes();
993 splx(s);
994#ifdef __FreeBSD__
995 PF_UNLOCK();
996#endif
997
998#ifdef __FreeBSD__
999 callout_reset(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz,
1000 pf_purge_timeout, to);
1001#else
1002 timeout_add(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz);
1003#endif
1004}
1005
1006u_int32_t
1007pf_state_expires(const struct pf_state *state)
1008{
1009 u_int32_t timeout;
1010 u_int32_t start;
1011 u_int32_t end;
1012 u_int32_t states;
1013
1014 /* handle all PFTM_* > PFTM_MAX here */
1015 if (state->timeout == PFTM_PURGE)
1016 return (time_second);
1017 if (state->timeout == PFTM_UNTIL_PACKET)
1018 return (0);
1019#ifdef __FreeBSD__
1020 KASSERT((state->timeout < PFTM_MAX),
1021 ("pf_state_expires: timeout > PFTM_MAX"));
1022#else
1023 KASSERT(state->timeout < PFTM_MAX);
1024#endif
1025 timeout = state->rule.ptr->timeout[state->timeout];
1026 if (!timeout)
1027 timeout = pf_default_rule.timeout[state->timeout];
1028 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
1029 if (start) {
1030 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];
1031 states = state->rule.ptr->states;
1032 } else {
1033 start = pf_default_rule.timeout[PFTM_ADAPTIVE_START];
1034 end = pf_default_rule.timeout[PFTM_ADAPTIVE_END];
1035 states = pf_status.states;
1036 }
1037 if (end && states > start && start < end) {
1038 if (states < end)
1039 return (state->expire + timeout * (end - states) /
1040 (end - start));
1041 else
1042 return (time_second);
1043 }
1044 return (state->expire + timeout);
1045}
1046
1047void
1048pf_purge_expired_src_nodes(void)
1049{
1050 struct pf_src_node *cur, *next;
1051
1052 for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
1053 next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
1054
1055 if (cur->states <= 0 && cur->expire <= time_second) {
1056 if (cur->rule.ptr != NULL) {
1057 cur->rule.ptr->src_nodes--;
1058 if (cur->rule.ptr->states <= 0 &&
1059 cur->rule.ptr->max_src_nodes <= 0)
1060 pf_rm_rule(NULL, cur->rule.ptr);
1061 }
1062 RB_REMOVE(pf_src_tree, &tree_src_tracking, cur);
1063 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
1064 pf_status.src_nodes--;
1065 pool_put(&pf_src_tree_pl, cur);
1066 }
1067 }
1068}
1069
1070void
1071pf_src_tree_remove_state(struct pf_state *s)
1072{
1073 u_int32_t timeout;
1074
1075 if (s->src_node != NULL) {
1076 if (s->proto == IPPROTO_TCP) {
1077 if (s->src.state == PF_TCPS_PROXY_DST ||
1078 s->timeout >= PFTM_TCP_ESTABLISHED)
1079 --s->src_node->conn;
1080 }
1081 if (--s->src_node->states <= 0) {
1082 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1083 if (!timeout)
1084 timeout =
1085 pf_default_rule.timeout[PFTM_SRC_NODE];
1086 s->src_node->expire = time_second + timeout;
1087 }
1088 }
1089 if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
1090 if (--s->nat_src_node->states <= 0) {
1091 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1092 if (!timeout)
1093 timeout =
1094 pf_default_rule.timeout[PFTM_SRC_NODE];
1095 s->nat_src_node->expire = time_second + timeout;
1096 }
1097 }
1098 s->src_node = s->nat_src_node = NULL;
1099}
1100
1101void
1102pf_purge_expired_state(struct pf_state *cur)
1103{
1104#ifdef __FreeBSD__
2/* $OpenBSD: pf.c,v 1.483 2005/03/15 17:38:43 dhartmei Exp $ */
3
4/*
5 * Copyright (c) 2001 Daniel Hartmeier
6 * Copyright (c) 2002,2003 Henning Brauer
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * - Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Effort sponsored in part by the Defense Advanced Research Projects
34 * Agency (DARPA) and Air Force Research Laboratory, Air Force
35 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
36 *
37 */
38
39#ifdef __FreeBSD__
40#include "opt_inet.h"
41#include "opt_inet6.h"
42#endif
43
44#ifdef __FreeBSD__
45#include "opt_bpf.h"
46#include "opt_pf.h"
47
48#ifdef DEV_BPF
49#define NBPFILTER DEV_BPF
50#else
51#define NBPFILTER 0
52#endif
53
54#ifdef DEV_PFLOG
55#define NPFLOG DEV_PFLOG
56#else
57#define NPFLOG 0
58#endif
59
60#ifdef DEV_PFSYNC
61#define NPFSYNC DEV_PFSYNC
62#else
63#define NPFSYNC 0
64#endif
65
66#else
67#include "bpfilter.h"
68#include "pflog.h"
69#include "pfsync.h"
70#endif
71
72#include <sys/param.h>
73#include <sys/systm.h>
74#include <sys/mbuf.h>
75#include <sys/filio.h>
76#include <sys/socket.h>
77#include <sys/socketvar.h>
78#include <sys/kernel.h>
79#include <sys/time.h>
80#ifdef __FreeBSD__
81#include <sys/sysctl.h>
82#include <sys/endian.h>
83#else
84#include <sys/pool.h>
85#endif
86
87#include <net/if.h>
88#include <net/if_types.h>
89#include <net/bpf.h>
90#include <net/route.h>
91
92#include <netinet/in.h>
93#include <netinet/in_var.h>
94#include <netinet/in_systm.h>
95#include <netinet/ip.h>
96#include <netinet/ip_var.h>
97#include <netinet/tcp.h>
98#include <netinet/tcp_seq.h>
99#include <netinet/udp.h>
100#include <netinet/ip_icmp.h>
101#include <netinet/in_pcb.h>
102#include <netinet/tcp_timer.h>
103#include <netinet/tcp_var.h>
104#include <netinet/udp_var.h>
105#include <netinet/icmp_var.h>
106#include <netinet/if_ether.h>
107
108#ifndef __FreeBSD__
109#include <dev/rndvar.h>
110#endif
111#include <net/pfvar.h>
112#include <net/if_pflog.h>
113
114#if NPFSYNC > 0
115#include <net/if_pfsync.h>
116#endif /* NPFSYNC > 0 */
117
118#ifdef INET6
119#include <netinet/ip6.h>
120#include <netinet/in_pcb.h>
121#include <netinet/icmp6.h>
122#include <netinet6/nd6.h>
123#ifdef __FreeBSD__
124#include <netinet6/ip6_var.h>
125#include <netinet6/in6_pcb.h>
126#endif
127#endif /* INET6 */
128
129#ifdef __FreeBSD__
130#include <machine/in_cksum.h>
131#include <sys/limits.h>
132#include <sys/ucred.h>
133
134extern int ip_optcopy(struct ip *, struct ip *);
135#endif
136
137#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
138
139/*
140 * Global variables
141 */
142
143struct pf_anchor_global pf_anchors;
144struct pf_ruleset pf_main_ruleset;
145struct pf_altqqueue pf_altqs[2];
146struct pf_palist pf_pabuf;
147struct pf_altqqueue *pf_altqs_active;
148struct pf_altqqueue *pf_altqs_inactive;
149struct pf_status pf_status;
150
151u_int32_t ticket_altqs_active;
152u_int32_t ticket_altqs_inactive;
153int altqs_inactive_open;
154u_int32_t ticket_pabuf;
155
156#ifdef __FreeBSD__
157struct callout pf_expire_to; /* expire timeout */
158#else
159struct timeout pf_expire_to; /* expire timeout */
160#endif
161
162struct pf_anchor_stackframe {
163 struct pf_ruleset *rs;
164 struct pf_rule *r;
165 struct pf_anchor_node *parent;
166 struct pf_anchor *child;
167} pf_anchor_stack[64];
168
169#ifdef __FreeBSD__
170uma_zone_t pf_src_tree_pl, pf_rule_pl;
171uma_zone_t pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
172#else
173struct pool pf_src_tree_pl, pf_rule_pl;
174struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
175#endif
176
177void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
178
179void pf_init_threshold(struct pf_threshold *, u_int32_t,
180 u_int32_t);
181void pf_add_threshold(struct pf_threshold *);
182int pf_check_threshold(struct pf_threshold *);
183
184void pf_change_ap(struct pf_addr *, u_int16_t *,
185 u_int16_t *, u_int16_t *, struct pf_addr *,
186 u_int16_t, u_int8_t, sa_family_t);
187#ifdef INET6
188void pf_change_a6(struct pf_addr *, u_int16_t *,
189 struct pf_addr *, u_int8_t);
190#endif /* INET6 */
191void pf_change_icmp(struct pf_addr *, u_int16_t *,
192 struct pf_addr *, struct pf_addr *, u_int16_t,
193 u_int16_t *, u_int16_t *, u_int16_t *,
194 u_int16_t *, u_int8_t, sa_family_t);
195void pf_send_tcp(const struct pf_rule *, sa_family_t,
196 const struct pf_addr *, const struct pf_addr *,
197 u_int16_t, u_int16_t, u_int32_t, u_int32_t,
198 u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
199 struct ether_header *, struct ifnet *);
200void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
201 sa_family_t, struct pf_rule *);
202struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
203 int, int, struct pfi_kif *,
204 struct pf_addr *, u_int16_t, struct pf_addr *,
205 u_int16_t, int);
206struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
207 int, int, struct pfi_kif *, struct pf_src_node **,
208 struct pf_addr *, u_int16_t,
209 struct pf_addr *, u_int16_t,
210 struct pf_addr *, u_int16_t *);
211int pf_test_tcp(struct pf_rule **, struct pf_state **,
212 int, struct pfi_kif *, struct mbuf *, int,
213 void *, struct pf_pdesc *, struct pf_rule **,
214#ifdef __FreeBSD__
215 struct pf_ruleset **, struct ifqueue *,
216 struct inpcb *);
217#else
218 struct pf_ruleset **, struct ifqueue *);
219#endif
220int pf_test_udp(struct pf_rule **, struct pf_state **,
221 int, struct pfi_kif *, struct mbuf *, int,
222 void *, struct pf_pdesc *, struct pf_rule **,
223#ifdef __FreeBSD__
224 struct pf_ruleset **, struct ifqueue *,
225 struct inpcb *);
226#else
227 struct pf_ruleset **, struct ifqueue *);
228#endif
229int pf_test_icmp(struct pf_rule **, struct pf_state **,
230 int, struct pfi_kif *, struct mbuf *, int,
231 void *, struct pf_pdesc *, struct pf_rule **,
232 struct pf_ruleset **, struct ifqueue *);
233int pf_test_other(struct pf_rule **, struct pf_state **,
234 int, struct pfi_kif *, struct mbuf *, int, void *,
235 struct pf_pdesc *, struct pf_rule **,
236 struct pf_ruleset **, struct ifqueue *);
237int pf_test_fragment(struct pf_rule **, int,
238 struct pfi_kif *, struct mbuf *, void *,
239 struct pf_pdesc *, struct pf_rule **,
240 struct pf_ruleset **);
241int pf_test_state_tcp(struct pf_state **, int,
242 struct pfi_kif *, struct mbuf *, int,
243 void *, struct pf_pdesc *, u_short *);
244int pf_test_state_udp(struct pf_state **, int,
245 struct pfi_kif *, struct mbuf *, int,
246 void *, struct pf_pdesc *);
247int pf_test_state_icmp(struct pf_state **, int,
248 struct pfi_kif *, struct mbuf *, int,
249 void *, struct pf_pdesc *, u_short *);
250int pf_test_state_other(struct pf_state **, int,
251 struct pfi_kif *, struct pf_pdesc *);
252struct pf_tag *pf_get_tag(struct mbuf *);
253int pf_match_tag(struct mbuf *, struct pf_rule *,
254 struct pf_tag **, int *);
255void pf_hash(struct pf_addr *, struct pf_addr *,
256 struct pf_poolhashkey *, sa_family_t);
257int pf_map_addr(u_int8_t, struct pf_rule *,
258 struct pf_addr *, struct pf_addr *,
259 struct pf_addr *, struct pf_src_node **);
260int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
261 struct pf_addr *, struct pf_addr *, u_int16_t,
262 struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
263 struct pf_src_node **);
264void pf_route(struct mbuf **, struct pf_rule *, int,
265 struct ifnet *, struct pf_state *);
266void pf_route6(struct mbuf **, struct pf_rule *, int,
267 struct ifnet *, struct pf_state *);
268#ifdef __FreeBSD__
269int pf_socket_lookup(uid_t *, gid_t *,
270 int, struct pf_pdesc *, struct inpcb *);
271#else
272int pf_socket_lookup(uid_t *, gid_t *,
273 int, struct pf_pdesc *);
274#endif
275u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t,
276 sa_family_t);
277u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
278 sa_family_t);
279u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t,
280 u_int16_t);
281void pf_set_rt_ifp(struct pf_state *,
282 struct pf_addr *);
283int pf_check_proto_cksum(struct mbuf *, int, int,
284 u_int8_t, sa_family_t);
285int pf_addr_wrap_neq(struct pf_addr_wrap *,
286 struct pf_addr_wrap *);
287static int pf_add_mbuf_tag(struct mbuf *, u_int);
288struct pf_state *pf_find_state_recurse(struct pfi_kif *,
289 struct pf_state *, u_int8_t);
290int pf_src_connlimit(struct pf_state **);
291int pf_check_congestion(struct ifqueue *);
292
293#ifdef __FreeBSD__
294int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len);
295
296struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX];
297
298#else
299struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
300 { &pf_state_pl, PFSTATE_HIWAT },
301 { &pf_src_tree_pl, PFSNODE_HIWAT },
302 { &pf_frent_pl, PFFRAG_FRENT_HIWAT }
303};
304#endif
305
306#define STATE_LOOKUP() \
307 do { \
308 if (direction == PF_IN) \
309 *state = pf_find_state_recurse( \
310 kif, &key, PF_EXT_GWY); \
311 else \
312 *state = pf_find_state_recurse( \
313 kif, &key, PF_LAN_EXT); \
314 if (*state == NULL || (*state)->timeout == PFTM_PURGE) \
315 return (PF_DROP); \
316 if (direction == PF_OUT && \
317 (((*state)->rule.ptr->rt == PF_ROUTETO && \
318 (*state)->rule.ptr->direction == PF_OUT) || \
319 ((*state)->rule.ptr->rt == PF_REPLYTO && \
320 (*state)->rule.ptr->direction == PF_IN)) && \
321 (*state)->rt_kif != NULL && \
322 (*state)->rt_kif != kif) \
323 return (PF_PASS); \
324 } while (0)
325
326#define STATE_TRANSLATE(s) \
327 (s)->lan.addr.addr32[0] != (s)->gwy.addr.addr32[0] || \
328 ((s)->af == AF_INET6 && \
329 ((s)->lan.addr.addr32[1] != (s)->gwy.addr.addr32[1] || \
330 (s)->lan.addr.addr32[2] != (s)->gwy.addr.addr32[2] || \
331 (s)->lan.addr.addr32[3] != (s)->gwy.addr.addr32[3])) || \
332 (s)->lan.port != (s)->gwy.port
333
334#define BOUND_IFACE(r, k) (((r)->rule_flag & PFRULE_IFBOUND) ? (k) : \
335 ((r)->rule_flag & PFRULE_GRBOUND) ? (k)->pfik_parent : \
336 (k)->pfik_parent->pfik_parent)
337
338#define STATE_INC_COUNTERS(s) \
339 do { \
340 s->rule.ptr->states++; \
341 if (s->anchor.ptr != NULL) \
342 s->anchor.ptr->states++; \
343 if (s->nat_rule.ptr != NULL) \
344 s->nat_rule.ptr->states++; \
345 } while (0)
346
347#define STATE_DEC_COUNTERS(s) \
348 do { \
349 if (s->nat_rule.ptr != NULL) \
350 s->nat_rule.ptr->states--; \
351 if (s->anchor.ptr != NULL) \
352 s->anchor.ptr->states--; \
353 s->rule.ptr->states--; \
354 } while (0)
355
356#ifndef __FreeBSD__
357static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
358static __inline int pf_state_compare_lan_ext(struct pf_state *,
359 struct pf_state *);
360static __inline int pf_state_compare_ext_gwy(struct pf_state *,
361 struct pf_state *);
362static __inline int pf_state_compare_id(struct pf_state *,
363 struct pf_state *);
364static __inline int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
365#else
366static int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
367static int pf_state_compare_lan_ext(struct pf_state *,
368 struct pf_state *);
369static int pf_state_compare_ext_gwy(struct pf_state *,
370 struct pf_state *);
371static int pf_state_compare_id(struct pf_state *,
372 struct pf_state *);
373static int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
374#endif
375
376struct pf_src_tree tree_src_tracking;
377
378struct pf_state_tree_id tree_id;
379struct pf_state_queue state_updates;
380
381RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
382RB_GENERATE(pf_state_tree_lan_ext, pf_state,
383 u.s.entry_lan_ext, pf_state_compare_lan_ext);
384RB_GENERATE(pf_state_tree_ext_gwy, pf_state,
385 u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
386RB_GENERATE(pf_state_tree_id, pf_state,
387 u.s.entry_id, pf_state_compare_id);
388RB_GENERATE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
389RB_GENERATE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
390
391#ifdef __FreeBSD__
392static int
393#else
394static __inline int
395#endif
396pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
397{
398 int diff;
399
400 if (a->rule.ptr > b->rule.ptr)
401 return (1);
402 if (a->rule.ptr < b->rule.ptr)
403 return (-1);
404 if ((diff = a->af - b->af) != 0)
405 return (diff);
406 switch (a->af) {
407#ifdef INET
408 case AF_INET:
409 if (a->addr.addr32[0] > b->addr.addr32[0])
410 return (1);
411 if (a->addr.addr32[0] < b->addr.addr32[0])
412 return (-1);
413 break;
414#endif /* INET */
415#ifdef INET6
416 case AF_INET6:
417 if (a->addr.addr32[3] > b->addr.addr32[3])
418 return (1);
419 if (a->addr.addr32[3] < b->addr.addr32[3])
420 return (-1);
421 if (a->addr.addr32[2] > b->addr.addr32[2])
422 return (1);
423 if (a->addr.addr32[2] < b->addr.addr32[2])
424 return (-1);
425 if (a->addr.addr32[1] > b->addr.addr32[1])
426 return (1);
427 if (a->addr.addr32[1] < b->addr.addr32[1])
428 return (-1);
429 if (a->addr.addr32[0] > b->addr.addr32[0])
430 return (1);
431 if (a->addr.addr32[0] < b->addr.addr32[0])
432 return (-1);
433 break;
434#endif /* INET6 */
435 }
436 return (0);
437}
438
439#ifdef __FreeBSD__
440static int
441#else
442static __inline int
443#endif
444pf_state_compare_lan_ext(struct pf_state *a, struct pf_state *b)
445{
446 int diff;
447
448 if ((diff = a->proto - b->proto) != 0)
449 return (diff);
450 if ((diff = a->af - b->af) != 0)
451 return (diff);
452 switch (a->af) {
453#ifdef INET
454 case AF_INET:
455 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
456 return (1);
457 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
458 return (-1);
459 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
460 return (1);
461 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
462 return (-1);
463 break;
464#endif /* INET */
465#ifdef INET6
466 case AF_INET6:
467 if (a->lan.addr.addr32[3] > b->lan.addr.addr32[3])
468 return (1);
469 if (a->lan.addr.addr32[3] < b->lan.addr.addr32[3])
470 return (-1);
471 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
472 return (1);
473 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
474 return (-1);
475 if (a->lan.addr.addr32[2] > b->lan.addr.addr32[2])
476 return (1);
477 if (a->lan.addr.addr32[2] < b->lan.addr.addr32[2])
478 return (-1);
479 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
480 return (1);
481 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
482 return (-1);
483 if (a->lan.addr.addr32[1] > b->lan.addr.addr32[1])
484 return (1);
485 if (a->lan.addr.addr32[1] < b->lan.addr.addr32[1])
486 return (-1);
487 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
488 return (1);
489 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
490 return (-1);
491 if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
492 return (1);
493 if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
494 return (-1);
495 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
496 return (1);
497 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
498 return (-1);
499 break;
500#endif /* INET6 */
501 }
502
503 if ((diff = a->lan.port - b->lan.port) != 0)
504 return (diff);
505 if ((diff = a->ext.port - b->ext.port) != 0)
506 return (diff);
507
508 return (0);
509}
510
511#ifdef __FreeBSD__
512static int
513#else
514static __inline int
515#endif
516pf_state_compare_ext_gwy(struct pf_state *a, struct pf_state *b)
517{
518 int diff;
519
520 if ((diff = a->proto - b->proto) != 0)
521 return (diff);
522 if ((diff = a->af - b->af) != 0)
523 return (diff);
524 switch (a->af) {
525#ifdef INET
526 case AF_INET:
527 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
528 return (1);
529 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
530 return (-1);
531 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
532 return (1);
533 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
534 return (-1);
535 break;
536#endif /* INET */
537#ifdef INET6
538 case AF_INET6:
539 if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
540 return (1);
541 if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
542 return (-1);
543 if (a->gwy.addr.addr32[3] > b->gwy.addr.addr32[3])
544 return (1);
545 if (a->gwy.addr.addr32[3] < b->gwy.addr.addr32[3])
546 return (-1);
547 if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
548 return (1);
549 if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
550 return (-1);
551 if (a->gwy.addr.addr32[2] > b->gwy.addr.addr32[2])
552 return (1);
553 if (a->gwy.addr.addr32[2] < b->gwy.addr.addr32[2])
554 return (-1);
555 if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
556 return (1);
557 if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
558 return (-1);
559 if (a->gwy.addr.addr32[1] > b->gwy.addr.addr32[1])
560 return (1);
561 if (a->gwy.addr.addr32[1] < b->gwy.addr.addr32[1])
562 return (-1);
563 if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
564 return (1);
565 if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
566 return (-1);
567 if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
568 return (1);
569 if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
570 return (-1);
571 break;
572#endif /* INET6 */
573 }
574
575 if ((diff = a->ext.port - b->ext.port) != 0)
576 return (diff);
577 if ((diff = a->gwy.port - b->gwy.port) != 0)
578 return (diff);
579
580 return (0);
581}
582
583#ifdef __FreeBSD__
584static int
585#else
586static __inline int
587#endif
588pf_state_compare_id(struct pf_state *a, struct pf_state *b)
589{
590 if (a->id > b->id)
591 return (1);
592 if (a->id < b->id)
593 return (-1);
594 if (a->creatorid > b->creatorid)
595 return (1);
596 if (a->creatorid < b->creatorid)
597 return (-1);
598
599 return (0);
600}
601
602#ifdef __FreeBSD__
603static int
604#else
605static __inline int
606#endif
607pf_anchor_compare(struct pf_anchor *a, struct pf_anchor *b)
608{
609 int c = strcmp(a->path, b->path);
610
611 return (c ? (c < 0 ? -1 : 1) : 0);
612}
613
614#ifdef INET6
615void
616pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
617{
618 switch (af) {
619#ifdef INET
620 case AF_INET:
621 dst->addr32[0] = src->addr32[0];
622 break;
623#endif /* INET */
624 case AF_INET6:
625 dst->addr32[0] = src->addr32[0];
626 dst->addr32[1] = src->addr32[1];
627 dst->addr32[2] = src->addr32[2];
628 dst->addr32[3] = src->addr32[3];
629 break;
630 }
631}
632#endif /* INET6 */
633
634struct pf_state *
635pf_find_state_byid(struct pf_state *key)
636{
637 pf_status.fcounters[FCNT_STATE_SEARCH]++;
638 return (RB_FIND(pf_state_tree_id, &tree_id, key));
639}
640
641struct pf_state *
642pf_find_state_recurse(struct pfi_kif *kif, struct pf_state *key, u_int8_t tree)
643{
644 struct pf_state *s;
645
646 pf_status.fcounters[FCNT_STATE_SEARCH]++;
647
648 switch (tree) {
649 case PF_LAN_EXT:
650 for (; kif != NULL; kif = kif->pfik_parent) {
651 s = RB_FIND(pf_state_tree_lan_ext,
652 &kif->pfik_lan_ext, key);
653 if (s != NULL)
654 return (s);
655 }
656 return (NULL);
657 case PF_EXT_GWY:
658 for (; kif != NULL; kif = kif->pfik_parent) {
659 s = RB_FIND(pf_state_tree_ext_gwy,
660 &kif->pfik_ext_gwy, key);
661 if (s != NULL)
662 return (s);
663 }
664 return (NULL);
665 default:
666 panic("pf_find_state_recurse");
667 }
668}
669
670struct pf_state *
671pf_find_state_all(struct pf_state *key, u_int8_t tree, int *more)
672{
673 struct pf_state *s, *ss = NULL;
674 struct pfi_kif *kif;
675
676 pf_status.fcounters[FCNT_STATE_SEARCH]++;
677
678 switch (tree) {
679 case PF_LAN_EXT:
680 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
681 s = RB_FIND(pf_state_tree_lan_ext,
682 &kif->pfik_lan_ext, key);
683 if (s == NULL)
684 continue;
685 if (more == NULL)
686 return (s);
687 ss = s;
688 (*more)++;
689 }
690 return (ss);
691 case PF_EXT_GWY:
692 TAILQ_FOREACH(kif, &pfi_statehead, pfik_w_states) {
693 s = RB_FIND(pf_state_tree_ext_gwy,
694 &kif->pfik_ext_gwy, key);
695 if (s == NULL)
696 continue;
697 if (more == NULL)
698 return (s);
699 ss = s;
700 (*more)++;
701 }
702 return (ss);
703 default:
704 panic("pf_find_state_all");
705 }
706}
707
708void
709pf_init_threshold(struct pf_threshold *threshold,
710 u_int32_t limit, u_int32_t seconds)
711{
712 threshold->limit = limit * PF_THRESHOLD_MULT;
713 threshold->seconds = seconds;
714 threshold->count = 0;
715 threshold->last = time_second;
716}
717
718void
719pf_add_threshold(struct pf_threshold *threshold)
720{
721 u_int32_t t = time_second, diff = t - threshold->last;
722
723 if (diff >= threshold->seconds)
724 threshold->count = 0;
725 else
726 threshold->count -= threshold->count * diff /
727 threshold->seconds;
728 threshold->count += PF_THRESHOLD_MULT;
729 threshold->last = t;
730}
731
732int
733pf_check_threshold(struct pf_threshold *threshold)
734{
735 return (threshold->count > threshold->limit);
736}
737
738int
739pf_src_connlimit(struct pf_state **state)
740{
741 struct pf_state *s;
742 int bad = 0;
743
744 (*state)->src_node->conn++;
745 pf_add_threshold(&(*state)->src_node->conn_rate);
746
747 if ((*state)->rule.ptr->max_src_conn &&
748 (*state)->rule.ptr->max_src_conn <
749 (*state)->src_node->conn) {
750 pf_status.lcounters[LCNT_SRCCONN]++;
751 bad++;
752 }
753
754 if ((*state)->rule.ptr->max_src_conn_rate.limit &&
755 pf_check_threshold(&(*state)->src_node->conn_rate)) {
756 pf_status.lcounters[LCNT_SRCCONNRATE]++;
757 bad++;
758 }
759
760 if (!bad)
761 return (0);
762
763 if ((*state)->rule.ptr->overload_tbl) {
764 struct pfr_addr p;
765 u_int32_t killed = 0;
766
767 pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
768 if (pf_status.debug >= PF_DEBUG_MISC) {
769 printf("pf_src_connlimit: blocking address ");
770 pf_print_host(&(*state)->src_node->addr, 0,
771 (*state)->af);
772 }
773
774 bzero(&p, sizeof(p));
775 p.pfra_af = (*state)->af;
776 switch ((*state)->af) {
777#ifdef INET
778 case AF_INET:
779 p.pfra_net = 32;
780 p.pfra_ip4addr = (*state)->src_node->addr.v4;
781 break;
782#endif /* INET */
783#ifdef INET6
784 case AF_INET6:
785 p.pfra_net = 128;
786 p.pfra_ip6addr = (*state)->src_node->addr.v6;
787 break;
788#endif /* INET6 */
789 }
790
791 pfr_insert_kentry((*state)->rule.ptr->overload_tbl,
792 &p, time_second);
793
794 /* kill existing states if that's required. */
795 if ((*state)->rule.ptr->flush) {
796 pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
797
798 RB_FOREACH(s, pf_state_tree_id, &tree_id) {
799 /*
800 * Kill states from this source. (Only those
801 * from the same rule if PF_FLUSH_GLOBAL is not
802 * set)
803 */
804 if (s->af == (*state)->af &&
805 (((*state)->direction == PF_OUT &&
806 PF_AEQ(&(*state)->src_node->addr,
807 &s->lan.addr, s->af)) ||
808 ((*state)->direction == PF_IN &&
809 PF_AEQ(&(*state)->src_node->addr,
810 &s->ext.addr, s->af))) &&
811 ((*state)->rule.ptr->flush &
812 PF_FLUSH_GLOBAL ||
813 (*state)->rule.ptr == s->rule.ptr)) {
814 s->timeout = PFTM_PURGE;
815 s->src.state = s->dst.state =
816 TCPS_CLOSED;
817 killed++;
818 }
819 }
820 if (pf_status.debug >= PF_DEBUG_MISC)
821 printf(", %u states killed", killed);
822 }
823 if (pf_status.debug >= PF_DEBUG_MISC)
824 printf("\n");
825 }
826
827 /* kill this state */
828 (*state)->timeout = PFTM_PURGE;
829 (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
830 return (1);
831}
832
833int
834pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
835 struct pf_addr *src, sa_family_t af)
836{
837 struct pf_src_node k;
838
839 if (*sn == NULL) {
840 k.af = af;
841 PF_ACPY(&k.addr, src, af);
842 if (rule->rule_flag & PFRULE_RULESRCTRACK ||
843 rule->rpool.opts & PF_POOL_STICKYADDR)
844 k.rule.ptr = rule;
845 else
846 k.rule.ptr = NULL;
847 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
848 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
849 }
850 if (*sn == NULL) {
851 if (!rule->max_src_nodes ||
852 rule->src_nodes < rule->max_src_nodes)
853 (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT);
854 else
855 pf_status.lcounters[LCNT_SRCNODES]++;
856 if ((*sn) == NULL)
857 return (-1);
858 bzero(*sn, sizeof(struct pf_src_node));
859
860 pf_init_threshold(&(*sn)->conn_rate,
861 rule->max_src_conn_rate.limit,
862 rule->max_src_conn_rate.seconds);
863
864 (*sn)->af = af;
865 if (rule->rule_flag & PFRULE_RULESRCTRACK ||
866 rule->rpool.opts & PF_POOL_STICKYADDR)
867 (*sn)->rule.ptr = rule;
868 else
869 (*sn)->rule.ptr = NULL;
870 PF_ACPY(&(*sn)->addr, src, af);
871 if (RB_INSERT(pf_src_tree,
872 &tree_src_tracking, *sn) != NULL) {
873 if (pf_status.debug >= PF_DEBUG_MISC) {
874 printf("pf: src_tree insert failed: ");
875 pf_print_host(&(*sn)->addr, 0, af);
876 printf("\n");
877 }
878 pool_put(&pf_src_tree_pl, *sn);
879 return (-1);
880 }
881 (*sn)->creation = time_second;
882 (*sn)->ruletype = rule->action;
883 if ((*sn)->rule.ptr != NULL)
884 (*sn)->rule.ptr->src_nodes++;
885 pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
886 pf_status.src_nodes++;
887 } else {
888 if (rule->max_src_states &&
889 (*sn)->states >= rule->max_src_states) {
890 pf_status.lcounters[LCNT_SRCSTATES]++;
891 return (-1);
892 }
893 }
894 return (0);
895}
896
897int
898pf_insert_state(struct pfi_kif *kif, struct pf_state *state)
899{
900 /* Thou MUST NOT insert multiple duplicate keys */
901 state->u.s.kif = kif;
902 if (RB_INSERT(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state)) {
903 if (pf_status.debug >= PF_DEBUG_MISC) {
904 printf("pf: state insert failed: tree_lan_ext");
905 printf(" lan: ");
906 pf_print_host(&state->lan.addr, state->lan.port,
907 state->af);
908 printf(" gwy: ");
909 pf_print_host(&state->gwy.addr, state->gwy.port,
910 state->af);
911 printf(" ext: ");
912 pf_print_host(&state->ext.addr, state->ext.port,
913 state->af);
914 if (state->sync_flags & PFSTATE_FROMSYNC)
915 printf(" (from sync)");
916 printf("\n");
917 }
918 return (-1);
919 }
920
921 if (RB_INSERT(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state)) {
922 if (pf_status.debug >= PF_DEBUG_MISC) {
923 printf("pf: state insert failed: tree_ext_gwy");
924 printf(" lan: ");
925 pf_print_host(&state->lan.addr, state->lan.port,
926 state->af);
927 printf(" gwy: ");
928 pf_print_host(&state->gwy.addr, state->gwy.port,
929 state->af);
930 printf(" ext: ");
931 pf_print_host(&state->ext.addr, state->ext.port,
932 state->af);
933 if (state->sync_flags & PFSTATE_FROMSYNC)
934 printf(" (from sync)");
935 printf("\n");
936 }
937 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
938 return (-1);
939 }
940
941 if (state->id == 0 && state->creatorid == 0) {
942 state->id = htobe64(pf_status.stateid++);
943 state->creatorid = pf_status.hostid;
944 }
945 if (RB_INSERT(pf_state_tree_id, &tree_id, state) != NULL) {
946 if (pf_status.debug >= PF_DEBUG_MISC) {
947#ifdef __FreeBSD__
948 printf("pf: state insert failed: "
949 "id: %016llx creatorid: %08x",
950 (long long)be64toh(state->id),
951 ntohl(state->creatorid));
952#else
953 printf("pf: state insert failed: "
954 "id: %016llx creatorid: %08x",
955 betoh64(state->id), ntohl(state->creatorid));
956#endif
957 if (state->sync_flags & PFSTATE_FROMSYNC)
958 printf(" (from sync)");
959 printf("\n");
960 }
961 RB_REMOVE(pf_state_tree_lan_ext, &kif->pfik_lan_ext, state);
962 RB_REMOVE(pf_state_tree_ext_gwy, &kif->pfik_ext_gwy, state);
963 return (-1);
964 }
965 TAILQ_INSERT_HEAD(&state_updates, state, u.s.entry_updates);
966
967 pf_status.fcounters[FCNT_STATE_INSERT]++;
968 pf_status.states++;
969 pfi_attach_state(kif);
970#if NPFSYNC
971 pfsync_insert_state(state);
972#endif
973 return (0);
974}
975
976void
977pf_purge_timeout(void *arg)
978{
979#ifdef __FreeBSD__
980 struct callout *to = arg;
981#else
982 struct timeout *to = arg;
983#endif
984 int s;
985
986#ifdef __FreeBSD__
987 PF_LOCK();
988#endif
989 s = splsoftnet();
990 pf_purge_expired_states();
991 pf_purge_expired_fragments();
992 pf_purge_expired_src_nodes();
993 splx(s);
994#ifdef __FreeBSD__
995 PF_UNLOCK();
996#endif
997
998#ifdef __FreeBSD__
999 callout_reset(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz,
1000 pf_purge_timeout, to);
1001#else
1002 timeout_add(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz);
1003#endif
1004}
1005
1006u_int32_t
1007pf_state_expires(const struct pf_state *state)
1008{
1009 u_int32_t timeout;
1010 u_int32_t start;
1011 u_int32_t end;
1012 u_int32_t states;
1013
1014 /* handle all PFTM_* > PFTM_MAX here */
1015 if (state->timeout == PFTM_PURGE)
1016 return (time_second);
1017 if (state->timeout == PFTM_UNTIL_PACKET)
1018 return (0);
1019#ifdef __FreeBSD__
1020 KASSERT((state->timeout < PFTM_MAX),
1021 ("pf_state_expires: timeout > PFTM_MAX"));
1022#else
1023 KASSERT(state->timeout < PFTM_MAX);
1024#endif
1025 timeout = state->rule.ptr->timeout[state->timeout];
1026 if (!timeout)
1027 timeout = pf_default_rule.timeout[state->timeout];
1028 start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
1029 if (start) {
1030 end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];
1031 states = state->rule.ptr->states;
1032 } else {
1033 start = pf_default_rule.timeout[PFTM_ADAPTIVE_START];
1034 end = pf_default_rule.timeout[PFTM_ADAPTIVE_END];
1035 states = pf_status.states;
1036 }
1037 if (end && states > start && start < end) {
1038 if (states < end)
1039 return (state->expire + timeout * (end - states) /
1040 (end - start));
1041 else
1042 return (time_second);
1043 }
1044 return (state->expire + timeout);
1045}
1046
1047void
1048pf_purge_expired_src_nodes(void)
1049{
1050 struct pf_src_node *cur, *next;
1051
1052 for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
1053 next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
1054
1055 if (cur->states <= 0 && cur->expire <= time_second) {
1056 if (cur->rule.ptr != NULL) {
1057 cur->rule.ptr->src_nodes--;
1058 if (cur->rule.ptr->states <= 0 &&
1059 cur->rule.ptr->max_src_nodes <= 0)
1060 pf_rm_rule(NULL, cur->rule.ptr);
1061 }
1062 RB_REMOVE(pf_src_tree, &tree_src_tracking, cur);
1063 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
1064 pf_status.src_nodes--;
1065 pool_put(&pf_src_tree_pl, cur);
1066 }
1067 }
1068}
1069
1070void
1071pf_src_tree_remove_state(struct pf_state *s)
1072{
1073 u_int32_t timeout;
1074
1075 if (s->src_node != NULL) {
1076 if (s->proto == IPPROTO_TCP) {
1077 if (s->src.state == PF_TCPS_PROXY_DST ||
1078 s->timeout >= PFTM_TCP_ESTABLISHED)
1079 --s->src_node->conn;
1080 }
1081 if (--s->src_node->states <= 0) {
1082 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1083 if (!timeout)
1084 timeout =
1085 pf_default_rule.timeout[PFTM_SRC_NODE];
1086 s->src_node->expire = time_second + timeout;
1087 }
1088 }
1089 if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
1090 if (--s->nat_src_node->states <= 0) {
1091 timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1092 if (!timeout)
1093 timeout =
1094 pf_default_rule.timeout[PFTM_SRC_NODE];
1095 s->nat_src_node->expire = time_second + timeout;
1096 }
1097 }
1098 s->src_node = s->nat_src_node = NULL;
1099}
1100
1101void
1102pf_purge_expired_state(struct pf_state *cur)
1103{
1104#ifdef __FreeBSD__
1105 if (cur->sync_flags & PFSTATE_EXPIRING)
1105 if (cur->local_flags & PFSTATE_EXPIRING)
1106 return;
1106 return;
1107 cur->sync_flags |= PFSTATE_EXPIRING;
1107 cur->local_flags |= PFSTATE_EXPIRING;
1108#endif
1109 if (cur->src.state == PF_TCPS_PROXY_DST)
1110 pf_send_tcp(cur->rule.ptr, cur->af,
1111 &cur->ext.addr, &cur->lan.addr,
1112 cur->ext.port, cur->lan.port,
1113 cur->src.seqhi, cur->src.seqlo + 1,
1114 TH_RST|TH_ACK, 0, 0, 0, 1, NULL, NULL);
1115 RB_REMOVE(pf_state_tree_ext_gwy,
1116 &cur->u.s.kif->pfik_ext_gwy, cur);
1117 RB_REMOVE(pf_state_tree_lan_ext,
1118 &cur->u.s.kif->pfik_lan_ext, cur);
1119 RB_REMOVE(pf_state_tree_id, &tree_id, cur);
1120#if NPFSYNC
1121 pfsync_delete_state(cur);
1122#endif
1123 pf_src_tree_remove_state(cur);
1124 if (--cur->rule.ptr->states <= 0 &&
1125 cur->rule.ptr->src_nodes <= 0)
1126 pf_rm_rule(NULL, cur->rule.ptr);
1127 if (cur->nat_rule.ptr != NULL)
1128 if (--cur->nat_rule.ptr->states <= 0 &&
1129 cur->nat_rule.ptr->src_nodes <= 0)
1130 pf_rm_rule(NULL, cur->nat_rule.ptr);
1131 if (cur->anchor.ptr != NULL)
1132 if (--cur->anchor.ptr->states <= 0)
1133 pf_rm_rule(NULL, cur->anchor.ptr);
1134 pf_normalize_tcp_cleanup(cur);
1135 pfi_detach_state(cur->u.s.kif);
1136 TAILQ_REMOVE(&state_updates, cur, u.s.entry_updates);
1137 if (cur->tag)
1138 pf_tag_unref(cur->tag);
1139 pool_put(&pf_state_pl, cur);
1140 pf_status.fcounters[FCNT_STATE_REMOVALS]++;
1141 pf_status.states--;
1142}
1143
1144void
1145pf_purge_expired_states(void)
1146{
1147 struct pf_state *cur, *next;
1148
1149 for (cur = RB_MIN(pf_state_tree_id, &tree_id);
1150 cur; cur = next) {
1151 next = RB_NEXT(pf_state_tree_id, &tree_id, cur);
1152 if (pf_state_expires(cur) <= time_second)
1153 pf_purge_expired_state(cur);
1154 }
1155}
1156
1157int
1158pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
1159{
1160 if (aw->type != PF_ADDR_TABLE)
1161 return (0);
1162 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)
1163 return (1);
1164 return (0);
1165}
1166
1167void
1168pf_tbladdr_remove(struct pf_addr_wrap *aw)
1169{
1170 if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL)
1171 return;
1172 pfr_detach_table(aw->p.tbl);
1173 aw->p.tbl = NULL;
1174}
1175
1176void
1177pf_tbladdr_copyout(struct pf_addr_wrap *aw)
1178{
1179 struct pfr_ktable *kt = aw->p.tbl;
1180
1181 if (aw->type != PF_ADDR_TABLE || kt == NULL)
1182 return;
1183 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
1184 kt = kt->pfrkt_root;
1185 aw->p.tbl = NULL;
1186 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
1187 kt->pfrkt_cnt : -1;
1188}
1189
1190void
1191pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
1192{
1193 switch (af) {
1194#ifdef INET
1195 case AF_INET: {
1196 u_int32_t a = ntohl(addr->addr32[0]);
1197 printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255,
1198 (a>>8)&255, a&255);
1199 if (p) {
1200 p = ntohs(p);
1201 printf(":%u", p);
1202 }
1203 break;
1204 }
1205#endif /* INET */
1206#ifdef INET6
1207 case AF_INET6: {
1208 u_int16_t b;
1209 u_int8_t i, curstart = 255, curend = 0,
1210 maxstart = 0, maxend = 0;
1211 for (i = 0; i < 8; i++) {
1212 if (!addr->addr16[i]) {
1213 if (curstart == 255)
1214 curstart = i;
1215 else
1216 curend = i;
1217 } else {
1218 if (curstart) {
1219 if ((curend - curstart) >
1220 (maxend - maxstart)) {
1221 maxstart = curstart;
1222 maxend = curend;
1223 curstart = 255;
1224 }
1225 }
1226 }
1227 }
1228 for (i = 0; i < 8; i++) {
1229 if (i >= maxstart && i <= maxend) {
1230 if (maxend != 7) {
1231 if (i == maxstart)
1232 printf(":");
1233 } else {
1234 if (i == maxend)
1235 printf(":");
1236 }
1237 } else {
1238 b = ntohs(addr->addr16[i]);
1239 printf("%x", b);
1240 if (i < 7)
1241 printf(":");
1242 }
1243 }
1244 if (p) {
1245 p = ntohs(p);
1246 printf("[%u]", p);
1247 }
1248 break;
1249 }
1250#endif /* INET6 */
1251 }
1252}
1253
1254void
1255pf_print_state(struct pf_state *s)
1256{
1257 switch (s->proto) {
1258 case IPPROTO_TCP:
1259 printf("TCP ");
1260 break;
1261 case IPPROTO_UDP:
1262 printf("UDP ");
1263 break;
1264 case IPPROTO_ICMP:
1265 printf("ICMP ");
1266 break;
1267 case IPPROTO_ICMPV6:
1268 printf("ICMPV6 ");
1269 break;
1270 default:
1271 printf("%u ", s->proto);
1272 break;
1273 }
1274 pf_print_host(&s->lan.addr, s->lan.port, s->af);
1275 printf(" ");
1276 pf_print_host(&s->gwy.addr, s->gwy.port, s->af);
1277 printf(" ");
1278 pf_print_host(&s->ext.addr, s->ext.port, s->af);
1279 printf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo,
1280 s->src.seqhi, s->src.max_win, s->src.seqdiff);
1281 if (s->src.wscale && s->dst.wscale)
1282 printf(" wscale=%u", s->src.wscale & PF_WSCALE_MASK);
1283 printf("]");
1284 printf(" [lo=%u high=%u win=%u modulator=%u", s->dst.seqlo,
1285 s->dst.seqhi, s->dst.max_win, s->dst.seqdiff);
1286 if (s->src.wscale && s->dst.wscale)
1287 printf(" wscale=%u", s->dst.wscale & PF_WSCALE_MASK);
1288 printf("]");
1289 printf(" %u:%u", s->src.state, s->dst.state);
1290}
1291
1292void
1293pf_print_flags(u_int8_t f)
1294{
1295 if (f)
1296 printf(" ");
1297 if (f & TH_FIN)
1298 printf("F");
1299 if (f & TH_SYN)
1300 printf("S");
1301 if (f & TH_RST)
1302 printf("R");
1303 if (f & TH_PUSH)
1304 printf("P");
1305 if (f & TH_ACK)
1306 printf("A");
1307 if (f & TH_URG)
1308 printf("U");
1309 if (f & TH_ECE)
1310 printf("E");
1311 if (f & TH_CWR)
1312 printf("W");
1313}
1314
1315#define PF_SET_SKIP_STEPS(i) \
1316 do { \
1317 while (head[i] != cur) { \
1318 head[i]->skip[i].ptr = cur; \
1319 head[i] = TAILQ_NEXT(head[i], entries); \
1320 } \
1321 } while (0)
1322
1323void
1324pf_calc_skip_steps(struct pf_rulequeue *rules)
1325{
1326 struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT];
1327 int i;
1328
1329 cur = TAILQ_FIRST(rules);
1330 prev = cur;
1331 for (i = 0; i < PF_SKIP_COUNT; ++i)
1332 head[i] = cur;
1333 while (cur != NULL) {
1334
1335 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
1336 PF_SET_SKIP_STEPS(PF_SKIP_IFP);
1337 if (cur->direction != prev->direction)
1338 PF_SET_SKIP_STEPS(PF_SKIP_DIR);
1339 if (cur->af != prev->af)
1340 PF_SET_SKIP_STEPS(PF_SKIP_AF);
1341 if (cur->proto != prev->proto)
1342 PF_SET_SKIP_STEPS(PF_SKIP_PROTO);
1343 if (cur->src.neg != prev->src.neg ||
1344 pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr))
1345 PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR);
1346 if (cur->src.port[0] != prev->src.port[0] ||
1347 cur->src.port[1] != prev->src.port[1] ||
1348 cur->src.port_op != prev->src.port_op)
1349 PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
1350 if (cur->dst.neg != prev->dst.neg ||
1351 pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
1352 PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
1353 if (cur->dst.port[0] != prev->dst.port[0] ||
1354 cur->dst.port[1] != prev->dst.port[1] ||
1355 cur->dst.port_op != prev->dst.port_op)
1356 PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
1357
1358 prev = cur;
1359 cur = TAILQ_NEXT(cur, entries);
1360 }
1361 for (i = 0; i < PF_SKIP_COUNT; ++i)
1362 PF_SET_SKIP_STEPS(i);
1363}
1364
1365int
1366pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
1367{
1368 if (aw1->type != aw2->type)
1369 return (1);
1370 switch (aw1->type) {
1371 case PF_ADDR_ADDRMASK:
1372 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
1373 return (1);
1374 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
1375 return (1);
1376 return (0);
1377 case PF_ADDR_DYNIFTL:
1378 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
1379 case PF_ADDR_NOROUTE:
1380 return (0);
1381 case PF_ADDR_TABLE:
1382 return (aw1->p.tbl != aw2->p.tbl);
1383 default:
1384 printf("invalid address type: %d\n", aw1->type);
1385 return (1);
1386 }
1387}
1388
1389u_int16_t
1390pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp)
1391{
1392 u_int32_t l;
1393
1394 if (udp && !cksum)
1395 return (0x0000);
1396 l = cksum + old - new;
1397 l = (l >> 16) + (l & 65535);
1398 l = l & 65535;
1399 if (udp && !l)
1400 return (0xFFFF);
1401 return (l);
1402}
1403
1404void
1405pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc,
1406 struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af)
1407{
1408 struct pf_addr ao;
1409 u_int16_t po = *p;
1410
1411 PF_ACPY(&ao, a, af);
1412 PF_ACPY(a, an, af);
1413
1414 *p = pn;
1415
1416 switch (af) {
1417#ifdef INET
1418 case AF_INET:
1419 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
1420 ao.addr16[0], an->addr16[0], 0),
1421 ao.addr16[1], an->addr16[1], 0);
1422 *p = pn;
1423 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
1424 ao.addr16[0], an->addr16[0], u),
1425 ao.addr16[1], an->addr16[1], u),
1426 po, pn, u);
1427 break;
1428#endif /* INET */
1429#ifdef INET6
1430 case AF_INET6:
1431 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1432 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1433 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
1434 ao.addr16[0], an->addr16[0], u),
1435 ao.addr16[1], an->addr16[1], u),
1436 ao.addr16[2], an->addr16[2], u),
1437 ao.addr16[3], an->addr16[3], u),
1438 ao.addr16[4], an->addr16[4], u),
1439 ao.addr16[5], an->addr16[5], u),
1440 ao.addr16[6], an->addr16[6], u),
1441 ao.addr16[7], an->addr16[7], u),
1442 po, pn, u);
1443 break;
1444#endif /* INET6 */
1445 }
1446}
1447
1448
1449/* Changes a u_int32_t. Uses a void * so there are no align restrictions */
1450void
1451pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u)
1452{
1453 u_int32_t ao;
1454
1455 memcpy(&ao, a, sizeof(ao));
1456 memcpy(a, &an, sizeof(u_int32_t));
1457 *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u),
1458 ao % 65536, an % 65536, u);
1459}
1460
1461#ifdef INET6
1462void
1463pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u)
1464{
1465 struct pf_addr ao;
1466
1467 PF_ACPY(&ao, a, AF_INET6);
1468 PF_ACPY(a, an, AF_INET6);
1469
1470 *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1471 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1472 pf_cksum_fixup(pf_cksum_fixup(*c,
1473 ao.addr16[0], an->addr16[0], u),
1474 ao.addr16[1], an->addr16[1], u),
1475 ao.addr16[2], an->addr16[2], u),
1476 ao.addr16[3], an->addr16[3], u),
1477 ao.addr16[4], an->addr16[4], u),
1478 ao.addr16[5], an->addr16[5], u),
1479 ao.addr16[6], an->addr16[6], u),
1480 ao.addr16[7], an->addr16[7], u);
1481}
1482#endif /* INET6 */
1483
1484void
1485pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa,
1486 struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c,
1487 u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af)
1488{
1489 struct pf_addr oia, ooa;
1490
1491 PF_ACPY(&oia, ia, af);
1492 PF_ACPY(&ooa, oa, af);
1493
1494 /* Change inner protocol port, fix inner protocol checksum. */
1495 if (ip != NULL) {
1496 u_int16_t oip = *ip;
1497 u_int32_t opc = 0; /* make the compiler happy */
1498
1499 if (pc != NULL)
1500 opc = *pc;
1501 *ip = np;
1502 if (pc != NULL)
1503 *pc = pf_cksum_fixup(*pc, oip, *ip, u);
1504 *ic = pf_cksum_fixup(*ic, oip, *ip, 0);
1505 if (pc != NULL)
1506 *ic = pf_cksum_fixup(*ic, opc, *pc, 0);
1507 }
1508 /* Change inner ip address, fix inner ip and icmp checksums. */
1509 PF_ACPY(ia, na, af);
1510 switch (af) {
1511#ifdef INET
1512 case AF_INET: {
1513 u_int32_t oh2c = *h2c;
1514
1515 *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c,
1516 oia.addr16[0], ia->addr16[0], 0),
1517 oia.addr16[1], ia->addr16[1], 0);
1518 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
1519 oia.addr16[0], ia->addr16[0], 0),
1520 oia.addr16[1], ia->addr16[1], 0);
1521 *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0);
1522 break;
1523 }
1524#endif /* INET */
1525#ifdef INET6
1526 case AF_INET6:
1527 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1528 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1529 pf_cksum_fixup(pf_cksum_fixup(*ic,
1530 oia.addr16[0], ia->addr16[0], u),
1531 oia.addr16[1], ia->addr16[1], u),
1532 oia.addr16[2], ia->addr16[2], u),
1533 oia.addr16[3], ia->addr16[3], u),
1534 oia.addr16[4], ia->addr16[4], u),
1535 oia.addr16[5], ia->addr16[5], u),
1536 oia.addr16[6], ia->addr16[6], u),
1537 oia.addr16[7], ia->addr16[7], u);
1538 break;
1539#endif /* INET6 */
1540 }
1541 /* Change outer ip address, fix outer ip or icmpv6 checksum. */
1542 PF_ACPY(oa, na, af);
1543 switch (af) {
1544#ifdef INET
1545 case AF_INET:
1546 *hc = pf_cksum_fixup(pf_cksum_fixup(*hc,
1547 ooa.addr16[0], oa->addr16[0], 0),
1548 ooa.addr16[1], oa->addr16[1], 0);
1549 break;
1550#endif /* INET */
1551#ifdef INET6
1552 case AF_INET6:
1553 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1554 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1555 pf_cksum_fixup(pf_cksum_fixup(*ic,
1556 ooa.addr16[0], oa->addr16[0], u),
1557 ooa.addr16[1], oa->addr16[1], u),
1558 ooa.addr16[2], oa->addr16[2], u),
1559 ooa.addr16[3], oa->addr16[3], u),
1560 ooa.addr16[4], oa->addr16[4], u),
1561 ooa.addr16[5], oa->addr16[5], u),
1562 ooa.addr16[6], oa->addr16[6], u),
1563 ooa.addr16[7], oa->addr16[7], u);
1564 break;
1565#endif /* INET6 */
1566 }
1567}
1568
1569void
1570pf_send_tcp(const struct pf_rule *r, sa_family_t af,
1571 const struct pf_addr *saddr, const struct pf_addr *daddr,
1572 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
1573 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
1574 struct ether_header *eh, struct ifnet *ifp)
1575{
1576 struct mbuf *m;
1577 int len = 0, tlen; /* make the compiler happy */
1578#ifdef INET
1579 struct ip *h = NULL; /* make the compiler happy */
1580#endif /* INET */
1581#ifdef INET6
1582 struct ip6_hdr *h6 = NULL; /* make the compiler happy */
1583#endif /* INET6 */
1584 struct tcphdr *th = NULL; /* make the compiler happy */
1585 char *opt;
1586
1587 /* maximum segment size tcp option */
1588 tlen = sizeof(struct tcphdr);
1589 if (mss)
1590 tlen += 4;
1591
1592 switch (af) {
1593#ifdef INET
1594 case AF_INET:
1595 len = sizeof(struct ip) + tlen;
1596 break;
1597#endif /* INET */
1598#ifdef INET6
1599 case AF_INET6:
1600 len = sizeof(struct ip6_hdr) + tlen;
1601 break;
1602#endif /* INET6 */
1603 }
1604
1605 /* create outgoing mbuf */
1606 m = m_gethdr(M_DONTWAIT, MT_HEADER);
1607 if (m == NULL)
1608 return;
1609 if (tag) {
1610#ifdef __FreeBSD__
1611 m->m_flags |= M_SKIP_FIREWALL;
1612#else
1613 struct m_tag *mtag;
1614
1615 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
1616 if (mtag == NULL) {
1617 m_freem(m);
1618 return;
1619 }
1620 m_tag_prepend(m, mtag);
1621#endif
1622 }
1623#ifdef ALTQ
1624 if (r != NULL && r->qid) {
1625 struct m_tag *mtag;
1626 struct altq_tag *atag;
1627
1628 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
1629 if (mtag != NULL) {
1630 atag = (struct altq_tag *)(mtag + 1);
1631 atag->qid = r->qid;
1632 /* add hints for ecn */
1633 atag->af = af;
1634 atag->hdr = mtod(m, struct ip *);
1635 m_tag_prepend(m, mtag);
1636 }
1637 }
1638#endif /* ALTQ */
1639 m->m_data += max_linkhdr;
1640 m->m_pkthdr.len = m->m_len = len;
1641 m->m_pkthdr.rcvif = NULL;
1642 bzero(m->m_data, len);
1643 switch (af) {
1644#ifdef INET
1645 case AF_INET:
1646 h = mtod(m, struct ip *);
1647
1648 /* IP header fields included in the TCP checksum */
1649 h->ip_p = IPPROTO_TCP;
1650 h->ip_len = htons(tlen);
1651 h->ip_src.s_addr = saddr->v4.s_addr;
1652 h->ip_dst.s_addr = daddr->v4.s_addr;
1653
1654 th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip));
1655 break;
1656#endif /* INET */
1657#ifdef INET6
1658 case AF_INET6:
1659 h6 = mtod(m, struct ip6_hdr *);
1660
1661 /* IP header fields included in the TCP checksum */
1662 h6->ip6_nxt = IPPROTO_TCP;
1663 h6->ip6_plen = htons(tlen);
1664 memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr));
1665 memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr));
1666
1667 th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr));
1668 break;
1669#endif /* INET6 */
1670 }
1671
1672 /* TCP header */
1673 th->th_sport = sport;
1674 th->th_dport = dport;
1675 th->th_seq = htonl(seq);
1676 th->th_ack = htonl(ack);
1677 th->th_off = tlen >> 2;
1678 th->th_flags = flags;
1679 th->th_win = htons(win);
1680
1681 if (mss) {
1682 opt = (char *)(th + 1);
1683 opt[0] = TCPOPT_MAXSEG;
1684 opt[1] = 4;
1685 HTONS(mss);
1686 bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2);
1687 }
1688
1689 switch (af) {
1690#ifdef INET
1691 case AF_INET:
1692 /* TCP checksum */
1693 th->th_sum = in_cksum(m, len);
1694
1695 /* Finish the IP header */
1696 h->ip_v = 4;
1697 h->ip_hl = sizeof(*h) >> 2;
1698 h->ip_tos = IPTOS_LOWDELAY;
1699#ifdef __FreeBSD__
1700 h->ip_off = path_mtu_discovery ? IP_DF : 0;
1701 h->ip_len = len;
1702#else
1703 h->ip_off = htons(ip_mtudisc ? IP_DF : 0);
1704 h->ip_len = htons(len);
1705#endif
1706 h->ip_ttl = ttl ? ttl : ip_defttl;
1707 h->ip_sum = 0;
1708 if (eh == NULL) {
1709#ifdef __FreeBSD__
1710 PF_UNLOCK();
1711 ip_output(m, (void *)NULL, (void *)NULL, 0,
1712 (void *)NULL, (void *)NULL);
1713 PF_LOCK();
1714#else /* ! __FreeBSD__ */
1715 ip_output(m, (void *)NULL, (void *)NULL, 0,
1716 (void *)NULL, (void *)NULL);
1717#endif
1718 } else {
1719 struct route ro;
1720 struct rtentry rt;
1721 struct ether_header *e = (void *)ro.ro_dst.sa_data;
1722
1723 if (ifp == NULL) {
1724 m_freem(m);
1725 return;
1726 }
1727 rt.rt_ifp = ifp;
1728 ro.ro_rt = &rt;
1729 ro.ro_dst.sa_len = sizeof(ro.ro_dst);
1730 ro.ro_dst.sa_family = pseudo_AF_HDRCMPLT;
1731 bcopy(eh->ether_dhost, e->ether_shost, ETHER_ADDR_LEN);
1732 bcopy(eh->ether_shost, e->ether_dhost, ETHER_ADDR_LEN);
1733 e->ether_type = eh->ether_type;
1734#ifdef __FreeBSD__
1735 PF_UNLOCK();
1736 /* XXX_IMPORT: later */
1737 ip_output(m, (void *)NULL, &ro, 0,
1738 (void *)NULL, (void *)NULL);
1739 PF_LOCK();
1740#else /* ! __FreeBSD__ */
1741 ip_output(m, (void *)NULL, &ro, IP_ROUTETOETHER,
1742 (void *)NULL, (void *)NULL);
1743#endif
1744 }
1745 break;
1746#endif /* INET */
1747#ifdef INET6
1748 case AF_INET6:
1749 /* TCP checksum */
1750 th->th_sum = in6_cksum(m, IPPROTO_TCP,
1751 sizeof(struct ip6_hdr), tlen);
1752
1753 h6->ip6_vfc |= IPV6_VERSION;
1754 h6->ip6_hlim = IPV6_DEFHLIM;
1755
1756#ifdef __FreeBSD__
1757 PF_UNLOCK();
1758 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
1759 PF_LOCK();
1760#else
1761 ip6_output(m, NULL, NULL, 0, NULL, NULL);
1762#endif
1763 break;
1764#endif /* INET6 */
1765 }
1766}
1767
1768void
1769pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
1770 struct pf_rule *r)
1771{
1772#ifdef ALTQ
1773 struct m_tag *mtag;
1774#endif
1775 struct mbuf *m0;
1776#ifdef __FreeBSD__
1777 struct ip *ip;
1778#endif
1779
1780#ifdef __FreeBSD__
1781 m0 = m_copypacket(m, M_DONTWAIT);
1782 if (m0 == NULL)
1783 return;
1784 m0->m_flags |= M_SKIP_FIREWALL;
1785#else
1786 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
1787 if (mtag == NULL)
1788 return;
1789 m0 = m_copy(m, 0, M_COPYALL);
1790 if (m0 == NULL) {
1791 m_tag_free(mtag);
1792 return;
1793 }
1794 m_tag_prepend(m0, mtag);
1795#endif
1796
1797#ifdef ALTQ
1798 if (r->qid) {
1799 struct altq_tag *atag;
1800
1801 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
1802 if (mtag != NULL) {
1803 atag = (struct altq_tag *)(mtag + 1);
1804 atag->qid = r->qid;
1805 /* add hints for ecn */
1806 atag->af = af;
1807 atag->hdr = mtod(m0, struct ip *);
1808 m_tag_prepend(m0, mtag);
1809 }
1810 }
1811#endif /* ALTQ */
1812
1813 switch (af) {
1814#ifdef INET
1815 case AF_INET:
1816#ifdef __FreeBSD__
1817 /* icmp_error() expects host byte ordering */
1818 ip = mtod(m0, struct ip *);
1819 NTOHS(ip->ip_len);
1820 NTOHS(ip->ip_off);
1821 PF_UNLOCK();
1822 icmp_error(m0, type, code, 0, 0);
1823 PF_LOCK();
1824#else
1825 icmp_error(m0, type, code, 0, (void *)NULL);
1826#endif
1827 break;
1828#endif /* INET */
1829#ifdef INET6
1830 case AF_INET6:
1831#ifdef __FreeBSD__
1832 PF_UNLOCK();
1833#endif
1834 icmp6_error(m0, type, code, 0);
1835#ifdef __FreeBSD__
1836 PF_LOCK();
1837#endif
1838 break;
1839#endif /* INET6 */
1840 }
1841}
1842
1843/*
1844 * Return 1 if the addresses a and b match (with mask m), otherwise return 0.
1845 * If n is 0, they match if they are equal. If n is != 0, they match if they
1846 * are different.
1847 */
1848int
1849pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
1850 struct pf_addr *b, sa_family_t af)
1851{
1852 int match = 0;
1853
1854 switch (af) {
1855#ifdef INET
1856 case AF_INET:
1857 if ((a->addr32[0] & m->addr32[0]) ==
1858 (b->addr32[0] & m->addr32[0]))
1859 match++;
1860 break;
1861#endif /* INET */
1862#ifdef INET6
1863 case AF_INET6:
1864 if (((a->addr32[0] & m->addr32[0]) ==
1865 (b->addr32[0] & m->addr32[0])) &&
1866 ((a->addr32[1] & m->addr32[1]) ==
1867 (b->addr32[1] & m->addr32[1])) &&
1868 ((a->addr32[2] & m->addr32[2]) ==
1869 (b->addr32[2] & m->addr32[2])) &&
1870 ((a->addr32[3] & m->addr32[3]) ==
1871 (b->addr32[3] & m->addr32[3])))
1872 match++;
1873 break;
1874#endif /* INET6 */
1875 }
1876 if (match) {
1877 if (n)
1878 return (0);
1879 else
1880 return (1);
1881 } else {
1882 if (n)
1883 return (1);
1884 else
1885 return (0);
1886 }
1887}
1888
1889int
1890pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
1891{
1892 switch (op) {
1893 case PF_OP_IRG:
1894 return ((p > a1) && (p < a2));
1895 case PF_OP_XRG:
1896 return ((p < a1) || (p > a2));
1897 case PF_OP_RRG:
1898 return ((p >= a1) && (p <= a2));
1899 case PF_OP_EQ:
1900 return (p == a1);
1901 case PF_OP_NE:
1902 return (p != a1);
1903 case PF_OP_LT:
1904 return (p < a1);
1905 case PF_OP_LE:
1906 return (p <= a1);
1907 case PF_OP_GT:
1908 return (p > a1);
1909 case PF_OP_GE:
1910 return (p >= a1);
1911 }
1912 return (0); /* never reached */
1913}
1914
1915int
1916pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
1917{
1918 NTOHS(a1);
1919 NTOHS(a2);
1920 NTOHS(p);
1921 return (pf_match(op, a1, a2, p));
1922}
1923
1924int
1925pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
1926{
1927 if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
1928 return (0);
1929 return (pf_match(op, a1, a2, u));
1930}
1931
1932int
1933pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
1934{
1935 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
1936 return (0);
1937 return (pf_match(op, a1, a2, g));
1938}
1939
1940struct pf_tag *
1941pf_get_tag(struct mbuf *m)
1942{
1943 struct m_tag *mtag;
1944
1945 if ((mtag = m_tag_find(m, PACKET_TAG_PF_TAG, NULL)) != NULL)
1946 return ((struct pf_tag *)(mtag + 1));
1947 else
1948 return (NULL);
1949}
1950
1951int
1952pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_tag **pftag, int *tag)
1953{
1954 if (*tag == -1) { /* find mbuf tag */
1955 *pftag = pf_get_tag(m);
1956 if (*pftag != NULL)
1957 *tag = (*pftag)->tag;
1958 else
1959 *tag = 0;
1960 }
1961
1962 return ((!r->match_tag_not && r->match_tag == *tag) ||
1963 (r->match_tag_not && r->match_tag != *tag));
1964}
1965
1966int
1967pf_tag_packet(struct mbuf *m, struct pf_tag *pftag, int tag)
1968{
1969 struct m_tag *mtag;
1970
1971 if (tag <= 0)
1972 return (0);
1973
1974 if (pftag == NULL) {
1975 mtag = m_tag_get(PACKET_TAG_PF_TAG, sizeof(*pftag), M_NOWAIT);
1976 if (mtag == NULL)
1977 return (1);
1978 ((struct pf_tag *)(mtag + 1))->tag = tag;
1979 m_tag_prepend(m, mtag);
1980 } else
1981 pftag->tag = tag;
1982
1983 return (0);
1984}
1985
1986static void
1987pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n,
1988 struct pf_rule **r, struct pf_rule **a)
1989{
1990 struct pf_anchor_stackframe *f;
1991
1992 if (*depth >= sizeof(pf_anchor_stack) /
1993 sizeof(pf_anchor_stack[0])) {
1994 printf("pf_step_into_anchor: stack overflow\n");
1995 *r = TAILQ_NEXT(*r, entries);
1996 return;
1997 } else if (*depth == 0 && a != NULL)
1998 *a = *r;
1999 f = pf_anchor_stack + (*depth)++;
2000 f->rs = *rs;
2001 f->r = *r;
2002 if ((*r)->anchor_wildcard) {
2003 f->parent = &(*r)->anchor->children;
2004 if ((f->child = RB_MIN(pf_anchor_node, f->parent)) ==
2005 NULL) {
2006 *r = NULL;
2007 return;
2008 }
2009 *rs = &f->child->ruleset;
2010 } else {
2011 f->parent = NULL;
2012 f->child = NULL;
2013 *rs = &(*r)->anchor->ruleset;
2014 }
2015 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2016}
2017
2018static void
2019pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n,
2020 struct pf_rule **r, struct pf_rule **a)
2021{
2022 struct pf_anchor_stackframe *f;
2023
2024 do {
2025 if (*depth <= 0)
2026 break;
2027 f = pf_anchor_stack + *depth - 1;
2028 if (f->parent != NULL && f->child != NULL) {
2029 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child);
2030 if (f->child != NULL) {
2031 *rs = &f->child->ruleset;
2032 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2033 if (*r == NULL)
2034 continue;
2035 else
2036 break;
2037 }
2038 }
2039 (*depth)--;
2040 if (*depth == 0 && a != NULL)
2041 *a = NULL;
2042 *rs = f->rs;
2043 *r = TAILQ_NEXT(f->r, entries);
2044 } while (*r == NULL);
2045}
2046
2047#ifdef INET6
2048void
2049pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
2050 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af)
2051{
2052 switch (af) {
2053#ifdef INET
2054 case AF_INET:
2055 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
2056 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
2057 break;
2058#endif /* INET */
2059 case AF_INET6:
2060 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
2061 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
2062 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) |
2063 ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]);
2064 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) |
2065 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]);
2066 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) |
2067 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]);
2068 break;
2069 }
2070}
2071
2072void
2073pf_addr_inc(struct pf_addr *addr, sa_family_t af)
2074{
2075 switch (af) {
2076#ifdef INET
2077 case AF_INET:
2078 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1);
2079 break;
2080#endif /* INET */
2081 case AF_INET6:
2082 if (addr->addr32[3] == 0xffffffff) {
2083 addr->addr32[3] = 0;
2084 if (addr->addr32[2] == 0xffffffff) {
2085 addr->addr32[2] = 0;
2086 if (addr->addr32[1] == 0xffffffff) {
2087 addr->addr32[1] = 0;
2088 addr->addr32[0] =
2089 htonl(ntohl(addr->addr32[0]) + 1);
2090 } else
2091 addr->addr32[1] =
2092 htonl(ntohl(addr->addr32[1]) + 1);
2093 } else
2094 addr->addr32[2] =
2095 htonl(ntohl(addr->addr32[2]) + 1);
2096 } else
2097 addr->addr32[3] =
2098 htonl(ntohl(addr->addr32[3]) + 1);
2099 break;
2100 }
2101}
2102#endif /* INET6 */
2103
2104#define mix(a,b,c) \
2105 do { \
2106 a -= b; a -= c; a ^= (c >> 13); \
2107 b -= c; b -= a; b ^= (a << 8); \
2108 c -= a; c -= b; c ^= (b >> 13); \
2109 a -= b; a -= c; a ^= (c >> 12); \
2110 b -= c; b -= a; b ^= (a << 16); \
2111 c -= a; c -= b; c ^= (b >> 5); \
2112 a -= b; a -= c; a ^= (c >> 3); \
2113 b -= c; b -= a; b ^= (a << 10); \
2114 c -= a; c -= b; c ^= (b >> 15); \
2115 } while (0)
2116
2117/*
2118 * hash function based on bridge_hash in if_bridge.c
2119 */
2120void
2121pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
2122 struct pf_poolhashkey *key, sa_family_t af)
2123{
2124 u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0];
2125
2126 switch (af) {
2127#ifdef INET
2128 case AF_INET:
2129 a += inaddr->addr32[0];
2130 b += key->key32[1];
2131 mix(a, b, c);
2132 hash->addr32[0] = c + key->key32[2];
2133 break;
2134#endif /* INET */
2135#ifdef INET6
2136 case AF_INET6:
2137 a += inaddr->addr32[0];
2138 b += inaddr->addr32[2];
2139 mix(a, b, c);
2140 hash->addr32[0] = c;
2141 a += inaddr->addr32[1];
2142 b += inaddr->addr32[3];
2143 c += key->key32[1];
2144 mix(a, b, c);
2145 hash->addr32[1] = c;
2146 a += inaddr->addr32[2];
2147 b += inaddr->addr32[1];
2148 c += key->key32[2];
2149 mix(a, b, c);
2150 hash->addr32[2] = c;
2151 a += inaddr->addr32[3];
2152 b += inaddr->addr32[0];
2153 c += key->key32[3];
2154 mix(a, b, c);
2155 hash->addr32[3] = c;
2156 break;
2157#endif /* INET6 */
2158 }
2159}
2160
2161int
2162pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
2163 struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
2164{
2165 unsigned char hash[16];
2166 struct pf_pool *rpool = &r->rpool;
2167 struct pf_addr *raddr = &rpool->cur->addr.v.a.addr;
2168 struct pf_addr *rmask = &rpool->cur->addr.v.a.mask;
2169 struct pf_pooladdr *acur = rpool->cur;
2170 struct pf_src_node k;
2171
2172 if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
2173 (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
2174 k.af = af;
2175 PF_ACPY(&k.addr, saddr, af);
2176 if (r->rule_flag & PFRULE_RULESRCTRACK ||
2177 r->rpool.opts & PF_POOL_STICKYADDR)
2178 k.rule.ptr = r;
2179 else
2180 k.rule.ptr = NULL;
2181 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
2182 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
2183 if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
2184 PF_ACPY(naddr, &(*sn)->raddr, af);
2185 if (pf_status.debug >= PF_DEBUG_MISC) {
2186 printf("pf_map_addr: src tracking maps ");
2187 pf_print_host(&k.addr, 0, af);
2188 printf(" to ");
2189 pf_print_host(naddr, 0, af);
2190 printf("\n");
2191 }
2192 return (0);
2193 }
2194 }
2195
2196 if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
2197 return (1);
2198 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2199 switch (af) {
2200#ifdef INET
2201 case AF_INET:
2202 if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
2203 (rpool->opts & PF_POOL_TYPEMASK) !=
2204 PF_POOL_ROUNDROBIN)
2205 return (1);
2206 raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
2207 rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
2208 break;
2209#endif /* INET */
2210#ifdef INET6
2211 case AF_INET6:
2212 if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
2213 (rpool->opts & PF_POOL_TYPEMASK) !=
2214 PF_POOL_ROUNDROBIN)
2215 return (1);
2216 raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
2217 rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
2218 break;
2219#endif /* INET6 */
2220 }
2221 } else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2222 if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
2223 return (1); /* unsupported */
2224 } else {
2225 raddr = &rpool->cur->addr.v.a.addr;
2226 rmask = &rpool->cur->addr.v.a.mask;
2227 }
2228
2229 switch (rpool->opts & PF_POOL_TYPEMASK) {
2230 case PF_POOL_NONE:
2231 PF_ACPY(naddr, raddr, af);
2232 break;
2233 case PF_POOL_BITMASK:
2234 PF_POOLMASK(naddr, raddr, rmask, saddr, af);
2235 break;
2236 case PF_POOL_RANDOM:
2237 if (init_addr != NULL && PF_AZERO(init_addr, af)) {
2238 switch (af) {
2239#ifdef INET
2240 case AF_INET:
2241 rpool->counter.addr32[0] = htonl(arc4random());
2242 break;
2243#endif /* INET */
2244#ifdef INET6
2245 case AF_INET6:
2246 if (rmask->addr32[3] != 0xffffffff)
2247 rpool->counter.addr32[3] =
2248 htonl(arc4random());
2249 else
2250 break;
2251 if (rmask->addr32[2] != 0xffffffff)
2252 rpool->counter.addr32[2] =
2253 htonl(arc4random());
2254 else
2255 break;
2256 if (rmask->addr32[1] != 0xffffffff)
2257 rpool->counter.addr32[1] =
2258 htonl(arc4random());
2259 else
2260 break;
2261 if (rmask->addr32[0] != 0xffffffff)
2262 rpool->counter.addr32[0] =
2263 htonl(arc4random());
2264 break;
2265#endif /* INET6 */
2266 }
2267 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
2268 PF_ACPY(init_addr, naddr, af);
2269
2270 } else {
2271 PF_AINC(&rpool->counter, af);
2272 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
2273 }
2274 break;
2275 case PF_POOL_SRCHASH:
2276 pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
2277 PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
2278 break;
2279 case PF_POOL_ROUNDROBIN:
2280 if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2281 if (!pfr_pool_get(rpool->cur->addr.p.tbl,
2282 &rpool->tblidx, &rpool->counter,
2283 &raddr, &rmask, af))
2284 goto get_addr;
2285 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2286 if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
2287 &rpool->tblidx, &rpool->counter,
2288 &raddr, &rmask, af))
2289 goto get_addr;
2290 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
2291 goto get_addr;
2292
2293 try_next:
2294 if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL)
2295 rpool->cur = TAILQ_FIRST(&rpool->list);
2296 if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2297 rpool->tblidx = -1;
2298 if (pfr_pool_get(rpool->cur->addr.p.tbl,
2299 &rpool->tblidx, &rpool->counter,
2300 &raddr, &rmask, af)) {
2301 /* table contains no address of type 'af' */
2302 if (rpool->cur != acur)
2303 goto try_next;
2304 return (1);
2305 }
2306 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2307 rpool->tblidx = -1;
2308 if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
2309 &rpool->tblidx, &rpool->counter,
2310 &raddr, &rmask, af)) {
2311 /* table contains no address of type 'af' */
2312 if (rpool->cur != acur)
2313 goto try_next;
2314 return (1);
2315 }
2316 } else {
2317 raddr = &rpool->cur->addr.v.a.addr;
2318 rmask = &rpool->cur->addr.v.a.mask;
2319 PF_ACPY(&rpool->counter, raddr, af);
2320 }
2321
2322 get_addr:
2323 PF_ACPY(naddr, &rpool->counter, af);
2324 if (init_addr != NULL && PF_AZERO(init_addr, af))
2325 PF_ACPY(init_addr, naddr, af);
2326 PF_AINC(&rpool->counter, af);
2327 break;
2328 }
2329 if (*sn != NULL)
2330 PF_ACPY(&(*sn)->raddr, naddr, af);
2331
2332 if (pf_status.debug >= PF_DEBUG_MISC &&
2333 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
2334 printf("pf_map_addr: selected address ");
2335 pf_print_host(naddr, 0, af);
2336 printf("\n");
2337 }
2338
2339 return (0);
2340}
2341
2342int
2343pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
2344 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
2345 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
2346 struct pf_src_node **sn)
2347{
2348 struct pf_state key;
2349 struct pf_addr init_addr;
2350 u_int16_t cut;
2351
2352 bzero(&init_addr, sizeof(init_addr));
2353 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
2354 return (1);
2355
2356 if (proto == IPPROTO_ICMP) {
2357 low = 1;
2358 high = 65535;
2359 }
2360
2361 do {
2362 key.af = af;
2363 key.proto = proto;
2364 PF_ACPY(&key.ext.addr, daddr, key.af);
2365 PF_ACPY(&key.gwy.addr, naddr, key.af);
2366 key.ext.port = dport;
2367
2368 /*
2369 * port search; start random, step;
2370 * similar 2 portloop in in_pcbbind
2371 */
2372 if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
2373 proto == IPPROTO_ICMP)) {
2374 key.gwy.port = dport;
2375 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
2376 return (0);
2377 } else if (low == 0 && high == 0) {
2378 key.gwy.port = *nport;
2379 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
2380 return (0);
2381 } else if (low == high) {
2382 key.gwy.port = htons(low);
2383 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) {
2384 *nport = htons(low);
2385 return (0);
2386 }
2387 } else {
2388 u_int16_t tmp;
2389
2390 if (low > high) {
2391 tmp = low;
2392 low = high;
2393 high = tmp;
2394 }
2395 /* low < high */
2396 cut = htonl(arc4random()) % (1 + high - low) + low;
2397 /* low <= cut <= high */
2398 for (tmp = cut; tmp <= high; ++(tmp)) {
2399 key.gwy.port = htons(tmp);
2400 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
2401 NULL) {
2402 *nport = htons(tmp);
2403 return (0);
2404 }
2405 }
2406 for (tmp = cut - 1; tmp >= low; --(tmp)) {
2407 key.gwy.port = htons(tmp);
2408 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
2409 NULL) {
2410 *nport = htons(tmp);
2411 return (0);
2412 }
2413 }
2414 }
2415
2416 switch (r->rpool.opts & PF_POOL_TYPEMASK) {
2417 case PF_POOL_RANDOM:
2418 case PF_POOL_ROUNDROBIN:
2419 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
2420 return (1);
2421 break;
2422 case PF_POOL_NONE:
2423 case PF_POOL_SRCHASH:
2424 case PF_POOL_BITMASK:
2425 default:
2426 return (1);
2427 }
2428 } while (! PF_AEQ(&init_addr, naddr, af) );
2429
2430 return (1); /* none available */
2431}
2432
2433struct pf_rule *
2434pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
2435 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
2436 struct pf_addr *daddr, u_int16_t dport, int rs_num)
2437{
2438 struct pf_rule *r, *rm = NULL;
2439 struct pf_ruleset *ruleset = NULL;
2440 struct pf_tag *pftag = NULL;
2441 int tag = -1;
2442 int asd = 0;
2443
2444 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
2445 while (r && rm == NULL) {
2446 struct pf_rule_addr *src = NULL, *dst = NULL;
2447 struct pf_addr_wrap *xdst = NULL;
2448
2449 if (r->action == PF_BINAT && direction == PF_IN) {
2450 src = &r->dst;
2451 if (r->rpool.cur != NULL)
2452 xdst = &r->rpool.cur->addr;
2453 } else {
2454 src = &r->src;
2455 dst = &r->dst;
2456 }
2457
2458 r->evaluations++;
2459 if (r->kif != NULL &&
2460 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
2461 r = r->skip[PF_SKIP_IFP].ptr;
2462 else if (r->direction && r->direction != direction)
2463 r = r->skip[PF_SKIP_DIR].ptr;
2464 else if (r->af && r->af != pd->af)
2465 r = r->skip[PF_SKIP_AF].ptr;
2466 else if (r->proto && r->proto != pd->proto)
2467 r = r->skip[PF_SKIP_PROTO].ptr;
2468 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, src->neg))
2469 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR :
2470 PF_SKIP_DST_ADDR].ptr;
2471 else if (src->port_op && !pf_match_port(src->port_op,
2472 src->port[0], src->port[1], sport))
2473 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
2474 PF_SKIP_DST_PORT].ptr;
2475 else if (dst != NULL &&
2476 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg))
2477 r = r->skip[PF_SKIP_DST_ADDR].ptr;
2478 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, 0))
2479 r = TAILQ_NEXT(r, entries);
2480 else if (dst != NULL && dst->port_op &&
2481 !pf_match_port(dst->port_op, dst->port[0],
2482 dst->port[1], dport))
2483 r = r->skip[PF_SKIP_DST_PORT].ptr;
2484 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
2485 r = TAILQ_NEXT(r, entries);
2486 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
2487 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
2488 off, pd->hdr.tcp), r->os_fingerprint)))
2489 r = TAILQ_NEXT(r, entries);
2490 else {
2491 if (r->tag)
2492 tag = r->tag;
2493 if (r->anchor == NULL) {
2494 rm = r;
2495 } else
2496 pf_step_into_anchor(&asd, &ruleset, rs_num, &r, NULL);
2497 }
2498 if (r == NULL)
2499 pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r, NULL);
2500 }
2501 if (pf_tag_packet(m, pftag, tag))
2502 return (NULL);
2503 if (rm != NULL && (rm->action == PF_NONAT ||
2504 rm->action == PF_NORDR || rm->action == PF_NOBINAT))
2505 return (NULL);
2506 return (rm);
2507}
2508
2509struct pf_rule *
2510pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
2511 struct pfi_kif *kif, struct pf_src_node **sn,
2512 struct pf_addr *saddr, u_int16_t sport,
2513 struct pf_addr *daddr, u_int16_t dport,
2514 struct pf_addr *naddr, u_int16_t *nport)
2515{
2516 struct pf_rule *r = NULL;
2517
2518 if (direction == PF_OUT) {
2519 r = pf_match_translation(pd, m, off, direction, kif, saddr,
2520 sport, daddr, dport, PF_RULESET_BINAT);
2521 if (r == NULL)
2522 r = pf_match_translation(pd, m, off, direction, kif,
2523 saddr, sport, daddr, dport, PF_RULESET_NAT);
2524 } else {
2525 r = pf_match_translation(pd, m, off, direction, kif, saddr,
2526 sport, daddr, dport, PF_RULESET_RDR);
2527 if (r == NULL)
2528 r = pf_match_translation(pd, m, off, direction, kif,
2529 saddr, sport, daddr, dport, PF_RULESET_BINAT);
2530 }
2531
2532 if (r != NULL) {
2533 switch (r->action) {
2534 case PF_NONAT:
2535 case PF_NOBINAT:
2536 case PF_NORDR:
2537 return (NULL);
2538 case PF_NAT:
2539 if (pf_get_sport(pd->af, pd->proto, r, saddr,
2540 daddr, dport, naddr, nport, r->rpool.proxy_port[0],
2541 r->rpool.proxy_port[1], sn)) {
2542 DPFPRINTF(PF_DEBUG_MISC,
2543 ("pf: NAT proxy port allocation "
2544 "(%u-%u) failed\n",
2545 r->rpool.proxy_port[0],
2546 r->rpool.proxy_port[1]));
2547 return (NULL);
2548 }
2549 break;
2550 case PF_BINAT:
2551 switch (direction) {
2552 case PF_OUT:
2553 if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
2554 switch (pd->af) {
2555#ifdef INET
2556 case AF_INET:
2557 if (r->rpool.cur->addr.p.dyn->
2558 pfid_acnt4 < 1)
2559 return (NULL);
2560 PF_POOLMASK(naddr,
2561 &r->rpool.cur->addr.p.dyn->
2562 pfid_addr4,
2563 &r->rpool.cur->addr.p.dyn->
2564 pfid_mask4,
2565 saddr, AF_INET);
2566 break;
2567#endif /* INET */
2568#ifdef INET6
2569 case AF_INET6:
2570 if (r->rpool.cur->addr.p.dyn->
2571 pfid_acnt6 < 1)
2572 return (NULL);
2573 PF_POOLMASK(naddr,
2574 &r->rpool.cur->addr.p.dyn->
2575 pfid_addr6,
2576 &r->rpool.cur->addr.p.dyn->
2577 pfid_mask6,
2578 saddr, AF_INET6);
2579 break;
2580#endif /* INET6 */
2581 }
2582 } else
2583 PF_POOLMASK(naddr,
2584 &r->rpool.cur->addr.v.a.addr,
2585 &r->rpool.cur->addr.v.a.mask,
2586 saddr, pd->af);
2587 break;
2588 case PF_IN:
2589 if (r->src.addr.type == PF_ADDR_DYNIFTL) {
2590 switch (pd->af) {
2591#ifdef INET
2592 case AF_INET:
2593 if (r->src.addr.p.dyn->
2594 pfid_acnt4 < 1)
2595 return (NULL);
2596 PF_POOLMASK(naddr,
2597 &r->src.addr.p.dyn->
2598 pfid_addr4,
2599 &r->src.addr.p.dyn->
2600 pfid_mask4,
2601 daddr, AF_INET);
2602 break;
2603#endif /* INET */
2604#ifdef INET6
2605 case AF_INET6:
2606 if (r->src.addr.p.dyn->
2607 pfid_acnt6 < 1)
2608 return (NULL);
2609 PF_POOLMASK(naddr,
2610 &r->src.addr.p.dyn->
2611 pfid_addr6,
2612 &r->src.addr.p.dyn->
2613 pfid_mask6,
2614 daddr, AF_INET6);
2615 break;
2616#endif /* INET6 */
2617 }
2618 } else
2619 PF_POOLMASK(naddr,
2620 &r->src.addr.v.a.addr,
2621 &r->src.addr.v.a.mask, daddr,
2622 pd->af);
2623 break;
2624 }
2625 break;
2626 case PF_RDR: {
2627 if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
2628 return (NULL);
2629 if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
2630 PF_POOL_BITMASK)
2631 PF_POOLMASK(naddr, naddr,
2632 &r->rpool.cur->addr.v.a.mask, daddr,
2633 pd->af);
2634
2635 if (r->rpool.proxy_port[1]) {
2636 u_int32_t tmp_nport;
2637
2638 tmp_nport = ((ntohs(dport) -
2639 ntohs(r->dst.port[0])) %
2640 (r->rpool.proxy_port[1] -
2641 r->rpool.proxy_port[0] + 1)) +
2642 r->rpool.proxy_port[0];
2643
2644 /* wrap around if necessary */
2645 if (tmp_nport > 65535)
2646 tmp_nport -= 65535;
2647 *nport = htons((u_int16_t)tmp_nport);
2648 } else if (r->rpool.proxy_port[0])
2649 *nport = htons(r->rpool.proxy_port[0]);
2650 break;
2651 }
2652 default:
2653 return (NULL);
2654 }
2655 }
2656
2657 return (r);
2658}
2659
2660int
2661#ifdef __FreeBSD__
2662pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd,
2663 struct inpcb *inp_arg)
2664#else
2665pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd)
2666#endif
2667{
2668 struct pf_addr *saddr, *daddr;
2669 u_int16_t sport, dport;
2670#ifdef __FreeBSD__
2671 struct inpcbinfo *pi;
2672#else
2673 struct inpcbtable *tb;
2674#endif
2675 struct inpcb *inp;
2676
2677 *uid = UID_MAX;
2678 *gid = GID_MAX;
2679#ifdef __FreeBSD__
2680 if (inp_arg != NULL) {
2681 INP_LOCK_ASSERT(inp_arg);
2682 if (inp_arg->inp_socket) {
2683 *uid = inp_arg->inp_socket->so_cred->cr_uid;
2684 *gid = inp_arg->inp_socket->so_cred->cr_groups[0];
2685 return (1);
2686 } else
2687 return (0);
2688 }
2689#endif
2690 switch (pd->proto) {
2691 case IPPROTO_TCP:
2692 sport = pd->hdr.tcp->th_sport;
2693 dport = pd->hdr.tcp->th_dport;
2694#ifdef __FreeBSD__
2695 pi = &tcbinfo;
2696#else
2697 tb = &tcbtable;
2698#endif
2699 break;
2700 case IPPROTO_UDP:
2701 sport = pd->hdr.udp->uh_sport;
2702 dport = pd->hdr.udp->uh_dport;
2703#ifdef __FreeBSD__
2704 pi = &udbinfo;
2705#else
2706 tb = &udbtable;
2707#endif
2708 break;
2709 default:
2710 return (0);
2711 }
2712 if (direction == PF_IN) {
2713 saddr = pd->src;
2714 daddr = pd->dst;
2715 } else {
2716 u_int16_t p;
2717
2718 p = sport;
2719 sport = dport;
2720 dport = p;
2721 saddr = pd->dst;
2722 daddr = pd->src;
2723 }
2724 switch (pd->af) {
2725#ifdef INET
2726 case AF_INET:
2727#ifdef __FreeBSD__
2728 INP_INFO_RLOCK(pi); /* XXX LOR */
2729 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4,
2730 dport, 0, NULL);
2731 if (inp == NULL) {
2732 inp = in_pcblookup_hash(pi, saddr->v4, sport,
2733 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL);
2734 if(inp == NULL) {
2735 INP_INFO_RUNLOCK(pi);
2736 return (0);
2737 }
2738 }
2739#else
2740 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport);
2741 if (inp == NULL) {
2742 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0);
2743 if (inp == NULL)
2744 return (0);
2745 }
2746#endif
2747 break;
2748#endif /* INET */
2749#ifdef INET6
2750 case AF_INET6:
2751#ifdef __FreeBSD__
2752 INP_INFO_RLOCK(pi);
2753 inp = in6_pcblookup_hash(pi, &saddr->v6, sport,
2754 &daddr->v6, dport, 0, NULL);
2755 if (inp == NULL) {
2756 inp = in6_pcblookup_hash(pi, &saddr->v6, sport,
2757 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL);
2758 if (inp == NULL) {
2759 INP_INFO_RUNLOCK(pi);
2760 return (0);
2761 }
2762 }
2763#else
2764 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6,
2765 dport);
2766 if (inp == NULL) {
2767 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0);
2768 if (inp == NULL)
2769 return (0);
2770 }
2771#endif
2772 break;
2773#endif /* INET6 */
2774
2775 default:
2776 return (0);
2777 }
2778#ifdef __FreeBSD__
2779 INP_LOCK(inp);
2780 if ((inp->inp_socket == NULL) || (inp->inp_socket->so_cred == NULL)) {
2781 INP_UNLOCK(inp);
2782 INP_INFO_RUNLOCK(pi);
2783 return (0);
2784 }
2785 *uid = inp->inp_socket->so_cred->cr_uid;
2786 *gid = inp->inp_socket->so_cred->cr_groups[0];
2787 INP_UNLOCK(inp);
2788 INP_INFO_RUNLOCK(pi);
2789#else
2790 *uid = inp->inp_socket->so_euid;
2791 *gid = inp->inp_socket->so_egid;
2792#endif
2793 return (1);
2794}
2795
2796u_int8_t
2797pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
2798{
2799 int hlen;
2800 u_int8_t hdr[60];
2801 u_int8_t *opt, optlen;
2802 u_int8_t wscale = 0;
2803
2804 hlen = th_off << 2; /* hlen <= sizeof(hdr) */
2805 if (hlen <= sizeof(struct tcphdr))
2806 return (0);
2807 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
2808 return (0);
2809 opt = hdr + sizeof(struct tcphdr);
2810 hlen -= sizeof(struct tcphdr);
2811 while (hlen >= 3) {
2812 switch (*opt) {
2813 case TCPOPT_EOL:
2814 case TCPOPT_NOP:
2815 ++opt;
2816 --hlen;
2817 break;
2818 case TCPOPT_WINDOW:
2819 wscale = opt[2];
2820 if (wscale > TCP_MAX_WINSHIFT)
2821 wscale = TCP_MAX_WINSHIFT;
2822 wscale |= PF_WSCALE_FLAG;
2823 /* FALLTHROUGH */
2824 default:
2825 optlen = opt[1];
2826 if (optlen < 2)
2827 optlen = 2;
2828 hlen -= optlen;
2829 opt += optlen;
2830 break;
2831 }
2832 }
2833 return (wscale);
2834}
2835
2836u_int16_t
2837pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
2838{
2839 int hlen;
2840 u_int8_t hdr[60];
2841 u_int8_t *opt, optlen;
2842 u_int16_t mss = tcp_mssdflt;
2843
2844 hlen = th_off << 2; /* hlen <= sizeof(hdr) */
2845 if (hlen <= sizeof(struct tcphdr))
2846 return (0);
2847 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
2848 return (0);
2849 opt = hdr + sizeof(struct tcphdr);
2850 hlen -= sizeof(struct tcphdr);
2851 while (hlen >= TCPOLEN_MAXSEG) {
2852 switch (*opt) {
2853 case TCPOPT_EOL:
2854 case TCPOPT_NOP:
2855 ++opt;
2856 --hlen;
2857 break;
2858 case TCPOPT_MAXSEG:
2859 bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2);
2860 NTOHS(mss);
2861 /* FALLTHROUGH */
2862 default:
2863 optlen = opt[1];
2864 if (optlen < 2)
2865 optlen = 2;
2866 hlen -= optlen;
2867 opt += optlen;
2868 break;
2869 }
2870 }
2871 return (mss);
2872}
2873
2874u_int16_t
2875pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer)
2876{
2877#ifdef INET
2878 struct sockaddr_in *dst;
2879 struct route ro;
2880#endif /* INET */
2881#ifdef INET6
2882 struct sockaddr_in6 *dst6;
2883 struct route_in6 ro6;
2884#endif /* INET6 */
2885 struct rtentry *rt = NULL;
2886 int hlen = 0; /* make the compiler happy */
2887 u_int16_t mss = tcp_mssdflt;
2888
2889 switch (af) {
2890#ifdef INET
2891 case AF_INET:
2892 hlen = sizeof(struct ip);
2893 bzero(&ro, sizeof(ro));
2894 dst = (struct sockaddr_in *)&ro.ro_dst;
2895 dst->sin_family = AF_INET;
2896 dst->sin_len = sizeof(*dst);
2897 dst->sin_addr = addr->v4;
2898#ifdef __FreeBSD__
2899#ifdef RTF_PRCLONING
2900 rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING));
2901#else /* !RTF_PRCLONING */
2902 rtalloc_ign(&ro, RTF_CLONING);
2903#endif
2904#else /* ! __FreeBSD__ */
2905 rtalloc_noclone(&ro, NO_CLONING);
2906#endif
2907 rt = ro.ro_rt;
2908 break;
2909#endif /* INET */
2910#ifdef INET6
2911 case AF_INET6:
2912 hlen = sizeof(struct ip6_hdr);
2913 bzero(&ro6, sizeof(ro6));
2914 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst;
2915 dst6->sin6_family = AF_INET6;
2916 dst6->sin6_len = sizeof(*dst6);
2917 dst6->sin6_addr = addr->v6;
2918#ifdef __FreeBSD__
2919#ifdef RTF_PRCLONING
2920 rtalloc_ign((struct route *)&ro6,
2921 (RTF_CLONING | RTF_PRCLONING));
2922#else /* !RTF_PRCLONING */
2923 rtalloc_ign((struct route *)&ro6, RTF_CLONING);
2924#endif
2925#else /* ! __FreeBSD__ */
2926 rtalloc_noclone((struct route *)&ro6, NO_CLONING);
2927#endif
2928 rt = ro6.ro_rt;
2929 break;
2930#endif /* INET6 */
2931 }
2932
2933 if (rt && rt->rt_ifp) {
2934 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr);
2935 mss = max(tcp_mssdflt, mss);
2936 RTFREE(rt);
2937 }
2938 mss = min(mss, offer);
2939 mss = max(mss, 64); /* sanity - at least max opt space */
2940 return (mss);
2941}
2942
2943void
2944pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
2945{
2946 struct pf_rule *r = s->rule.ptr;
2947
2948 s->rt_kif = NULL;
2949 if (!r->rt || r->rt == PF_FASTROUTE)
2950 return;
2951 switch (s->af) {
2952#ifdef INET
2953 case AF_INET:
2954 pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL,
2955 &s->nat_src_node);
2956 s->rt_kif = r->rpool.cur->kif;
2957 break;
2958#endif /* INET */
2959#ifdef INET6
2960 case AF_INET6:
2961 pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL,
2962 &s->nat_src_node);
2963 s->rt_kif = r->rpool.cur->kif;
2964 break;
2965#endif /* INET6 */
2966 }
2967}
2968
2969int
2970pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
2971 struct pfi_kif *kif, struct mbuf *m, int off, void *h,
2972#ifdef __FreeBSD__
2973 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
2974 struct ifqueue *ifq, struct inpcb *inp)
2975#else
2976 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
2977 struct ifqueue *ifq)
2978#endif
2979{
2980 struct pf_rule *nr = NULL;
2981 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
2982 struct tcphdr *th = pd->hdr.tcp;
2983 u_int16_t bport, nport = 0;
2984 sa_family_t af = pd->af;
2985 int lookup = -1;
2986 uid_t uid;
2987 gid_t gid;
2988 struct pf_rule *r, *a = NULL;
2989 struct pf_ruleset *ruleset = NULL;
2990 struct pf_src_node *nsn = NULL;
2991 u_short reason;
2992 int rewrite = 0;
2993 struct pf_tag *pftag = NULL;
2994 int tag = -1;
2995 u_int16_t mss = tcp_mssdflt;
2996 int asd = 0;
2997
2998 if (pf_check_congestion(ifq)) {
2999 REASON_SET(&reason, PFRES_CONGEST);
3000 return (PF_DROP);
3001 }
3002
3003 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3004
3005 if (direction == PF_OUT) {
3006 bport = nport = th->th_sport;
3007 /* check outgoing packet for BINAT/NAT */
3008 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
3009 saddr, th->th_sport, daddr, th->th_dport,
3010 &pd->naddr, &nport)) != NULL) {
3011 PF_ACPY(&pd->baddr, saddr, af);
3012 pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
3013 &th->th_sum, &pd->naddr, nport, 0, af);
3014 rewrite++;
3015 if (nr->natpass)
3016 r = NULL;
3017 pd->nat_rule = nr;
3018 }
3019 } else {
3020 bport = nport = th->th_dport;
3021 /* check incoming packet for BINAT/RDR */
3022 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
3023 saddr, th->th_sport, daddr, th->th_dport,
3024 &pd->naddr, &nport)) != NULL) {
3025 PF_ACPY(&pd->baddr, daddr, af);
3026 pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
3027 &th->th_sum, &pd->naddr, nport, 0, af);
3028 rewrite++;
3029 if (nr->natpass)
3030 r = NULL;
3031 pd->nat_rule = nr;
3032 }
3033 }
3034
3035 while (r != NULL) {
3036 r->evaluations++;
3037 if (r->kif != NULL &&
3038 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
3039 r = r->skip[PF_SKIP_IFP].ptr;
3040 else if (r->direction && r->direction != direction)
3041 r = r->skip[PF_SKIP_DIR].ptr;
3042 else if (r->af && r->af != af)
3043 r = r->skip[PF_SKIP_AF].ptr;
3044 else if (r->proto && r->proto != IPPROTO_TCP)
3045 r = r->skip[PF_SKIP_PROTO].ptr;
3046 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg))
3047 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3048 else if (r->src.port_op && !pf_match_port(r->src.port_op,
3049 r->src.port[0], r->src.port[1], th->th_sport))
3050 r = r->skip[PF_SKIP_SRC_PORT].ptr;
3051 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg))
3052 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3053 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
3054 r->dst.port[0], r->dst.port[1], th->th_dport))
3055 r = r->skip[PF_SKIP_DST_PORT].ptr;
3056 else if (r->tos && !(r->tos & pd->tos))
3057 r = TAILQ_NEXT(r, entries);
3058 else if (r->rule_flag & PFRULE_FRAGMENT)
3059 r = TAILQ_NEXT(r, entries);
3060 else if ((r->flagset & th->th_flags) != r->flags)
3061 r = TAILQ_NEXT(r, entries);
3062 else if (r->uid.op && (lookup != -1 || (lookup =
3063#ifdef __FreeBSD__
3064 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
3065#else
3066 pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
3067#endif
3068 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
3069 uid))
3070 r = TAILQ_NEXT(r, entries);
3071 else if (r->gid.op && (lookup != -1 || (lookup =
3072#ifdef __FreeBSD__
3073 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
3074#else
3075 pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
3076#endif
3077 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
3078 gid))
3079 r = TAILQ_NEXT(r, entries);
3080 else if (r->prob && r->prob <= arc4random())
3081 r = TAILQ_NEXT(r, entries);
3082 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
3083 r = TAILQ_NEXT(r, entries);
3084 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
3085 pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint))
3086 r = TAILQ_NEXT(r, entries);
3087 else {
3088 if (r->tag)
3089 tag = r->tag;
3090 if (r->anchor == NULL) {
3091 *rm = r;
3092 *am = a;
3093 *rsm = ruleset;
3094 if ((*rm)->quick)
3095 break;
3096 r = TAILQ_NEXT(r, entries);
3097 } else
3098 pf_step_into_anchor(&asd, &ruleset,
3099 PF_RULESET_FILTER, &r, &a);
3100 }
3101 if (r == NULL)
3102 pf_step_out_of_anchor(&asd, &ruleset,
3103 PF_RULESET_FILTER, &r, &a);
3104 }
3105 r = *rm;
3106 a = *am;
3107 ruleset = *rsm;
3108
3109 REASON_SET(&reason, PFRES_MATCH);
3110
3111 if (r->log) {
3112 if (rewrite)
3113 m_copyback(m, off, sizeof(*th), (caddr_t)th);
3114 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
3115 }
3116
3117 if ((r->action == PF_DROP) &&
3118 ((r->rule_flag & PFRULE_RETURNRST) ||
3119 (r->rule_flag & PFRULE_RETURNICMP) ||
3120 (r->rule_flag & PFRULE_RETURN))) {
3121 /* undo NAT changes, if they have taken place */
3122 if (nr != NULL) {
3123 if (direction == PF_OUT) {
3124 pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
3125 &th->th_sum, &pd->baddr, bport, 0, af);
3126 rewrite++;
3127 } else {
3128 pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
3129 &th->th_sum, &pd->baddr, bport, 0, af);
3130 rewrite++;
3131 }
3132 }
3133 if (((r->rule_flag & PFRULE_RETURNRST) ||
3134 (r->rule_flag & PFRULE_RETURN)) &&
3135 !(th->th_flags & TH_RST)) {
3136 u_int32_t ack = ntohl(th->th_seq) + pd->p_len;
3137
3138 if (th->th_flags & TH_SYN)
3139 ack++;
3140 if (th->th_flags & TH_FIN)
3141 ack++;
3142 pf_send_tcp(r, af, pd->dst,
3143 pd->src, th->th_dport, th->th_sport,
3144 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
3145 r->return_ttl, 1, pd->eh, kif->pfik_ifp);
3146 } else if ((af == AF_INET) && r->return_icmp)
3147 pf_send_icmp(m, r->return_icmp >> 8,
3148 r->return_icmp & 255, af, r);
3149 else if ((af == AF_INET6) && r->return_icmp6)
3150 pf_send_icmp(m, r->return_icmp6 >> 8,
3151 r->return_icmp6 & 255, af, r);
3152 }
3153
3154 if (r->action == PF_DROP)
3155 return (PF_DROP);
3156
3157 if (pf_tag_packet(m, pftag, tag)) {
3158 REASON_SET(&reason, PFRES_MEMORY);
3159 return (PF_DROP);
3160 }
3161
3162 if (r->keep_state || nr != NULL ||
3163 (pd->flags & PFDESC_TCP_NORM)) {
3164 /* create new state */
3165 u_int16_t len;
3166 struct pf_state *s = NULL;
3167 struct pf_src_node *sn = NULL;
3168
3169 len = pd->tot_len - off - (th->th_off << 2);
3170
3171 /* check maximums */
3172 if (r->max_states && (r->states >= r->max_states)) {
3173 pf_status.lcounters[LCNT_STATES]++;
3174 REASON_SET(&reason, PFRES_MAXSTATES);
3175 goto cleanup;
3176 }
3177 /* src node for flter rule */
3178 if ((r->rule_flag & PFRULE_SRCTRACK ||
3179 r->rpool.opts & PF_POOL_STICKYADDR) &&
3180 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3181 REASON_SET(&reason, PFRES_SRCLIMIT);
3182 goto cleanup;
3183 }
3184 /* src node for translation rule */
3185 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
3186 ((direction == PF_OUT &&
3187 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
3188 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
3189 REASON_SET(&reason, PFRES_SRCLIMIT);
3190 goto cleanup;
3191 }
3192 s = pool_get(&pf_state_pl, PR_NOWAIT);
3193 if (s == NULL) {
3194 REASON_SET(&reason, PFRES_MEMORY);
3195cleanup:
3196 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
3197 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
3198 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3199 pf_status.src_nodes--;
3200 pool_put(&pf_src_tree_pl, sn);
3201 }
3202 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
3203 nsn->expire == 0) {
3204 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
3205 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3206 pf_status.src_nodes--;
3207 pool_put(&pf_src_tree_pl, nsn);
3208 }
3209 return (PF_DROP);
3210 }
3211 bzero(s, sizeof(*s));
3212 s->rule.ptr = r;
3213 s->nat_rule.ptr = nr;
3214 s->anchor.ptr = a;
3215 STATE_INC_COUNTERS(s);
3216 s->allow_opts = r->allow_opts;
3217 s->log = r->log & 2;
3218 s->proto = IPPROTO_TCP;
3219 s->direction = direction;
3220 s->af = af;
3221 if (direction == PF_OUT) {
3222 PF_ACPY(&s->gwy.addr, saddr, af);
3223 s->gwy.port = th->th_sport; /* sport */
3224 PF_ACPY(&s->ext.addr, daddr, af);
3225 s->ext.port = th->th_dport;
3226 if (nr != NULL) {
3227 PF_ACPY(&s->lan.addr, &pd->baddr, af);
3228 s->lan.port = bport;
3229 } else {
3230 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
3231 s->lan.port = s->gwy.port;
3232 }
3233 } else {
3234 PF_ACPY(&s->lan.addr, daddr, af);
3235 s->lan.port = th->th_dport;
3236 PF_ACPY(&s->ext.addr, saddr, af);
3237 s->ext.port = th->th_sport;
3238 if (nr != NULL) {
3239 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
3240 s->gwy.port = bport;
3241 } else {
3242 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
3243 s->gwy.port = s->lan.port;
3244 }
3245 }
3246
3247 s->src.seqlo = ntohl(th->th_seq);
3248 s->src.seqhi = s->src.seqlo + len + 1;
3249 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
3250 r->keep_state == PF_STATE_MODULATE) {
3251 /* Generate sequence number modulator */
3252 while ((s->src.seqdiff = htonl(arc4random())) == 0)
3253 ;
3254 pf_change_a(&th->th_seq, &th->th_sum,
3255 htonl(s->src.seqlo + s->src.seqdiff), 0);
3256 rewrite = 1;
3257 } else
3258 s->src.seqdiff = 0;
3259 if (th->th_flags & TH_SYN) {
3260 s->src.seqhi++;
3261 s->src.wscale = pf_get_wscale(m, off, th->th_off, af);
3262 }
3263 s->src.max_win = MAX(ntohs(th->th_win), 1);
3264 if (s->src.wscale & PF_WSCALE_MASK) {
3265 /* Remove scale factor from initial window */
3266 int win = s->src.max_win;
3267 win += 1 << (s->src.wscale & PF_WSCALE_MASK);
3268 s->src.max_win = (win - 1) >>
3269 (s->src.wscale & PF_WSCALE_MASK);
3270 }
3271 if (th->th_flags & TH_FIN)
3272 s->src.seqhi++;
3273 s->dst.seqhi = 1;
3274 s->dst.max_win = 1;
3275 s->src.state = TCPS_SYN_SENT;
3276 s->dst.state = TCPS_CLOSED;
3277 s->creation = time_second;
3278 s->expire = time_second;
3279 s->timeout = PFTM_TCP_FIRST_PACKET;
3280 pf_set_rt_ifp(s, saddr);
3281 if (sn != NULL) {
3282 s->src_node = sn;
3283 s->src_node->states++;
3284 }
3285 if (nsn != NULL) {
3286 PF_ACPY(&nsn->raddr, &pd->naddr, af);
3287 s->nat_src_node = nsn;
3288 s->nat_src_node->states++;
3289 }
3290 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m,
3291 off, pd, th, &s->src, &s->dst)) {
3292 REASON_SET(&reason, PFRES_MEMORY);
3293 pf_src_tree_remove_state(s);
3294 STATE_DEC_COUNTERS(s);
3295 pool_put(&pf_state_pl, s);
3296 return (PF_DROP);
3297 }
3298 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub &&
3299 pf_normalize_tcp_stateful(m, off, pd, &reason, th, s,
3300 &s->src, &s->dst, &rewrite)) {
3301 /* This really shouldn't happen!!! */
3302 DPFPRINTF(PF_DEBUG_URGENT,
3303 ("pf_normalize_tcp_stateful failed on first pkt"));
3304 pf_normalize_tcp_cleanup(s);
3305 pf_src_tree_remove_state(s);
3306 STATE_DEC_COUNTERS(s);
3307 pool_put(&pf_state_pl, s);
3308 return (PF_DROP);
3309 }
3310 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
3311 pf_normalize_tcp_cleanup(s);
3312 REASON_SET(&reason, PFRES_STATEINS);
3313 pf_src_tree_remove_state(s);
3314 STATE_DEC_COUNTERS(s);
3315 pool_put(&pf_state_pl, s);
3316 return (PF_DROP);
3317 } else
3318 *sm = s;
3319 if (tag > 0) {
3320 pf_tag_ref(tag);
3321 s->tag = tag;
3322 }
3323 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
3324 r->keep_state == PF_STATE_SYNPROXY) {
3325 s->src.state = PF_TCPS_PROXY_SRC;
3326 if (nr != NULL) {
3327 if (direction == PF_OUT) {
3328 pf_change_ap(saddr, &th->th_sport,
3329 pd->ip_sum, &th->th_sum, &pd->baddr,
3330 bport, 0, af);
3331 } else {
3332 pf_change_ap(daddr, &th->th_dport,
3333 pd->ip_sum, &th->th_sum, &pd->baddr,
3334 bport, 0, af);
3335 }
3336 }
3337 s->src.seqhi = htonl(arc4random());
3338 /* Find mss option */
3339 mss = pf_get_mss(m, off, th->th_off, af);
3340 mss = pf_calc_mss(saddr, af, mss);
3341 mss = pf_calc_mss(daddr, af, mss);
3342 s->src.mss = mss;
3343 pf_send_tcp(r, af, daddr, saddr, th->th_dport,
3344 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
3345 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, NULL, NULL);
3346 REASON_SET(&reason, PFRES_SYNPROXY);
3347 return (PF_SYNPROXY_DROP);
3348 }
3349 }
3350
3351 /* copy back packet headers if we performed NAT operations */
3352 if (rewrite)
3353 m_copyback(m, off, sizeof(*th), (caddr_t)th);
3354
3355 return (PF_PASS);
3356}
3357
3358int
3359pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
3360 struct pfi_kif *kif, struct mbuf *m, int off, void *h,
3361#ifdef __FreeBSD__
3362 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
3363 struct ifqueue *ifq, struct inpcb *inp)
3364#else
3365 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
3366 struct ifqueue *ifq)
3367#endif
3368{
3369 struct pf_rule *nr = NULL;
3370 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3371 struct udphdr *uh = pd->hdr.udp;
3372 u_int16_t bport, nport = 0;
3373 sa_family_t af = pd->af;
3374 int lookup = -1;
3375 uid_t uid;
3376 gid_t gid;
3377 struct pf_rule *r, *a = NULL;
3378 struct pf_ruleset *ruleset = NULL;
3379 struct pf_src_node *nsn = NULL;
3380 u_short reason;
3381 int rewrite = 0;
3382 struct pf_tag *pftag = NULL;
3383 int tag = -1;
3384 int asd = 0;
3385
3386 if (pf_check_congestion(ifq)) {
3387 REASON_SET(&reason, PFRES_CONGEST);
3388 return (PF_DROP);
3389 }
3390
3391 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3392
3393 if (direction == PF_OUT) {
3394 bport = nport = uh->uh_sport;
3395 /* check outgoing packet for BINAT/NAT */
3396 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
3397 saddr, uh->uh_sport, daddr, uh->uh_dport,
3398 &pd->naddr, &nport)) != NULL) {
3399 PF_ACPY(&pd->baddr, saddr, af);
3400 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum,
3401 &uh->uh_sum, &pd->naddr, nport, 1, af);
3402 rewrite++;
3403 if (nr->natpass)
3404 r = NULL;
3405 pd->nat_rule = nr;
3406 }
3407 } else {
3408 bport = nport = uh->uh_dport;
3409 /* check incoming packet for BINAT/RDR */
3410 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
3411 saddr, uh->uh_sport, daddr, uh->uh_dport, &pd->naddr,
3412 &nport)) != NULL) {
3413 PF_ACPY(&pd->baddr, daddr, af);
3414 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum,
3415 &uh->uh_sum, &pd->naddr, nport, 1, af);
3416 rewrite++;
3417 if (nr->natpass)
3418 r = NULL;
3419 pd->nat_rule = nr;
3420 }
3421 }
3422
3423 while (r != NULL) {
3424 r->evaluations++;
3425 if (r->kif != NULL &&
3426 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
3427 r = r->skip[PF_SKIP_IFP].ptr;
3428 else if (r->direction && r->direction != direction)
3429 r = r->skip[PF_SKIP_DIR].ptr;
3430 else if (r->af && r->af != af)
3431 r = r->skip[PF_SKIP_AF].ptr;
3432 else if (r->proto && r->proto != IPPROTO_UDP)
3433 r = r->skip[PF_SKIP_PROTO].ptr;
3434 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg))
3435 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3436 else if (r->src.port_op && !pf_match_port(r->src.port_op,
3437 r->src.port[0], r->src.port[1], uh->uh_sport))
3438 r = r->skip[PF_SKIP_SRC_PORT].ptr;
3439 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg))
3440 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3441 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
3442 r->dst.port[0], r->dst.port[1], uh->uh_dport))
3443 r = r->skip[PF_SKIP_DST_PORT].ptr;
3444 else if (r->tos && !(r->tos & pd->tos))
3445 r = TAILQ_NEXT(r, entries);
3446 else if (r->rule_flag & PFRULE_FRAGMENT)
3447 r = TAILQ_NEXT(r, entries);
3448 else if (r->uid.op && (lookup != -1 || (lookup =
3449#ifdef __FreeBSD__
3450 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
3451#else
3452 pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
3453#endif
3454 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
3455 uid))
3456 r = TAILQ_NEXT(r, entries);
3457 else if (r->gid.op && (lookup != -1 || (lookup =
3458#ifdef __FreeBSD__
3459 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
3460#else
3461 pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
3462#endif
3463 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
3464 gid))
3465 r = TAILQ_NEXT(r, entries);
3466 else if (r->prob && r->prob <= arc4random())
3467 r = TAILQ_NEXT(r, entries);
3468 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
3469 r = TAILQ_NEXT(r, entries);
3470 else if (r->os_fingerprint != PF_OSFP_ANY)
3471 r = TAILQ_NEXT(r, entries);
3472 else {
3473 if (r->tag)
3474 tag = r->tag;
3475 if (r->anchor == NULL) {
3476 *rm = r;
3477 *am = a;
3478 *rsm = ruleset;
3479 if ((*rm)->quick)
3480 break;
3481 r = TAILQ_NEXT(r, entries);
3482 } else
3483 pf_step_into_anchor(&asd, &ruleset,
3484 PF_RULESET_FILTER, &r, &a);
3485 }
3486 if (r == NULL)
3487 pf_step_out_of_anchor(&asd, &ruleset,
3488 PF_RULESET_FILTER, &r, &a);
3489 }
3490 r = *rm;
3491 a = *am;
3492 ruleset = *rsm;
3493
3494 REASON_SET(&reason, PFRES_MATCH);
3495
3496 if (r->log) {
3497 if (rewrite)
3498 m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
3499 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
3500 }
3501
3502 if ((r->action == PF_DROP) &&
3503 ((r->rule_flag & PFRULE_RETURNICMP) ||
3504 (r->rule_flag & PFRULE_RETURN))) {
3505 /* undo NAT changes, if they have taken place */
3506 if (nr != NULL) {
3507 if (direction == PF_OUT) {
3508 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum,
3509 &uh->uh_sum, &pd->baddr, bport, 1, af);
3510 rewrite++;
3511 } else {
3512 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum,
3513 &uh->uh_sum, &pd->baddr, bport, 1, af);
3514 rewrite++;
3515 }
3516 }
3517 if ((af == AF_INET) && r->return_icmp)
3518 pf_send_icmp(m, r->return_icmp >> 8,
3519 r->return_icmp & 255, af, r);
3520 else if ((af == AF_INET6) && r->return_icmp6)
3521 pf_send_icmp(m, r->return_icmp6 >> 8,
3522 r->return_icmp6 & 255, af, r);
3523 }
3524
3525 if (r->action == PF_DROP)
3526 return (PF_DROP);
3527
3528 if (pf_tag_packet(m, pftag, tag)) {
3529 REASON_SET(&reason, PFRES_MEMORY);
3530 return (PF_DROP);
3531 }
3532
3533 if (r->keep_state || nr != NULL) {
3534 /* create new state */
3535 struct pf_state *s = NULL;
3536 struct pf_src_node *sn = NULL;
3537
3538 /* check maximums */
3539 if (r->max_states && (r->states >= r->max_states)) {
3540 pf_status.lcounters[LCNT_STATES]++;
3541 REASON_SET(&reason, PFRES_MAXSTATES);
3542 goto cleanup;
3543 }
3544 /* src node for flter rule */
3545 if ((r->rule_flag & PFRULE_SRCTRACK ||
3546 r->rpool.opts & PF_POOL_STICKYADDR) &&
3547 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3548 REASON_SET(&reason, PFRES_SRCLIMIT);
3549 goto cleanup;
3550 }
3551 /* src node for translation rule */
3552 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
3553 ((direction == PF_OUT &&
3554 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
3555 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
3556 REASON_SET(&reason, PFRES_SRCLIMIT);
3557 goto cleanup;
3558 }
3559 s = pool_get(&pf_state_pl, PR_NOWAIT);
3560 if (s == NULL) {
3561 REASON_SET(&reason, PFRES_MEMORY);
3562cleanup:
3563 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
3564 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
3565 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3566 pf_status.src_nodes--;
3567 pool_put(&pf_src_tree_pl, sn);
3568 }
3569 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
3570 nsn->expire == 0) {
3571 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
3572 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3573 pf_status.src_nodes--;
3574 pool_put(&pf_src_tree_pl, nsn);
3575 }
3576 return (PF_DROP);
3577 }
3578 bzero(s, sizeof(*s));
3579 s->rule.ptr = r;
3580 s->nat_rule.ptr = nr;
3581 s->anchor.ptr = a;
3582 STATE_INC_COUNTERS(s);
3583 s->allow_opts = r->allow_opts;
3584 s->log = r->log & 2;
3585 s->proto = IPPROTO_UDP;
3586 s->direction = direction;
3587 s->af = af;
3588 if (direction == PF_OUT) {
3589 PF_ACPY(&s->gwy.addr, saddr, af);
3590 s->gwy.port = uh->uh_sport;
3591 PF_ACPY(&s->ext.addr, daddr, af);
3592 s->ext.port = uh->uh_dport;
3593 if (nr != NULL) {
3594 PF_ACPY(&s->lan.addr, &pd->baddr, af);
3595 s->lan.port = bport;
3596 } else {
3597 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
3598 s->lan.port = s->gwy.port;
3599 }
3600 } else {
3601 PF_ACPY(&s->lan.addr, daddr, af);
3602 s->lan.port = uh->uh_dport;
3603 PF_ACPY(&s->ext.addr, saddr, af);
3604 s->ext.port = uh->uh_sport;
3605 if (nr != NULL) {
3606 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
3607 s->gwy.port = bport;
3608 } else {
3609 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
3610 s->gwy.port = s->lan.port;
3611 }
3612 }
3613 s->src.state = PFUDPS_SINGLE;
3614 s->dst.state = PFUDPS_NO_TRAFFIC;
3615 s->creation = time_second;
3616 s->expire = time_second;
3617 s->timeout = PFTM_UDP_FIRST_PACKET;
3618 pf_set_rt_ifp(s, saddr);
3619 if (sn != NULL) {
3620 s->src_node = sn;
3621 s->src_node->states++;
3622 }
3623 if (nsn != NULL) {
3624 PF_ACPY(&nsn->raddr, &pd->naddr, af);
3625 s->nat_src_node = nsn;
3626 s->nat_src_node->states++;
3627 }
3628 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
3629 REASON_SET(&reason, PFRES_STATEINS);
3630 pf_src_tree_remove_state(s);
3631 STATE_DEC_COUNTERS(s);
3632 pool_put(&pf_state_pl, s);
3633 return (PF_DROP);
3634 } else
3635 *sm = s;
3636 if (tag > 0) {
3637 pf_tag_ref(tag);
3638 s->tag = tag;
3639 }
3640 }
3641
3642 /* copy back packet headers if we performed NAT operations */
3643 if (rewrite)
3644 m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
3645
3646 return (PF_PASS);
3647}
3648
3649int
3650pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
3651 struct pfi_kif *kif, struct mbuf *m, int off, void *h,
3652 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
3653 struct ifqueue *ifq)
3654{
3655 struct pf_rule *nr = NULL;
3656 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3657 struct pf_rule *r, *a = NULL;
3658 struct pf_ruleset *ruleset = NULL;
3659 struct pf_src_node *nsn = NULL;
3660 u_short reason;
3661 u_int16_t icmpid = 0, bport, nport = 0;
3662 sa_family_t af = pd->af;
3663 u_int8_t icmptype = 0; /* make the compiler happy */
3664 u_int8_t icmpcode = 0; /* make the compiler happy */
3665 int state_icmp = 0;
3666 struct pf_tag *pftag = NULL;
3667 int tag = -1;
3668#ifdef INET6
3669 int rewrite = 0;
3670#endif /* INET6 */
3671 int asd = 0;
3672
3673 if (pf_check_congestion(ifq)) {
3674 REASON_SET(&reason, PFRES_CONGEST);
3675 return (PF_DROP);
3676 }
3677
3678 switch (pd->proto) {
3679#ifdef INET
3680 case IPPROTO_ICMP:
3681 icmptype = pd->hdr.icmp->icmp_type;
3682 icmpcode = pd->hdr.icmp->icmp_code;
3683 icmpid = pd->hdr.icmp->icmp_id;
3684
3685 if (icmptype == ICMP_UNREACH ||
3686 icmptype == ICMP_SOURCEQUENCH ||
3687 icmptype == ICMP_REDIRECT ||
3688 icmptype == ICMP_TIMXCEED ||
3689 icmptype == ICMP_PARAMPROB)
3690 state_icmp++;
3691 break;
3692#endif /* INET */
3693#ifdef INET6
3694 case IPPROTO_ICMPV6:
3695 icmptype = pd->hdr.icmp6->icmp6_type;
3696 icmpcode = pd->hdr.icmp6->icmp6_code;
3697 icmpid = pd->hdr.icmp6->icmp6_id;
3698
3699 if (icmptype == ICMP6_DST_UNREACH ||
3700 icmptype == ICMP6_PACKET_TOO_BIG ||
3701 icmptype == ICMP6_TIME_EXCEEDED ||
3702 icmptype == ICMP6_PARAM_PROB)
3703 state_icmp++;
3704 break;
3705#endif /* INET6 */
3706 }
3707
3708 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3709
3710 if (direction == PF_OUT) {
3711 bport = nport = icmpid;
3712 /* check outgoing packet for BINAT/NAT */
3713 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
3714 saddr, icmpid, daddr, icmpid, &pd->naddr, &nport)) !=
3715 NULL) {
3716 PF_ACPY(&pd->baddr, saddr, af);
3717 switch (af) {
3718#ifdef INET
3719 case AF_INET:
3720 pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
3721 pd->naddr.v4.s_addr, 0);
3722 pd->hdr.icmp->icmp_cksum = pf_cksum_fixup(
3723 pd->hdr.icmp->icmp_cksum, icmpid, nport, 0);
3724 pd->hdr.icmp->icmp_id = nport;
3725 m_copyback(m, off, ICMP_MINLEN,
3726 (caddr_t)pd->hdr.icmp);
3727 break;
3728#endif /* INET */
3729#ifdef INET6
3730 case AF_INET6:
3731 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum,
3732 &pd->naddr, 0);
3733 rewrite++;
3734 break;
3735#endif /* INET6 */
3736 }
3737 if (nr->natpass)
3738 r = NULL;
3739 pd->nat_rule = nr;
3740 }
3741 } else {
3742 bport = nport = icmpid;
3743 /* check incoming packet for BINAT/RDR */
3744 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
3745 saddr, icmpid, daddr, icmpid, &pd->naddr, &nport)) !=
3746 NULL) {
3747 PF_ACPY(&pd->baddr, daddr, af);
3748 switch (af) {
3749#ifdef INET
3750 case AF_INET:
3751 pf_change_a(&daddr->v4.s_addr,
3752 pd->ip_sum, pd->naddr.v4.s_addr, 0);
3753 break;
3754#endif /* INET */
3755#ifdef INET6
3756 case AF_INET6:
3757 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum,
3758 &pd->naddr, 0);
3759 rewrite++;
3760 break;
3761#endif /* INET6 */
3762 }
3763 if (nr->natpass)
3764 r = NULL;
3765 pd->nat_rule = nr;
3766 }
3767 }
3768
3769 while (r != NULL) {
3770 r->evaluations++;
3771 if (r->kif != NULL &&
3772 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
3773 r = r->skip[PF_SKIP_IFP].ptr;
3774 else if (r->direction && r->direction != direction)
3775 r = r->skip[PF_SKIP_DIR].ptr;
3776 else if (r->af && r->af != af)
3777 r = r->skip[PF_SKIP_AF].ptr;
3778 else if (r->proto && r->proto != pd->proto)
3779 r = r->skip[PF_SKIP_PROTO].ptr;
3780 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg))
3781 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3782 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg))
3783 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3784 else if (r->type && r->type != icmptype + 1)
3785 r = TAILQ_NEXT(r, entries);
3786 else if (r->code && r->code != icmpcode + 1)
3787 r = TAILQ_NEXT(r, entries);
3788 else if (r->tos && !(r->tos & pd->tos))
3789 r = TAILQ_NEXT(r, entries);
3790 else if (r->rule_flag & PFRULE_FRAGMENT)
3791 r = TAILQ_NEXT(r, entries);
3792 else if (r->prob && r->prob <= arc4random())
3793 r = TAILQ_NEXT(r, entries);
3794 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
3795 r = TAILQ_NEXT(r, entries);
3796 else if (r->os_fingerprint != PF_OSFP_ANY)
3797 r = TAILQ_NEXT(r, entries);
3798 else {
3799 if (r->tag)
3800 tag = r->tag;
3801 if (r->anchor == NULL) {
3802 *rm = r;
3803 *am = a;
3804 *rsm = ruleset;
3805 if ((*rm)->quick)
3806 break;
3807 r = TAILQ_NEXT(r, entries);
3808 } else
3809 pf_step_into_anchor(&asd, &ruleset,
3810 PF_RULESET_FILTER, &r, &a);
3811 }
3812 if (r == NULL)
3813 pf_step_out_of_anchor(&asd, &ruleset,
3814 PF_RULESET_FILTER, &r, &a);
3815 }
3816 r = *rm;
3817 a = *am;
3818 ruleset = *rsm;
3819
3820 REASON_SET(&reason, PFRES_MATCH);
3821
3822 if (r->log) {
3823#ifdef INET6
3824 if (rewrite)
3825 m_copyback(m, off, sizeof(struct icmp6_hdr),
3826 (caddr_t)pd->hdr.icmp6);
3827#endif /* INET6 */
3828 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
3829 }
3830
3831 if (r->action != PF_PASS)
3832 return (PF_DROP);
3833
3834 if (pf_tag_packet(m, pftag, tag)) {
3835 REASON_SET(&reason, PFRES_MEMORY);
3836 return (PF_DROP);
3837 }
3838
3839 if (!state_icmp && (r->keep_state || nr != NULL)) {
3840 /* create new state */
3841 struct pf_state *s = NULL;
3842 struct pf_src_node *sn = NULL;
3843
3844 /* check maximums */
3845 if (r->max_states && (r->states >= r->max_states)) {
3846 pf_status.lcounters[LCNT_STATES]++;
3847 REASON_SET(&reason, PFRES_MAXSTATES);
3848 goto cleanup;
3849 }
3850 /* src node for flter rule */
3851 if ((r->rule_flag & PFRULE_SRCTRACK ||
3852 r->rpool.opts & PF_POOL_STICKYADDR) &&
3853 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3854 REASON_SET(&reason, PFRES_SRCLIMIT);
3855 goto cleanup;
3856 }
3857 /* src node for translation rule */
3858 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
3859 ((direction == PF_OUT &&
3860 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
3861 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
3862 REASON_SET(&reason, PFRES_SRCLIMIT);
3863 goto cleanup;
3864 }
3865 s = pool_get(&pf_state_pl, PR_NOWAIT);
3866 if (s == NULL) {
3867 REASON_SET(&reason, PFRES_MEMORY);
3868cleanup:
3869 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
3870 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
3871 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3872 pf_status.src_nodes--;
3873 pool_put(&pf_src_tree_pl, sn);
3874 }
3875 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
3876 nsn->expire == 0) {
3877 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
3878 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3879 pf_status.src_nodes--;
3880 pool_put(&pf_src_tree_pl, nsn);
3881 }
3882 return (PF_DROP);
3883 }
3884 bzero(s, sizeof(*s));
3885 s->rule.ptr = r;
3886 s->nat_rule.ptr = nr;
3887 s->anchor.ptr = a;
3888 STATE_INC_COUNTERS(s);
3889 s->allow_opts = r->allow_opts;
3890 s->log = r->log & 2;
3891 s->proto = pd->proto;
3892 s->direction = direction;
3893 s->af = af;
3894 if (direction == PF_OUT) {
3895 PF_ACPY(&s->gwy.addr, saddr, af);
3896 s->gwy.port = nport;
3897 PF_ACPY(&s->ext.addr, daddr, af);
3898 s->ext.port = 0;
3899 if (nr != NULL) {
3900 PF_ACPY(&s->lan.addr, &pd->baddr, af);
3901 s->lan.port = bport;
3902 } else {
3903 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
3904 s->lan.port = s->gwy.port;
3905 }
3906 } else {
3907 PF_ACPY(&s->lan.addr, daddr, af);
3908 s->lan.port = nport;
3909 PF_ACPY(&s->ext.addr, saddr, af);
3910 s->ext.port = 0;
3911 if (nr != NULL) {
3912 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
3913 s->gwy.port = bport;
3914 } else {
3915 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
3916 s->gwy.port = s->lan.port;
3917 }
3918 }
3919 s->creation = time_second;
3920 s->expire = time_second;
3921 s->timeout = PFTM_ICMP_FIRST_PACKET;
3922 pf_set_rt_ifp(s, saddr);
3923 if (sn != NULL) {
3924 s->src_node = sn;
3925 s->src_node->states++;
3926 }
3927 if (nsn != NULL) {
3928 PF_ACPY(&nsn->raddr, &pd->naddr, af);
3929 s->nat_src_node = nsn;
3930 s->nat_src_node->states++;
3931 }
3932 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
3933 REASON_SET(&reason, PFRES_STATEINS);
3934 pf_src_tree_remove_state(s);
3935 STATE_DEC_COUNTERS(s);
3936 pool_put(&pf_state_pl, s);
3937 return (PF_DROP);
3938 } else
3939 *sm = s;
3940 if (tag > 0) {
3941 pf_tag_ref(tag);
3942 s->tag = tag;
3943 }
3944 }
3945
3946#ifdef INET6
3947 /* copy back packet headers if we performed IPv6 NAT operations */
3948 if (rewrite)
3949 m_copyback(m, off, sizeof(struct icmp6_hdr),
3950 (caddr_t)pd->hdr.icmp6);
3951#endif /* INET6 */
3952
3953 return (PF_PASS);
3954}
3955
3956int
3957pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction,
3958 struct pfi_kif *kif, struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
3959 struct pf_rule **am, struct pf_ruleset **rsm, struct ifqueue *ifq)
3960{
3961 struct pf_rule *nr = NULL;
3962 struct pf_rule *r, *a = NULL;
3963 struct pf_ruleset *ruleset = NULL;
3964 struct pf_src_node *nsn = NULL;
3965 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3966 sa_family_t af = pd->af;
3967 u_short reason;
3968 struct pf_tag *pftag = NULL;
3969 int tag = -1;
3970 int asd = 0;
3971
3972 if (pf_check_congestion(ifq)) {
3973 REASON_SET(&reason, PFRES_CONGEST);
3974 return (PF_DROP);
3975 }
3976
3977 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3978
3979 if (direction == PF_OUT) {
3980 /* check outgoing packet for BINAT/NAT */
3981 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
3982 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) {
3983 PF_ACPY(&pd->baddr, saddr, af);
3984 switch (af) {
3985#ifdef INET
3986 case AF_INET:
3987 pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
3988 pd->naddr.v4.s_addr, 0);
3989 break;
3990#endif /* INET */
3991#ifdef INET6
3992 case AF_INET6:
3993 PF_ACPY(saddr, &pd->naddr, af);
3994 break;
3995#endif /* INET6 */
3996 }
3997 if (nr->natpass)
3998 r = NULL;
3999 pd->nat_rule = nr;
4000 }
4001 } else {
4002 /* check incoming packet for BINAT/RDR */
4003 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
4004 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) {
4005 PF_ACPY(&pd->baddr, daddr, af);
4006 switch (af) {
4007#ifdef INET
4008 case AF_INET:
4009 pf_change_a(&daddr->v4.s_addr,
4010 pd->ip_sum, pd->naddr.v4.s_addr, 0);
4011 break;
4012#endif /* INET */
4013#ifdef INET6
4014 case AF_INET6:
4015 PF_ACPY(daddr, &pd->naddr, af);
4016 break;
4017#endif /* INET6 */
4018 }
4019 if (nr->natpass)
4020 r = NULL;
4021 pd->nat_rule = nr;
4022 }
4023 }
4024
4025 while (r != NULL) {
4026 r->evaluations++;
4027 if (r->kif != NULL &&
4028 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
4029 r = r->skip[PF_SKIP_IFP].ptr;
4030 else if (r->direction && r->direction != direction)
4031 r = r->skip[PF_SKIP_DIR].ptr;
4032 else if (r->af && r->af != af)
4033 r = r->skip[PF_SKIP_AF].ptr;
4034 else if (r->proto && r->proto != pd->proto)
4035 r = r->skip[PF_SKIP_PROTO].ptr;
4036 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.neg))
4037 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
4038 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.neg))
4039 r = r->skip[PF_SKIP_DST_ADDR].ptr;
4040 else if (r->tos && !(r->tos & pd->tos))
4041 r = TAILQ_NEXT(r, entries);
4042 else if (r->rule_flag & PFRULE_FRAGMENT)
4043 r = TAILQ_NEXT(r, entries);
4044 else if (r->prob && r->prob <= arc4random())
4045 r = TAILQ_NEXT(r, entries);
4046 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
4047 r = TAILQ_NEXT(r, entries);
4048 else if (r->os_fingerprint != PF_OSFP_ANY)
4049 r = TAILQ_NEXT(r, entries);
4050 else {
4051 if (r->tag)
4052 tag = r->tag;
4053 if (r->anchor == NULL) {
4054 *rm = r;
4055 *am = a;
4056 *rsm = ruleset;
4057 if ((*rm)->quick)
4058 break;
4059 r = TAILQ_NEXT(r, entries);
4060 } else
4061 pf_step_into_anchor(&asd, &ruleset,
4062 PF_RULESET_FILTER, &r, &a);
4063 }
4064 if (r == NULL)
4065 pf_step_out_of_anchor(&asd, &ruleset,
4066 PF_RULESET_FILTER, &r, &a);
4067 }
4068 r = *rm;
4069 a = *am;
4070 ruleset = *rsm;
4071
4072 REASON_SET(&reason, PFRES_MATCH);
4073
4074 if (r->log)
4075 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
4076
4077 if ((r->action == PF_DROP) &&
4078 ((r->rule_flag & PFRULE_RETURNICMP) ||
4079 (r->rule_flag & PFRULE_RETURN))) {
4080 struct pf_addr *a = NULL;
4081
4082 if (nr != NULL) {
4083 if (direction == PF_OUT)
4084 a = saddr;
4085 else
4086 a = daddr;
4087 }
4088 if (a != NULL) {
4089 switch (af) {
4090#ifdef INET
4091 case AF_INET:
4092 pf_change_a(&a->v4.s_addr, pd->ip_sum,
4093 pd->baddr.v4.s_addr, 0);
4094 break;
4095#endif /* INET */
4096#ifdef INET6
4097 case AF_INET6:
4098 PF_ACPY(a, &pd->baddr, af);
4099 break;
4100#endif /* INET6 */
4101 }
4102 }
4103 if ((af == AF_INET) && r->return_icmp)
4104 pf_send_icmp(m, r->return_icmp >> 8,
4105 r->return_icmp & 255, af, r);
4106 else if ((af == AF_INET6) && r->return_icmp6)
4107 pf_send_icmp(m, r->return_icmp6 >> 8,
4108 r->return_icmp6 & 255, af, r);
4109 }
4110
4111 if (r->action != PF_PASS)
4112 return (PF_DROP);
4113
4114 if (pf_tag_packet(m, pftag, tag)) {
4115 REASON_SET(&reason, PFRES_MEMORY);
4116 return (PF_DROP);
4117 }
4118
4119 if (r->keep_state || nr != NULL) {
4120 /* create new state */
4121 struct pf_state *s = NULL;
4122 struct pf_src_node *sn = NULL;
4123
4124 /* check maximums */
4125 if (r->max_states && (r->states >= r->max_states)) {
4126 pf_status.lcounters[LCNT_STATES]++;
4127 REASON_SET(&reason, PFRES_MAXSTATES);
4128 goto cleanup;
4129 }
4130 /* src node for flter rule */
4131 if ((r->rule_flag & PFRULE_SRCTRACK ||
4132 r->rpool.opts & PF_POOL_STICKYADDR) &&
4133 pf_insert_src_node(&sn, r, saddr, af) != 0) {
4134 REASON_SET(&reason, PFRES_SRCLIMIT);
4135 goto cleanup;
4136 }
4137 /* src node for translation rule */
4138 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
4139 ((direction == PF_OUT &&
4140 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
4141 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
4142 REASON_SET(&reason, PFRES_SRCLIMIT);
4143 goto cleanup;
4144 }
4145 s = pool_get(&pf_state_pl, PR_NOWAIT);
4146 if (s == NULL) {
4147 REASON_SET(&reason, PFRES_MEMORY);
4148cleanup:
4149 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
4150 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
4151 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
4152 pf_status.src_nodes--;
4153 pool_put(&pf_src_tree_pl, sn);
4154 }
4155 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
4156 nsn->expire == 0) {
4157 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
4158 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
4159 pf_status.src_nodes--;
4160 pool_put(&pf_src_tree_pl, nsn);
4161 }
4162 return (PF_DROP);
4163 }
4164 bzero(s, sizeof(*s));
4165 s->rule.ptr = r;
4166 s->nat_rule.ptr = nr;
4167 s->anchor.ptr = a;
4168 STATE_INC_COUNTERS(s);
4169 s->allow_opts = r->allow_opts;
4170 s->log = r->log & 2;
4171 s->proto = pd->proto;
4172 s->direction = direction;
4173 s->af = af;
4174 if (direction == PF_OUT) {
4175 PF_ACPY(&s->gwy.addr, saddr, af);
4176 PF_ACPY(&s->ext.addr, daddr, af);
4177 if (nr != NULL)
4178 PF_ACPY(&s->lan.addr, &pd->baddr, af);
4179 else
4180 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
4181 } else {
4182 PF_ACPY(&s->lan.addr, daddr, af);
4183 PF_ACPY(&s->ext.addr, saddr, af);
4184 if (nr != NULL)
4185 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
4186 else
4187 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
4188 }
4189 s->src.state = PFOTHERS_SINGLE;
4190 s->dst.state = PFOTHERS_NO_TRAFFIC;
4191 s->creation = time_second;
4192 s->expire = time_second;
4193 s->timeout = PFTM_OTHER_FIRST_PACKET;
4194 pf_set_rt_ifp(s, saddr);
4195 if (sn != NULL) {
4196 s->src_node = sn;
4197 s->src_node->states++;
4198 }
4199 if (nsn != NULL) {
4200 PF_ACPY(&nsn->raddr, &pd->naddr, af);
4201 s->nat_src_node = nsn;
4202 s->nat_src_node->states++;
4203 }
4204 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
4205 REASON_SET(&reason, PFRES_STATEINS);
4206 pf_src_tree_remove_state(s);
4207 STATE_DEC_COUNTERS(s);
4208 pool_put(&pf_state_pl, s);
4209 return (PF_DROP);
4210 } else
4211 *sm = s;
4212 if (tag > 0) {
4213 pf_tag_ref(tag);
4214 s->tag = tag;
4215 }
4216 }
4217
4218 return (PF_PASS);
4219}
4220
4221int
4222pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
4223 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am,
4224 struct pf_ruleset **rsm)
4225{
4226 struct pf_rule *r, *a = NULL;
4227 struct pf_ruleset *ruleset = NULL;
4228 sa_family_t af = pd->af;
4229 u_short reason;
4230 struct pf_tag *pftag = NULL;
4231 int tag = -1;
4232 int asd = 0;
4233
4234 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
4235 while (r != NULL) {
4236 r->evaluations++;
4237 if (r->kif != NULL &&
4238 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
4239 r = r->skip[PF_SKIP_IFP].ptr;
4240 else if (r->direction && r->direction != direction)
4241 r = r->skip[PF_SKIP_DIR].ptr;
4242 else if (r->af && r->af != af)
4243 r = r->skip[PF_SKIP_AF].ptr;
4244 else if (r->proto && r->proto != pd->proto)
4245 r = r->skip[PF_SKIP_PROTO].ptr;
4246 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.neg))
4247 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
4248 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.neg))
4249 r = r->skip[PF_SKIP_DST_ADDR].ptr;
4250 else if (r->tos && !(r->tos & pd->tos))
4251 r = TAILQ_NEXT(r, entries);
4252 else if (r->src.port_op || r->dst.port_op ||
4253 r->flagset || r->type || r->code ||
4254 r->os_fingerprint != PF_OSFP_ANY)
4255 r = TAILQ_NEXT(r, entries);
4256 else if (r->prob && r->prob <= arc4random())
4257 r = TAILQ_NEXT(r, entries);
4258 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
4259 r = TAILQ_NEXT(r, entries);
4260 else {
4261 if (r->anchor == NULL) {
4262 *rm = r;
4263 *am = a;
4264 *rsm = ruleset;
4265 if ((*rm)->quick)
4266 break;
4267 r = TAILQ_NEXT(r, entries);
4268 } else
4269 pf_step_into_anchor(&asd, &ruleset,
4270 PF_RULESET_FILTER, &r, &a);
4271 }
4272 if (r == NULL)
4273 pf_step_out_of_anchor(&asd, &ruleset,
4274 PF_RULESET_FILTER, &r, &a);
4275 }
4276 r = *rm;
4277 a = *am;
4278 ruleset = *rsm;
4279
4280 REASON_SET(&reason, PFRES_MATCH);
4281
4282 if (r->log)
4283 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
4284
4285 if (r->action != PF_PASS)
4286 return (PF_DROP);
4287
4288 if (pf_tag_packet(m, pftag, tag)) {
4289 REASON_SET(&reason, PFRES_MEMORY);
4290 return (PF_DROP);
4291 }
4292
4293 return (PF_PASS);
4294}
4295
4296int
4297pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
4298 struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
4299 u_short *reason)
4300{
4301 struct pf_state key;
4302 struct tcphdr *th = pd->hdr.tcp;
4303 u_int16_t win = ntohs(th->th_win);
4304 u_int32_t ack, end, seq, orig_seq;
4305 u_int8_t sws, dws;
4306 int ackskew;
4307 int copyback = 0;
4308 struct pf_state_peer *src, *dst;
4309
4310 key.af = pd->af;
4311 key.proto = IPPROTO_TCP;
4312 if (direction == PF_IN) {
4313 PF_ACPY(&key.ext.addr, pd->src, key.af);
4314 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4315 key.ext.port = th->th_sport;
4316 key.gwy.port = th->th_dport;
4317 } else {
4318 PF_ACPY(&key.lan.addr, pd->src, key.af);
4319 PF_ACPY(&key.ext.addr, pd->dst, key.af);
4320 key.lan.port = th->th_sport;
4321 key.ext.port = th->th_dport;
4322 }
4323
4324 STATE_LOOKUP();
4325
4326 if (direction == (*state)->direction) {
4327 src = &(*state)->src;
4328 dst = &(*state)->dst;
4329 } else {
4330 src = &(*state)->dst;
4331 dst = &(*state)->src;
4332 }
4333
4334 if ((*state)->src.state == PF_TCPS_PROXY_SRC) {
4335 if (direction != (*state)->direction) {
4336 REASON_SET(reason, PFRES_SYNPROXY);
4337 return (PF_SYNPROXY_DROP);
4338 }
4339 if (th->th_flags & TH_SYN) {
4340 if (ntohl(th->th_seq) != (*state)->src.seqlo) {
4341 REASON_SET(reason, PFRES_SYNPROXY);
4342 return (PF_DROP);
4343 }
4344 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
4345 pd->src, th->th_dport, th->th_sport,
4346 (*state)->src.seqhi, ntohl(th->th_seq) + 1,
4347 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1,
4348 NULL, NULL);
4349 REASON_SET(reason, PFRES_SYNPROXY);
4350 return (PF_SYNPROXY_DROP);
4351 } else if (!(th->th_flags & TH_ACK) ||
4352 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
4353 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
4354 REASON_SET(reason, PFRES_SYNPROXY);
4355 return (PF_DROP);
4356 } else if ((*state)->src_node != NULL &&
4357 pf_src_connlimit(state)) {
4358 REASON_SET(reason, PFRES_SRCLIMIT);
4359 return (PF_DROP);
4360 } else
4361 (*state)->src.state = PF_TCPS_PROXY_DST;
4362 }
4363 if ((*state)->src.state == PF_TCPS_PROXY_DST) {
4364 struct pf_state_host *src, *dst;
4365
4366 if (direction == PF_OUT) {
4367 src = &(*state)->gwy;
4368 dst = &(*state)->ext;
4369 } else {
4370 src = &(*state)->ext;
4371 dst = &(*state)->lan;
4372 }
4373 if (direction == (*state)->direction) {
4374 if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) ||
4375 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
4376 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
4377 REASON_SET(reason, PFRES_SYNPROXY);
4378 return (PF_DROP);
4379 }
4380 (*state)->src.max_win = MAX(ntohs(th->th_win), 1);
4381 if ((*state)->dst.seqhi == 1)
4382 (*state)->dst.seqhi = htonl(arc4random());
4383 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
4384 &dst->addr, src->port, dst->port,
4385 (*state)->dst.seqhi, 0, TH_SYN, 0,
4386 (*state)->src.mss, 0, 0, NULL, NULL);
4387 REASON_SET(reason, PFRES_SYNPROXY);
4388 return (PF_SYNPROXY_DROP);
4389 } else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
4390 (TH_SYN|TH_ACK)) ||
4391 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) {
4392 REASON_SET(reason, PFRES_SYNPROXY);
4393 return (PF_DROP);
4394 } else {
4395 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1);
4396 (*state)->dst.seqlo = ntohl(th->th_seq);
4397 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
4398 pd->src, th->th_dport, th->th_sport,
4399 ntohl(th->th_ack), ntohl(th->th_seq) + 1,
4400 TH_ACK, (*state)->src.max_win, 0, 0, 0,
4401 NULL, NULL);
4402 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
4403 &dst->addr, src->port, dst->port,
4404 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
4405 TH_ACK, (*state)->dst.max_win, 0, 0, 1,
4406 NULL, NULL);
4407 (*state)->src.seqdiff = (*state)->dst.seqhi -
4408 (*state)->src.seqlo;
4409 (*state)->dst.seqdiff = (*state)->src.seqhi -
4410 (*state)->dst.seqlo;
4411 (*state)->src.seqhi = (*state)->src.seqlo +
4412 (*state)->dst.max_win;
4413 (*state)->dst.seqhi = (*state)->dst.seqlo +
4414 (*state)->src.max_win;
4415 (*state)->src.wscale = (*state)->dst.wscale = 0;
4416 (*state)->src.state = (*state)->dst.state =
4417 TCPS_ESTABLISHED;
4418 REASON_SET(reason, PFRES_SYNPROXY);
4419 return (PF_SYNPROXY_DROP);
4420 }
4421 }
4422
4423 if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
4424 sws = src->wscale & PF_WSCALE_MASK;
4425 dws = dst->wscale & PF_WSCALE_MASK;
4426 } else
4427 sws = dws = 0;
4428
4429 /*
4430 * Sequence tracking algorithm from Guido van Rooij's paper:
4431 * http://www.madison-gurkha.com/publications/tcp_filtering/
4432 * tcp_filtering.ps
4433 */
4434
4435 orig_seq = seq = ntohl(th->th_seq);
4436 if (src->seqlo == 0) {
4437 /* First packet from this end. Set its state */
4438
4439 if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) &&
4440 src->scrub == NULL) {
4441 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) {
4442 REASON_SET(reason, PFRES_MEMORY);
4443 return (PF_DROP);
4444 }
4445 }
4446
4447 /* Deferred generation of sequence number modulator */
4448 if (dst->seqdiff && !src->seqdiff) {
4449 while ((src->seqdiff = htonl(arc4random())) == 0)
4450 ;
4451 ack = ntohl(th->th_ack) - dst->seqdiff;
4452 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
4453 src->seqdiff), 0);
4454 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
4455 copyback = 1;
4456 } else {
4457 ack = ntohl(th->th_ack);
4458 }
4459
4460 end = seq + pd->p_len;
4461 if (th->th_flags & TH_SYN) {
4462 end++;
4463 if (dst->wscale & PF_WSCALE_FLAG) {
4464 src->wscale = pf_get_wscale(m, off, th->th_off,
4465 pd->af);
4466 if (src->wscale & PF_WSCALE_FLAG) {
4467 /* Remove scale factor from initial
4468 * window */
4469 sws = src->wscale & PF_WSCALE_MASK;
4470 win = ((u_int32_t)win + (1 << sws) - 1)
4471 >> sws;
4472 dws = dst->wscale & PF_WSCALE_MASK;
4473 } else {
4474 /* fixup other window */
4475 dst->max_win <<= dst->wscale &
4476 PF_WSCALE_MASK;
4477 /* in case of a retrans SYN|ACK */
4478 dst->wscale = 0;
4479 }
4480 }
4481 }
4482 if (th->th_flags & TH_FIN)
4483 end++;
4484
4485 src->seqlo = seq;
4486 if (src->state < TCPS_SYN_SENT)
4487 src->state = TCPS_SYN_SENT;
4488
4489 /*
4490 * May need to slide the window (seqhi may have been set by
4491 * the crappy stack check or if we picked up the connection
4492 * after establishment)
4493 */
4494 if (src->seqhi == 1 ||
4495 SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi))
4496 src->seqhi = end + MAX(1, dst->max_win << dws);
4497 if (win > src->max_win)
4498 src->max_win = win;
4499
4500 } else {
4501 ack = ntohl(th->th_ack) - dst->seqdiff;
4502 if (src->seqdiff) {
4503 /* Modulate sequence numbers */
4504 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
4505 src->seqdiff), 0);
4506 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
4507 copyback = 1;
4508 }
4509 end = seq + pd->p_len;
4510 if (th->th_flags & TH_SYN)
4511 end++;
4512 if (th->th_flags & TH_FIN)
4513 end++;
4514 }
4515
4516 if ((th->th_flags & TH_ACK) == 0) {
4517 /* Let it pass through the ack skew check */
4518 ack = dst->seqlo;
4519 } else if ((ack == 0 &&
4520 (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) ||
4521 /* broken tcp stacks do not set ack */
4522 (dst->state < TCPS_SYN_SENT)) {
4523 /*
4524 * Many stacks (ours included) will set the ACK number in an
4525 * FIN|ACK if the SYN times out -- no sequence to ACK.
4526 */
4527 ack = dst->seqlo;
4528 }
4529
4530 if (seq == end) {
4531 /* Ease sequencing restrictions on no data packets */
4532 seq = src->seqlo;
4533 end = seq;
4534 }
4535
4536 ackskew = dst->seqlo - ack;
4537
4538#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */
4539 if (SEQ_GEQ(src->seqhi, end) &&
4540 /* Last octet inside other's window space */
4541 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
4542 /* Retrans: not more than one window back */
4543 (ackskew >= -MAXACKWINDOW) &&
4544 /* Acking not more than one reassembled fragment backwards */
4545 (ackskew <= (MAXACKWINDOW << sws)) &&
4546 /* Acking not more than one window forward */
4547 ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
4548 (pd->flags & PFDESC_IP_REAS) == 0)) {
4549 /* Require an exact sequence match on resets when possible */
4550
4551 if (dst->scrub || src->scrub) {
4552 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
4553 *state, src, dst, &copyback))
4554 return (PF_DROP);
4555 }
4556
4557 /* update max window */
4558 if (src->max_win < win)
4559 src->max_win = win;
4560 /* synchronize sequencing */
4561 if (SEQ_GT(end, src->seqlo))
4562 src->seqlo = end;
4563 /* slide the window of what the other end can send */
4564 if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
4565 dst->seqhi = ack + MAX((win << sws), 1);
4566
4567
4568 /* update states */
4569 if (th->th_flags & TH_SYN)
4570 if (src->state < TCPS_SYN_SENT)
4571 src->state = TCPS_SYN_SENT;
4572 if (th->th_flags & TH_FIN)
4573 if (src->state < TCPS_CLOSING)
4574 src->state = TCPS_CLOSING;
4575 if (th->th_flags & TH_ACK) {
4576 if (dst->state == TCPS_SYN_SENT) {
4577 dst->state = TCPS_ESTABLISHED;
4578 if (src->state == TCPS_ESTABLISHED &&
4579 (*state)->src_node != NULL &&
4580 pf_src_connlimit(state)) {
4581 REASON_SET(reason, PFRES_SRCLIMIT);
4582 return (PF_DROP);
4583 }
4584 } else if (dst->state == TCPS_CLOSING)
4585 dst->state = TCPS_FIN_WAIT_2;
4586 }
4587 if (th->th_flags & TH_RST)
4588 src->state = dst->state = TCPS_TIME_WAIT;
4589
4590 /* update expire time */
4591 (*state)->expire = time_second;
4592 if (src->state >= TCPS_FIN_WAIT_2 &&
4593 dst->state >= TCPS_FIN_WAIT_2)
4594 (*state)->timeout = PFTM_TCP_CLOSED;
4595 else if (src->state >= TCPS_FIN_WAIT_2 ||
4596 dst->state >= TCPS_FIN_WAIT_2)
4597 (*state)->timeout = PFTM_TCP_FIN_WAIT;
4598 else if (src->state < TCPS_ESTABLISHED ||
4599 dst->state < TCPS_ESTABLISHED)
4600 (*state)->timeout = PFTM_TCP_OPENING;
4601 else if (src->state >= TCPS_CLOSING ||
4602 dst->state >= TCPS_CLOSING)
4603 (*state)->timeout = PFTM_TCP_CLOSING;
4604 else
4605 (*state)->timeout = PFTM_TCP_ESTABLISHED;
4606
4607 /* Fall through to PASS packet */
4608
4609 } else if ((dst->state < TCPS_SYN_SENT ||
4610 dst->state >= TCPS_FIN_WAIT_2 ||
4611 src->state >= TCPS_FIN_WAIT_2) &&
4612 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) &&
4613 /* Within a window forward of the originating packet */
4614 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) {
4615 /* Within a window backward of the originating packet */
4616
4617 /*
4618 * This currently handles three situations:
4619 * 1) Stupid stacks will shotgun SYNs before their peer
4620 * replies.
4621 * 2) When PF catches an already established stream (the
4622 * firewall rebooted, the state table was flushed, routes
4623 * changed...)
4624 * 3) Packets get funky immediately after the connection
4625 * closes (this should catch Solaris spurious ACK|FINs
4626 * that web servers like to spew after a close)
4627 *
4628 * This must be a little more careful than the above code
4629 * since packet floods will also be caught here. We don't
4630 * update the TTL here to mitigate the damage of a packet
4631 * flood and so the same code can handle awkward establishment
4632 * and a loosened connection close.
4633 * In the establishment case, a correct peer response will
4634 * validate the connection, go through the normal state code
4635 * and keep updating the state TTL.
4636 */
4637
4638 if (pf_status.debug >= PF_DEBUG_MISC) {
4639 printf("pf: loose state match: ");
4640 pf_print_state(*state);
4641 pf_print_flags(th->th_flags);
4642 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d\n",
4643 seq, ack, pd->p_len, ackskew,
4644 (*state)->packets[0], (*state)->packets[1]);
4645 }
4646
4647 if (dst->scrub || src->scrub) {
4648 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
4649 *state, src, dst, &copyback))
4650 return (PF_DROP);
4651 }
4652
4653 /* update max window */
4654 if (src->max_win < win)
4655 src->max_win = win;
4656 /* synchronize sequencing */
4657 if (SEQ_GT(end, src->seqlo))
4658 src->seqlo = end;
4659 /* slide the window of what the other end can send */
4660 if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
4661 dst->seqhi = ack + MAX((win << sws), 1);
4662
4663 /*
4664 * Cannot set dst->seqhi here since this could be a shotgunned
4665 * SYN and not an already established connection.
4666 */
4667
4668 if (th->th_flags & TH_FIN)
4669 if (src->state < TCPS_CLOSING)
4670 src->state = TCPS_CLOSING;
4671 if (th->th_flags & TH_RST)
4672 src->state = dst->state = TCPS_TIME_WAIT;
4673
4674 /* Fall through to PASS packet */
4675
4676 } else {
4677 if ((*state)->dst.state == TCPS_SYN_SENT &&
4678 (*state)->src.state == TCPS_SYN_SENT) {
4679 /* Send RST for state mismatches during handshake */
4680 if (!(th->th_flags & TH_RST))
4681 pf_send_tcp((*state)->rule.ptr, pd->af,
4682 pd->dst, pd->src, th->th_dport,
4683 th->th_sport, ntohl(th->th_ack), 0,
4684 TH_RST, 0, 0,
4685 (*state)->rule.ptr->return_ttl, 1,
4686 pd->eh, kif->pfik_ifp);
4687 src->seqlo = 0;
4688 src->seqhi = 1;
4689 src->max_win = 1;
4690 } else if (pf_status.debug >= PF_DEBUG_MISC) {
4691 printf("pf: BAD state: ");
4692 pf_print_state(*state);
4693 pf_print_flags(th->th_flags);
4694 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d "
4695 "dir=%s,%s\n", seq, ack, pd->p_len, ackskew,
4696 (*state)->packets[0], (*state)->packets[1],
4697 direction == PF_IN ? "in" : "out",
4698 direction == (*state)->direction ? "fwd" : "rev");
4699 printf("pf: State failure on: %c %c %c %c | %c %c\n",
4700 SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
4701 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
4702 ' ': '2',
4703 (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
4704 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',
4705 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5',
4706 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6');
4707 }
4708 REASON_SET(reason, PFRES_BADSTATE);
4709 return (PF_DROP);
4710 }
4711
4712 /* Any packets which have gotten here are to be passed */
4713
4714 /* translate source/destination address, if necessary */
4715 if (STATE_TRANSLATE(*state)) {
4716 if (direction == PF_OUT)
4717 pf_change_ap(pd->src, &th->th_sport, pd->ip_sum,
4718 &th->th_sum, &(*state)->gwy.addr,
4719 (*state)->gwy.port, 0, pd->af);
4720 else
4721 pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum,
4722 &th->th_sum, &(*state)->lan.addr,
4723 (*state)->lan.port, 0, pd->af);
4724 m_copyback(m, off, sizeof(*th), (caddr_t)th);
4725 } else if (copyback) {
4726 /* Copyback sequence modulation or stateful scrub changes */
4727 m_copyback(m, off, sizeof(*th), (caddr_t)th);
4728 }
4729
4730 return (PF_PASS);
4731}
4732
4733int
4734pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
4735 struct mbuf *m, int off, void *h, struct pf_pdesc *pd)
4736{
4737 struct pf_state_peer *src, *dst;
4738 struct pf_state key;
4739 struct udphdr *uh = pd->hdr.udp;
4740
4741 key.af = pd->af;
4742 key.proto = IPPROTO_UDP;
4743 if (direction == PF_IN) {
4744 PF_ACPY(&key.ext.addr, pd->src, key.af);
4745 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4746 key.ext.port = uh->uh_sport;
4747 key.gwy.port = uh->uh_dport;
4748 } else {
4749 PF_ACPY(&key.lan.addr, pd->src, key.af);
4750 PF_ACPY(&key.ext.addr, pd->dst, key.af);
4751 key.lan.port = uh->uh_sport;
4752 key.ext.port = uh->uh_dport;
4753 }
4754
4755 STATE_LOOKUP();
4756
4757 if (direction == (*state)->direction) {
4758 src = &(*state)->src;
4759 dst = &(*state)->dst;
4760 } else {
4761 src = &(*state)->dst;
4762 dst = &(*state)->src;
4763 }
4764
4765 /* update states */
4766 if (src->state < PFUDPS_SINGLE)
4767 src->state = PFUDPS_SINGLE;
4768 if (dst->state == PFUDPS_SINGLE)
4769 dst->state = PFUDPS_MULTIPLE;
4770
4771 /* update expire time */
4772 (*state)->expire = time_second;
4773 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE)
4774 (*state)->timeout = PFTM_UDP_MULTIPLE;
4775 else
4776 (*state)->timeout = PFTM_UDP_SINGLE;
4777
4778 /* translate source/destination address, if necessary */
4779 if (STATE_TRANSLATE(*state)) {
4780 if (direction == PF_OUT)
4781 pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum,
4782 &uh->uh_sum, &(*state)->gwy.addr,
4783 (*state)->gwy.port, 1, pd->af);
4784 else
4785 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum,
4786 &uh->uh_sum, &(*state)->lan.addr,
4787 (*state)->lan.port, 1, pd->af);
4788 m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
4789 }
4790
4791 return (PF_PASS);
4792}
4793
4794int
4795pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
4796 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason)
4797{
4798 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
4799 u_int16_t icmpid = 0; /* make the compiler happy */
4800 u_int16_t *icmpsum = NULL; /* make the compiler happy */
4801 u_int8_t icmptype = 0; /* make the compiler happy */
4802 int state_icmp = 0;
4803
4804 switch (pd->proto) {
4805#ifdef INET
4806 case IPPROTO_ICMP:
4807 icmptype = pd->hdr.icmp->icmp_type;
4808 icmpid = pd->hdr.icmp->icmp_id;
4809 icmpsum = &pd->hdr.icmp->icmp_cksum;
4810
4811 if (icmptype == ICMP_UNREACH ||
4812 icmptype == ICMP_SOURCEQUENCH ||
4813 icmptype == ICMP_REDIRECT ||
4814 icmptype == ICMP_TIMXCEED ||
4815 icmptype == ICMP_PARAMPROB)
4816 state_icmp++;
4817 break;
4818#endif /* INET */
4819#ifdef INET6
4820 case IPPROTO_ICMPV6:
4821 icmptype = pd->hdr.icmp6->icmp6_type;
4822 icmpid = pd->hdr.icmp6->icmp6_id;
4823 icmpsum = &pd->hdr.icmp6->icmp6_cksum;
4824
4825 if (icmptype == ICMP6_DST_UNREACH ||
4826 icmptype == ICMP6_PACKET_TOO_BIG ||
4827 icmptype == ICMP6_TIME_EXCEEDED ||
4828 icmptype == ICMP6_PARAM_PROB)
4829 state_icmp++;
4830 break;
4831#endif /* INET6 */
4832 }
4833
4834 if (!state_icmp) {
4835
4836 /*
4837 * ICMP query/reply message not related to a TCP/UDP packet.
4838 * Search for an ICMP state.
4839 */
4840 struct pf_state key;
4841
4842 key.af = pd->af;
4843 key.proto = pd->proto;
4844 if (direction == PF_IN) {
4845 PF_ACPY(&key.ext.addr, pd->src, key.af);
4846 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4847 key.ext.port = 0;
4848 key.gwy.port = icmpid;
4849 } else {
4850 PF_ACPY(&key.lan.addr, pd->src, key.af);
4851 PF_ACPY(&key.ext.addr, pd->dst, key.af);
4852 key.lan.port = icmpid;
4853 key.ext.port = 0;
4854 }
4855
4856 STATE_LOOKUP();
4857
4858 (*state)->expire = time_second;
4859 (*state)->timeout = PFTM_ICMP_ERROR_REPLY;
4860
4861 /* translate source/destination address, if necessary */
4862 if (STATE_TRANSLATE(*state)) {
4863 if (direction == PF_OUT) {
4864 switch (pd->af) {
4865#ifdef INET
4866 case AF_INET:
4867 pf_change_a(&saddr->v4.s_addr,
4868 pd->ip_sum,
4869 (*state)->gwy.addr.v4.s_addr, 0);
4870 pd->hdr.icmp->icmp_cksum =
4871 pf_cksum_fixup(
4872 pd->hdr.icmp->icmp_cksum, icmpid,
4873 (*state)->gwy.port, 0);
4874 pd->hdr.icmp->icmp_id =
4875 (*state)->gwy.port;
4876 m_copyback(m, off, ICMP_MINLEN,
4877 (caddr_t)pd->hdr.icmp);
4878 break;
4879#endif /* INET */
4880#ifdef INET6
4881 case AF_INET6:
4882 pf_change_a6(saddr,
4883 &pd->hdr.icmp6->icmp6_cksum,
4884 &(*state)->gwy.addr, 0);
4885 m_copyback(m, off,
4886 sizeof(struct icmp6_hdr),
4887 (caddr_t)pd->hdr.icmp6);
4888 break;
4889#endif /* INET6 */
4890 }
4891 } else {
4892 switch (pd->af) {
4893#ifdef INET
4894 case AF_INET:
4895 pf_change_a(&daddr->v4.s_addr,
4896 pd->ip_sum,
4897 (*state)->lan.addr.v4.s_addr, 0);
4898 pd->hdr.icmp->icmp_cksum =
4899 pf_cksum_fixup(
4900 pd->hdr.icmp->icmp_cksum, icmpid,
4901 (*state)->lan.port, 0);
4902 pd->hdr.icmp->icmp_id =
4903 (*state)->lan.port;
4904 m_copyback(m, off, ICMP_MINLEN,
4905 (caddr_t)pd->hdr.icmp);
4906 break;
4907#endif /* INET */
4908#ifdef INET6
4909 case AF_INET6:
4910 pf_change_a6(daddr,
4911 &pd->hdr.icmp6->icmp6_cksum,
4912 &(*state)->lan.addr, 0);
4913 m_copyback(m, off,
4914 sizeof(struct icmp6_hdr),
4915 (caddr_t)pd->hdr.icmp6);
4916 break;
4917#endif /* INET6 */
4918 }
4919 }
4920 }
4921
4922 return (PF_PASS);
4923
4924 } else {
4925 /*
4926 * ICMP error message in response to a TCP/UDP packet.
4927 * Extract the inner TCP/UDP header and search for that state.
4928 */
4929
4930 struct pf_pdesc pd2;
4931#ifdef INET
4932 struct ip h2;
4933#endif /* INET */
4934#ifdef INET6
4935 struct ip6_hdr h2_6;
4936 int terminal = 0;
4937#endif /* INET6 */
4938 int ipoff2 = 0; /* make the compiler happy */
4939 int off2 = 0; /* make the compiler happy */
4940
4941 pd2.af = pd->af;
4942 switch (pd->af) {
4943#ifdef INET
4944 case AF_INET:
4945 /* offset of h2 in mbuf chain */
4946 ipoff2 = off + ICMP_MINLEN;
4947
4948 if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2),
4949 NULL, reason, pd2.af)) {
4950 DPFPRINTF(PF_DEBUG_MISC,
4951 ("pf: ICMP error message too short "
4952 "(ip)\n"));
4953 return (PF_DROP);
4954 }
4955 /*
4956 * ICMP error messages don't refer to non-first
4957 * fragments
4958 */
4959 if (h2.ip_off & htons(IP_OFFMASK)) {
4960 REASON_SET(reason, PFRES_FRAG);
4961 return (PF_DROP);
4962 }
4963
4964 /* offset of protocol header that follows h2 */
4965 off2 = ipoff2 + (h2.ip_hl << 2);
4966
4967 pd2.proto = h2.ip_p;
4968 pd2.src = (struct pf_addr *)&h2.ip_src;
4969 pd2.dst = (struct pf_addr *)&h2.ip_dst;
4970 pd2.ip_sum = &h2.ip_sum;
4971 break;
4972#endif /* INET */
4973#ifdef INET6
4974 case AF_INET6:
4975 ipoff2 = off + sizeof(struct icmp6_hdr);
4976
4977 if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6),
4978 NULL, reason, pd2.af)) {
4979 DPFPRINTF(PF_DEBUG_MISC,
4980 ("pf: ICMP error message too short "
4981 "(ip6)\n"));
4982 return (PF_DROP);
4983 }
4984 pd2.proto = h2_6.ip6_nxt;
4985 pd2.src = (struct pf_addr *)&h2_6.ip6_src;
4986 pd2.dst = (struct pf_addr *)&h2_6.ip6_dst;
4987 pd2.ip_sum = NULL;
4988 off2 = ipoff2 + sizeof(h2_6);
4989 do {
4990 switch (pd2.proto) {
4991 case IPPROTO_FRAGMENT:
4992 /*
4993 * ICMPv6 error messages for
4994 * non-first fragments
4995 */
4996 REASON_SET(reason, PFRES_FRAG);
4997 return (PF_DROP);
4998 case IPPROTO_AH:
4999 case IPPROTO_HOPOPTS:
5000 case IPPROTO_ROUTING:
5001 case IPPROTO_DSTOPTS: {
5002 /* get next header and header length */
5003 struct ip6_ext opt6;
5004
5005 if (!pf_pull_hdr(m, off2, &opt6,
5006 sizeof(opt6), NULL, reason,
5007 pd2.af)) {
5008 DPFPRINTF(PF_DEBUG_MISC,
5009 ("pf: ICMPv6 short opt\n"));
5010 return (PF_DROP);
5011 }
5012 if (pd2.proto == IPPROTO_AH)
5013 off2 += (opt6.ip6e_len + 2) * 4;
5014 else
5015 off2 += (opt6.ip6e_len + 1) * 8;
5016 pd2.proto = opt6.ip6e_nxt;
5017 /* goto the next header */
5018 break;
5019 }
5020 default:
5021 terminal++;
5022 break;
5023 }
5024 } while (!terminal);
5025 break;
5026#endif /* INET6 */
5027 }
5028
5029 switch (pd2.proto) {
5030 case IPPROTO_TCP: {
5031 struct tcphdr th;
5032 u_int32_t seq;
5033 struct pf_state key;
5034 struct pf_state_peer *src, *dst;
5035 u_int8_t dws;
5036 int copyback = 0;
5037
5038 /*
5039 * Only the first 8 bytes of the TCP header can be
5040 * expected. Don't access any TCP header fields after
5041 * th_seq, an ackskew test is not possible.
5042 */
5043 if (!pf_pull_hdr(m, off2, &th, 8, NULL, reason,
5044 pd2.af)) {
5045 DPFPRINTF(PF_DEBUG_MISC,
5046 ("pf: ICMP error message too short "
5047 "(tcp)\n"));
5048 return (PF_DROP);
5049 }
5050
5051 key.af = pd2.af;
5052 key.proto = IPPROTO_TCP;
5053 if (direction == PF_IN) {
5054 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
5055 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
5056 key.ext.port = th.th_dport;
5057 key.gwy.port = th.th_sport;
5058 } else {
5059 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
5060 PF_ACPY(&key.ext.addr, pd2.src, key.af);
5061 key.lan.port = th.th_dport;
5062 key.ext.port = th.th_sport;
5063 }
5064
5065 STATE_LOOKUP();
5066
5067 if (direction == (*state)->direction) {
5068 src = &(*state)->dst;
5069 dst = &(*state)->src;
5070 } else {
5071 src = &(*state)->src;
5072 dst = &(*state)->dst;
5073 }
5074
5075 if (src->wscale && dst->wscale &&
5076 !(th.th_flags & TH_SYN))
5077 dws = dst->wscale & PF_WSCALE_MASK;
5078 else
5079 dws = 0;
5080
5081 /* Demodulate sequence number */
5082 seq = ntohl(th.th_seq) - src->seqdiff;
5083 if (src->seqdiff) {
5084 pf_change_a(&th.th_seq, icmpsum,
5085 htonl(seq), 0);
5086 copyback = 1;
5087 }
5088
5089 if (!SEQ_GEQ(src->seqhi, seq) ||
5090 !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws))) {
5091 if (pf_status.debug >= PF_DEBUG_MISC) {
5092 printf("pf: BAD ICMP %d:%d ",
5093 icmptype, pd->hdr.icmp->icmp_code);
5094 pf_print_host(pd->src, 0, pd->af);
5095 printf(" -> ");
5096 pf_print_host(pd->dst, 0, pd->af);
5097 printf(" state: ");
5098 pf_print_state(*state);
5099 printf(" seq=%u\n", seq);
5100 }
5101 REASON_SET(reason, PFRES_BADSTATE);
5102 return (PF_DROP);
5103 }
5104
5105 if (STATE_TRANSLATE(*state)) {
5106 if (direction == PF_IN) {
5107 pf_change_icmp(pd2.src, &th.th_sport,
5108 daddr, &(*state)->lan.addr,
5109 (*state)->lan.port, NULL,
5110 pd2.ip_sum, icmpsum,
5111 pd->ip_sum, 0, pd2.af);
5112 } else {
5113 pf_change_icmp(pd2.dst, &th.th_dport,
5114 saddr, &(*state)->gwy.addr,
5115 (*state)->gwy.port, NULL,
5116 pd2.ip_sum, icmpsum,
5117 pd->ip_sum, 0, pd2.af);
5118 }
5119 copyback = 1;
5120 }
5121
5122 if (copyback) {
5123 switch (pd2.af) {
5124#ifdef INET
5125 case AF_INET:
5126 m_copyback(m, off, ICMP_MINLEN,
5127 (caddr_t)pd->hdr.icmp);
5128 m_copyback(m, ipoff2, sizeof(h2),
5129 (caddr_t)&h2);
5130 break;
5131#endif /* INET */
5132#ifdef INET6
5133 case AF_INET6:
5134 m_copyback(m, off,
5135 sizeof(struct icmp6_hdr),
5136 (caddr_t)pd->hdr.icmp6);
5137 m_copyback(m, ipoff2, sizeof(h2_6),
5138 (caddr_t)&h2_6);
5139 break;
5140#endif /* INET6 */
5141 }
5142 m_copyback(m, off2, 8, (caddr_t)&th);
5143 }
5144
5145 return (PF_PASS);
5146 break;
5147 }
5148 case IPPROTO_UDP: {
5149 struct udphdr uh;
5150 struct pf_state key;
5151
5152 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh),
5153 NULL, reason, pd2.af)) {
5154 DPFPRINTF(PF_DEBUG_MISC,
5155 ("pf: ICMP error message too short "
5156 "(udp)\n"));
5157 return (PF_DROP);
5158 }
5159
5160 key.af = pd2.af;
5161 key.proto = IPPROTO_UDP;
5162 if (direction == PF_IN) {
5163 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
5164 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
5165 key.ext.port = uh.uh_dport;
5166 key.gwy.port = uh.uh_sport;
5167 } else {
5168 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
5169 PF_ACPY(&key.ext.addr, pd2.src, key.af);
5170 key.lan.port = uh.uh_dport;
5171 key.ext.port = uh.uh_sport;
5172 }
5173
5174 STATE_LOOKUP();
5175
5176 if (STATE_TRANSLATE(*state)) {
5177 if (direction == PF_IN) {
5178 pf_change_icmp(pd2.src, &uh.uh_sport,
5179 daddr, &(*state)->lan.addr,
5180 (*state)->lan.port, &uh.uh_sum,
5181 pd2.ip_sum, icmpsum,
5182 pd->ip_sum, 1, pd2.af);
5183 } else {
5184 pf_change_icmp(pd2.dst, &uh.uh_dport,
5185 saddr, &(*state)->gwy.addr,
5186 (*state)->gwy.port, &uh.uh_sum,
5187 pd2.ip_sum, icmpsum,
5188 pd->ip_sum, 1, pd2.af);
5189 }
5190 switch (pd2.af) {
5191#ifdef INET
5192 case AF_INET:
5193 m_copyback(m, off, ICMP_MINLEN,
5194 (caddr_t)pd->hdr.icmp);
5195 m_copyback(m, ipoff2, sizeof(h2),
5196 (caddr_t)&h2);
5197 break;
5198#endif /* INET */
5199#ifdef INET6
5200 case AF_INET6:
5201 m_copyback(m, off,
5202 sizeof(struct icmp6_hdr),
5203 (caddr_t)pd->hdr.icmp6);
5204 m_copyback(m, ipoff2, sizeof(h2_6),
5205 (caddr_t)&h2_6);
5206 break;
5207#endif /* INET6 */
5208 }
5209 m_copyback(m, off2, sizeof(uh),
5210 (caddr_t)&uh);
5211 }
5212
5213 return (PF_PASS);
5214 break;
5215 }
5216#ifdef INET
5217 case IPPROTO_ICMP: {
5218 struct icmp iih;
5219 struct pf_state key;
5220
5221 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN,
5222 NULL, reason, pd2.af)) {
5223 DPFPRINTF(PF_DEBUG_MISC,
5224 ("pf: ICMP error message too short i"
5225 "(icmp)\n"));
5226 return (PF_DROP);
5227 }
5228
5229 key.af = pd2.af;
5230 key.proto = IPPROTO_ICMP;
5231 if (direction == PF_IN) {
5232 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
5233 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
5234 key.ext.port = 0;
5235 key.gwy.port = iih.icmp_id;
5236 } else {
5237 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
5238 PF_ACPY(&key.ext.addr, pd2.src, key.af);
5239 key.lan.port = iih.icmp_id;
5240 key.ext.port = 0;
5241 }
5242
5243 STATE_LOOKUP();
5244
5245 if (STATE_TRANSLATE(*state)) {
5246 if (direction == PF_IN) {
5247 pf_change_icmp(pd2.src, &iih.icmp_id,
5248 daddr, &(*state)->lan.addr,
5249 (*state)->lan.port, NULL,
5250 pd2.ip_sum, icmpsum,
5251 pd->ip_sum, 0, AF_INET);
5252 } else {
5253 pf_change_icmp(pd2.dst, &iih.icmp_id,
5254 saddr, &(*state)->gwy.addr,
5255 (*state)->gwy.port, NULL,
5256 pd2.ip_sum, icmpsum,
5257 pd->ip_sum, 0, AF_INET);
5258 }
5259 m_copyback(m, off, ICMP_MINLEN,
5260 (caddr_t)pd->hdr.icmp);
5261 m_copyback(m, ipoff2, sizeof(h2),
5262 (caddr_t)&h2);
5263 m_copyback(m, off2, ICMP_MINLEN,
5264 (caddr_t)&iih);
5265 }
5266
5267 return (PF_PASS);
5268 break;
5269 }
5270#endif /* INET */
5271#ifdef INET6
5272 case IPPROTO_ICMPV6: {
5273 struct icmp6_hdr iih;
5274 struct pf_state key;
5275
5276 if (!pf_pull_hdr(m, off2, &iih,
5277 sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
5278 DPFPRINTF(PF_DEBUG_MISC,
5279 ("pf: ICMP error message too short "
5280 "(icmp6)\n"));
5281 return (PF_DROP);
5282 }
5283
5284 key.af = pd2.af;
5285 key.proto = IPPROTO_ICMPV6;
5286 if (direction == PF_IN) {
5287 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
5288 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
5289 key.ext.port = 0;
5290 key.gwy.port = iih.icmp6_id;
5291 } else {
5292 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
5293 PF_ACPY(&key.ext.addr, pd2.src, key.af);
5294 key.lan.port = iih.icmp6_id;
5295 key.ext.port = 0;
5296 }
5297
5298 STATE_LOOKUP();
5299
5300 if (STATE_TRANSLATE(*state)) {
5301 if (direction == PF_IN) {
5302 pf_change_icmp(pd2.src, &iih.icmp6_id,
5303 daddr, &(*state)->lan.addr,
5304 (*state)->lan.port, NULL,
5305 pd2.ip_sum, icmpsum,
5306 pd->ip_sum, 0, AF_INET6);
5307 } else {
5308 pf_change_icmp(pd2.dst, &iih.icmp6_id,
5309 saddr, &(*state)->gwy.addr,
5310 (*state)->gwy.port, NULL,
5311 pd2.ip_sum, icmpsum,
5312 pd->ip_sum, 0, AF_INET6);
5313 }
5314 m_copyback(m, off, sizeof(struct icmp6_hdr),
5315 (caddr_t)pd->hdr.icmp6);
5316 m_copyback(m, ipoff2, sizeof(h2_6),
5317 (caddr_t)&h2_6);
5318 m_copyback(m, off2, sizeof(struct icmp6_hdr),
5319 (caddr_t)&iih);
5320 }
5321
5322 return (PF_PASS);
5323 break;
5324 }
5325#endif /* INET6 */
5326 default: {
5327 struct pf_state key;
5328
5329 key.af = pd2.af;
5330 key.proto = pd2.proto;
5331 if (direction == PF_IN) {
5332 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
5333 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
5334 key.ext.port = 0;
5335 key.gwy.port = 0;
5336 } else {
5337 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
5338 PF_ACPY(&key.ext.addr, pd2.src, key.af);
5339 key.lan.port = 0;
5340 key.ext.port = 0;
5341 }
5342
5343 STATE_LOOKUP();
5344
5345 if (STATE_TRANSLATE(*state)) {
5346 if (direction == PF_IN) {
5347 pf_change_icmp(pd2.src, NULL,
5348 daddr, &(*state)->lan.addr,
5349 0, NULL,
5350 pd2.ip_sum, icmpsum,
5351 pd->ip_sum, 0, pd2.af);
5352 } else {
5353 pf_change_icmp(pd2.dst, NULL,
5354 saddr, &(*state)->gwy.addr,
5355 0, NULL,
5356 pd2.ip_sum, icmpsum,
5357 pd->ip_sum, 0, pd2.af);
5358 }
5359 switch (pd2.af) {
5360#ifdef INET
5361 case AF_INET:
5362 m_copyback(m, off, ICMP_MINLEN,
5363 (caddr_t)pd->hdr.icmp);
5364 m_copyback(m, ipoff2, sizeof(h2),
5365 (caddr_t)&h2);
5366 break;
5367#endif /* INET */
5368#ifdef INET6
5369 case AF_INET6:
5370 m_copyback(m, off,
5371 sizeof(struct icmp6_hdr),
5372 (caddr_t)pd->hdr.icmp6);
5373 m_copyback(m, ipoff2, sizeof(h2_6),
5374 (caddr_t)&h2_6);
5375 break;
5376#endif /* INET6 */
5377 }
5378 }
5379
5380 return (PF_PASS);
5381 break;
5382 }
5383 }
5384 }
5385}
5386
5387int
5388pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
5389 struct pf_pdesc *pd)
5390{
5391 struct pf_state_peer *src, *dst;
5392 struct pf_state key;
5393
5394 key.af = pd->af;
5395 key.proto = pd->proto;
5396 if (direction == PF_IN) {
5397 PF_ACPY(&key.ext.addr, pd->src, key.af);
5398 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
5399 key.ext.port = 0;
5400 key.gwy.port = 0;
5401 } else {
5402 PF_ACPY(&key.lan.addr, pd->src, key.af);
5403 PF_ACPY(&key.ext.addr, pd->dst, key.af);
5404 key.lan.port = 0;
5405 key.ext.port = 0;
5406 }
5407
5408 STATE_LOOKUP();
5409
5410 if (direction == (*state)->direction) {
5411 src = &(*state)->src;
5412 dst = &(*state)->dst;
5413 } else {
5414 src = &(*state)->dst;
5415 dst = &(*state)->src;
5416 }
5417
5418 /* update states */
5419 if (src->state < PFOTHERS_SINGLE)
5420 src->state = PFOTHERS_SINGLE;
5421 if (dst->state == PFOTHERS_SINGLE)
5422 dst->state = PFOTHERS_MULTIPLE;
5423
5424 /* update expire time */
5425 (*state)->expire = time_second;
5426 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE)
5427 (*state)->timeout = PFTM_OTHER_MULTIPLE;
5428 else
5429 (*state)->timeout = PFTM_OTHER_SINGLE;
5430
5431 /* translate source/destination address, if necessary */
5432 if (STATE_TRANSLATE(*state)) {
5433 if (direction == PF_OUT)
5434 switch (pd->af) {
5435#ifdef INET
5436 case AF_INET:
5437 pf_change_a(&pd->src->v4.s_addr,
5438 pd->ip_sum, (*state)->gwy.addr.v4.s_addr,
5439 0);
5440 break;
5441#endif /* INET */
5442#ifdef INET6
5443 case AF_INET6:
5444 PF_ACPY(pd->src, &(*state)->gwy.addr, pd->af);
5445 break;
5446#endif /* INET6 */
5447 }
5448 else
5449 switch (pd->af) {
5450#ifdef INET
5451 case AF_INET:
5452 pf_change_a(&pd->dst->v4.s_addr,
5453 pd->ip_sum, (*state)->lan.addr.v4.s_addr,
5454 0);
5455 break;
5456#endif /* INET */
5457#ifdef INET6
5458 case AF_INET6:
5459 PF_ACPY(pd->dst, &(*state)->lan.addr, pd->af);
5460 break;
5461#endif /* INET6 */
5462 }
5463 }
5464
5465 return (PF_PASS);
5466}
5467
5468/*
5469 * ipoff and off are measured from the start of the mbuf chain.
5470 * h must be at "ipoff" on the mbuf chain.
5471 */
5472void *
5473pf_pull_hdr(struct mbuf *m, int off, void *p, int len,
5474 u_short *actionp, u_short *reasonp, sa_family_t af)
5475{
5476 switch (af) {
5477#ifdef INET
5478 case AF_INET: {
5479 struct ip *h = mtod(m, struct ip *);
5480 u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
5481
5482 if (fragoff) {
5483 if (fragoff >= len)
5484 ACTION_SET(actionp, PF_PASS);
5485 else {
5486 ACTION_SET(actionp, PF_DROP);
5487 REASON_SET(reasonp, PFRES_FRAG);
5488 }
5489 return (NULL);
5490 }
5491 if (m->m_pkthdr.len < off + len ||
5492 ntohs(h->ip_len) < off + len) {
5493 ACTION_SET(actionp, PF_DROP);
5494 REASON_SET(reasonp, PFRES_SHORT);
5495 return (NULL);
5496 }
5497 break;
5498 }
5499#endif /* INET */
5500#ifdef INET6
5501 case AF_INET6: {
5502 struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
5503
5504 if (m->m_pkthdr.len < off + len ||
5505 (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) <
5506 (unsigned)(off + len)) {
5507 ACTION_SET(actionp, PF_DROP);
5508 REASON_SET(reasonp, PFRES_SHORT);
5509 return (NULL);
5510 }
5511 break;
5512 }
5513#endif /* INET6 */
5514 }
5515 m_copydata(m, off, len, p);
5516 return (p);
5517}
5518
5519int
5520pf_routable(struct pf_addr *addr, sa_family_t af)
5521{
5522 struct sockaddr_in *dst;
5523#ifdef INET6
5524 struct sockaddr_in6 *dst6;
5525 struct route_in6 ro;
5526#else
5527 struct route ro;
5528#endif
5529
5530 bzero(&ro, sizeof(ro));
5531 switch (af) {
5532 case AF_INET:
5533 dst = satosin(&ro.ro_dst);
5534 dst->sin_family = AF_INET;
5535 dst->sin_len = sizeof(*dst);
5536 dst->sin_addr = addr->v4;
5537 break;
5538#ifdef INET6
5539 case AF_INET6:
5540 dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
5541 dst6->sin6_family = AF_INET6;
5542 dst6->sin6_len = sizeof(*dst6);
5543 dst6->sin6_addr = addr->v6;
5544 break;
5545#endif /* INET6 */
5546 default:
5547 return (0);
5548 }
5549
5550#ifdef __FreeBSD__
5551#ifdef RTF_PRCLONING
5552 rtalloc_ign((struct route *)&ro, (RTF_CLONING | RTF_PRCLONING));
5553#else /* !RTF_PRCLONING */
5554 rtalloc_ign((struct route *)&ro, RTF_CLONING);
5555#endif
5556#else /* ! __FreeBSD__ */
5557 rtalloc_noclone((struct route *)&ro, NO_CLONING);
5558#endif
5559
5560 if (ro.ro_rt != NULL) {
5561 RTFREE(ro.ro_rt);
5562 return (1);
5563 }
5564
5565 return (0);
5566}
5567
5568int
5569pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw)
5570{
5571 struct sockaddr_in *dst;
5572#ifdef INET6
5573 struct sockaddr_in6 *dst6;
5574 struct route_in6 ro;
5575#else
5576 struct route ro;
5577#endif
5578 int ret = 0;
5579
5580 bzero(&ro, sizeof(ro));
5581 switch (af) {
5582 case AF_INET:
5583 dst = satosin(&ro.ro_dst);
5584 dst->sin_family = AF_INET;
5585 dst->sin_len = sizeof(*dst);
5586 dst->sin_addr = addr->v4;
5587 break;
5588#ifdef INET6
5589 case AF_INET6:
5590 dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
5591 dst6->sin6_family = AF_INET6;
5592 dst6->sin6_len = sizeof(*dst6);
5593 dst6->sin6_addr = addr->v6;
5594 break;
5595#endif /* INET6 */
5596 default:
5597 return (0);
5598 }
5599
5600#ifdef __FreeBSD__
5601# ifdef RTF_PRCLONING
5602 rtalloc_ign((struct route *)&ro, (RTF_CLONING|RTF_PRCLONING));
5603# else /* !RTF_PRCLONING */
5604 rtalloc_ign((struct route *)&ro, RTF_CLONING);
5605# endif
5606#else /* ! __FreeBSD__ */
5607 rtalloc_noclone((struct route *)&ro, NO_CLONING);
5608#endif
5609
5610 if (ro.ro_rt != NULL) {
5611#ifdef __FreeBSD__
5612 /* XXX_IMPORT: later */
5613#else
5614 if (ro.ro_rt->rt_labelid == aw->v.rtlabel)
5615 ret = 1;
5616#endif
5617 RTFREE(ro.ro_rt);
5618 }
5619
5620 return (ret);
5621}
5622
5623#ifdef INET
5624
5625void
5626pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
5627 struct pf_state *s)
5628{
5629 struct mbuf *m0, *m1;
5630 struct m_tag *mtag;
5631 struct route iproute;
5632 struct route *ro = NULL; /* XXX: was uninitialized */
5633 struct sockaddr_in *dst;
5634 struct ip *ip;
5635 struct ifnet *ifp = NULL;
5636 struct pf_addr naddr;
5637 struct pf_src_node *sn = NULL;
5638 int error = 0;
5639#ifdef __FreeBSD__
5640 int sw_csum;
5641#endif
5642
5643 if (m == NULL || *m == NULL || r == NULL ||
5644 (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
5645 panic("pf_route: invalid parameters");
5646
5647 if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) {
5648 if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) ==
5649 NULL) {
5650 m0 = *m;
5651 *m = NULL;
5652 goto bad;
5653 }
5654 *(char *)(mtag + 1) = 1;
5655 m_tag_prepend(*m, mtag);
5656 } else {
5657 if (*(char *)(mtag + 1) > 3) {
5658 m0 = *m;
5659 *m = NULL;
5660 goto bad;
5661 }
5662 (*(char *)(mtag + 1))++;
5663 }
5664
5665 if (r->rt == PF_DUPTO) {
5666#ifdef __FreeBSD__
5667 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
5668#else
5669 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
5670#endif
5671 return;
5672 } else {
5673 if ((r->rt == PF_REPLYTO) == (r->direction == dir))
5674 return;
5675 m0 = *m;
5676 }
5677
5678 if (m0->m_len < sizeof(struct ip)) {
5679 DPFPRINTF(PF_DEBUG_URGENT,
5680 ("pf_route: m0->m_len < sizeof(struct ip)\n"));
5681 goto bad;
5682 }
5683
5684 ip = mtod(m0, struct ip *);
5685
5686 ro = &iproute;
5687 bzero((caddr_t)ro, sizeof(*ro));
5688 dst = satosin(&ro->ro_dst);
5689 dst->sin_family = AF_INET;
5690 dst->sin_len = sizeof(*dst);
5691 dst->sin_addr = ip->ip_dst;
5692
5693 if (r->rt == PF_FASTROUTE) {
5694 rtalloc(ro);
5695 if (ro->ro_rt == 0) {
5696 ipstat.ips_noroute++;
5697 goto bad;
5698 }
5699
5700 ifp = ro->ro_rt->rt_ifp;
5701 ro->ro_rt->rt_use++;
5702
5703 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
5704 dst = satosin(ro->ro_rt->rt_gateway);
5705 } else {
5706 if (TAILQ_EMPTY(&r->rpool.list)) {
5707 DPFPRINTF(PF_DEBUG_URGENT,
5708 ("pf_route: TAILQ_EMPTY(&r->rpool.list)\n"));
5709 goto bad;
5710 }
5711 if (s == NULL) {
5712 pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
5713 &naddr, NULL, &sn);
5714 if (!PF_AZERO(&naddr, AF_INET))
5715 dst->sin_addr.s_addr = naddr.v4.s_addr;
5716 ifp = r->rpool.cur->kif ?
5717 r->rpool.cur->kif->pfik_ifp : NULL;
5718 } else {
5719 if (!PF_AZERO(&s->rt_addr, AF_INET))
5720 dst->sin_addr.s_addr =
5721 s->rt_addr.v4.s_addr;
5722 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
5723 }
5724 }
5725 if (ifp == NULL)
5726 goto bad;
5727
5728 if (oifp != ifp) {
5729#ifdef __FreeBSD__
5730 PF_UNLOCK();
5731 if (pf_test(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) {
5732 PF_LOCK();
5733 goto bad;
5734 } else if (m0 == NULL) {
5735 PF_LOCK();
5736 goto done;
5737 }
5738 PF_LOCK();
5739#else
5740 if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS)
5741 goto bad;
5742 else if (m0 == NULL)
5743 goto done;
5744#endif
5745 if (m0->m_len < sizeof(struct ip)) {
5746 DPFPRINTF(PF_DEBUG_URGENT,
5747 ("pf_route: m0->m_len < sizeof(struct ip)\n"));
5748 goto bad;
5749 }
5750 ip = mtod(m0, struct ip *);
5751 }
5752
5753#ifdef __FreeBSD__
5754 /* Copied from FreeBSD 5.1-CURRENT ip_output. */
5755 m0->m_pkthdr.csum_flags |= CSUM_IP;
5756 sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist;
5757 if (sw_csum & CSUM_DELAY_DATA) {
5758 /*
5759 * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least)
5760 */
5761 NTOHS(ip->ip_len);
5762 NTOHS(ip->ip_off); /* XXX: needed? */
5763 in_delayed_cksum(m0);
5764 HTONS(ip->ip_len);
5765 HTONS(ip->ip_off);
5766 sw_csum &= ~CSUM_DELAY_DATA;
5767 }
5768 m0->m_pkthdr.csum_flags &= ifp->if_hwassist;
5769
5770 if (ntohs(ip->ip_len) <= ifp->if_mtu ||
5771 (ifp->if_hwassist & CSUM_FRAGMENT &&
5772 ((ip->ip_off & htons(IP_DF)) == 0))) {
5773 /*
5774 * ip->ip_len = htons(ip->ip_len);
5775 * ip->ip_off = htons(ip->ip_off);
5776 */
5777 ip->ip_sum = 0;
5778 if (sw_csum & CSUM_DELAY_IP) {
5779 /* From KAME */
5780 if (ip->ip_v == IPVERSION &&
5781 (ip->ip_hl << 2) == sizeof(*ip)) {
5782 ip->ip_sum = in_cksum_hdr(ip);
5783 } else {
5784 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
5785 }
5786 }
5787 PF_UNLOCK();
5788 error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro->ro_rt);
5789 PF_LOCK();
5790 goto done;
5791 }
5792
5793#else
5794 /* Copied from ip_output. */
5795#ifdef IPSEC
5796 /*
5797 * If deferred crypto processing is needed, check that the
5798 * interface supports it.
5799 */
5800 if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL))
5801 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) {
5802 /* Notify IPsec to do its own crypto. */
5803 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
5804 goto bad;
5805 }
5806#endif /* IPSEC */
5807
5808 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */
5809 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) {
5810 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) ||
5811 ifp->if_bridge != NULL) {
5812 in_delayed_cksum(m0);
5813 m0->m_pkthdr.csum &= ~M_TCPV4_CSUM_OUT; /* Clear */
5814 }
5815 } else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) {
5816 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) ||
5817 ifp->if_bridge != NULL) {
5818 in_delayed_cksum(m0);
5819 m0->m_pkthdr.csum &= ~M_UDPV4_CSUM_OUT; /* Clear */
5820 }
5821 }
5822
5823 if (ntohs(ip->ip_len) <= ifp->if_mtu) {
5824 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
5825 ifp->if_bridge == NULL) {
5826 m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT;
5827 ipstat.ips_outhwcsum++;
5828 } else {
5829 ip->ip_sum = 0;
5830 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
5831 }
5832 /* Update relevant hardware checksum stats for TCP/UDP */
5833 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT)
5834 tcpstat.tcps_outhwcsum++;
5835 else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT)
5836 udpstat.udps_outhwcsum++;
5837 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL);
5838 goto done;
5839 }
5840#endif
5841 /*
5842 * Too large for interface; fragment if possible.
5843 * Must be able to put at least 8 bytes per fragment.
5844 */
5845 if (ip->ip_off & htons(IP_DF)) {
5846 ipstat.ips_cantfrag++;
5847 if (r->rt != PF_DUPTO) {
5848#ifdef __FreeBSD__
5849 /* icmp_error() expects host byte ordering */
5850 NTOHS(ip->ip_len);
5851 NTOHS(ip->ip_off);
5852 PF_UNLOCK();
5853 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
5854 ifp->if_mtu);
5855 PF_LOCK();
5856#else
5857 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
5858 ifp);
5859#endif
5860 goto done;
5861 } else
5862 goto bad;
5863 }
5864
5865 m1 = m0;
5866#ifdef __FreeBSD__
5867 /*
5868 * XXX: is cheaper + less error prone than own function
5869 */
5870 NTOHS(ip->ip_len);
5871 NTOHS(ip->ip_off);
5872 error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum);
5873#else
5874 error = ip_fragment(m0, ifp, ifp->if_mtu);
5875#endif
5876 if (error) {
5877#ifndef __FreeBSD__ /* ip_fragment does not do m_freem() on FreeBSD */
5878 m0 = NULL;
5879#endif
5880 goto bad;
5881 }
5882
5883 for (m0 = m1; m0; m0 = m1) {
5884 m1 = m0->m_nextpkt;
5885 m0->m_nextpkt = 0;
5886#ifdef __FreeBSD__
5887 if (error == 0) {
5888 PF_UNLOCK();
5889 error = (*ifp->if_output)(ifp, m0, sintosa(dst),
5890 NULL);
5891 PF_LOCK();
5892 } else
5893#else
5894 if (error == 0)
5895 error = (*ifp->if_output)(ifp, m0, sintosa(dst),
5896 NULL);
5897 else
5898#endif
5899 m_freem(m0);
5900 }
5901
5902 if (error == 0)
5903 ipstat.ips_fragmented++;
5904
5905done:
5906 if (r->rt != PF_DUPTO)
5907 *m = NULL;
5908 if (ro == &iproute && ro->ro_rt)
5909 RTFREE(ro->ro_rt);
5910 return;
5911
5912bad:
5913 m_freem(m0);
5914 goto done;
5915}
5916#endif /* INET */
5917
5918#ifdef INET6
5919void
5920pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
5921 struct pf_state *s)
5922{
5923 struct mbuf *m0;
5924 struct m_tag *mtag;
5925 struct route_in6 ip6route;
5926 struct route_in6 *ro;
5927 struct sockaddr_in6 *dst;
5928 struct ip6_hdr *ip6;
5929 struct ifnet *ifp = NULL;
5930 struct pf_addr naddr;
5931 struct pf_src_node *sn = NULL;
5932 int error = 0;
5933
5934 if (m == NULL || *m == NULL || r == NULL ||
5935 (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
5936 panic("pf_route6: invalid parameters");
5937
5938 if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) {
5939 if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) ==
5940 NULL) {
5941 m0 = *m;
5942 *m = NULL;
5943 goto bad;
5944 }
5945 *(char *)(mtag + 1) = 1;
5946 m_tag_prepend(*m, mtag);
5947 } else {
5948 if (*(char *)(mtag + 1) > 3) {
5949 m0 = *m;
5950 *m = NULL;
5951 goto bad;
5952 }
5953 (*(char *)(mtag + 1))++;
5954 }
5955
5956 if (r->rt == PF_DUPTO) {
5957#ifdef __FreeBSD__
5958 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
5959#else
5960 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
5961#endif
5962 return;
5963 } else {
5964 if ((r->rt == PF_REPLYTO) == (r->direction == dir))
5965 return;
5966 m0 = *m;
5967 }
5968
5969 if (m0->m_len < sizeof(struct ip6_hdr)) {
5970 DPFPRINTF(PF_DEBUG_URGENT,
5971 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n"));
5972 goto bad;
5973 }
5974 ip6 = mtod(m0, struct ip6_hdr *);
5975
5976 ro = &ip6route;
5977 bzero((caddr_t)ro, sizeof(*ro));
5978 dst = (struct sockaddr_in6 *)&ro->ro_dst;
5979 dst->sin6_family = AF_INET6;
5980 dst->sin6_len = sizeof(*dst);
5981 dst->sin6_addr = ip6->ip6_dst;
5982
5983 /* Cheat. */
5984 if (r->rt == PF_FASTROUTE) {
5985#ifdef __FreeBSD__
5986 m0->m_flags |= M_SKIP_FIREWALL;
5987 PF_UNLOCK();
5988 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
5989 PF_LOCK();
5990#else
5991 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
5992 if (mtag == NULL)
5993 goto bad;
5994 m_tag_prepend(m0, mtag);
5995 ip6_output(m0, NULL, NULL, 0, NULL, NULL);
5996#endif
5997 return;
5998 }
5999
6000 if (TAILQ_EMPTY(&r->rpool.list)) {
6001 DPFPRINTF(PF_DEBUG_URGENT,
6002 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n"));
6003 goto bad;
6004 }
6005 if (s == NULL) {
6006 pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
6007 &naddr, NULL, &sn);
6008 if (!PF_AZERO(&naddr, AF_INET6))
6009 PF_ACPY((struct pf_addr *)&dst->sin6_addr,
6010 &naddr, AF_INET6);
6011 ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
6012 } else {
6013 if (!PF_AZERO(&s->rt_addr, AF_INET6))
6014 PF_ACPY((struct pf_addr *)&dst->sin6_addr,
6015 &s->rt_addr, AF_INET6);
6016 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
6017 }
6018 if (ifp == NULL)
6019 goto bad;
6020
6021 if (oifp != ifp) {
6022#ifdef __FreeBSD__
6023 PF_UNLOCK();
6024 if (pf_test6(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) {
6025 PF_LOCK();
6026 goto bad;
6027 } else if (m0 == NULL) {
6028 PF_LOCK();
6029 goto done;
6030 }
6031 PF_LOCK();
6032#else
6033 if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS)
6034 goto bad;
6035 else if (m0 == NULL)
6036 goto done;
6037#endif
6038 if (m0->m_len < sizeof(struct ip6_hdr)) {
6039 DPFPRINTF(PF_DEBUG_URGENT,
6040 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n"));
6041 goto bad;
6042 }
6043 ip6 = mtod(m0, struct ip6_hdr *);
6044 }
6045
6046 /*
6047 * If the packet is too large for the outgoing interface,
6048 * send back an icmp6 error.
6049 */
6050 if (IN6_IS_ADDR_LINKLOCAL(&dst->sin6_addr))
6051 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
6052 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
6053#ifdef __FreeBSD__
6054 PF_UNLOCK();
6055#endif
6056 error = nd6_output(ifp, ifp, m0, dst, NULL);
6057#ifdef __FreeBSD__
6058 PF_LOCK();
6059#endif
6060 } else {
6061 in6_ifstat_inc(ifp, ifs6_in_toobig);
6062#ifdef __FreeBSD__
6063 if (r->rt != PF_DUPTO) {
6064 PF_UNLOCK();
6065 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
6066 PF_LOCK();
6067 } else
6068#else
6069 if (r->rt != PF_DUPTO)
6070 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
6071 else
6072#endif
6073 goto bad;
6074 }
6075
6076done:
6077 if (r->rt != PF_DUPTO)
6078 *m = NULL;
6079 return;
6080
6081bad:
6082 m_freem(m0);
6083 goto done;
6084}
6085#endif /* INET6 */
6086
6087
6088#ifdef __FreeBSD__
6089/*
6090 * FreeBSD supports cksum offloads for the following drivers.
6091 * em(4), fxp(4), ixgb(4), lge(4), ndis(4), nge(4), re(4),
6092 * ti(4), txp(4), xl(4)
6093 *
6094 * CSUM_DATA_VALID | CSUM_PSEUDO_HDR :
6095 * network driver performed cksum including pseudo header, need to verify
6096 * csum_data
6097 * CSUM_DATA_VALID :
6098 * network driver performed cksum, needs to additional pseudo header
6099 * cksum computation with partial csum_data(i.e. lack of H/W support for
6100 * pseudo header, for instance hme(4), sk(4) and possibly gem(4))
6101 *
6102 * After validating the cksum of packet, set both flag CSUM_DATA_VALID and
6103 * CSUM_PSEUDO_HDR in order to avoid recomputation of the cksum in upper
6104 * TCP/UDP layer.
6105 * Also, set csum_data to 0xffff to force cksum validation.
6106 */
6107int
6108pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af)
6109{
6110 u_int16_t sum = 0;
6111 int hw_assist = 0;
6112 struct ip *ip;
6113
6114 if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
6115 return (1);
6116 if (m->m_pkthdr.len < off + len)
6117 return (1);
6118
6119 switch (p) {
6120 case IPPROTO_TCP:
6121 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
6122 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) {
6123 sum = m->m_pkthdr.csum_data;
6124 } else {
6125 ip = mtod(m, struct ip *);
6126 sum = in_pseudo(ip->ip_src.s_addr,
6127 ip->ip_dst.s_addr, htonl((u_short)len +
6128 m->m_pkthdr.csum_data + IPPROTO_TCP));
6129 }
6130 sum ^= 0xffff;
6131 ++hw_assist;
6132 }
6133 break;
6134 case IPPROTO_UDP:
6135 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
6136 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) {
6137 sum = m->m_pkthdr.csum_data;
6138 } else {
6139 ip = mtod(m, struct ip *);
6140 sum = in_pseudo(ip->ip_src.s_addr,
6141 ip->ip_dst.s_addr, htonl((u_short)len +
6142 m->m_pkthdr.csum_data + IPPROTO_UDP));
6143 }
6144 sum ^= 0xffff;
6145 ++hw_assist;
6146 }
6147 break;
6148 case IPPROTO_ICMP:
6149#ifdef INET6
6150 case IPPROTO_ICMPV6:
6151#endif /* INET6 */
6152 break;
6153 default:
6154 return (1);
6155 }
6156
6157 if (!hw_assist) {
6158 switch (af) {
6159 case AF_INET:
6160 if (p == IPPROTO_ICMP) {
6161 if (m->m_len < off)
6162 return (1);
6163 m->m_data += off;
6164 m->m_len -= off;
6165 sum = in_cksum(m, len);
6166 m->m_data -= off;
6167 m->m_len += off;
6168 } else {
6169 if (m->m_len < sizeof(struct ip))
6170 return (1);
6171 sum = in4_cksum(m, p, off, len);
6172 }
6173 break;
6174#ifdef INET6
6175 case AF_INET6:
6176 if (m->m_len < sizeof(struct ip6_hdr))
6177 return (1);
6178 sum = in6_cksum(m, p, off, len);
6179 break;
6180#endif /* INET6 */
6181 default:
6182 return (1);
6183 }
6184 }
6185 if (sum) {
6186 switch (p) {
6187 case IPPROTO_TCP:
6188 tcpstat.tcps_rcvbadsum++;
6189 break;
6190 case IPPROTO_UDP:
6191 udpstat.udps_badsum++;
6192 break;
6193 case IPPROTO_ICMP:
6194 icmpstat.icps_checksum++;
6195 break;
6196#ifdef INET6
6197 case IPPROTO_ICMPV6:
6198 icmp6stat.icp6s_checksum++;
6199 break;
6200#endif /* INET6 */
6201 }
6202 return (1);
6203 } else {
6204 if (p == IPPROTO_TCP || p == IPPROTO_UDP) {
6205 m->m_pkthdr.csum_flags |=
6206 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
6207 m->m_pkthdr.csum_data = 0xffff;
6208 }
6209 }
6210 return (0);
6211}
6212#else
6213/*
6214 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag
6215 * off is the offset where the protocol header starts
6216 * len is the total length of protocol header plus payload
6217 * returns 0 when the checksum is valid, otherwise returns 1.
6218 */
6219int
6220pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,
6221 sa_family_t af)
6222{
6223 u_int16_t flag_ok, flag_bad;
6224 u_int16_t sum;
6225
6226 switch (p) {
6227 case IPPROTO_TCP:
6228 flag_ok = M_TCP_CSUM_IN_OK;
6229 flag_bad = M_TCP_CSUM_IN_BAD;
6230 break;
6231 case IPPROTO_UDP:
6232 flag_ok = M_UDP_CSUM_IN_OK;
6233 flag_bad = M_UDP_CSUM_IN_BAD;
6234 break;
6235 case IPPROTO_ICMP:
6236#ifdef INET6
6237 case IPPROTO_ICMPV6:
6238#endif /* INET6 */
6239 flag_ok = flag_bad = 0;
6240 break;
6241 default:
6242 return (1);
6243 }
6244 if (m->m_pkthdr.csum & flag_ok)
6245 return (0);
6246 if (m->m_pkthdr.csum & flag_bad)
6247 return (1);
6248 if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
6249 return (1);
6250 if (m->m_pkthdr.len < off + len)
6251 return (1);
6252 switch (af) {
6253#ifdef INET
6254 case AF_INET:
6255 if (p == IPPROTO_ICMP) {
6256 if (m->m_len < off)
6257 return (1);
6258 m->m_data += off;
6259 m->m_len -= off;
6260 sum = in_cksum(m, len);
6261 m->m_data -= off;
6262 m->m_len += off;
6263 } else {
6264 if (m->m_len < sizeof(struct ip))
6265 return (1);
6266 sum = in4_cksum(m, p, off, len);
6267 }
6268 break;
6269#endif /* INET */
6270#ifdef INET6
6271 case AF_INET6:
6272 if (m->m_len < sizeof(struct ip6_hdr))
6273 return (1);
6274 sum = in6_cksum(m, p, off, len);
6275 break;
6276#endif /* INET6 */
6277 default:
6278 return (1);
6279 }
6280 if (sum) {
6281 m->m_pkthdr.csum |= flag_bad;
6282 switch (p) {
6283 case IPPROTO_TCP:
6284 tcpstat.tcps_rcvbadsum++;
6285 break;
6286 case IPPROTO_UDP:
6287 udpstat.udps_badsum++;
6288 break;
6289 case IPPROTO_ICMP:
6290 icmpstat.icps_checksum++;
6291 break;
6292#ifdef INET6
6293 case IPPROTO_ICMPV6:
6294 icmp6stat.icp6s_checksum++;
6295 break;
6296#endif /* INET6 */
6297 }
6298 return (1);
6299 }
6300 m->m_pkthdr.csum |= flag_ok;
6301 return (0);
6302}
6303#endif
6304
6305static int
6306pf_add_mbuf_tag(struct mbuf *m, u_int tag)
6307{
6308 struct m_tag *mtag;
6309
6310 if (m_tag_find(m, tag, NULL) != NULL)
6311 return (0);
6312 mtag = m_tag_get(tag, 0, M_NOWAIT);
6313 if (mtag == NULL)
6314 return (1);
6315 m_tag_prepend(m, mtag);
6316 return (0);
6317}
6318
6319#ifdef INET
6320int
6321#ifdef __FreeBSD__
6322pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
6323 struct ether_header *eh, struct inpcb *inp)
6324#else
6325pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
6326 struct ether_header *eh)
6327#endif
6328{
6329 struct pfi_kif *kif;
6330 u_short action, reason = 0, log = 0;
6331 struct mbuf *m = *m0;
6332 struct ip *h = NULL; /* make the compiler happy */
6333 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
6334 struct pf_state *s = NULL;
6335 struct pf_ruleset *ruleset = NULL;
6336 struct pf_pdesc pd;
6337 int off, dirndx, pqid = 0;
6338
6339#ifdef __FreeBSD__
6340 PF_LOCK();
6341#endif
6342 if (!pf_status.running ||
6343#ifdef __FreeBSD__
6344 (m->m_flags & M_SKIP_FIREWALL)) {
6345 PF_UNLOCK();
6346#else
6347 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) {
6348#endif
6349 return (PF_PASS);
6350 }
6351
6352#ifdef __FreeBSD__
6353 /* XXX_IMPORT: later */
6354#else
6355 if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
6356 ifp = ifp->if_carpdev;
6357#endif
6358
6359 kif = pfi_index2kif[ifp->if_index];
6360 if (kif == NULL) {
6361#ifdef __FreeBSD__
6362 PF_UNLOCK();
6363#endif
6364 DPFPRINTF(PF_DEBUG_URGENT,
6365 ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname));
6366 return (PF_DROP);
6367 }
6368 if (kif->pfik_flags & PFI_IFLAG_SKIP) {
6369#ifdef __FreeBSD__
6370 PF_UNLOCK();
6371#endif
6372 return (PF_PASS);
6373 }
6374
6375#ifdef __FreeBSD__
6376 M_ASSERTPKTHDR(m);
6377#else
6378#ifdef DIAGNOSTIC
6379 if ((m->m_flags & M_PKTHDR) == 0)
6380 panic("non-M_PKTHDR is passed to pf_test");
6381#endif /* DIAGNOSTIC */
6382#endif /* __FreeBSD__ */
6383
6384 memset(&pd, 0, sizeof(pd));
6385 if (m->m_pkthdr.len < (int)sizeof(*h)) {
6386 action = PF_DROP;
6387 REASON_SET(&reason, PFRES_SHORT);
6388 log = 1;
6389 goto done;
6390 }
6391
6392 /* We do IP header normalization and packet reassembly here */
6393 if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) {
6394 action = PF_DROP;
6395 goto done;
6396 }
6397 m = *m0;
6398 h = mtod(m, struct ip *);
6399
6400 off = h->ip_hl << 2;
6401 if (off < (int)sizeof(*h)) {
6402 action = PF_DROP;
6403 REASON_SET(&reason, PFRES_SHORT);
6404 log = 1;
6405 goto done;
6406 }
6407
6408 pd.src = (struct pf_addr *)&h->ip_src;
6409 pd.dst = (struct pf_addr *)&h->ip_dst;
6410 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET);
6411 pd.ip_sum = &h->ip_sum;
6412 pd.proto = h->ip_p;
6413 pd.af = AF_INET;
6414 pd.tos = h->ip_tos;
6415 pd.tot_len = ntohs(h->ip_len);
6416 pd.eh = eh;
6417
6418 /* handle fragments that didn't get reassembled by normalization */
6419 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) {
6420 action = pf_test_fragment(&r, dir, kif, m, h,
6421 &pd, &a, &ruleset);
6422 goto done;
6423 }
6424
6425 switch (h->ip_p) {
6426
6427 case IPPROTO_TCP: {
6428 struct tcphdr th;
6429
6430 pd.hdr.tcp = &th;
6431 if (!pf_pull_hdr(m, off, &th, sizeof(th),
6432 &action, &reason, AF_INET)) {
6433 log = action != PF_PASS;
6434 goto done;
6435 }
6436 if (dir == PF_IN && pf_check_proto_cksum(m, off,
6437 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) {
6438 action = PF_DROP;
6439 goto done;
6440 }
6441 pd.p_len = pd.tot_len - off - (th.th_off << 2);
6442 if ((th.th_flags & TH_ACK) && pd.p_len == 0)
6443 pqid = 1;
6444 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
6445 if (action == PF_DROP)
6446 goto done;
6447 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
6448 &reason);
6449 if (action == PF_PASS) {
6450#if NPFSYNC
6451 pfsync_update_state(s);
6452#endif /* NPFSYNC */
6453 r = s->rule.ptr;
6454 a = s->anchor.ptr;
6455 log = s->log;
6456 } else if (s == NULL)
6457#ifdef __FreeBSD__
6458 action = pf_test_tcp(&r, &s, dir, kif,
6459 m, off, h, &pd, &a, &ruleset, NULL, inp);
6460#else
6461 action = pf_test_tcp(&r, &s, dir, kif,
6462 m, off, h, &pd, &a, &ruleset, &ipintrq);
6463#endif
6464 break;
6465 }
6466
6467 case IPPROTO_UDP: {
6468 struct udphdr uh;
6469
6470 pd.hdr.udp = &uh;
6471 if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
6472 &action, &reason, AF_INET)) {
6473 log = action != PF_PASS;
6474 goto done;
6475 }
6476 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m,
6477 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) {
6478 action = PF_DROP;
6479 goto done;
6480 }
6481 if (uh.uh_dport == 0 ||
6482 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
6483 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
6484 action = PF_DROP;
6485 goto done;
6486 }
6487 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
6488 if (action == PF_PASS) {
6489#if NPFSYNC
6490 pfsync_update_state(s);
6491#endif /* NPFSYNC */
6492 r = s->rule.ptr;
6493 a = s->anchor.ptr;
6494 log = s->log;
6495 } else if (s == NULL)
6496#ifdef __FreeBSD__
6497 action = pf_test_udp(&r, &s, dir, kif,
6498 m, off, h, &pd, &a, &ruleset, NULL, inp);
6499#else
6500 action = pf_test_udp(&r, &s, dir, kif,
6501 m, off, h, &pd, &a, &ruleset, &ipintrq);
6502#endif
6503 break;
6504 }
6505
6506 case IPPROTO_ICMP: {
6507 struct icmp ih;
6508
6509 pd.hdr.icmp = &ih;
6510 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN,
6511 &action, &reason, AF_INET)) {
6512 log = action != PF_PASS;
6513 goto done;
6514 }
6515 if (dir == PF_IN && pf_check_proto_cksum(m, off,
6516 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) {
6517 action = PF_DROP;
6518 goto done;
6519 }
6520 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd,
6521 &reason);
6522 if (action == PF_PASS) {
6523#if NPFSYNC
6524 pfsync_update_state(s);
6525#endif /* NPFSYNC */
6526 r = s->rule.ptr;
6527 a = s->anchor.ptr;
6528 log = s->log;
6529 } else if (s == NULL)
6530#ifdef __FreeBSD__
6531 action = pf_test_icmp(&r, &s, dir, kif,
6532 m, off, h, &pd, &a, &ruleset, NULL);
6533#else
6534 action = pf_test_icmp(&r, &s, dir, kif,
6535 m, off, h, &pd, &a, &ruleset, &ipintrq);
6536#endif
6537 break;
6538 }
6539
6540 default:
6541 action = pf_test_state_other(&s, dir, kif, &pd);
6542 if (action == PF_PASS) {
6543#if NPFSYNC
6544 pfsync_update_state(s);
6545#endif /* NPFSYNC */
6546 r = s->rule.ptr;
6547 a = s->anchor.ptr;
6548 log = s->log;
6549 } else if (s == NULL)
6550#ifdef __FreeBSD__
6551 action = pf_test_other(&r, &s, dir, kif, m, off, h,
6552 &pd, &a, &ruleset, NULL);
6553#else
6554 action = pf_test_other(&r, &s, dir, kif, m, off, h,
6555 &pd, &a, &ruleset, &ipintrq);
6556#endif
6557 break;
6558 }
6559
6560done:
6561 if (action == PF_PASS && h->ip_hl > 5 &&
6562 !((s && s->allow_opts) || r->allow_opts)) {
6563 action = PF_DROP;
6564 REASON_SET(&reason, PFRES_IPOPTIONS);
6565 log = 1;
6566 DPFPRINTF(PF_DEBUG_MISC,
6567 ("pf: dropping packet with ip options\n"));
6568 }
6569
6570 if (s && s->tag)
6571 pf_tag_packet(m, pf_get_tag(m), s->tag);
6572
6573#ifdef ALTQ
6574 if (action == PF_PASS && r->qid) {
6575 struct m_tag *mtag;
6576 struct altq_tag *atag;
6577
6578 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
6579 if (mtag != NULL) {
6580 atag = (struct altq_tag *)(mtag + 1);
6581 if (pqid || pd.tos == IPTOS_LOWDELAY)
6582 atag->qid = r->pqid;
6583 else
6584 atag->qid = r->qid;
6585 /* add hints for ecn */
6586 atag->af = AF_INET;
6587 atag->hdr = h;
6588 m_tag_prepend(m, mtag);
6589 }
6590 }
6591#endif /* ALTQ */
6592
6593 /*
6594 * connections redirected to loopback should not match sockets
6595 * bound specifically to loopback due to security implications,
6596 * see tcp_input() and in_pcblookup_listen().
6597 */
6598 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
6599 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
6600 (s->nat_rule.ptr->action == PF_RDR ||
6601 s->nat_rule.ptr->action == PF_BINAT) &&
6602 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET &&
6603 pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) {
6604 action = PF_DROP;
6605 REASON_SET(&reason, PFRES_MEMORY);
6606 }
6607
6608 if (log)
6609 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, a, ruleset);
6610
6611 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
6612 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++;
6613
6614 if (action == PF_PASS || r->action == PF_DROP) {
6615 r->packets++;
6616 r->bytes += pd.tot_len;
6617 if (a != NULL) {
6618 a->packets++;
6619 a->bytes += pd.tot_len;
6620 }
6621 if (s != NULL) {
6622 dirndx = (dir == s->direction) ? 0 : 1;
6623 s->packets[dirndx]++;
6624 s->bytes[dirndx] += pd.tot_len;
6625 if (s->nat_rule.ptr != NULL) {
6626 s->nat_rule.ptr->packets++;
6627 s->nat_rule.ptr->bytes += pd.tot_len;
6628 }
6629 if (s->src_node != NULL) {
6630 s->src_node->packets++;
6631 s->src_node->bytes += pd.tot_len;
6632 }
6633 if (s->nat_src_node != NULL) {
6634 s->nat_src_node->packets++;
6635 s->nat_src_node->bytes += pd.tot_len;
6636 }
6637 }
6638 tr = r;
6639 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
6640 if (nr != NULL) {
6641 struct pf_addr *x;
6642 /*
6643 * XXX: we need to make sure that the addresses
6644 * passed to pfr_update_stats() are the same than
6645 * the addresses used during matching (pfr_match)
6646 */
6647 if (r == &pf_default_rule) {
6648 tr = nr;
6649 x = (s == NULL || s->direction == dir) ?
6650 &pd.baddr : &pd.naddr;
6651 } else
6652 x = (s == NULL || s->direction == dir) ?
6653 &pd.naddr : &pd.baddr;
6654 if (x == &pd.baddr || s == NULL) {
6655 /* we need to change the address */
6656 if (dir == PF_OUT)
6657 pd.src = x;
6658 else
6659 pd.dst = x;
6660 }
6661 }
6662 if (tr->src.addr.type == PF_ADDR_TABLE)
6663 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL ||
6664 s->direction == dir) ? pd.src : pd.dst, pd.af,
6665 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
6666 tr->src.neg);
6667 if (tr->dst.addr.type == PF_ADDR_TABLE)
6668 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL ||
6669 s->direction == dir) ? pd.dst : pd.src, pd.af,
6670 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
6671 tr->dst.neg);
6672 }
6673
6674
6675 if (action == PF_SYNPROXY_DROP) {
6676 m_freem(*m0);
6677 *m0 = NULL;
6678 action = PF_PASS;
6679 } else if (r->rt)
6680 /* pf_route can free the mbuf causing *m0 to become NULL */
6681 pf_route(m0, r, dir, ifp, s);
6682
6683#ifdef __FreeBSD__
6684 PF_UNLOCK();
6685#endif
6686
6687 return (action);
6688}
6689#endif /* INET */
6690
6691#ifdef INET6
6692int
6693#ifdef __FreeBSD__
6694pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
6695 struct ether_header *eh, struct inpcb *inp)
6696#else
6697pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
6698 struct ether_header *eh)
6699#endif
6700{
6701 struct pfi_kif *kif;
6702 u_short action, reason = 0, log = 0;
6703 struct mbuf *m = *m0;
6704 struct ip6_hdr *h = NULL; /* make the compiler happy */
6705 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
6706 struct pf_state *s = NULL;
6707 struct pf_ruleset *ruleset = NULL;
6708 struct pf_pdesc pd;
6709 int off, terminal = 0, dirndx;
6710
6711#ifdef __FreeBSD__
6712 PF_LOCK();
6713#endif
6714
6715 if (!pf_status.running ||
6716#ifdef __FreeBSD__
6717 (m->m_flags & M_SKIP_FIREWALL)) {
6718 PF_UNLOCK();
6719#else
6720 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) {
6721#endif
6722 return (PF_PASS);
6723 }
6724
6725#ifdef __FreeBSD__
6726 /* XXX_IMPORT: later */
6727#else
6728 if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
6729 ifp = ifp->if_carpdev;
6730#endif
6731
6732 kif = pfi_index2kif[ifp->if_index];
6733 if (kif == NULL) {
6734#ifdef __FreeBSD__
6735 PF_UNLOCK();
6736#endif
6737 DPFPRINTF(PF_DEBUG_URGENT,
6738 ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname));
6739 return (PF_DROP);
6740 }
6741 if (kif->pfik_flags & PFI_IFLAG_SKIP) {
6742#ifdef __FreeBSD__
6743 PF_UNLOCK();
6744#endif
6745 return (PF_PASS);
6746 }
6747
6748#ifdef __FreeBSD__
6749 M_ASSERTPKTHDR(m);
6750#else
6751#ifdef DIAGNOSTIC
6752 if ((m->m_flags & M_PKTHDR) == 0)
6753 panic("non-M_PKTHDR is passed to pf_test6");
6754#endif /* DIAGNOSTIC */
6755#endif
6756
6757 memset(&pd, 0, sizeof(pd));
6758 if (m->m_pkthdr.len < (int)sizeof(*h)) {
6759 action = PF_DROP;
6760 REASON_SET(&reason, PFRES_SHORT);
6761 log = 1;
6762 goto done;
6763 }
6764
6765 /* We do IP header normalization and packet reassembly here */
6766 if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) {
6767 action = PF_DROP;
6768 goto done;
6769 }
6770 m = *m0;
6771 h = mtod(m, struct ip6_hdr *);
6772
6773 pd.src = (struct pf_addr *)&h->ip6_src;
6774 pd.dst = (struct pf_addr *)&h->ip6_dst;
6775 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET6);
6776 pd.ip_sum = NULL;
6777 pd.af = AF_INET6;
6778 pd.tos = 0;
6779 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
6780 pd.eh = eh;
6781
6782 off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr);
6783 pd.proto = h->ip6_nxt;
6784 do {
6785 switch (pd.proto) {
6786 case IPPROTO_FRAGMENT:
6787 action = pf_test_fragment(&r, dir, kif, m, h,
6788 &pd, &a, &ruleset);
6789 if (action == PF_DROP)
6790 REASON_SET(&reason, PFRES_FRAG);
6791 goto done;
6792 case IPPROTO_AH:
6793 case IPPROTO_HOPOPTS:
6794 case IPPROTO_ROUTING:
6795 case IPPROTO_DSTOPTS: {
6796 /* get next header and header length */
6797 struct ip6_ext opt6;
6798
6799 if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6),
6800 NULL, &reason, pd.af)) {
6801 DPFPRINTF(PF_DEBUG_MISC,
6802 ("pf: IPv6 short opt\n"));
6803 action = PF_DROP;
6804 log = 1;
6805 goto done;
6806 }
6807 if (pd.proto == IPPROTO_AH)
6808 off += (opt6.ip6e_len + 2) * 4;
6809 else
6810 off += (opt6.ip6e_len + 1) * 8;
6811 pd.proto = opt6.ip6e_nxt;
6812 /* goto the next header */
6813 break;
6814 }
6815 default:
6816 terminal++;
6817 break;
6818 }
6819 } while (!terminal);
6820
6821 switch (pd.proto) {
6822
6823 case IPPROTO_TCP: {
6824 struct tcphdr th;
6825
6826 pd.hdr.tcp = &th;
6827 if (!pf_pull_hdr(m, off, &th, sizeof(th),
6828 &action, &reason, AF_INET6)) {
6829 log = action != PF_PASS;
6830 goto done;
6831 }
6832 if (dir == PF_IN && pf_check_proto_cksum(m, off,
6833 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
6834 IPPROTO_TCP, AF_INET6)) {
6835 action = PF_DROP;
6836 REASON_SET(&reason, PFRES_PROTCKSUM);
6837 goto done;
6838 }
6839 pd.p_len = pd.tot_len - off - (th.th_off << 2);
6840 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
6841 if (action == PF_DROP)
6842 goto done;
6843 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
6844 &reason);
6845 if (action == PF_PASS) {
6846#if NPFSYNC
6847 pfsync_update_state(s);
6848#endif /* NPFSYNC */
6849 r = s->rule.ptr;
6850 a = s->anchor.ptr;
6851 log = s->log;
6852 } else if (s == NULL)
6853#ifdef __FreeBSD__
6854 action = pf_test_tcp(&r, &s, dir, kif,
6855 m, off, h, &pd, &a, &ruleset, NULL, inp);
6856#else
6857 action = pf_test_tcp(&r, &s, dir, kif,
6858 m, off, h, &pd, &a, &ruleset, &ip6intrq);
6859#endif
6860 break;
6861 }
6862
6863 case IPPROTO_UDP: {
6864 struct udphdr uh;
6865
6866 pd.hdr.udp = &uh;
6867 if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
6868 &action, &reason, AF_INET6)) {
6869 log = action != PF_PASS;
6870 goto done;
6871 }
6872 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m,
6873 off, ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
6874 IPPROTO_UDP, AF_INET6)) {
6875 action = PF_DROP;
6876 REASON_SET(&reason, PFRES_PROTCKSUM);
6877 goto done;
6878 }
6879 if (uh.uh_dport == 0 ||
6880 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
6881 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
6882 action = PF_DROP;
6883 goto done;
6884 }
6885 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
6886 if (action == PF_PASS) {
6887#if NPFSYNC
6888 pfsync_update_state(s);
6889#endif /* NPFSYNC */
6890 r = s->rule.ptr;
6891 a = s->anchor.ptr;
6892 log = s->log;
6893 } else if (s == NULL)
6894#ifdef __FreeBSD__
6895 action = pf_test_udp(&r, &s, dir, kif,
6896 m, off, h, &pd, &a, &ruleset, NULL, inp);
6897#else
6898 action = pf_test_udp(&r, &s, dir, kif,
6899 m, off, h, &pd, &a, &ruleset, &ip6intrq);
6900#endif
6901 break;
6902 }
6903
6904 case IPPROTO_ICMPV6: {
6905 struct icmp6_hdr ih;
6906
6907 pd.hdr.icmp6 = &ih;
6908 if (!pf_pull_hdr(m, off, &ih, sizeof(ih),
6909 &action, &reason, AF_INET6)) {
6910 log = action != PF_PASS;
6911 goto done;
6912 }
6913 if (dir == PF_IN && pf_check_proto_cksum(m, off,
6914 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
6915 IPPROTO_ICMPV6, AF_INET6)) {
6916 action = PF_DROP;
6917 REASON_SET(&reason, PFRES_PROTCKSUM);
6918 goto done;
6919 }
6920 action = pf_test_state_icmp(&s, dir, kif,
6921 m, off, h, &pd, &reason);
6922 if (action == PF_PASS) {
6923#if NPFSYNC
6924 pfsync_update_state(s);
6925#endif /* NPFSYNC */
6926 r = s->rule.ptr;
6927 a = s->anchor.ptr;
6928 log = s->log;
6929 } else if (s == NULL)
6930#ifdef __FreeBSD__
6931 action = pf_test_icmp(&r, &s, dir, kif,
6932 m, off, h, &pd, &a, &ruleset, NULL);
6933#else
6934 action = pf_test_icmp(&r, &s, dir, kif,
6935 m, off, h, &pd, &a, &ruleset, &ip6intrq);
6936#endif
6937 break;
6938 }
6939
6940 default:
6941 action = pf_test_state_other(&s, dir, kif, &pd);
6942 if (action == PF_PASS) {
6943#if NPFSYNC
6944 pfsync_update_state(s);
6945#endif /* NPFSYNC */
6946 r = s->rule.ptr;
6947 a = s->anchor.ptr;
6948 log = s->log;
6949 } else if (s == NULL)
6950#ifdef __FreeBSD__
6951 action = pf_test_other(&r, &s, dir, kif, m, off, h,
6952 &pd, &a, &ruleset, NULL);
6953#else
6954 action = pf_test_other(&r, &s, dir, kif, m, off, h,
6955 &pd, &a, &ruleset, &ip6intrq);
6956#endif
6957 break;
6958 }
6959
6960done:
6961 /* XXX handle IPv6 options, if not allowed. not implemented. */
6962
6963 if (s && s->tag)
6964 pf_tag_packet(m, pf_get_tag(m), s->tag);
6965
6966#ifdef ALTQ
6967 if (action == PF_PASS && r->qid) {
6968 struct m_tag *mtag;
6969 struct altq_tag *atag;
6970
6971 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
6972 if (mtag != NULL) {
6973 atag = (struct altq_tag *)(mtag + 1);
6974 if (pd.tos == IPTOS_LOWDELAY)
6975 atag->qid = r->pqid;
6976 else
6977 atag->qid = r->qid;
6978 /* add hints for ecn */
6979 atag->af = AF_INET6;
6980 atag->hdr = h;
6981 m_tag_prepend(m, mtag);
6982 }
6983 }
6984#endif /* ALTQ */
6985
6986 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
6987 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
6988 (s->nat_rule.ptr->action == PF_RDR ||
6989 s->nat_rule.ptr->action == PF_BINAT) &&
6990 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6) &&
6991 pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) {
6992 action = PF_DROP;
6993 REASON_SET(&reason, PFRES_MEMORY);
6994 }
6995
6996 if (log)
6997 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, r, a, ruleset);
6998
6999 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
7000 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++;
7001
7002 if (action == PF_PASS || r->action == PF_DROP) {
7003 r->packets++;
7004 r->bytes += pd.tot_len;
7005 if (a != NULL) {
7006 a->packets++;
7007 a->bytes += pd.tot_len;
7008 }
7009 if (s != NULL) {
7010 dirndx = (dir == s->direction) ? 0 : 1;
7011 s->packets[dirndx]++;
7012 s->bytes[dirndx] += pd.tot_len;
7013 if (s->nat_rule.ptr != NULL) {
7014 s->nat_rule.ptr->packets++;
7015 s->nat_rule.ptr->bytes += pd.tot_len;
7016 }
7017 if (s->src_node != NULL) {
7018 s->src_node->packets++;
7019 s->src_node->bytes += pd.tot_len;
7020 }
7021 if (s->nat_src_node != NULL) {
7022 s->nat_src_node->packets++;
7023 s->nat_src_node->bytes += pd.tot_len;
7024 }
7025 }
7026 tr = r;
7027 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
7028 if (nr != NULL) {
7029 struct pf_addr *x;
7030 /*
7031 * XXX: we need to make sure that the addresses
7032 * passed to pfr_update_stats() are the same than
7033 * the addresses used during matching (pfr_match)
7034 */
7035 if (r == &pf_default_rule) {
7036 tr = nr;
7037 x = (s == NULL || s->direction == dir) ?
7038 &pd.baddr : &pd.naddr;
7039 } else {
7040 x = (s == NULL || s->direction == dir) ?
7041 &pd.naddr : &pd.baddr;
7042 }
7043 if (x == &pd.baddr || s == NULL) {
7044 if (dir == PF_OUT)
7045 pd.src = x;
7046 else
7047 pd.dst = x;
7048 }
7049 }
7050 if (tr->src.addr.type == PF_ADDR_TABLE)
7051 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL ||
7052 s->direction == dir) ? pd.src : pd.dst, pd.af,
7053 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
7054 tr->src.neg);
7055 if (tr->dst.addr.type == PF_ADDR_TABLE)
7056 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL ||
7057 s->direction == dir) ? pd.dst : pd.src, pd.af,
7058 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
7059 tr->dst.neg);
7060 }
7061
7062
7063 if (action == PF_SYNPROXY_DROP) {
7064 m_freem(*m0);
7065 *m0 = NULL;
7066 action = PF_PASS;
7067 } else if (r->rt)
7068 /* pf_route6 can free the mbuf causing *m0 to become NULL */
7069 pf_route6(m0, r, dir, ifp, s);
7070
7071#ifdef __FreeBSD__
7072 PF_UNLOCK();
7073#endif
7074 return (action);
7075}
7076#endif /* INET6 */
7077
7078int
7079pf_check_congestion(struct ifqueue *ifq)
7080{
7081#ifdef __FreeBSD__
7082 /* XXX_IMPORT: later */
7083 return (0);
7084#else
7085 if (ifq->ifq_congestion)
7086 return (1);
7087 else
7088 return (0);
7089#endif
7090}
1108#endif
1109 if (cur->src.state == PF_TCPS_PROXY_DST)
1110 pf_send_tcp(cur->rule.ptr, cur->af,
1111 &cur->ext.addr, &cur->lan.addr,
1112 cur->ext.port, cur->lan.port,
1113 cur->src.seqhi, cur->src.seqlo + 1,
1114 TH_RST|TH_ACK, 0, 0, 0, 1, NULL, NULL);
1115 RB_REMOVE(pf_state_tree_ext_gwy,
1116 &cur->u.s.kif->pfik_ext_gwy, cur);
1117 RB_REMOVE(pf_state_tree_lan_ext,
1118 &cur->u.s.kif->pfik_lan_ext, cur);
1119 RB_REMOVE(pf_state_tree_id, &tree_id, cur);
1120#if NPFSYNC
1121 pfsync_delete_state(cur);
1122#endif
1123 pf_src_tree_remove_state(cur);
1124 if (--cur->rule.ptr->states <= 0 &&
1125 cur->rule.ptr->src_nodes <= 0)
1126 pf_rm_rule(NULL, cur->rule.ptr);
1127 if (cur->nat_rule.ptr != NULL)
1128 if (--cur->nat_rule.ptr->states <= 0 &&
1129 cur->nat_rule.ptr->src_nodes <= 0)
1130 pf_rm_rule(NULL, cur->nat_rule.ptr);
1131 if (cur->anchor.ptr != NULL)
1132 if (--cur->anchor.ptr->states <= 0)
1133 pf_rm_rule(NULL, cur->anchor.ptr);
1134 pf_normalize_tcp_cleanup(cur);
1135 pfi_detach_state(cur->u.s.kif);
1136 TAILQ_REMOVE(&state_updates, cur, u.s.entry_updates);
1137 if (cur->tag)
1138 pf_tag_unref(cur->tag);
1139 pool_put(&pf_state_pl, cur);
1140 pf_status.fcounters[FCNT_STATE_REMOVALS]++;
1141 pf_status.states--;
1142}
1143
1144void
1145pf_purge_expired_states(void)
1146{
1147 struct pf_state *cur, *next;
1148
1149 for (cur = RB_MIN(pf_state_tree_id, &tree_id);
1150 cur; cur = next) {
1151 next = RB_NEXT(pf_state_tree_id, &tree_id, cur);
1152 if (pf_state_expires(cur) <= time_second)
1153 pf_purge_expired_state(cur);
1154 }
1155}
1156
1157int
1158pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
1159{
1160 if (aw->type != PF_ADDR_TABLE)
1161 return (0);
1162 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)
1163 return (1);
1164 return (0);
1165}
1166
1167void
1168pf_tbladdr_remove(struct pf_addr_wrap *aw)
1169{
1170 if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL)
1171 return;
1172 pfr_detach_table(aw->p.tbl);
1173 aw->p.tbl = NULL;
1174}
1175
1176void
1177pf_tbladdr_copyout(struct pf_addr_wrap *aw)
1178{
1179 struct pfr_ktable *kt = aw->p.tbl;
1180
1181 if (aw->type != PF_ADDR_TABLE || kt == NULL)
1182 return;
1183 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
1184 kt = kt->pfrkt_root;
1185 aw->p.tbl = NULL;
1186 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
1187 kt->pfrkt_cnt : -1;
1188}
1189
1190void
1191pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
1192{
1193 switch (af) {
1194#ifdef INET
1195 case AF_INET: {
1196 u_int32_t a = ntohl(addr->addr32[0]);
1197 printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255,
1198 (a>>8)&255, a&255);
1199 if (p) {
1200 p = ntohs(p);
1201 printf(":%u", p);
1202 }
1203 break;
1204 }
1205#endif /* INET */
1206#ifdef INET6
1207 case AF_INET6: {
1208 u_int16_t b;
1209 u_int8_t i, curstart = 255, curend = 0,
1210 maxstart = 0, maxend = 0;
1211 for (i = 0; i < 8; i++) {
1212 if (!addr->addr16[i]) {
1213 if (curstart == 255)
1214 curstart = i;
1215 else
1216 curend = i;
1217 } else {
1218 if (curstart) {
1219 if ((curend - curstart) >
1220 (maxend - maxstart)) {
1221 maxstart = curstart;
1222 maxend = curend;
1223 curstart = 255;
1224 }
1225 }
1226 }
1227 }
1228 for (i = 0; i < 8; i++) {
1229 if (i >= maxstart && i <= maxend) {
1230 if (maxend != 7) {
1231 if (i == maxstart)
1232 printf(":");
1233 } else {
1234 if (i == maxend)
1235 printf(":");
1236 }
1237 } else {
1238 b = ntohs(addr->addr16[i]);
1239 printf("%x", b);
1240 if (i < 7)
1241 printf(":");
1242 }
1243 }
1244 if (p) {
1245 p = ntohs(p);
1246 printf("[%u]", p);
1247 }
1248 break;
1249 }
1250#endif /* INET6 */
1251 }
1252}
1253
1254void
1255pf_print_state(struct pf_state *s)
1256{
1257 switch (s->proto) {
1258 case IPPROTO_TCP:
1259 printf("TCP ");
1260 break;
1261 case IPPROTO_UDP:
1262 printf("UDP ");
1263 break;
1264 case IPPROTO_ICMP:
1265 printf("ICMP ");
1266 break;
1267 case IPPROTO_ICMPV6:
1268 printf("ICMPV6 ");
1269 break;
1270 default:
1271 printf("%u ", s->proto);
1272 break;
1273 }
1274 pf_print_host(&s->lan.addr, s->lan.port, s->af);
1275 printf(" ");
1276 pf_print_host(&s->gwy.addr, s->gwy.port, s->af);
1277 printf(" ");
1278 pf_print_host(&s->ext.addr, s->ext.port, s->af);
1279 printf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo,
1280 s->src.seqhi, s->src.max_win, s->src.seqdiff);
1281 if (s->src.wscale && s->dst.wscale)
1282 printf(" wscale=%u", s->src.wscale & PF_WSCALE_MASK);
1283 printf("]");
1284 printf(" [lo=%u high=%u win=%u modulator=%u", s->dst.seqlo,
1285 s->dst.seqhi, s->dst.max_win, s->dst.seqdiff);
1286 if (s->src.wscale && s->dst.wscale)
1287 printf(" wscale=%u", s->dst.wscale & PF_WSCALE_MASK);
1288 printf("]");
1289 printf(" %u:%u", s->src.state, s->dst.state);
1290}
1291
1292void
1293pf_print_flags(u_int8_t f)
1294{
1295 if (f)
1296 printf(" ");
1297 if (f & TH_FIN)
1298 printf("F");
1299 if (f & TH_SYN)
1300 printf("S");
1301 if (f & TH_RST)
1302 printf("R");
1303 if (f & TH_PUSH)
1304 printf("P");
1305 if (f & TH_ACK)
1306 printf("A");
1307 if (f & TH_URG)
1308 printf("U");
1309 if (f & TH_ECE)
1310 printf("E");
1311 if (f & TH_CWR)
1312 printf("W");
1313}
1314
1315#define PF_SET_SKIP_STEPS(i) \
1316 do { \
1317 while (head[i] != cur) { \
1318 head[i]->skip[i].ptr = cur; \
1319 head[i] = TAILQ_NEXT(head[i], entries); \
1320 } \
1321 } while (0)
1322
1323void
1324pf_calc_skip_steps(struct pf_rulequeue *rules)
1325{
1326 struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT];
1327 int i;
1328
1329 cur = TAILQ_FIRST(rules);
1330 prev = cur;
1331 for (i = 0; i < PF_SKIP_COUNT; ++i)
1332 head[i] = cur;
1333 while (cur != NULL) {
1334
1335 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
1336 PF_SET_SKIP_STEPS(PF_SKIP_IFP);
1337 if (cur->direction != prev->direction)
1338 PF_SET_SKIP_STEPS(PF_SKIP_DIR);
1339 if (cur->af != prev->af)
1340 PF_SET_SKIP_STEPS(PF_SKIP_AF);
1341 if (cur->proto != prev->proto)
1342 PF_SET_SKIP_STEPS(PF_SKIP_PROTO);
1343 if (cur->src.neg != prev->src.neg ||
1344 pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr))
1345 PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR);
1346 if (cur->src.port[0] != prev->src.port[0] ||
1347 cur->src.port[1] != prev->src.port[1] ||
1348 cur->src.port_op != prev->src.port_op)
1349 PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
1350 if (cur->dst.neg != prev->dst.neg ||
1351 pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
1352 PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
1353 if (cur->dst.port[0] != prev->dst.port[0] ||
1354 cur->dst.port[1] != prev->dst.port[1] ||
1355 cur->dst.port_op != prev->dst.port_op)
1356 PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
1357
1358 prev = cur;
1359 cur = TAILQ_NEXT(cur, entries);
1360 }
1361 for (i = 0; i < PF_SKIP_COUNT; ++i)
1362 PF_SET_SKIP_STEPS(i);
1363}
1364
1365int
1366pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
1367{
1368 if (aw1->type != aw2->type)
1369 return (1);
1370 switch (aw1->type) {
1371 case PF_ADDR_ADDRMASK:
1372 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
1373 return (1);
1374 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
1375 return (1);
1376 return (0);
1377 case PF_ADDR_DYNIFTL:
1378 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
1379 case PF_ADDR_NOROUTE:
1380 return (0);
1381 case PF_ADDR_TABLE:
1382 return (aw1->p.tbl != aw2->p.tbl);
1383 default:
1384 printf("invalid address type: %d\n", aw1->type);
1385 return (1);
1386 }
1387}
1388
1389u_int16_t
1390pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp)
1391{
1392 u_int32_t l;
1393
1394 if (udp && !cksum)
1395 return (0x0000);
1396 l = cksum + old - new;
1397 l = (l >> 16) + (l & 65535);
1398 l = l & 65535;
1399 if (udp && !l)
1400 return (0xFFFF);
1401 return (l);
1402}
1403
1404void
1405pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc,
1406 struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af)
1407{
1408 struct pf_addr ao;
1409 u_int16_t po = *p;
1410
1411 PF_ACPY(&ao, a, af);
1412 PF_ACPY(a, an, af);
1413
1414 *p = pn;
1415
1416 switch (af) {
1417#ifdef INET
1418 case AF_INET:
1419 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
1420 ao.addr16[0], an->addr16[0], 0),
1421 ao.addr16[1], an->addr16[1], 0);
1422 *p = pn;
1423 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
1424 ao.addr16[0], an->addr16[0], u),
1425 ao.addr16[1], an->addr16[1], u),
1426 po, pn, u);
1427 break;
1428#endif /* INET */
1429#ifdef INET6
1430 case AF_INET6:
1431 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1432 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1433 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
1434 ao.addr16[0], an->addr16[0], u),
1435 ao.addr16[1], an->addr16[1], u),
1436 ao.addr16[2], an->addr16[2], u),
1437 ao.addr16[3], an->addr16[3], u),
1438 ao.addr16[4], an->addr16[4], u),
1439 ao.addr16[5], an->addr16[5], u),
1440 ao.addr16[6], an->addr16[6], u),
1441 ao.addr16[7], an->addr16[7], u),
1442 po, pn, u);
1443 break;
1444#endif /* INET6 */
1445 }
1446}
1447
1448
1449/* Changes a u_int32_t. Uses a void * so there are no align restrictions */
1450void
1451pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u)
1452{
1453 u_int32_t ao;
1454
1455 memcpy(&ao, a, sizeof(ao));
1456 memcpy(a, &an, sizeof(u_int32_t));
1457 *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u),
1458 ao % 65536, an % 65536, u);
1459}
1460
1461#ifdef INET6
1462void
1463pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u)
1464{
1465 struct pf_addr ao;
1466
1467 PF_ACPY(&ao, a, AF_INET6);
1468 PF_ACPY(a, an, AF_INET6);
1469
1470 *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1471 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1472 pf_cksum_fixup(pf_cksum_fixup(*c,
1473 ao.addr16[0], an->addr16[0], u),
1474 ao.addr16[1], an->addr16[1], u),
1475 ao.addr16[2], an->addr16[2], u),
1476 ao.addr16[3], an->addr16[3], u),
1477 ao.addr16[4], an->addr16[4], u),
1478 ao.addr16[5], an->addr16[5], u),
1479 ao.addr16[6], an->addr16[6], u),
1480 ao.addr16[7], an->addr16[7], u);
1481}
1482#endif /* INET6 */
1483
1484void
1485pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa,
1486 struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c,
1487 u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af)
1488{
1489 struct pf_addr oia, ooa;
1490
1491 PF_ACPY(&oia, ia, af);
1492 PF_ACPY(&ooa, oa, af);
1493
1494 /* Change inner protocol port, fix inner protocol checksum. */
1495 if (ip != NULL) {
1496 u_int16_t oip = *ip;
1497 u_int32_t opc = 0; /* make the compiler happy */
1498
1499 if (pc != NULL)
1500 opc = *pc;
1501 *ip = np;
1502 if (pc != NULL)
1503 *pc = pf_cksum_fixup(*pc, oip, *ip, u);
1504 *ic = pf_cksum_fixup(*ic, oip, *ip, 0);
1505 if (pc != NULL)
1506 *ic = pf_cksum_fixup(*ic, opc, *pc, 0);
1507 }
1508 /* Change inner ip address, fix inner ip and icmp checksums. */
1509 PF_ACPY(ia, na, af);
1510 switch (af) {
1511#ifdef INET
1512 case AF_INET: {
1513 u_int32_t oh2c = *h2c;
1514
1515 *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c,
1516 oia.addr16[0], ia->addr16[0], 0),
1517 oia.addr16[1], ia->addr16[1], 0);
1518 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
1519 oia.addr16[0], ia->addr16[0], 0),
1520 oia.addr16[1], ia->addr16[1], 0);
1521 *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0);
1522 break;
1523 }
1524#endif /* INET */
1525#ifdef INET6
1526 case AF_INET6:
1527 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1528 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1529 pf_cksum_fixup(pf_cksum_fixup(*ic,
1530 oia.addr16[0], ia->addr16[0], u),
1531 oia.addr16[1], ia->addr16[1], u),
1532 oia.addr16[2], ia->addr16[2], u),
1533 oia.addr16[3], ia->addr16[3], u),
1534 oia.addr16[4], ia->addr16[4], u),
1535 oia.addr16[5], ia->addr16[5], u),
1536 oia.addr16[6], ia->addr16[6], u),
1537 oia.addr16[7], ia->addr16[7], u);
1538 break;
1539#endif /* INET6 */
1540 }
1541 /* Change outer ip address, fix outer ip or icmpv6 checksum. */
1542 PF_ACPY(oa, na, af);
1543 switch (af) {
1544#ifdef INET
1545 case AF_INET:
1546 *hc = pf_cksum_fixup(pf_cksum_fixup(*hc,
1547 ooa.addr16[0], oa->addr16[0], 0),
1548 ooa.addr16[1], oa->addr16[1], 0);
1549 break;
1550#endif /* INET */
1551#ifdef INET6
1552 case AF_INET6:
1553 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1554 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1555 pf_cksum_fixup(pf_cksum_fixup(*ic,
1556 ooa.addr16[0], oa->addr16[0], u),
1557 ooa.addr16[1], oa->addr16[1], u),
1558 ooa.addr16[2], oa->addr16[2], u),
1559 ooa.addr16[3], oa->addr16[3], u),
1560 ooa.addr16[4], oa->addr16[4], u),
1561 ooa.addr16[5], oa->addr16[5], u),
1562 ooa.addr16[6], oa->addr16[6], u),
1563 ooa.addr16[7], oa->addr16[7], u);
1564 break;
1565#endif /* INET6 */
1566 }
1567}
1568
1569void
1570pf_send_tcp(const struct pf_rule *r, sa_family_t af,
1571 const struct pf_addr *saddr, const struct pf_addr *daddr,
1572 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
1573 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
1574 struct ether_header *eh, struct ifnet *ifp)
1575{
1576 struct mbuf *m;
1577 int len = 0, tlen; /* make the compiler happy */
1578#ifdef INET
1579 struct ip *h = NULL; /* make the compiler happy */
1580#endif /* INET */
1581#ifdef INET6
1582 struct ip6_hdr *h6 = NULL; /* make the compiler happy */
1583#endif /* INET6 */
1584 struct tcphdr *th = NULL; /* make the compiler happy */
1585 char *opt;
1586
1587 /* maximum segment size tcp option */
1588 tlen = sizeof(struct tcphdr);
1589 if (mss)
1590 tlen += 4;
1591
1592 switch (af) {
1593#ifdef INET
1594 case AF_INET:
1595 len = sizeof(struct ip) + tlen;
1596 break;
1597#endif /* INET */
1598#ifdef INET6
1599 case AF_INET6:
1600 len = sizeof(struct ip6_hdr) + tlen;
1601 break;
1602#endif /* INET6 */
1603 }
1604
1605 /* create outgoing mbuf */
1606 m = m_gethdr(M_DONTWAIT, MT_HEADER);
1607 if (m == NULL)
1608 return;
1609 if (tag) {
1610#ifdef __FreeBSD__
1611 m->m_flags |= M_SKIP_FIREWALL;
1612#else
1613 struct m_tag *mtag;
1614
1615 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
1616 if (mtag == NULL) {
1617 m_freem(m);
1618 return;
1619 }
1620 m_tag_prepend(m, mtag);
1621#endif
1622 }
1623#ifdef ALTQ
1624 if (r != NULL && r->qid) {
1625 struct m_tag *mtag;
1626 struct altq_tag *atag;
1627
1628 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
1629 if (mtag != NULL) {
1630 atag = (struct altq_tag *)(mtag + 1);
1631 atag->qid = r->qid;
1632 /* add hints for ecn */
1633 atag->af = af;
1634 atag->hdr = mtod(m, struct ip *);
1635 m_tag_prepend(m, mtag);
1636 }
1637 }
1638#endif /* ALTQ */
1639 m->m_data += max_linkhdr;
1640 m->m_pkthdr.len = m->m_len = len;
1641 m->m_pkthdr.rcvif = NULL;
1642 bzero(m->m_data, len);
1643 switch (af) {
1644#ifdef INET
1645 case AF_INET:
1646 h = mtod(m, struct ip *);
1647
1648 /* IP header fields included in the TCP checksum */
1649 h->ip_p = IPPROTO_TCP;
1650 h->ip_len = htons(tlen);
1651 h->ip_src.s_addr = saddr->v4.s_addr;
1652 h->ip_dst.s_addr = daddr->v4.s_addr;
1653
1654 th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip));
1655 break;
1656#endif /* INET */
1657#ifdef INET6
1658 case AF_INET6:
1659 h6 = mtod(m, struct ip6_hdr *);
1660
1661 /* IP header fields included in the TCP checksum */
1662 h6->ip6_nxt = IPPROTO_TCP;
1663 h6->ip6_plen = htons(tlen);
1664 memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr));
1665 memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr));
1666
1667 th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr));
1668 break;
1669#endif /* INET6 */
1670 }
1671
1672 /* TCP header */
1673 th->th_sport = sport;
1674 th->th_dport = dport;
1675 th->th_seq = htonl(seq);
1676 th->th_ack = htonl(ack);
1677 th->th_off = tlen >> 2;
1678 th->th_flags = flags;
1679 th->th_win = htons(win);
1680
1681 if (mss) {
1682 opt = (char *)(th + 1);
1683 opt[0] = TCPOPT_MAXSEG;
1684 opt[1] = 4;
1685 HTONS(mss);
1686 bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2);
1687 }
1688
1689 switch (af) {
1690#ifdef INET
1691 case AF_INET:
1692 /* TCP checksum */
1693 th->th_sum = in_cksum(m, len);
1694
1695 /* Finish the IP header */
1696 h->ip_v = 4;
1697 h->ip_hl = sizeof(*h) >> 2;
1698 h->ip_tos = IPTOS_LOWDELAY;
1699#ifdef __FreeBSD__
1700 h->ip_off = path_mtu_discovery ? IP_DF : 0;
1701 h->ip_len = len;
1702#else
1703 h->ip_off = htons(ip_mtudisc ? IP_DF : 0);
1704 h->ip_len = htons(len);
1705#endif
1706 h->ip_ttl = ttl ? ttl : ip_defttl;
1707 h->ip_sum = 0;
1708 if (eh == NULL) {
1709#ifdef __FreeBSD__
1710 PF_UNLOCK();
1711 ip_output(m, (void *)NULL, (void *)NULL, 0,
1712 (void *)NULL, (void *)NULL);
1713 PF_LOCK();
1714#else /* ! __FreeBSD__ */
1715 ip_output(m, (void *)NULL, (void *)NULL, 0,
1716 (void *)NULL, (void *)NULL);
1717#endif
1718 } else {
1719 struct route ro;
1720 struct rtentry rt;
1721 struct ether_header *e = (void *)ro.ro_dst.sa_data;
1722
1723 if (ifp == NULL) {
1724 m_freem(m);
1725 return;
1726 }
1727 rt.rt_ifp = ifp;
1728 ro.ro_rt = &rt;
1729 ro.ro_dst.sa_len = sizeof(ro.ro_dst);
1730 ro.ro_dst.sa_family = pseudo_AF_HDRCMPLT;
1731 bcopy(eh->ether_dhost, e->ether_shost, ETHER_ADDR_LEN);
1732 bcopy(eh->ether_shost, e->ether_dhost, ETHER_ADDR_LEN);
1733 e->ether_type = eh->ether_type;
1734#ifdef __FreeBSD__
1735 PF_UNLOCK();
1736 /* XXX_IMPORT: later */
1737 ip_output(m, (void *)NULL, &ro, 0,
1738 (void *)NULL, (void *)NULL);
1739 PF_LOCK();
1740#else /* ! __FreeBSD__ */
1741 ip_output(m, (void *)NULL, &ro, IP_ROUTETOETHER,
1742 (void *)NULL, (void *)NULL);
1743#endif
1744 }
1745 break;
1746#endif /* INET */
1747#ifdef INET6
1748 case AF_INET6:
1749 /* TCP checksum */
1750 th->th_sum = in6_cksum(m, IPPROTO_TCP,
1751 sizeof(struct ip6_hdr), tlen);
1752
1753 h6->ip6_vfc |= IPV6_VERSION;
1754 h6->ip6_hlim = IPV6_DEFHLIM;
1755
1756#ifdef __FreeBSD__
1757 PF_UNLOCK();
1758 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
1759 PF_LOCK();
1760#else
1761 ip6_output(m, NULL, NULL, 0, NULL, NULL);
1762#endif
1763 break;
1764#endif /* INET6 */
1765 }
1766}
1767
1768void
1769pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
1770 struct pf_rule *r)
1771{
1772#ifdef ALTQ
1773 struct m_tag *mtag;
1774#endif
1775 struct mbuf *m0;
1776#ifdef __FreeBSD__
1777 struct ip *ip;
1778#endif
1779
1780#ifdef __FreeBSD__
1781 m0 = m_copypacket(m, M_DONTWAIT);
1782 if (m0 == NULL)
1783 return;
1784 m0->m_flags |= M_SKIP_FIREWALL;
1785#else
1786 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
1787 if (mtag == NULL)
1788 return;
1789 m0 = m_copy(m, 0, M_COPYALL);
1790 if (m0 == NULL) {
1791 m_tag_free(mtag);
1792 return;
1793 }
1794 m_tag_prepend(m0, mtag);
1795#endif
1796
1797#ifdef ALTQ
1798 if (r->qid) {
1799 struct altq_tag *atag;
1800
1801 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
1802 if (mtag != NULL) {
1803 atag = (struct altq_tag *)(mtag + 1);
1804 atag->qid = r->qid;
1805 /* add hints for ecn */
1806 atag->af = af;
1807 atag->hdr = mtod(m0, struct ip *);
1808 m_tag_prepend(m0, mtag);
1809 }
1810 }
1811#endif /* ALTQ */
1812
1813 switch (af) {
1814#ifdef INET
1815 case AF_INET:
1816#ifdef __FreeBSD__
1817 /* icmp_error() expects host byte ordering */
1818 ip = mtod(m0, struct ip *);
1819 NTOHS(ip->ip_len);
1820 NTOHS(ip->ip_off);
1821 PF_UNLOCK();
1822 icmp_error(m0, type, code, 0, 0);
1823 PF_LOCK();
1824#else
1825 icmp_error(m0, type, code, 0, (void *)NULL);
1826#endif
1827 break;
1828#endif /* INET */
1829#ifdef INET6
1830 case AF_INET6:
1831#ifdef __FreeBSD__
1832 PF_UNLOCK();
1833#endif
1834 icmp6_error(m0, type, code, 0);
1835#ifdef __FreeBSD__
1836 PF_LOCK();
1837#endif
1838 break;
1839#endif /* INET6 */
1840 }
1841}
1842
1843/*
1844 * Return 1 if the addresses a and b match (with mask m), otherwise return 0.
1845 * If n is 0, they match if they are equal. If n is != 0, they match if they
1846 * are different.
1847 */
1848int
1849pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
1850 struct pf_addr *b, sa_family_t af)
1851{
1852 int match = 0;
1853
1854 switch (af) {
1855#ifdef INET
1856 case AF_INET:
1857 if ((a->addr32[0] & m->addr32[0]) ==
1858 (b->addr32[0] & m->addr32[0]))
1859 match++;
1860 break;
1861#endif /* INET */
1862#ifdef INET6
1863 case AF_INET6:
1864 if (((a->addr32[0] & m->addr32[0]) ==
1865 (b->addr32[0] & m->addr32[0])) &&
1866 ((a->addr32[1] & m->addr32[1]) ==
1867 (b->addr32[1] & m->addr32[1])) &&
1868 ((a->addr32[2] & m->addr32[2]) ==
1869 (b->addr32[2] & m->addr32[2])) &&
1870 ((a->addr32[3] & m->addr32[3]) ==
1871 (b->addr32[3] & m->addr32[3])))
1872 match++;
1873 break;
1874#endif /* INET6 */
1875 }
1876 if (match) {
1877 if (n)
1878 return (0);
1879 else
1880 return (1);
1881 } else {
1882 if (n)
1883 return (1);
1884 else
1885 return (0);
1886 }
1887}
1888
1889int
1890pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
1891{
1892 switch (op) {
1893 case PF_OP_IRG:
1894 return ((p > a1) && (p < a2));
1895 case PF_OP_XRG:
1896 return ((p < a1) || (p > a2));
1897 case PF_OP_RRG:
1898 return ((p >= a1) && (p <= a2));
1899 case PF_OP_EQ:
1900 return (p == a1);
1901 case PF_OP_NE:
1902 return (p != a1);
1903 case PF_OP_LT:
1904 return (p < a1);
1905 case PF_OP_LE:
1906 return (p <= a1);
1907 case PF_OP_GT:
1908 return (p > a1);
1909 case PF_OP_GE:
1910 return (p >= a1);
1911 }
1912 return (0); /* never reached */
1913}
1914
1915int
1916pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
1917{
1918 NTOHS(a1);
1919 NTOHS(a2);
1920 NTOHS(p);
1921 return (pf_match(op, a1, a2, p));
1922}
1923
1924int
1925pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
1926{
1927 if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
1928 return (0);
1929 return (pf_match(op, a1, a2, u));
1930}
1931
1932int
1933pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
1934{
1935 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
1936 return (0);
1937 return (pf_match(op, a1, a2, g));
1938}
1939
1940struct pf_tag *
1941pf_get_tag(struct mbuf *m)
1942{
1943 struct m_tag *mtag;
1944
1945 if ((mtag = m_tag_find(m, PACKET_TAG_PF_TAG, NULL)) != NULL)
1946 return ((struct pf_tag *)(mtag + 1));
1947 else
1948 return (NULL);
1949}
1950
1951int
1952pf_match_tag(struct mbuf *m, struct pf_rule *r, struct pf_tag **pftag, int *tag)
1953{
1954 if (*tag == -1) { /* find mbuf tag */
1955 *pftag = pf_get_tag(m);
1956 if (*pftag != NULL)
1957 *tag = (*pftag)->tag;
1958 else
1959 *tag = 0;
1960 }
1961
1962 return ((!r->match_tag_not && r->match_tag == *tag) ||
1963 (r->match_tag_not && r->match_tag != *tag));
1964}
1965
1966int
1967pf_tag_packet(struct mbuf *m, struct pf_tag *pftag, int tag)
1968{
1969 struct m_tag *mtag;
1970
1971 if (tag <= 0)
1972 return (0);
1973
1974 if (pftag == NULL) {
1975 mtag = m_tag_get(PACKET_TAG_PF_TAG, sizeof(*pftag), M_NOWAIT);
1976 if (mtag == NULL)
1977 return (1);
1978 ((struct pf_tag *)(mtag + 1))->tag = tag;
1979 m_tag_prepend(m, mtag);
1980 } else
1981 pftag->tag = tag;
1982
1983 return (0);
1984}
1985
1986static void
1987pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n,
1988 struct pf_rule **r, struct pf_rule **a)
1989{
1990 struct pf_anchor_stackframe *f;
1991
1992 if (*depth >= sizeof(pf_anchor_stack) /
1993 sizeof(pf_anchor_stack[0])) {
1994 printf("pf_step_into_anchor: stack overflow\n");
1995 *r = TAILQ_NEXT(*r, entries);
1996 return;
1997 } else if (*depth == 0 && a != NULL)
1998 *a = *r;
1999 f = pf_anchor_stack + (*depth)++;
2000 f->rs = *rs;
2001 f->r = *r;
2002 if ((*r)->anchor_wildcard) {
2003 f->parent = &(*r)->anchor->children;
2004 if ((f->child = RB_MIN(pf_anchor_node, f->parent)) ==
2005 NULL) {
2006 *r = NULL;
2007 return;
2008 }
2009 *rs = &f->child->ruleset;
2010 } else {
2011 f->parent = NULL;
2012 f->child = NULL;
2013 *rs = &(*r)->anchor->ruleset;
2014 }
2015 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2016}
2017
2018static void
2019pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n,
2020 struct pf_rule **r, struct pf_rule **a)
2021{
2022 struct pf_anchor_stackframe *f;
2023
2024 do {
2025 if (*depth <= 0)
2026 break;
2027 f = pf_anchor_stack + *depth - 1;
2028 if (f->parent != NULL && f->child != NULL) {
2029 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child);
2030 if (f->child != NULL) {
2031 *rs = &f->child->ruleset;
2032 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
2033 if (*r == NULL)
2034 continue;
2035 else
2036 break;
2037 }
2038 }
2039 (*depth)--;
2040 if (*depth == 0 && a != NULL)
2041 *a = NULL;
2042 *rs = f->rs;
2043 *r = TAILQ_NEXT(f->r, entries);
2044 } while (*r == NULL);
2045}
2046
2047#ifdef INET6
2048void
2049pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
2050 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af)
2051{
2052 switch (af) {
2053#ifdef INET
2054 case AF_INET:
2055 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
2056 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
2057 break;
2058#endif /* INET */
2059 case AF_INET6:
2060 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
2061 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
2062 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) |
2063 ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]);
2064 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) |
2065 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]);
2066 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) |
2067 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]);
2068 break;
2069 }
2070}
2071
2072void
2073pf_addr_inc(struct pf_addr *addr, sa_family_t af)
2074{
2075 switch (af) {
2076#ifdef INET
2077 case AF_INET:
2078 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1);
2079 break;
2080#endif /* INET */
2081 case AF_INET6:
2082 if (addr->addr32[3] == 0xffffffff) {
2083 addr->addr32[3] = 0;
2084 if (addr->addr32[2] == 0xffffffff) {
2085 addr->addr32[2] = 0;
2086 if (addr->addr32[1] == 0xffffffff) {
2087 addr->addr32[1] = 0;
2088 addr->addr32[0] =
2089 htonl(ntohl(addr->addr32[0]) + 1);
2090 } else
2091 addr->addr32[1] =
2092 htonl(ntohl(addr->addr32[1]) + 1);
2093 } else
2094 addr->addr32[2] =
2095 htonl(ntohl(addr->addr32[2]) + 1);
2096 } else
2097 addr->addr32[3] =
2098 htonl(ntohl(addr->addr32[3]) + 1);
2099 break;
2100 }
2101}
2102#endif /* INET6 */
2103
2104#define mix(a,b,c) \
2105 do { \
2106 a -= b; a -= c; a ^= (c >> 13); \
2107 b -= c; b -= a; b ^= (a << 8); \
2108 c -= a; c -= b; c ^= (b >> 13); \
2109 a -= b; a -= c; a ^= (c >> 12); \
2110 b -= c; b -= a; b ^= (a << 16); \
2111 c -= a; c -= b; c ^= (b >> 5); \
2112 a -= b; a -= c; a ^= (c >> 3); \
2113 b -= c; b -= a; b ^= (a << 10); \
2114 c -= a; c -= b; c ^= (b >> 15); \
2115 } while (0)
2116
2117/*
2118 * hash function based on bridge_hash in if_bridge.c
2119 */
2120void
2121pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
2122 struct pf_poolhashkey *key, sa_family_t af)
2123{
2124 u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0];
2125
2126 switch (af) {
2127#ifdef INET
2128 case AF_INET:
2129 a += inaddr->addr32[0];
2130 b += key->key32[1];
2131 mix(a, b, c);
2132 hash->addr32[0] = c + key->key32[2];
2133 break;
2134#endif /* INET */
2135#ifdef INET6
2136 case AF_INET6:
2137 a += inaddr->addr32[0];
2138 b += inaddr->addr32[2];
2139 mix(a, b, c);
2140 hash->addr32[0] = c;
2141 a += inaddr->addr32[1];
2142 b += inaddr->addr32[3];
2143 c += key->key32[1];
2144 mix(a, b, c);
2145 hash->addr32[1] = c;
2146 a += inaddr->addr32[2];
2147 b += inaddr->addr32[1];
2148 c += key->key32[2];
2149 mix(a, b, c);
2150 hash->addr32[2] = c;
2151 a += inaddr->addr32[3];
2152 b += inaddr->addr32[0];
2153 c += key->key32[3];
2154 mix(a, b, c);
2155 hash->addr32[3] = c;
2156 break;
2157#endif /* INET6 */
2158 }
2159}
2160
2161int
2162pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
2163 struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
2164{
2165 unsigned char hash[16];
2166 struct pf_pool *rpool = &r->rpool;
2167 struct pf_addr *raddr = &rpool->cur->addr.v.a.addr;
2168 struct pf_addr *rmask = &rpool->cur->addr.v.a.mask;
2169 struct pf_pooladdr *acur = rpool->cur;
2170 struct pf_src_node k;
2171
2172 if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
2173 (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
2174 k.af = af;
2175 PF_ACPY(&k.addr, saddr, af);
2176 if (r->rule_flag & PFRULE_RULESRCTRACK ||
2177 r->rpool.opts & PF_POOL_STICKYADDR)
2178 k.rule.ptr = r;
2179 else
2180 k.rule.ptr = NULL;
2181 pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
2182 *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
2183 if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
2184 PF_ACPY(naddr, &(*sn)->raddr, af);
2185 if (pf_status.debug >= PF_DEBUG_MISC) {
2186 printf("pf_map_addr: src tracking maps ");
2187 pf_print_host(&k.addr, 0, af);
2188 printf(" to ");
2189 pf_print_host(naddr, 0, af);
2190 printf("\n");
2191 }
2192 return (0);
2193 }
2194 }
2195
2196 if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
2197 return (1);
2198 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2199 switch (af) {
2200#ifdef INET
2201 case AF_INET:
2202 if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
2203 (rpool->opts & PF_POOL_TYPEMASK) !=
2204 PF_POOL_ROUNDROBIN)
2205 return (1);
2206 raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
2207 rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
2208 break;
2209#endif /* INET */
2210#ifdef INET6
2211 case AF_INET6:
2212 if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
2213 (rpool->opts & PF_POOL_TYPEMASK) !=
2214 PF_POOL_ROUNDROBIN)
2215 return (1);
2216 raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
2217 rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
2218 break;
2219#endif /* INET6 */
2220 }
2221 } else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2222 if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
2223 return (1); /* unsupported */
2224 } else {
2225 raddr = &rpool->cur->addr.v.a.addr;
2226 rmask = &rpool->cur->addr.v.a.mask;
2227 }
2228
2229 switch (rpool->opts & PF_POOL_TYPEMASK) {
2230 case PF_POOL_NONE:
2231 PF_ACPY(naddr, raddr, af);
2232 break;
2233 case PF_POOL_BITMASK:
2234 PF_POOLMASK(naddr, raddr, rmask, saddr, af);
2235 break;
2236 case PF_POOL_RANDOM:
2237 if (init_addr != NULL && PF_AZERO(init_addr, af)) {
2238 switch (af) {
2239#ifdef INET
2240 case AF_INET:
2241 rpool->counter.addr32[0] = htonl(arc4random());
2242 break;
2243#endif /* INET */
2244#ifdef INET6
2245 case AF_INET6:
2246 if (rmask->addr32[3] != 0xffffffff)
2247 rpool->counter.addr32[3] =
2248 htonl(arc4random());
2249 else
2250 break;
2251 if (rmask->addr32[2] != 0xffffffff)
2252 rpool->counter.addr32[2] =
2253 htonl(arc4random());
2254 else
2255 break;
2256 if (rmask->addr32[1] != 0xffffffff)
2257 rpool->counter.addr32[1] =
2258 htonl(arc4random());
2259 else
2260 break;
2261 if (rmask->addr32[0] != 0xffffffff)
2262 rpool->counter.addr32[0] =
2263 htonl(arc4random());
2264 break;
2265#endif /* INET6 */
2266 }
2267 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
2268 PF_ACPY(init_addr, naddr, af);
2269
2270 } else {
2271 PF_AINC(&rpool->counter, af);
2272 PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
2273 }
2274 break;
2275 case PF_POOL_SRCHASH:
2276 pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
2277 PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
2278 break;
2279 case PF_POOL_ROUNDROBIN:
2280 if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2281 if (!pfr_pool_get(rpool->cur->addr.p.tbl,
2282 &rpool->tblidx, &rpool->counter,
2283 &raddr, &rmask, af))
2284 goto get_addr;
2285 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2286 if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
2287 &rpool->tblidx, &rpool->counter,
2288 &raddr, &rmask, af))
2289 goto get_addr;
2290 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
2291 goto get_addr;
2292
2293 try_next:
2294 if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL)
2295 rpool->cur = TAILQ_FIRST(&rpool->list);
2296 if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2297 rpool->tblidx = -1;
2298 if (pfr_pool_get(rpool->cur->addr.p.tbl,
2299 &rpool->tblidx, &rpool->counter,
2300 &raddr, &rmask, af)) {
2301 /* table contains no address of type 'af' */
2302 if (rpool->cur != acur)
2303 goto try_next;
2304 return (1);
2305 }
2306 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2307 rpool->tblidx = -1;
2308 if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
2309 &rpool->tblidx, &rpool->counter,
2310 &raddr, &rmask, af)) {
2311 /* table contains no address of type 'af' */
2312 if (rpool->cur != acur)
2313 goto try_next;
2314 return (1);
2315 }
2316 } else {
2317 raddr = &rpool->cur->addr.v.a.addr;
2318 rmask = &rpool->cur->addr.v.a.mask;
2319 PF_ACPY(&rpool->counter, raddr, af);
2320 }
2321
2322 get_addr:
2323 PF_ACPY(naddr, &rpool->counter, af);
2324 if (init_addr != NULL && PF_AZERO(init_addr, af))
2325 PF_ACPY(init_addr, naddr, af);
2326 PF_AINC(&rpool->counter, af);
2327 break;
2328 }
2329 if (*sn != NULL)
2330 PF_ACPY(&(*sn)->raddr, naddr, af);
2331
2332 if (pf_status.debug >= PF_DEBUG_MISC &&
2333 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
2334 printf("pf_map_addr: selected address ");
2335 pf_print_host(naddr, 0, af);
2336 printf("\n");
2337 }
2338
2339 return (0);
2340}
2341
2342int
2343pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
2344 struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
2345 struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
2346 struct pf_src_node **sn)
2347{
2348 struct pf_state key;
2349 struct pf_addr init_addr;
2350 u_int16_t cut;
2351
2352 bzero(&init_addr, sizeof(init_addr));
2353 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
2354 return (1);
2355
2356 if (proto == IPPROTO_ICMP) {
2357 low = 1;
2358 high = 65535;
2359 }
2360
2361 do {
2362 key.af = af;
2363 key.proto = proto;
2364 PF_ACPY(&key.ext.addr, daddr, key.af);
2365 PF_ACPY(&key.gwy.addr, naddr, key.af);
2366 key.ext.port = dport;
2367
2368 /*
2369 * port search; start random, step;
2370 * similar 2 portloop in in_pcbbind
2371 */
2372 if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
2373 proto == IPPROTO_ICMP)) {
2374 key.gwy.port = dport;
2375 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
2376 return (0);
2377 } else if (low == 0 && high == 0) {
2378 key.gwy.port = *nport;
2379 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
2380 return (0);
2381 } else if (low == high) {
2382 key.gwy.port = htons(low);
2383 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) {
2384 *nport = htons(low);
2385 return (0);
2386 }
2387 } else {
2388 u_int16_t tmp;
2389
2390 if (low > high) {
2391 tmp = low;
2392 low = high;
2393 high = tmp;
2394 }
2395 /* low < high */
2396 cut = htonl(arc4random()) % (1 + high - low) + low;
2397 /* low <= cut <= high */
2398 for (tmp = cut; tmp <= high; ++(tmp)) {
2399 key.gwy.port = htons(tmp);
2400 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
2401 NULL) {
2402 *nport = htons(tmp);
2403 return (0);
2404 }
2405 }
2406 for (tmp = cut - 1; tmp >= low; --(tmp)) {
2407 key.gwy.port = htons(tmp);
2408 if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
2409 NULL) {
2410 *nport = htons(tmp);
2411 return (0);
2412 }
2413 }
2414 }
2415
2416 switch (r->rpool.opts & PF_POOL_TYPEMASK) {
2417 case PF_POOL_RANDOM:
2418 case PF_POOL_ROUNDROBIN:
2419 if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
2420 return (1);
2421 break;
2422 case PF_POOL_NONE:
2423 case PF_POOL_SRCHASH:
2424 case PF_POOL_BITMASK:
2425 default:
2426 return (1);
2427 }
2428 } while (! PF_AEQ(&init_addr, naddr, af) );
2429
2430 return (1); /* none available */
2431}
2432
2433struct pf_rule *
2434pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
2435 int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
2436 struct pf_addr *daddr, u_int16_t dport, int rs_num)
2437{
2438 struct pf_rule *r, *rm = NULL;
2439 struct pf_ruleset *ruleset = NULL;
2440 struct pf_tag *pftag = NULL;
2441 int tag = -1;
2442 int asd = 0;
2443
2444 r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
2445 while (r && rm == NULL) {
2446 struct pf_rule_addr *src = NULL, *dst = NULL;
2447 struct pf_addr_wrap *xdst = NULL;
2448
2449 if (r->action == PF_BINAT && direction == PF_IN) {
2450 src = &r->dst;
2451 if (r->rpool.cur != NULL)
2452 xdst = &r->rpool.cur->addr;
2453 } else {
2454 src = &r->src;
2455 dst = &r->dst;
2456 }
2457
2458 r->evaluations++;
2459 if (r->kif != NULL &&
2460 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
2461 r = r->skip[PF_SKIP_IFP].ptr;
2462 else if (r->direction && r->direction != direction)
2463 r = r->skip[PF_SKIP_DIR].ptr;
2464 else if (r->af && r->af != pd->af)
2465 r = r->skip[PF_SKIP_AF].ptr;
2466 else if (r->proto && r->proto != pd->proto)
2467 r = r->skip[PF_SKIP_PROTO].ptr;
2468 else if (PF_MISMATCHAW(&src->addr, saddr, pd->af, src->neg))
2469 r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR :
2470 PF_SKIP_DST_ADDR].ptr;
2471 else if (src->port_op && !pf_match_port(src->port_op,
2472 src->port[0], src->port[1], sport))
2473 r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
2474 PF_SKIP_DST_PORT].ptr;
2475 else if (dst != NULL &&
2476 PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg))
2477 r = r->skip[PF_SKIP_DST_ADDR].ptr;
2478 else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af, 0))
2479 r = TAILQ_NEXT(r, entries);
2480 else if (dst != NULL && dst->port_op &&
2481 !pf_match_port(dst->port_op, dst->port[0],
2482 dst->port[1], dport))
2483 r = r->skip[PF_SKIP_DST_PORT].ptr;
2484 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
2485 r = TAILQ_NEXT(r, entries);
2486 else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
2487 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
2488 off, pd->hdr.tcp), r->os_fingerprint)))
2489 r = TAILQ_NEXT(r, entries);
2490 else {
2491 if (r->tag)
2492 tag = r->tag;
2493 if (r->anchor == NULL) {
2494 rm = r;
2495 } else
2496 pf_step_into_anchor(&asd, &ruleset, rs_num, &r, NULL);
2497 }
2498 if (r == NULL)
2499 pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r, NULL);
2500 }
2501 if (pf_tag_packet(m, pftag, tag))
2502 return (NULL);
2503 if (rm != NULL && (rm->action == PF_NONAT ||
2504 rm->action == PF_NORDR || rm->action == PF_NOBINAT))
2505 return (NULL);
2506 return (rm);
2507}
2508
2509struct pf_rule *
2510pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
2511 struct pfi_kif *kif, struct pf_src_node **sn,
2512 struct pf_addr *saddr, u_int16_t sport,
2513 struct pf_addr *daddr, u_int16_t dport,
2514 struct pf_addr *naddr, u_int16_t *nport)
2515{
2516 struct pf_rule *r = NULL;
2517
2518 if (direction == PF_OUT) {
2519 r = pf_match_translation(pd, m, off, direction, kif, saddr,
2520 sport, daddr, dport, PF_RULESET_BINAT);
2521 if (r == NULL)
2522 r = pf_match_translation(pd, m, off, direction, kif,
2523 saddr, sport, daddr, dport, PF_RULESET_NAT);
2524 } else {
2525 r = pf_match_translation(pd, m, off, direction, kif, saddr,
2526 sport, daddr, dport, PF_RULESET_RDR);
2527 if (r == NULL)
2528 r = pf_match_translation(pd, m, off, direction, kif,
2529 saddr, sport, daddr, dport, PF_RULESET_BINAT);
2530 }
2531
2532 if (r != NULL) {
2533 switch (r->action) {
2534 case PF_NONAT:
2535 case PF_NOBINAT:
2536 case PF_NORDR:
2537 return (NULL);
2538 case PF_NAT:
2539 if (pf_get_sport(pd->af, pd->proto, r, saddr,
2540 daddr, dport, naddr, nport, r->rpool.proxy_port[0],
2541 r->rpool.proxy_port[1], sn)) {
2542 DPFPRINTF(PF_DEBUG_MISC,
2543 ("pf: NAT proxy port allocation "
2544 "(%u-%u) failed\n",
2545 r->rpool.proxy_port[0],
2546 r->rpool.proxy_port[1]));
2547 return (NULL);
2548 }
2549 break;
2550 case PF_BINAT:
2551 switch (direction) {
2552 case PF_OUT:
2553 if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
2554 switch (pd->af) {
2555#ifdef INET
2556 case AF_INET:
2557 if (r->rpool.cur->addr.p.dyn->
2558 pfid_acnt4 < 1)
2559 return (NULL);
2560 PF_POOLMASK(naddr,
2561 &r->rpool.cur->addr.p.dyn->
2562 pfid_addr4,
2563 &r->rpool.cur->addr.p.dyn->
2564 pfid_mask4,
2565 saddr, AF_INET);
2566 break;
2567#endif /* INET */
2568#ifdef INET6
2569 case AF_INET6:
2570 if (r->rpool.cur->addr.p.dyn->
2571 pfid_acnt6 < 1)
2572 return (NULL);
2573 PF_POOLMASK(naddr,
2574 &r->rpool.cur->addr.p.dyn->
2575 pfid_addr6,
2576 &r->rpool.cur->addr.p.dyn->
2577 pfid_mask6,
2578 saddr, AF_INET6);
2579 break;
2580#endif /* INET6 */
2581 }
2582 } else
2583 PF_POOLMASK(naddr,
2584 &r->rpool.cur->addr.v.a.addr,
2585 &r->rpool.cur->addr.v.a.mask,
2586 saddr, pd->af);
2587 break;
2588 case PF_IN:
2589 if (r->src.addr.type == PF_ADDR_DYNIFTL) {
2590 switch (pd->af) {
2591#ifdef INET
2592 case AF_INET:
2593 if (r->src.addr.p.dyn->
2594 pfid_acnt4 < 1)
2595 return (NULL);
2596 PF_POOLMASK(naddr,
2597 &r->src.addr.p.dyn->
2598 pfid_addr4,
2599 &r->src.addr.p.dyn->
2600 pfid_mask4,
2601 daddr, AF_INET);
2602 break;
2603#endif /* INET */
2604#ifdef INET6
2605 case AF_INET6:
2606 if (r->src.addr.p.dyn->
2607 pfid_acnt6 < 1)
2608 return (NULL);
2609 PF_POOLMASK(naddr,
2610 &r->src.addr.p.dyn->
2611 pfid_addr6,
2612 &r->src.addr.p.dyn->
2613 pfid_mask6,
2614 daddr, AF_INET6);
2615 break;
2616#endif /* INET6 */
2617 }
2618 } else
2619 PF_POOLMASK(naddr,
2620 &r->src.addr.v.a.addr,
2621 &r->src.addr.v.a.mask, daddr,
2622 pd->af);
2623 break;
2624 }
2625 break;
2626 case PF_RDR: {
2627 if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
2628 return (NULL);
2629 if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
2630 PF_POOL_BITMASK)
2631 PF_POOLMASK(naddr, naddr,
2632 &r->rpool.cur->addr.v.a.mask, daddr,
2633 pd->af);
2634
2635 if (r->rpool.proxy_port[1]) {
2636 u_int32_t tmp_nport;
2637
2638 tmp_nport = ((ntohs(dport) -
2639 ntohs(r->dst.port[0])) %
2640 (r->rpool.proxy_port[1] -
2641 r->rpool.proxy_port[0] + 1)) +
2642 r->rpool.proxy_port[0];
2643
2644 /* wrap around if necessary */
2645 if (tmp_nport > 65535)
2646 tmp_nport -= 65535;
2647 *nport = htons((u_int16_t)tmp_nport);
2648 } else if (r->rpool.proxy_port[0])
2649 *nport = htons(r->rpool.proxy_port[0]);
2650 break;
2651 }
2652 default:
2653 return (NULL);
2654 }
2655 }
2656
2657 return (r);
2658}
2659
2660int
2661#ifdef __FreeBSD__
2662pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd,
2663 struct inpcb *inp_arg)
2664#else
2665pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd)
2666#endif
2667{
2668 struct pf_addr *saddr, *daddr;
2669 u_int16_t sport, dport;
2670#ifdef __FreeBSD__
2671 struct inpcbinfo *pi;
2672#else
2673 struct inpcbtable *tb;
2674#endif
2675 struct inpcb *inp;
2676
2677 *uid = UID_MAX;
2678 *gid = GID_MAX;
2679#ifdef __FreeBSD__
2680 if (inp_arg != NULL) {
2681 INP_LOCK_ASSERT(inp_arg);
2682 if (inp_arg->inp_socket) {
2683 *uid = inp_arg->inp_socket->so_cred->cr_uid;
2684 *gid = inp_arg->inp_socket->so_cred->cr_groups[0];
2685 return (1);
2686 } else
2687 return (0);
2688 }
2689#endif
2690 switch (pd->proto) {
2691 case IPPROTO_TCP:
2692 sport = pd->hdr.tcp->th_sport;
2693 dport = pd->hdr.tcp->th_dport;
2694#ifdef __FreeBSD__
2695 pi = &tcbinfo;
2696#else
2697 tb = &tcbtable;
2698#endif
2699 break;
2700 case IPPROTO_UDP:
2701 sport = pd->hdr.udp->uh_sport;
2702 dport = pd->hdr.udp->uh_dport;
2703#ifdef __FreeBSD__
2704 pi = &udbinfo;
2705#else
2706 tb = &udbtable;
2707#endif
2708 break;
2709 default:
2710 return (0);
2711 }
2712 if (direction == PF_IN) {
2713 saddr = pd->src;
2714 daddr = pd->dst;
2715 } else {
2716 u_int16_t p;
2717
2718 p = sport;
2719 sport = dport;
2720 dport = p;
2721 saddr = pd->dst;
2722 daddr = pd->src;
2723 }
2724 switch (pd->af) {
2725#ifdef INET
2726 case AF_INET:
2727#ifdef __FreeBSD__
2728 INP_INFO_RLOCK(pi); /* XXX LOR */
2729 inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4,
2730 dport, 0, NULL);
2731 if (inp == NULL) {
2732 inp = in_pcblookup_hash(pi, saddr->v4, sport,
2733 daddr->v4, dport, INPLOOKUP_WILDCARD, NULL);
2734 if(inp == NULL) {
2735 INP_INFO_RUNLOCK(pi);
2736 return (0);
2737 }
2738 }
2739#else
2740 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport);
2741 if (inp == NULL) {
2742 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0);
2743 if (inp == NULL)
2744 return (0);
2745 }
2746#endif
2747 break;
2748#endif /* INET */
2749#ifdef INET6
2750 case AF_INET6:
2751#ifdef __FreeBSD__
2752 INP_INFO_RLOCK(pi);
2753 inp = in6_pcblookup_hash(pi, &saddr->v6, sport,
2754 &daddr->v6, dport, 0, NULL);
2755 if (inp == NULL) {
2756 inp = in6_pcblookup_hash(pi, &saddr->v6, sport,
2757 &daddr->v6, dport, INPLOOKUP_WILDCARD, NULL);
2758 if (inp == NULL) {
2759 INP_INFO_RUNLOCK(pi);
2760 return (0);
2761 }
2762 }
2763#else
2764 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6,
2765 dport);
2766 if (inp == NULL) {
2767 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0);
2768 if (inp == NULL)
2769 return (0);
2770 }
2771#endif
2772 break;
2773#endif /* INET6 */
2774
2775 default:
2776 return (0);
2777 }
2778#ifdef __FreeBSD__
2779 INP_LOCK(inp);
2780 if ((inp->inp_socket == NULL) || (inp->inp_socket->so_cred == NULL)) {
2781 INP_UNLOCK(inp);
2782 INP_INFO_RUNLOCK(pi);
2783 return (0);
2784 }
2785 *uid = inp->inp_socket->so_cred->cr_uid;
2786 *gid = inp->inp_socket->so_cred->cr_groups[0];
2787 INP_UNLOCK(inp);
2788 INP_INFO_RUNLOCK(pi);
2789#else
2790 *uid = inp->inp_socket->so_euid;
2791 *gid = inp->inp_socket->so_egid;
2792#endif
2793 return (1);
2794}
2795
2796u_int8_t
2797pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
2798{
2799 int hlen;
2800 u_int8_t hdr[60];
2801 u_int8_t *opt, optlen;
2802 u_int8_t wscale = 0;
2803
2804 hlen = th_off << 2; /* hlen <= sizeof(hdr) */
2805 if (hlen <= sizeof(struct tcphdr))
2806 return (0);
2807 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
2808 return (0);
2809 opt = hdr + sizeof(struct tcphdr);
2810 hlen -= sizeof(struct tcphdr);
2811 while (hlen >= 3) {
2812 switch (*opt) {
2813 case TCPOPT_EOL:
2814 case TCPOPT_NOP:
2815 ++opt;
2816 --hlen;
2817 break;
2818 case TCPOPT_WINDOW:
2819 wscale = opt[2];
2820 if (wscale > TCP_MAX_WINSHIFT)
2821 wscale = TCP_MAX_WINSHIFT;
2822 wscale |= PF_WSCALE_FLAG;
2823 /* FALLTHROUGH */
2824 default:
2825 optlen = opt[1];
2826 if (optlen < 2)
2827 optlen = 2;
2828 hlen -= optlen;
2829 opt += optlen;
2830 break;
2831 }
2832 }
2833 return (wscale);
2834}
2835
2836u_int16_t
2837pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
2838{
2839 int hlen;
2840 u_int8_t hdr[60];
2841 u_int8_t *opt, optlen;
2842 u_int16_t mss = tcp_mssdflt;
2843
2844 hlen = th_off << 2; /* hlen <= sizeof(hdr) */
2845 if (hlen <= sizeof(struct tcphdr))
2846 return (0);
2847 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
2848 return (0);
2849 opt = hdr + sizeof(struct tcphdr);
2850 hlen -= sizeof(struct tcphdr);
2851 while (hlen >= TCPOLEN_MAXSEG) {
2852 switch (*opt) {
2853 case TCPOPT_EOL:
2854 case TCPOPT_NOP:
2855 ++opt;
2856 --hlen;
2857 break;
2858 case TCPOPT_MAXSEG:
2859 bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2);
2860 NTOHS(mss);
2861 /* FALLTHROUGH */
2862 default:
2863 optlen = opt[1];
2864 if (optlen < 2)
2865 optlen = 2;
2866 hlen -= optlen;
2867 opt += optlen;
2868 break;
2869 }
2870 }
2871 return (mss);
2872}
2873
2874u_int16_t
2875pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer)
2876{
2877#ifdef INET
2878 struct sockaddr_in *dst;
2879 struct route ro;
2880#endif /* INET */
2881#ifdef INET6
2882 struct sockaddr_in6 *dst6;
2883 struct route_in6 ro6;
2884#endif /* INET6 */
2885 struct rtentry *rt = NULL;
2886 int hlen = 0; /* make the compiler happy */
2887 u_int16_t mss = tcp_mssdflt;
2888
2889 switch (af) {
2890#ifdef INET
2891 case AF_INET:
2892 hlen = sizeof(struct ip);
2893 bzero(&ro, sizeof(ro));
2894 dst = (struct sockaddr_in *)&ro.ro_dst;
2895 dst->sin_family = AF_INET;
2896 dst->sin_len = sizeof(*dst);
2897 dst->sin_addr = addr->v4;
2898#ifdef __FreeBSD__
2899#ifdef RTF_PRCLONING
2900 rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING));
2901#else /* !RTF_PRCLONING */
2902 rtalloc_ign(&ro, RTF_CLONING);
2903#endif
2904#else /* ! __FreeBSD__ */
2905 rtalloc_noclone(&ro, NO_CLONING);
2906#endif
2907 rt = ro.ro_rt;
2908 break;
2909#endif /* INET */
2910#ifdef INET6
2911 case AF_INET6:
2912 hlen = sizeof(struct ip6_hdr);
2913 bzero(&ro6, sizeof(ro6));
2914 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst;
2915 dst6->sin6_family = AF_INET6;
2916 dst6->sin6_len = sizeof(*dst6);
2917 dst6->sin6_addr = addr->v6;
2918#ifdef __FreeBSD__
2919#ifdef RTF_PRCLONING
2920 rtalloc_ign((struct route *)&ro6,
2921 (RTF_CLONING | RTF_PRCLONING));
2922#else /* !RTF_PRCLONING */
2923 rtalloc_ign((struct route *)&ro6, RTF_CLONING);
2924#endif
2925#else /* ! __FreeBSD__ */
2926 rtalloc_noclone((struct route *)&ro6, NO_CLONING);
2927#endif
2928 rt = ro6.ro_rt;
2929 break;
2930#endif /* INET6 */
2931 }
2932
2933 if (rt && rt->rt_ifp) {
2934 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr);
2935 mss = max(tcp_mssdflt, mss);
2936 RTFREE(rt);
2937 }
2938 mss = min(mss, offer);
2939 mss = max(mss, 64); /* sanity - at least max opt space */
2940 return (mss);
2941}
2942
2943void
2944pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
2945{
2946 struct pf_rule *r = s->rule.ptr;
2947
2948 s->rt_kif = NULL;
2949 if (!r->rt || r->rt == PF_FASTROUTE)
2950 return;
2951 switch (s->af) {
2952#ifdef INET
2953 case AF_INET:
2954 pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL,
2955 &s->nat_src_node);
2956 s->rt_kif = r->rpool.cur->kif;
2957 break;
2958#endif /* INET */
2959#ifdef INET6
2960 case AF_INET6:
2961 pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL,
2962 &s->nat_src_node);
2963 s->rt_kif = r->rpool.cur->kif;
2964 break;
2965#endif /* INET6 */
2966 }
2967}
2968
2969int
2970pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
2971 struct pfi_kif *kif, struct mbuf *m, int off, void *h,
2972#ifdef __FreeBSD__
2973 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
2974 struct ifqueue *ifq, struct inpcb *inp)
2975#else
2976 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
2977 struct ifqueue *ifq)
2978#endif
2979{
2980 struct pf_rule *nr = NULL;
2981 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
2982 struct tcphdr *th = pd->hdr.tcp;
2983 u_int16_t bport, nport = 0;
2984 sa_family_t af = pd->af;
2985 int lookup = -1;
2986 uid_t uid;
2987 gid_t gid;
2988 struct pf_rule *r, *a = NULL;
2989 struct pf_ruleset *ruleset = NULL;
2990 struct pf_src_node *nsn = NULL;
2991 u_short reason;
2992 int rewrite = 0;
2993 struct pf_tag *pftag = NULL;
2994 int tag = -1;
2995 u_int16_t mss = tcp_mssdflt;
2996 int asd = 0;
2997
2998 if (pf_check_congestion(ifq)) {
2999 REASON_SET(&reason, PFRES_CONGEST);
3000 return (PF_DROP);
3001 }
3002
3003 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3004
3005 if (direction == PF_OUT) {
3006 bport = nport = th->th_sport;
3007 /* check outgoing packet for BINAT/NAT */
3008 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
3009 saddr, th->th_sport, daddr, th->th_dport,
3010 &pd->naddr, &nport)) != NULL) {
3011 PF_ACPY(&pd->baddr, saddr, af);
3012 pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
3013 &th->th_sum, &pd->naddr, nport, 0, af);
3014 rewrite++;
3015 if (nr->natpass)
3016 r = NULL;
3017 pd->nat_rule = nr;
3018 }
3019 } else {
3020 bport = nport = th->th_dport;
3021 /* check incoming packet for BINAT/RDR */
3022 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
3023 saddr, th->th_sport, daddr, th->th_dport,
3024 &pd->naddr, &nport)) != NULL) {
3025 PF_ACPY(&pd->baddr, daddr, af);
3026 pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
3027 &th->th_sum, &pd->naddr, nport, 0, af);
3028 rewrite++;
3029 if (nr->natpass)
3030 r = NULL;
3031 pd->nat_rule = nr;
3032 }
3033 }
3034
3035 while (r != NULL) {
3036 r->evaluations++;
3037 if (r->kif != NULL &&
3038 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
3039 r = r->skip[PF_SKIP_IFP].ptr;
3040 else if (r->direction && r->direction != direction)
3041 r = r->skip[PF_SKIP_DIR].ptr;
3042 else if (r->af && r->af != af)
3043 r = r->skip[PF_SKIP_AF].ptr;
3044 else if (r->proto && r->proto != IPPROTO_TCP)
3045 r = r->skip[PF_SKIP_PROTO].ptr;
3046 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg))
3047 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3048 else if (r->src.port_op && !pf_match_port(r->src.port_op,
3049 r->src.port[0], r->src.port[1], th->th_sport))
3050 r = r->skip[PF_SKIP_SRC_PORT].ptr;
3051 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg))
3052 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3053 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
3054 r->dst.port[0], r->dst.port[1], th->th_dport))
3055 r = r->skip[PF_SKIP_DST_PORT].ptr;
3056 else if (r->tos && !(r->tos & pd->tos))
3057 r = TAILQ_NEXT(r, entries);
3058 else if (r->rule_flag & PFRULE_FRAGMENT)
3059 r = TAILQ_NEXT(r, entries);
3060 else if ((r->flagset & th->th_flags) != r->flags)
3061 r = TAILQ_NEXT(r, entries);
3062 else if (r->uid.op && (lookup != -1 || (lookup =
3063#ifdef __FreeBSD__
3064 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
3065#else
3066 pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
3067#endif
3068 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
3069 uid))
3070 r = TAILQ_NEXT(r, entries);
3071 else if (r->gid.op && (lookup != -1 || (lookup =
3072#ifdef __FreeBSD__
3073 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
3074#else
3075 pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
3076#endif
3077 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
3078 gid))
3079 r = TAILQ_NEXT(r, entries);
3080 else if (r->prob && r->prob <= arc4random())
3081 r = TAILQ_NEXT(r, entries);
3082 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
3083 r = TAILQ_NEXT(r, entries);
3084 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
3085 pf_osfp_fingerprint(pd, m, off, th), r->os_fingerprint))
3086 r = TAILQ_NEXT(r, entries);
3087 else {
3088 if (r->tag)
3089 tag = r->tag;
3090 if (r->anchor == NULL) {
3091 *rm = r;
3092 *am = a;
3093 *rsm = ruleset;
3094 if ((*rm)->quick)
3095 break;
3096 r = TAILQ_NEXT(r, entries);
3097 } else
3098 pf_step_into_anchor(&asd, &ruleset,
3099 PF_RULESET_FILTER, &r, &a);
3100 }
3101 if (r == NULL)
3102 pf_step_out_of_anchor(&asd, &ruleset,
3103 PF_RULESET_FILTER, &r, &a);
3104 }
3105 r = *rm;
3106 a = *am;
3107 ruleset = *rsm;
3108
3109 REASON_SET(&reason, PFRES_MATCH);
3110
3111 if (r->log) {
3112 if (rewrite)
3113 m_copyback(m, off, sizeof(*th), (caddr_t)th);
3114 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
3115 }
3116
3117 if ((r->action == PF_DROP) &&
3118 ((r->rule_flag & PFRULE_RETURNRST) ||
3119 (r->rule_flag & PFRULE_RETURNICMP) ||
3120 (r->rule_flag & PFRULE_RETURN))) {
3121 /* undo NAT changes, if they have taken place */
3122 if (nr != NULL) {
3123 if (direction == PF_OUT) {
3124 pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
3125 &th->th_sum, &pd->baddr, bport, 0, af);
3126 rewrite++;
3127 } else {
3128 pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
3129 &th->th_sum, &pd->baddr, bport, 0, af);
3130 rewrite++;
3131 }
3132 }
3133 if (((r->rule_flag & PFRULE_RETURNRST) ||
3134 (r->rule_flag & PFRULE_RETURN)) &&
3135 !(th->th_flags & TH_RST)) {
3136 u_int32_t ack = ntohl(th->th_seq) + pd->p_len;
3137
3138 if (th->th_flags & TH_SYN)
3139 ack++;
3140 if (th->th_flags & TH_FIN)
3141 ack++;
3142 pf_send_tcp(r, af, pd->dst,
3143 pd->src, th->th_dport, th->th_sport,
3144 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
3145 r->return_ttl, 1, pd->eh, kif->pfik_ifp);
3146 } else if ((af == AF_INET) && r->return_icmp)
3147 pf_send_icmp(m, r->return_icmp >> 8,
3148 r->return_icmp & 255, af, r);
3149 else if ((af == AF_INET6) && r->return_icmp6)
3150 pf_send_icmp(m, r->return_icmp6 >> 8,
3151 r->return_icmp6 & 255, af, r);
3152 }
3153
3154 if (r->action == PF_DROP)
3155 return (PF_DROP);
3156
3157 if (pf_tag_packet(m, pftag, tag)) {
3158 REASON_SET(&reason, PFRES_MEMORY);
3159 return (PF_DROP);
3160 }
3161
3162 if (r->keep_state || nr != NULL ||
3163 (pd->flags & PFDESC_TCP_NORM)) {
3164 /* create new state */
3165 u_int16_t len;
3166 struct pf_state *s = NULL;
3167 struct pf_src_node *sn = NULL;
3168
3169 len = pd->tot_len - off - (th->th_off << 2);
3170
3171 /* check maximums */
3172 if (r->max_states && (r->states >= r->max_states)) {
3173 pf_status.lcounters[LCNT_STATES]++;
3174 REASON_SET(&reason, PFRES_MAXSTATES);
3175 goto cleanup;
3176 }
3177 /* src node for flter rule */
3178 if ((r->rule_flag & PFRULE_SRCTRACK ||
3179 r->rpool.opts & PF_POOL_STICKYADDR) &&
3180 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3181 REASON_SET(&reason, PFRES_SRCLIMIT);
3182 goto cleanup;
3183 }
3184 /* src node for translation rule */
3185 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
3186 ((direction == PF_OUT &&
3187 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
3188 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
3189 REASON_SET(&reason, PFRES_SRCLIMIT);
3190 goto cleanup;
3191 }
3192 s = pool_get(&pf_state_pl, PR_NOWAIT);
3193 if (s == NULL) {
3194 REASON_SET(&reason, PFRES_MEMORY);
3195cleanup:
3196 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
3197 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
3198 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3199 pf_status.src_nodes--;
3200 pool_put(&pf_src_tree_pl, sn);
3201 }
3202 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
3203 nsn->expire == 0) {
3204 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
3205 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3206 pf_status.src_nodes--;
3207 pool_put(&pf_src_tree_pl, nsn);
3208 }
3209 return (PF_DROP);
3210 }
3211 bzero(s, sizeof(*s));
3212 s->rule.ptr = r;
3213 s->nat_rule.ptr = nr;
3214 s->anchor.ptr = a;
3215 STATE_INC_COUNTERS(s);
3216 s->allow_opts = r->allow_opts;
3217 s->log = r->log & 2;
3218 s->proto = IPPROTO_TCP;
3219 s->direction = direction;
3220 s->af = af;
3221 if (direction == PF_OUT) {
3222 PF_ACPY(&s->gwy.addr, saddr, af);
3223 s->gwy.port = th->th_sport; /* sport */
3224 PF_ACPY(&s->ext.addr, daddr, af);
3225 s->ext.port = th->th_dport;
3226 if (nr != NULL) {
3227 PF_ACPY(&s->lan.addr, &pd->baddr, af);
3228 s->lan.port = bport;
3229 } else {
3230 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
3231 s->lan.port = s->gwy.port;
3232 }
3233 } else {
3234 PF_ACPY(&s->lan.addr, daddr, af);
3235 s->lan.port = th->th_dport;
3236 PF_ACPY(&s->ext.addr, saddr, af);
3237 s->ext.port = th->th_sport;
3238 if (nr != NULL) {
3239 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
3240 s->gwy.port = bport;
3241 } else {
3242 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
3243 s->gwy.port = s->lan.port;
3244 }
3245 }
3246
3247 s->src.seqlo = ntohl(th->th_seq);
3248 s->src.seqhi = s->src.seqlo + len + 1;
3249 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
3250 r->keep_state == PF_STATE_MODULATE) {
3251 /* Generate sequence number modulator */
3252 while ((s->src.seqdiff = htonl(arc4random())) == 0)
3253 ;
3254 pf_change_a(&th->th_seq, &th->th_sum,
3255 htonl(s->src.seqlo + s->src.seqdiff), 0);
3256 rewrite = 1;
3257 } else
3258 s->src.seqdiff = 0;
3259 if (th->th_flags & TH_SYN) {
3260 s->src.seqhi++;
3261 s->src.wscale = pf_get_wscale(m, off, th->th_off, af);
3262 }
3263 s->src.max_win = MAX(ntohs(th->th_win), 1);
3264 if (s->src.wscale & PF_WSCALE_MASK) {
3265 /* Remove scale factor from initial window */
3266 int win = s->src.max_win;
3267 win += 1 << (s->src.wscale & PF_WSCALE_MASK);
3268 s->src.max_win = (win - 1) >>
3269 (s->src.wscale & PF_WSCALE_MASK);
3270 }
3271 if (th->th_flags & TH_FIN)
3272 s->src.seqhi++;
3273 s->dst.seqhi = 1;
3274 s->dst.max_win = 1;
3275 s->src.state = TCPS_SYN_SENT;
3276 s->dst.state = TCPS_CLOSED;
3277 s->creation = time_second;
3278 s->expire = time_second;
3279 s->timeout = PFTM_TCP_FIRST_PACKET;
3280 pf_set_rt_ifp(s, saddr);
3281 if (sn != NULL) {
3282 s->src_node = sn;
3283 s->src_node->states++;
3284 }
3285 if (nsn != NULL) {
3286 PF_ACPY(&nsn->raddr, &pd->naddr, af);
3287 s->nat_src_node = nsn;
3288 s->nat_src_node->states++;
3289 }
3290 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m,
3291 off, pd, th, &s->src, &s->dst)) {
3292 REASON_SET(&reason, PFRES_MEMORY);
3293 pf_src_tree_remove_state(s);
3294 STATE_DEC_COUNTERS(s);
3295 pool_put(&pf_state_pl, s);
3296 return (PF_DROP);
3297 }
3298 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub &&
3299 pf_normalize_tcp_stateful(m, off, pd, &reason, th, s,
3300 &s->src, &s->dst, &rewrite)) {
3301 /* This really shouldn't happen!!! */
3302 DPFPRINTF(PF_DEBUG_URGENT,
3303 ("pf_normalize_tcp_stateful failed on first pkt"));
3304 pf_normalize_tcp_cleanup(s);
3305 pf_src_tree_remove_state(s);
3306 STATE_DEC_COUNTERS(s);
3307 pool_put(&pf_state_pl, s);
3308 return (PF_DROP);
3309 }
3310 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
3311 pf_normalize_tcp_cleanup(s);
3312 REASON_SET(&reason, PFRES_STATEINS);
3313 pf_src_tree_remove_state(s);
3314 STATE_DEC_COUNTERS(s);
3315 pool_put(&pf_state_pl, s);
3316 return (PF_DROP);
3317 } else
3318 *sm = s;
3319 if (tag > 0) {
3320 pf_tag_ref(tag);
3321 s->tag = tag;
3322 }
3323 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
3324 r->keep_state == PF_STATE_SYNPROXY) {
3325 s->src.state = PF_TCPS_PROXY_SRC;
3326 if (nr != NULL) {
3327 if (direction == PF_OUT) {
3328 pf_change_ap(saddr, &th->th_sport,
3329 pd->ip_sum, &th->th_sum, &pd->baddr,
3330 bport, 0, af);
3331 } else {
3332 pf_change_ap(daddr, &th->th_dport,
3333 pd->ip_sum, &th->th_sum, &pd->baddr,
3334 bport, 0, af);
3335 }
3336 }
3337 s->src.seqhi = htonl(arc4random());
3338 /* Find mss option */
3339 mss = pf_get_mss(m, off, th->th_off, af);
3340 mss = pf_calc_mss(saddr, af, mss);
3341 mss = pf_calc_mss(daddr, af, mss);
3342 s->src.mss = mss;
3343 pf_send_tcp(r, af, daddr, saddr, th->th_dport,
3344 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
3345 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, NULL, NULL);
3346 REASON_SET(&reason, PFRES_SYNPROXY);
3347 return (PF_SYNPROXY_DROP);
3348 }
3349 }
3350
3351 /* copy back packet headers if we performed NAT operations */
3352 if (rewrite)
3353 m_copyback(m, off, sizeof(*th), (caddr_t)th);
3354
3355 return (PF_PASS);
3356}
3357
3358int
3359pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
3360 struct pfi_kif *kif, struct mbuf *m, int off, void *h,
3361#ifdef __FreeBSD__
3362 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
3363 struct ifqueue *ifq, struct inpcb *inp)
3364#else
3365 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
3366 struct ifqueue *ifq)
3367#endif
3368{
3369 struct pf_rule *nr = NULL;
3370 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3371 struct udphdr *uh = pd->hdr.udp;
3372 u_int16_t bport, nport = 0;
3373 sa_family_t af = pd->af;
3374 int lookup = -1;
3375 uid_t uid;
3376 gid_t gid;
3377 struct pf_rule *r, *a = NULL;
3378 struct pf_ruleset *ruleset = NULL;
3379 struct pf_src_node *nsn = NULL;
3380 u_short reason;
3381 int rewrite = 0;
3382 struct pf_tag *pftag = NULL;
3383 int tag = -1;
3384 int asd = 0;
3385
3386 if (pf_check_congestion(ifq)) {
3387 REASON_SET(&reason, PFRES_CONGEST);
3388 return (PF_DROP);
3389 }
3390
3391 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3392
3393 if (direction == PF_OUT) {
3394 bport = nport = uh->uh_sport;
3395 /* check outgoing packet for BINAT/NAT */
3396 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
3397 saddr, uh->uh_sport, daddr, uh->uh_dport,
3398 &pd->naddr, &nport)) != NULL) {
3399 PF_ACPY(&pd->baddr, saddr, af);
3400 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum,
3401 &uh->uh_sum, &pd->naddr, nport, 1, af);
3402 rewrite++;
3403 if (nr->natpass)
3404 r = NULL;
3405 pd->nat_rule = nr;
3406 }
3407 } else {
3408 bport = nport = uh->uh_dport;
3409 /* check incoming packet for BINAT/RDR */
3410 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
3411 saddr, uh->uh_sport, daddr, uh->uh_dport, &pd->naddr,
3412 &nport)) != NULL) {
3413 PF_ACPY(&pd->baddr, daddr, af);
3414 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum,
3415 &uh->uh_sum, &pd->naddr, nport, 1, af);
3416 rewrite++;
3417 if (nr->natpass)
3418 r = NULL;
3419 pd->nat_rule = nr;
3420 }
3421 }
3422
3423 while (r != NULL) {
3424 r->evaluations++;
3425 if (r->kif != NULL &&
3426 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
3427 r = r->skip[PF_SKIP_IFP].ptr;
3428 else if (r->direction && r->direction != direction)
3429 r = r->skip[PF_SKIP_DIR].ptr;
3430 else if (r->af && r->af != af)
3431 r = r->skip[PF_SKIP_AF].ptr;
3432 else if (r->proto && r->proto != IPPROTO_UDP)
3433 r = r->skip[PF_SKIP_PROTO].ptr;
3434 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg))
3435 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3436 else if (r->src.port_op && !pf_match_port(r->src.port_op,
3437 r->src.port[0], r->src.port[1], uh->uh_sport))
3438 r = r->skip[PF_SKIP_SRC_PORT].ptr;
3439 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg))
3440 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3441 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
3442 r->dst.port[0], r->dst.port[1], uh->uh_dport))
3443 r = r->skip[PF_SKIP_DST_PORT].ptr;
3444 else if (r->tos && !(r->tos & pd->tos))
3445 r = TAILQ_NEXT(r, entries);
3446 else if (r->rule_flag & PFRULE_FRAGMENT)
3447 r = TAILQ_NEXT(r, entries);
3448 else if (r->uid.op && (lookup != -1 || (lookup =
3449#ifdef __FreeBSD__
3450 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
3451#else
3452 pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
3453#endif
3454 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
3455 uid))
3456 r = TAILQ_NEXT(r, entries);
3457 else if (r->gid.op && (lookup != -1 || (lookup =
3458#ifdef __FreeBSD__
3459 pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
3460#else
3461 pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
3462#endif
3463 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
3464 gid))
3465 r = TAILQ_NEXT(r, entries);
3466 else if (r->prob && r->prob <= arc4random())
3467 r = TAILQ_NEXT(r, entries);
3468 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
3469 r = TAILQ_NEXT(r, entries);
3470 else if (r->os_fingerprint != PF_OSFP_ANY)
3471 r = TAILQ_NEXT(r, entries);
3472 else {
3473 if (r->tag)
3474 tag = r->tag;
3475 if (r->anchor == NULL) {
3476 *rm = r;
3477 *am = a;
3478 *rsm = ruleset;
3479 if ((*rm)->quick)
3480 break;
3481 r = TAILQ_NEXT(r, entries);
3482 } else
3483 pf_step_into_anchor(&asd, &ruleset,
3484 PF_RULESET_FILTER, &r, &a);
3485 }
3486 if (r == NULL)
3487 pf_step_out_of_anchor(&asd, &ruleset,
3488 PF_RULESET_FILTER, &r, &a);
3489 }
3490 r = *rm;
3491 a = *am;
3492 ruleset = *rsm;
3493
3494 REASON_SET(&reason, PFRES_MATCH);
3495
3496 if (r->log) {
3497 if (rewrite)
3498 m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
3499 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
3500 }
3501
3502 if ((r->action == PF_DROP) &&
3503 ((r->rule_flag & PFRULE_RETURNICMP) ||
3504 (r->rule_flag & PFRULE_RETURN))) {
3505 /* undo NAT changes, if they have taken place */
3506 if (nr != NULL) {
3507 if (direction == PF_OUT) {
3508 pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum,
3509 &uh->uh_sum, &pd->baddr, bport, 1, af);
3510 rewrite++;
3511 } else {
3512 pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum,
3513 &uh->uh_sum, &pd->baddr, bport, 1, af);
3514 rewrite++;
3515 }
3516 }
3517 if ((af == AF_INET) && r->return_icmp)
3518 pf_send_icmp(m, r->return_icmp >> 8,
3519 r->return_icmp & 255, af, r);
3520 else if ((af == AF_INET6) && r->return_icmp6)
3521 pf_send_icmp(m, r->return_icmp6 >> 8,
3522 r->return_icmp6 & 255, af, r);
3523 }
3524
3525 if (r->action == PF_DROP)
3526 return (PF_DROP);
3527
3528 if (pf_tag_packet(m, pftag, tag)) {
3529 REASON_SET(&reason, PFRES_MEMORY);
3530 return (PF_DROP);
3531 }
3532
3533 if (r->keep_state || nr != NULL) {
3534 /* create new state */
3535 struct pf_state *s = NULL;
3536 struct pf_src_node *sn = NULL;
3537
3538 /* check maximums */
3539 if (r->max_states && (r->states >= r->max_states)) {
3540 pf_status.lcounters[LCNT_STATES]++;
3541 REASON_SET(&reason, PFRES_MAXSTATES);
3542 goto cleanup;
3543 }
3544 /* src node for flter rule */
3545 if ((r->rule_flag & PFRULE_SRCTRACK ||
3546 r->rpool.opts & PF_POOL_STICKYADDR) &&
3547 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3548 REASON_SET(&reason, PFRES_SRCLIMIT);
3549 goto cleanup;
3550 }
3551 /* src node for translation rule */
3552 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
3553 ((direction == PF_OUT &&
3554 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
3555 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
3556 REASON_SET(&reason, PFRES_SRCLIMIT);
3557 goto cleanup;
3558 }
3559 s = pool_get(&pf_state_pl, PR_NOWAIT);
3560 if (s == NULL) {
3561 REASON_SET(&reason, PFRES_MEMORY);
3562cleanup:
3563 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
3564 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
3565 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3566 pf_status.src_nodes--;
3567 pool_put(&pf_src_tree_pl, sn);
3568 }
3569 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
3570 nsn->expire == 0) {
3571 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
3572 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3573 pf_status.src_nodes--;
3574 pool_put(&pf_src_tree_pl, nsn);
3575 }
3576 return (PF_DROP);
3577 }
3578 bzero(s, sizeof(*s));
3579 s->rule.ptr = r;
3580 s->nat_rule.ptr = nr;
3581 s->anchor.ptr = a;
3582 STATE_INC_COUNTERS(s);
3583 s->allow_opts = r->allow_opts;
3584 s->log = r->log & 2;
3585 s->proto = IPPROTO_UDP;
3586 s->direction = direction;
3587 s->af = af;
3588 if (direction == PF_OUT) {
3589 PF_ACPY(&s->gwy.addr, saddr, af);
3590 s->gwy.port = uh->uh_sport;
3591 PF_ACPY(&s->ext.addr, daddr, af);
3592 s->ext.port = uh->uh_dport;
3593 if (nr != NULL) {
3594 PF_ACPY(&s->lan.addr, &pd->baddr, af);
3595 s->lan.port = bport;
3596 } else {
3597 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
3598 s->lan.port = s->gwy.port;
3599 }
3600 } else {
3601 PF_ACPY(&s->lan.addr, daddr, af);
3602 s->lan.port = uh->uh_dport;
3603 PF_ACPY(&s->ext.addr, saddr, af);
3604 s->ext.port = uh->uh_sport;
3605 if (nr != NULL) {
3606 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
3607 s->gwy.port = bport;
3608 } else {
3609 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
3610 s->gwy.port = s->lan.port;
3611 }
3612 }
3613 s->src.state = PFUDPS_SINGLE;
3614 s->dst.state = PFUDPS_NO_TRAFFIC;
3615 s->creation = time_second;
3616 s->expire = time_second;
3617 s->timeout = PFTM_UDP_FIRST_PACKET;
3618 pf_set_rt_ifp(s, saddr);
3619 if (sn != NULL) {
3620 s->src_node = sn;
3621 s->src_node->states++;
3622 }
3623 if (nsn != NULL) {
3624 PF_ACPY(&nsn->raddr, &pd->naddr, af);
3625 s->nat_src_node = nsn;
3626 s->nat_src_node->states++;
3627 }
3628 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
3629 REASON_SET(&reason, PFRES_STATEINS);
3630 pf_src_tree_remove_state(s);
3631 STATE_DEC_COUNTERS(s);
3632 pool_put(&pf_state_pl, s);
3633 return (PF_DROP);
3634 } else
3635 *sm = s;
3636 if (tag > 0) {
3637 pf_tag_ref(tag);
3638 s->tag = tag;
3639 }
3640 }
3641
3642 /* copy back packet headers if we performed NAT operations */
3643 if (rewrite)
3644 m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
3645
3646 return (PF_PASS);
3647}
3648
3649int
3650pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
3651 struct pfi_kif *kif, struct mbuf *m, int off, void *h,
3652 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
3653 struct ifqueue *ifq)
3654{
3655 struct pf_rule *nr = NULL;
3656 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3657 struct pf_rule *r, *a = NULL;
3658 struct pf_ruleset *ruleset = NULL;
3659 struct pf_src_node *nsn = NULL;
3660 u_short reason;
3661 u_int16_t icmpid = 0, bport, nport = 0;
3662 sa_family_t af = pd->af;
3663 u_int8_t icmptype = 0; /* make the compiler happy */
3664 u_int8_t icmpcode = 0; /* make the compiler happy */
3665 int state_icmp = 0;
3666 struct pf_tag *pftag = NULL;
3667 int tag = -1;
3668#ifdef INET6
3669 int rewrite = 0;
3670#endif /* INET6 */
3671 int asd = 0;
3672
3673 if (pf_check_congestion(ifq)) {
3674 REASON_SET(&reason, PFRES_CONGEST);
3675 return (PF_DROP);
3676 }
3677
3678 switch (pd->proto) {
3679#ifdef INET
3680 case IPPROTO_ICMP:
3681 icmptype = pd->hdr.icmp->icmp_type;
3682 icmpcode = pd->hdr.icmp->icmp_code;
3683 icmpid = pd->hdr.icmp->icmp_id;
3684
3685 if (icmptype == ICMP_UNREACH ||
3686 icmptype == ICMP_SOURCEQUENCH ||
3687 icmptype == ICMP_REDIRECT ||
3688 icmptype == ICMP_TIMXCEED ||
3689 icmptype == ICMP_PARAMPROB)
3690 state_icmp++;
3691 break;
3692#endif /* INET */
3693#ifdef INET6
3694 case IPPROTO_ICMPV6:
3695 icmptype = pd->hdr.icmp6->icmp6_type;
3696 icmpcode = pd->hdr.icmp6->icmp6_code;
3697 icmpid = pd->hdr.icmp6->icmp6_id;
3698
3699 if (icmptype == ICMP6_DST_UNREACH ||
3700 icmptype == ICMP6_PACKET_TOO_BIG ||
3701 icmptype == ICMP6_TIME_EXCEEDED ||
3702 icmptype == ICMP6_PARAM_PROB)
3703 state_icmp++;
3704 break;
3705#endif /* INET6 */
3706 }
3707
3708 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3709
3710 if (direction == PF_OUT) {
3711 bport = nport = icmpid;
3712 /* check outgoing packet for BINAT/NAT */
3713 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
3714 saddr, icmpid, daddr, icmpid, &pd->naddr, &nport)) !=
3715 NULL) {
3716 PF_ACPY(&pd->baddr, saddr, af);
3717 switch (af) {
3718#ifdef INET
3719 case AF_INET:
3720 pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
3721 pd->naddr.v4.s_addr, 0);
3722 pd->hdr.icmp->icmp_cksum = pf_cksum_fixup(
3723 pd->hdr.icmp->icmp_cksum, icmpid, nport, 0);
3724 pd->hdr.icmp->icmp_id = nport;
3725 m_copyback(m, off, ICMP_MINLEN,
3726 (caddr_t)pd->hdr.icmp);
3727 break;
3728#endif /* INET */
3729#ifdef INET6
3730 case AF_INET6:
3731 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum,
3732 &pd->naddr, 0);
3733 rewrite++;
3734 break;
3735#endif /* INET6 */
3736 }
3737 if (nr->natpass)
3738 r = NULL;
3739 pd->nat_rule = nr;
3740 }
3741 } else {
3742 bport = nport = icmpid;
3743 /* check incoming packet for BINAT/RDR */
3744 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
3745 saddr, icmpid, daddr, icmpid, &pd->naddr, &nport)) !=
3746 NULL) {
3747 PF_ACPY(&pd->baddr, daddr, af);
3748 switch (af) {
3749#ifdef INET
3750 case AF_INET:
3751 pf_change_a(&daddr->v4.s_addr,
3752 pd->ip_sum, pd->naddr.v4.s_addr, 0);
3753 break;
3754#endif /* INET */
3755#ifdef INET6
3756 case AF_INET6:
3757 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum,
3758 &pd->naddr, 0);
3759 rewrite++;
3760 break;
3761#endif /* INET6 */
3762 }
3763 if (nr->natpass)
3764 r = NULL;
3765 pd->nat_rule = nr;
3766 }
3767 }
3768
3769 while (r != NULL) {
3770 r->evaluations++;
3771 if (r->kif != NULL &&
3772 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
3773 r = r->skip[PF_SKIP_IFP].ptr;
3774 else if (r->direction && r->direction != direction)
3775 r = r->skip[PF_SKIP_DIR].ptr;
3776 else if (r->af && r->af != af)
3777 r = r->skip[PF_SKIP_AF].ptr;
3778 else if (r->proto && r->proto != pd->proto)
3779 r = r->skip[PF_SKIP_PROTO].ptr;
3780 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, r->src.neg))
3781 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3782 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, r->dst.neg))
3783 r = r->skip[PF_SKIP_DST_ADDR].ptr;
3784 else if (r->type && r->type != icmptype + 1)
3785 r = TAILQ_NEXT(r, entries);
3786 else if (r->code && r->code != icmpcode + 1)
3787 r = TAILQ_NEXT(r, entries);
3788 else if (r->tos && !(r->tos & pd->tos))
3789 r = TAILQ_NEXT(r, entries);
3790 else if (r->rule_flag & PFRULE_FRAGMENT)
3791 r = TAILQ_NEXT(r, entries);
3792 else if (r->prob && r->prob <= arc4random())
3793 r = TAILQ_NEXT(r, entries);
3794 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
3795 r = TAILQ_NEXT(r, entries);
3796 else if (r->os_fingerprint != PF_OSFP_ANY)
3797 r = TAILQ_NEXT(r, entries);
3798 else {
3799 if (r->tag)
3800 tag = r->tag;
3801 if (r->anchor == NULL) {
3802 *rm = r;
3803 *am = a;
3804 *rsm = ruleset;
3805 if ((*rm)->quick)
3806 break;
3807 r = TAILQ_NEXT(r, entries);
3808 } else
3809 pf_step_into_anchor(&asd, &ruleset,
3810 PF_RULESET_FILTER, &r, &a);
3811 }
3812 if (r == NULL)
3813 pf_step_out_of_anchor(&asd, &ruleset,
3814 PF_RULESET_FILTER, &r, &a);
3815 }
3816 r = *rm;
3817 a = *am;
3818 ruleset = *rsm;
3819
3820 REASON_SET(&reason, PFRES_MATCH);
3821
3822 if (r->log) {
3823#ifdef INET6
3824 if (rewrite)
3825 m_copyback(m, off, sizeof(struct icmp6_hdr),
3826 (caddr_t)pd->hdr.icmp6);
3827#endif /* INET6 */
3828 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
3829 }
3830
3831 if (r->action != PF_PASS)
3832 return (PF_DROP);
3833
3834 if (pf_tag_packet(m, pftag, tag)) {
3835 REASON_SET(&reason, PFRES_MEMORY);
3836 return (PF_DROP);
3837 }
3838
3839 if (!state_icmp && (r->keep_state || nr != NULL)) {
3840 /* create new state */
3841 struct pf_state *s = NULL;
3842 struct pf_src_node *sn = NULL;
3843
3844 /* check maximums */
3845 if (r->max_states && (r->states >= r->max_states)) {
3846 pf_status.lcounters[LCNT_STATES]++;
3847 REASON_SET(&reason, PFRES_MAXSTATES);
3848 goto cleanup;
3849 }
3850 /* src node for flter rule */
3851 if ((r->rule_flag & PFRULE_SRCTRACK ||
3852 r->rpool.opts & PF_POOL_STICKYADDR) &&
3853 pf_insert_src_node(&sn, r, saddr, af) != 0) {
3854 REASON_SET(&reason, PFRES_SRCLIMIT);
3855 goto cleanup;
3856 }
3857 /* src node for translation rule */
3858 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
3859 ((direction == PF_OUT &&
3860 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
3861 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
3862 REASON_SET(&reason, PFRES_SRCLIMIT);
3863 goto cleanup;
3864 }
3865 s = pool_get(&pf_state_pl, PR_NOWAIT);
3866 if (s == NULL) {
3867 REASON_SET(&reason, PFRES_MEMORY);
3868cleanup:
3869 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
3870 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
3871 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3872 pf_status.src_nodes--;
3873 pool_put(&pf_src_tree_pl, sn);
3874 }
3875 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
3876 nsn->expire == 0) {
3877 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
3878 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3879 pf_status.src_nodes--;
3880 pool_put(&pf_src_tree_pl, nsn);
3881 }
3882 return (PF_DROP);
3883 }
3884 bzero(s, sizeof(*s));
3885 s->rule.ptr = r;
3886 s->nat_rule.ptr = nr;
3887 s->anchor.ptr = a;
3888 STATE_INC_COUNTERS(s);
3889 s->allow_opts = r->allow_opts;
3890 s->log = r->log & 2;
3891 s->proto = pd->proto;
3892 s->direction = direction;
3893 s->af = af;
3894 if (direction == PF_OUT) {
3895 PF_ACPY(&s->gwy.addr, saddr, af);
3896 s->gwy.port = nport;
3897 PF_ACPY(&s->ext.addr, daddr, af);
3898 s->ext.port = 0;
3899 if (nr != NULL) {
3900 PF_ACPY(&s->lan.addr, &pd->baddr, af);
3901 s->lan.port = bport;
3902 } else {
3903 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
3904 s->lan.port = s->gwy.port;
3905 }
3906 } else {
3907 PF_ACPY(&s->lan.addr, daddr, af);
3908 s->lan.port = nport;
3909 PF_ACPY(&s->ext.addr, saddr, af);
3910 s->ext.port = 0;
3911 if (nr != NULL) {
3912 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
3913 s->gwy.port = bport;
3914 } else {
3915 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
3916 s->gwy.port = s->lan.port;
3917 }
3918 }
3919 s->creation = time_second;
3920 s->expire = time_second;
3921 s->timeout = PFTM_ICMP_FIRST_PACKET;
3922 pf_set_rt_ifp(s, saddr);
3923 if (sn != NULL) {
3924 s->src_node = sn;
3925 s->src_node->states++;
3926 }
3927 if (nsn != NULL) {
3928 PF_ACPY(&nsn->raddr, &pd->naddr, af);
3929 s->nat_src_node = nsn;
3930 s->nat_src_node->states++;
3931 }
3932 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
3933 REASON_SET(&reason, PFRES_STATEINS);
3934 pf_src_tree_remove_state(s);
3935 STATE_DEC_COUNTERS(s);
3936 pool_put(&pf_state_pl, s);
3937 return (PF_DROP);
3938 } else
3939 *sm = s;
3940 if (tag > 0) {
3941 pf_tag_ref(tag);
3942 s->tag = tag;
3943 }
3944 }
3945
3946#ifdef INET6
3947 /* copy back packet headers if we performed IPv6 NAT operations */
3948 if (rewrite)
3949 m_copyback(m, off, sizeof(struct icmp6_hdr),
3950 (caddr_t)pd->hdr.icmp6);
3951#endif /* INET6 */
3952
3953 return (PF_PASS);
3954}
3955
3956int
3957pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction,
3958 struct pfi_kif *kif, struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
3959 struct pf_rule **am, struct pf_ruleset **rsm, struct ifqueue *ifq)
3960{
3961 struct pf_rule *nr = NULL;
3962 struct pf_rule *r, *a = NULL;
3963 struct pf_ruleset *ruleset = NULL;
3964 struct pf_src_node *nsn = NULL;
3965 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
3966 sa_family_t af = pd->af;
3967 u_short reason;
3968 struct pf_tag *pftag = NULL;
3969 int tag = -1;
3970 int asd = 0;
3971
3972 if (pf_check_congestion(ifq)) {
3973 REASON_SET(&reason, PFRES_CONGEST);
3974 return (PF_DROP);
3975 }
3976
3977 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3978
3979 if (direction == PF_OUT) {
3980 /* check outgoing packet for BINAT/NAT */
3981 if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
3982 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) {
3983 PF_ACPY(&pd->baddr, saddr, af);
3984 switch (af) {
3985#ifdef INET
3986 case AF_INET:
3987 pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
3988 pd->naddr.v4.s_addr, 0);
3989 break;
3990#endif /* INET */
3991#ifdef INET6
3992 case AF_INET6:
3993 PF_ACPY(saddr, &pd->naddr, af);
3994 break;
3995#endif /* INET6 */
3996 }
3997 if (nr->natpass)
3998 r = NULL;
3999 pd->nat_rule = nr;
4000 }
4001 } else {
4002 /* check incoming packet for BINAT/RDR */
4003 if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
4004 saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) {
4005 PF_ACPY(&pd->baddr, daddr, af);
4006 switch (af) {
4007#ifdef INET
4008 case AF_INET:
4009 pf_change_a(&daddr->v4.s_addr,
4010 pd->ip_sum, pd->naddr.v4.s_addr, 0);
4011 break;
4012#endif /* INET */
4013#ifdef INET6
4014 case AF_INET6:
4015 PF_ACPY(daddr, &pd->naddr, af);
4016 break;
4017#endif /* INET6 */
4018 }
4019 if (nr->natpass)
4020 r = NULL;
4021 pd->nat_rule = nr;
4022 }
4023 }
4024
4025 while (r != NULL) {
4026 r->evaluations++;
4027 if (r->kif != NULL &&
4028 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
4029 r = r->skip[PF_SKIP_IFP].ptr;
4030 else if (r->direction && r->direction != direction)
4031 r = r->skip[PF_SKIP_DIR].ptr;
4032 else if (r->af && r->af != af)
4033 r = r->skip[PF_SKIP_AF].ptr;
4034 else if (r->proto && r->proto != pd->proto)
4035 r = r->skip[PF_SKIP_PROTO].ptr;
4036 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.neg))
4037 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
4038 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.neg))
4039 r = r->skip[PF_SKIP_DST_ADDR].ptr;
4040 else if (r->tos && !(r->tos & pd->tos))
4041 r = TAILQ_NEXT(r, entries);
4042 else if (r->rule_flag & PFRULE_FRAGMENT)
4043 r = TAILQ_NEXT(r, entries);
4044 else if (r->prob && r->prob <= arc4random())
4045 r = TAILQ_NEXT(r, entries);
4046 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
4047 r = TAILQ_NEXT(r, entries);
4048 else if (r->os_fingerprint != PF_OSFP_ANY)
4049 r = TAILQ_NEXT(r, entries);
4050 else {
4051 if (r->tag)
4052 tag = r->tag;
4053 if (r->anchor == NULL) {
4054 *rm = r;
4055 *am = a;
4056 *rsm = ruleset;
4057 if ((*rm)->quick)
4058 break;
4059 r = TAILQ_NEXT(r, entries);
4060 } else
4061 pf_step_into_anchor(&asd, &ruleset,
4062 PF_RULESET_FILTER, &r, &a);
4063 }
4064 if (r == NULL)
4065 pf_step_out_of_anchor(&asd, &ruleset,
4066 PF_RULESET_FILTER, &r, &a);
4067 }
4068 r = *rm;
4069 a = *am;
4070 ruleset = *rsm;
4071
4072 REASON_SET(&reason, PFRES_MATCH);
4073
4074 if (r->log)
4075 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
4076
4077 if ((r->action == PF_DROP) &&
4078 ((r->rule_flag & PFRULE_RETURNICMP) ||
4079 (r->rule_flag & PFRULE_RETURN))) {
4080 struct pf_addr *a = NULL;
4081
4082 if (nr != NULL) {
4083 if (direction == PF_OUT)
4084 a = saddr;
4085 else
4086 a = daddr;
4087 }
4088 if (a != NULL) {
4089 switch (af) {
4090#ifdef INET
4091 case AF_INET:
4092 pf_change_a(&a->v4.s_addr, pd->ip_sum,
4093 pd->baddr.v4.s_addr, 0);
4094 break;
4095#endif /* INET */
4096#ifdef INET6
4097 case AF_INET6:
4098 PF_ACPY(a, &pd->baddr, af);
4099 break;
4100#endif /* INET6 */
4101 }
4102 }
4103 if ((af == AF_INET) && r->return_icmp)
4104 pf_send_icmp(m, r->return_icmp >> 8,
4105 r->return_icmp & 255, af, r);
4106 else if ((af == AF_INET6) && r->return_icmp6)
4107 pf_send_icmp(m, r->return_icmp6 >> 8,
4108 r->return_icmp6 & 255, af, r);
4109 }
4110
4111 if (r->action != PF_PASS)
4112 return (PF_DROP);
4113
4114 if (pf_tag_packet(m, pftag, tag)) {
4115 REASON_SET(&reason, PFRES_MEMORY);
4116 return (PF_DROP);
4117 }
4118
4119 if (r->keep_state || nr != NULL) {
4120 /* create new state */
4121 struct pf_state *s = NULL;
4122 struct pf_src_node *sn = NULL;
4123
4124 /* check maximums */
4125 if (r->max_states && (r->states >= r->max_states)) {
4126 pf_status.lcounters[LCNT_STATES]++;
4127 REASON_SET(&reason, PFRES_MAXSTATES);
4128 goto cleanup;
4129 }
4130 /* src node for flter rule */
4131 if ((r->rule_flag & PFRULE_SRCTRACK ||
4132 r->rpool.opts & PF_POOL_STICKYADDR) &&
4133 pf_insert_src_node(&sn, r, saddr, af) != 0) {
4134 REASON_SET(&reason, PFRES_SRCLIMIT);
4135 goto cleanup;
4136 }
4137 /* src node for translation rule */
4138 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
4139 ((direction == PF_OUT &&
4140 pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
4141 (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
4142 REASON_SET(&reason, PFRES_SRCLIMIT);
4143 goto cleanup;
4144 }
4145 s = pool_get(&pf_state_pl, PR_NOWAIT);
4146 if (s == NULL) {
4147 REASON_SET(&reason, PFRES_MEMORY);
4148cleanup:
4149 if (sn != NULL && sn->states == 0 && sn->expire == 0) {
4150 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
4151 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
4152 pf_status.src_nodes--;
4153 pool_put(&pf_src_tree_pl, sn);
4154 }
4155 if (nsn != sn && nsn != NULL && nsn->states == 0 &&
4156 nsn->expire == 0) {
4157 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
4158 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
4159 pf_status.src_nodes--;
4160 pool_put(&pf_src_tree_pl, nsn);
4161 }
4162 return (PF_DROP);
4163 }
4164 bzero(s, sizeof(*s));
4165 s->rule.ptr = r;
4166 s->nat_rule.ptr = nr;
4167 s->anchor.ptr = a;
4168 STATE_INC_COUNTERS(s);
4169 s->allow_opts = r->allow_opts;
4170 s->log = r->log & 2;
4171 s->proto = pd->proto;
4172 s->direction = direction;
4173 s->af = af;
4174 if (direction == PF_OUT) {
4175 PF_ACPY(&s->gwy.addr, saddr, af);
4176 PF_ACPY(&s->ext.addr, daddr, af);
4177 if (nr != NULL)
4178 PF_ACPY(&s->lan.addr, &pd->baddr, af);
4179 else
4180 PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
4181 } else {
4182 PF_ACPY(&s->lan.addr, daddr, af);
4183 PF_ACPY(&s->ext.addr, saddr, af);
4184 if (nr != NULL)
4185 PF_ACPY(&s->gwy.addr, &pd->baddr, af);
4186 else
4187 PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
4188 }
4189 s->src.state = PFOTHERS_SINGLE;
4190 s->dst.state = PFOTHERS_NO_TRAFFIC;
4191 s->creation = time_second;
4192 s->expire = time_second;
4193 s->timeout = PFTM_OTHER_FIRST_PACKET;
4194 pf_set_rt_ifp(s, saddr);
4195 if (sn != NULL) {
4196 s->src_node = sn;
4197 s->src_node->states++;
4198 }
4199 if (nsn != NULL) {
4200 PF_ACPY(&nsn->raddr, &pd->naddr, af);
4201 s->nat_src_node = nsn;
4202 s->nat_src_node->states++;
4203 }
4204 if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
4205 REASON_SET(&reason, PFRES_STATEINS);
4206 pf_src_tree_remove_state(s);
4207 STATE_DEC_COUNTERS(s);
4208 pool_put(&pf_state_pl, s);
4209 return (PF_DROP);
4210 } else
4211 *sm = s;
4212 if (tag > 0) {
4213 pf_tag_ref(tag);
4214 s->tag = tag;
4215 }
4216 }
4217
4218 return (PF_PASS);
4219}
4220
4221int
4222pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
4223 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am,
4224 struct pf_ruleset **rsm)
4225{
4226 struct pf_rule *r, *a = NULL;
4227 struct pf_ruleset *ruleset = NULL;
4228 sa_family_t af = pd->af;
4229 u_short reason;
4230 struct pf_tag *pftag = NULL;
4231 int tag = -1;
4232 int asd = 0;
4233
4234 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
4235 while (r != NULL) {
4236 r->evaluations++;
4237 if (r->kif != NULL &&
4238 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
4239 r = r->skip[PF_SKIP_IFP].ptr;
4240 else if (r->direction && r->direction != direction)
4241 r = r->skip[PF_SKIP_DIR].ptr;
4242 else if (r->af && r->af != af)
4243 r = r->skip[PF_SKIP_AF].ptr;
4244 else if (r->proto && r->proto != pd->proto)
4245 r = r->skip[PF_SKIP_PROTO].ptr;
4246 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.neg))
4247 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
4248 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.neg))
4249 r = r->skip[PF_SKIP_DST_ADDR].ptr;
4250 else if (r->tos && !(r->tos & pd->tos))
4251 r = TAILQ_NEXT(r, entries);
4252 else if (r->src.port_op || r->dst.port_op ||
4253 r->flagset || r->type || r->code ||
4254 r->os_fingerprint != PF_OSFP_ANY)
4255 r = TAILQ_NEXT(r, entries);
4256 else if (r->prob && r->prob <= arc4random())
4257 r = TAILQ_NEXT(r, entries);
4258 else if (r->match_tag && !pf_match_tag(m, r, &pftag, &tag))
4259 r = TAILQ_NEXT(r, entries);
4260 else {
4261 if (r->anchor == NULL) {
4262 *rm = r;
4263 *am = a;
4264 *rsm = ruleset;
4265 if ((*rm)->quick)
4266 break;
4267 r = TAILQ_NEXT(r, entries);
4268 } else
4269 pf_step_into_anchor(&asd, &ruleset,
4270 PF_RULESET_FILTER, &r, &a);
4271 }
4272 if (r == NULL)
4273 pf_step_out_of_anchor(&asd, &ruleset,
4274 PF_RULESET_FILTER, &r, &a);
4275 }
4276 r = *rm;
4277 a = *am;
4278 ruleset = *rsm;
4279
4280 REASON_SET(&reason, PFRES_MATCH);
4281
4282 if (r->log)
4283 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
4284
4285 if (r->action != PF_PASS)
4286 return (PF_DROP);
4287
4288 if (pf_tag_packet(m, pftag, tag)) {
4289 REASON_SET(&reason, PFRES_MEMORY);
4290 return (PF_DROP);
4291 }
4292
4293 return (PF_PASS);
4294}
4295
4296int
4297pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
4298 struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
4299 u_short *reason)
4300{
4301 struct pf_state key;
4302 struct tcphdr *th = pd->hdr.tcp;
4303 u_int16_t win = ntohs(th->th_win);
4304 u_int32_t ack, end, seq, orig_seq;
4305 u_int8_t sws, dws;
4306 int ackskew;
4307 int copyback = 0;
4308 struct pf_state_peer *src, *dst;
4309
4310 key.af = pd->af;
4311 key.proto = IPPROTO_TCP;
4312 if (direction == PF_IN) {
4313 PF_ACPY(&key.ext.addr, pd->src, key.af);
4314 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4315 key.ext.port = th->th_sport;
4316 key.gwy.port = th->th_dport;
4317 } else {
4318 PF_ACPY(&key.lan.addr, pd->src, key.af);
4319 PF_ACPY(&key.ext.addr, pd->dst, key.af);
4320 key.lan.port = th->th_sport;
4321 key.ext.port = th->th_dport;
4322 }
4323
4324 STATE_LOOKUP();
4325
4326 if (direction == (*state)->direction) {
4327 src = &(*state)->src;
4328 dst = &(*state)->dst;
4329 } else {
4330 src = &(*state)->dst;
4331 dst = &(*state)->src;
4332 }
4333
4334 if ((*state)->src.state == PF_TCPS_PROXY_SRC) {
4335 if (direction != (*state)->direction) {
4336 REASON_SET(reason, PFRES_SYNPROXY);
4337 return (PF_SYNPROXY_DROP);
4338 }
4339 if (th->th_flags & TH_SYN) {
4340 if (ntohl(th->th_seq) != (*state)->src.seqlo) {
4341 REASON_SET(reason, PFRES_SYNPROXY);
4342 return (PF_DROP);
4343 }
4344 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
4345 pd->src, th->th_dport, th->th_sport,
4346 (*state)->src.seqhi, ntohl(th->th_seq) + 1,
4347 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1,
4348 NULL, NULL);
4349 REASON_SET(reason, PFRES_SYNPROXY);
4350 return (PF_SYNPROXY_DROP);
4351 } else if (!(th->th_flags & TH_ACK) ||
4352 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
4353 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
4354 REASON_SET(reason, PFRES_SYNPROXY);
4355 return (PF_DROP);
4356 } else if ((*state)->src_node != NULL &&
4357 pf_src_connlimit(state)) {
4358 REASON_SET(reason, PFRES_SRCLIMIT);
4359 return (PF_DROP);
4360 } else
4361 (*state)->src.state = PF_TCPS_PROXY_DST;
4362 }
4363 if ((*state)->src.state == PF_TCPS_PROXY_DST) {
4364 struct pf_state_host *src, *dst;
4365
4366 if (direction == PF_OUT) {
4367 src = &(*state)->gwy;
4368 dst = &(*state)->ext;
4369 } else {
4370 src = &(*state)->ext;
4371 dst = &(*state)->lan;
4372 }
4373 if (direction == (*state)->direction) {
4374 if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) ||
4375 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
4376 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
4377 REASON_SET(reason, PFRES_SYNPROXY);
4378 return (PF_DROP);
4379 }
4380 (*state)->src.max_win = MAX(ntohs(th->th_win), 1);
4381 if ((*state)->dst.seqhi == 1)
4382 (*state)->dst.seqhi = htonl(arc4random());
4383 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
4384 &dst->addr, src->port, dst->port,
4385 (*state)->dst.seqhi, 0, TH_SYN, 0,
4386 (*state)->src.mss, 0, 0, NULL, NULL);
4387 REASON_SET(reason, PFRES_SYNPROXY);
4388 return (PF_SYNPROXY_DROP);
4389 } else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
4390 (TH_SYN|TH_ACK)) ||
4391 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) {
4392 REASON_SET(reason, PFRES_SYNPROXY);
4393 return (PF_DROP);
4394 } else {
4395 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1);
4396 (*state)->dst.seqlo = ntohl(th->th_seq);
4397 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
4398 pd->src, th->th_dport, th->th_sport,
4399 ntohl(th->th_ack), ntohl(th->th_seq) + 1,
4400 TH_ACK, (*state)->src.max_win, 0, 0, 0,
4401 NULL, NULL);
4402 pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
4403 &dst->addr, src->port, dst->port,
4404 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
4405 TH_ACK, (*state)->dst.max_win, 0, 0, 1,
4406 NULL, NULL);
4407 (*state)->src.seqdiff = (*state)->dst.seqhi -
4408 (*state)->src.seqlo;
4409 (*state)->dst.seqdiff = (*state)->src.seqhi -
4410 (*state)->dst.seqlo;
4411 (*state)->src.seqhi = (*state)->src.seqlo +
4412 (*state)->dst.max_win;
4413 (*state)->dst.seqhi = (*state)->dst.seqlo +
4414 (*state)->src.max_win;
4415 (*state)->src.wscale = (*state)->dst.wscale = 0;
4416 (*state)->src.state = (*state)->dst.state =
4417 TCPS_ESTABLISHED;
4418 REASON_SET(reason, PFRES_SYNPROXY);
4419 return (PF_SYNPROXY_DROP);
4420 }
4421 }
4422
4423 if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
4424 sws = src->wscale & PF_WSCALE_MASK;
4425 dws = dst->wscale & PF_WSCALE_MASK;
4426 } else
4427 sws = dws = 0;
4428
4429 /*
4430 * Sequence tracking algorithm from Guido van Rooij's paper:
4431 * http://www.madison-gurkha.com/publications/tcp_filtering/
4432 * tcp_filtering.ps
4433 */
4434
4435 orig_seq = seq = ntohl(th->th_seq);
4436 if (src->seqlo == 0) {
4437 /* First packet from this end. Set its state */
4438
4439 if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) &&
4440 src->scrub == NULL) {
4441 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) {
4442 REASON_SET(reason, PFRES_MEMORY);
4443 return (PF_DROP);
4444 }
4445 }
4446
4447 /* Deferred generation of sequence number modulator */
4448 if (dst->seqdiff && !src->seqdiff) {
4449 while ((src->seqdiff = htonl(arc4random())) == 0)
4450 ;
4451 ack = ntohl(th->th_ack) - dst->seqdiff;
4452 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
4453 src->seqdiff), 0);
4454 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
4455 copyback = 1;
4456 } else {
4457 ack = ntohl(th->th_ack);
4458 }
4459
4460 end = seq + pd->p_len;
4461 if (th->th_flags & TH_SYN) {
4462 end++;
4463 if (dst->wscale & PF_WSCALE_FLAG) {
4464 src->wscale = pf_get_wscale(m, off, th->th_off,
4465 pd->af);
4466 if (src->wscale & PF_WSCALE_FLAG) {
4467 /* Remove scale factor from initial
4468 * window */
4469 sws = src->wscale & PF_WSCALE_MASK;
4470 win = ((u_int32_t)win + (1 << sws) - 1)
4471 >> sws;
4472 dws = dst->wscale & PF_WSCALE_MASK;
4473 } else {
4474 /* fixup other window */
4475 dst->max_win <<= dst->wscale &
4476 PF_WSCALE_MASK;
4477 /* in case of a retrans SYN|ACK */
4478 dst->wscale = 0;
4479 }
4480 }
4481 }
4482 if (th->th_flags & TH_FIN)
4483 end++;
4484
4485 src->seqlo = seq;
4486 if (src->state < TCPS_SYN_SENT)
4487 src->state = TCPS_SYN_SENT;
4488
4489 /*
4490 * May need to slide the window (seqhi may have been set by
4491 * the crappy stack check or if we picked up the connection
4492 * after establishment)
4493 */
4494 if (src->seqhi == 1 ||
4495 SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi))
4496 src->seqhi = end + MAX(1, dst->max_win << dws);
4497 if (win > src->max_win)
4498 src->max_win = win;
4499
4500 } else {
4501 ack = ntohl(th->th_ack) - dst->seqdiff;
4502 if (src->seqdiff) {
4503 /* Modulate sequence numbers */
4504 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
4505 src->seqdiff), 0);
4506 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
4507 copyback = 1;
4508 }
4509 end = seq + pd->p_len;
4510 if (th->th_flags & TH_SYN)
4511 end++;
4512 if (th->th_flags & TH_FIN)
4513 end++;
4514 }
4515
4516 if ((th->th_flags & TH_ACK) == 0) {
4517 /* Let it pass through the ack skew check */
4518 ack = dst->seqlo;
4519 } else if ((ack == 0 &&
4520 (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) ||
4521 /* broken tcp stacks do not set ack */
4522 (dst->state < TCPS_SYN_SENT)) {
4523 /*
4524 * Many stacks (ours included) will set the ACK number in an
4525 * FIN|ACK if the SYN times out -- no sequence to ACK.
4526 */
4527 ack = dst->seqlo;
4528 }
4529
4530 if (seq == end) {
4531 /* Ease sequencing restrictions on no data packets */
4532 seq = src->seqlo;
4533 end = seq;
4534 }
4535
4536 ackskew = dst->seqlo - ack;
4537
4538#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */
4539 if (SEQ_GEQ(src->seqhi, end) &&
4540 /* Last octet inside other's window space */
4541 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
4542 /* Retrans: not more than one window back */
4543 (ackskew >= -MAXACKWINDOW) &&
4544 /* Acking not more than one reassembled fragment backwards */
4545 (ackskew <= (MAXACKWINDOW << sws)) &&
4546 /* Acking not more than one window forward */
4547 ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
4548 (pd->flags & PFDESC_IP_REAS) == 0)) {
4549 /* Require an exact sequence match on resets when possible */
4550
4551 if (dst->scrub || src->scrub) {
4552 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
4553 *state, src, dst, &copyback))
4554 return (PF_DROP);
4555 }
4556
4557 /* update max window */
4558 if (src->max_win < win)
4559 src->max_win = win;
4560 /* synchronize sequencing */
4561 if (SEQ_GT(end, src->seqlo))
4562 src->seqlo = end;
4563 /* slide the window of what the other end can send */
4564 if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
4565 dst->seqhi = ack + MAX((win << sws), 1);
4566
4567
4568 /* update states */
4569 if (th->th_flags & TH_SYN)
4570 if (src->state < TCPS_SYN_SENT)
4571 src->state = TCPS_SYN_SENT;
4572 if (th->th_flags & TH_FIN)
4573 if (src->state < TCPS_CLOSING)
4574 src->state = TCPS_CLOSING;
4575 if (th->th_flags & TH_ACK) {
4576 if (dst->state == TCPS_SYN_SENT) {
4577 dst->state = TCPS_ESTABLISHED;
4578 if (src->state == TCPS_ESTABLISHED &&
4579 (*state)->src_node != NULL &&
4580 pf_src_connlimit(state)) {
4581 REASON_SET(reason, PFRES_SRCLIMIT);
4582 return (PF_DROP);
4583 }
4584 } else if (dst->state == TCPS_CLOSING)
4585 dst->state = TCPS_FIN_WAIT_2;
4586 }
4587 if (th->th_flags & TH_RST)
4588 src->state = dst->state = TCPS_TIME_WAIT;
4589
4590 /* update expire time */
4591 (*state)->expire = time_second;
4592 if (src->state >= TCPS_FIN_WAIT_2 &&
4593 dst->state >= TCPS_FIN_WAIT_2)
4594 (*state)->timeout = PFTM_TCP_CLOSED;
4595 else if (src->state >= TCPS_FIN_WAIT_2 ||
4596 dst->state >= TCPS_FIN_WAIT_2)
4597 (*state)->timeout = PFTM_TCP_FIN_WAIT;
4598 else if (src->state < TCPS_ESTABLISHED ||
4599 dst->state < TCPS_ESTABLISHED)
4600 (*state)->timeout = PFTM_TCP_OPENING;
4601 else if (src->state >= TCPS_CLOSING ||
4602 dst->state >= TCPS_CLOSING)
4603 (*state)->timeout = PFTM_TCP_CLOSING;
4604 else
4605 (*state)->timeout = PFTM_TCP_ESTABLISHED;
4606
4607 /* Fall through to PASS packet */
4608
4609 } else if ((dst->state < TCPS_SYN_SENT ||
4610 dst->state >= TCPS_FIN_WAIT_2 ||
4611 src->state >= TCPS_FIN_WAIT_2) &&
4612 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) &&
4613 /* Within a window forward of the originating packet */
4614 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) {
4615 /* Within a window backward of the originating packet */
4616
4617 /*
4618 * This currently handles three situations:
4619 * 1) Stupid stacks will shotgun SYNs before their peer
4620 * replies.
4621 * 2) When PF catches an already established stream (the
4622 * firewall rebooted, the state table was flushed, routes
4623 * changed...)
4624 * 3) Packets get funky immediately after the connection
4625 * closes (this should catch Solaris spurious ACK|FINs
4626 * that web servers like to spew after a close)
4627 *
4628 * This must be a little more careful than the above code
4629 * since packet floods will also be caught here. We don't
4630 * update the TTL here to mitigate the damage of a packet
4631 * flood and so the same code can handle awkward establishment
4632 * and a loosened connection close.
4633 * In the establishment case, a correct peer response will
4634 * validate the connection, go through the normal state code
4635 * and keep updating the state TTL.
4636 */
4637
4638 if (pf_status.debug >= PF_DEBUG_MISC) {
4639 printf("pf: loose state match: ");
4640 pf_print_state(*state);
4641 pf_print_flags(th->th_flags);
4642 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d\n",
4643 seq, ack, pd->p_len, ackskew,
4644 (*state)->packets[0], (*state)->packets[1]);
4645 }
4646
4647 if (dst->scrub || src->scrub) {
4648 if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
4649 *state, src, dst, &copyback))
4650 return (PF_DROP);
4651 }
4652
4653 /* update max window */
4654 if (src->max_win < win)
4655 src->max_win = win;
4656 /* synchronize sequencing */
4657 if (SEQ_GT(end, src->seqlo))
4658 src->seqlo = end;
4659 /* slide the window of what the other end can send */
4660 if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
4661 dst->seqhi = ack + MAX((win << sws), 1);
4662
4663 /*
4664 * Cannot set dst->seqhi here since this could be a shotgunned
4665 * SYN and not an already established connection.
4666 */
4667
4668 if (th->th_flags & TH_FIN)
4669 if (src->state < TCPS_CLOSING)
4670 src->state = TCPS_CLOSING;
4671 if (th->th_flags & TH_RST)
4672 src->state = dst->state = TCPS_TIME_WAIT;
4673
4674 /* Fall through to PASS packet */
4675
4676 } else {
4677 if ((*state)->dst.state == TCPS_SYN_SENT &&
4678 (*state)->src.state == TCPS_SYN_SENT) {
4679 /* Send RST for state mismatches during handshake */
4680 if (!(th->th_flags & TH_RST))
4681 pf_send_tcp((*state)->rule.ptr, pd->af,
4682 pd->dst, pd->src, th->th_dport,
4683 th->th_sport, ntohl(th->th_ack), 0,
4684 TH_RST, 0, 0,
4685 (*state)->rule.ptr->return_ttl, 1,
4686 pd->eh, kif->pfik_ifp);
4687 src->seqlo = 0;
4688 src->seqhi = 1;
4689 src->max_win = 1;
4690 } else if (pf_status.debug >= PF_DEBUG_MISC) {
4691 printf("pf: BAD state: ");
4692 pf_print_state(*state);
4693 pf_print_flags(th->th_flags);
4694 printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d "
4695 "dir=%s,%s\n", seq, ack, pd->p_len, ackskew,
4696 (*state)->packets[0], (*state)->packets[1],
4697 direction == PF_IN ? "in" : "out",
4698 direction == (*state)->direction ? "fwd" : "rev");
4699 printf("pf: State failure on: %c %c %c %c | %c %c\n",
4700 SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
4701 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
4702 ' ': '2',
4703 (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
4704 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',
4705 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5',
4706 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6');
4707 }
4708 REASON_SET(reason, PFRES_BADSTATE);
4709 return (PF_DROP);
4710 }
4711
4712 /* Any packets which have gotten here are to be passed */
4713
4714 /* translate source/destination address, if necessary */
4715 if (STATE_TRANSLATE(*state)) {
4716 if (direction == PF_OUT)
4717 pf_change_ap(pd->src, &th->th_sport, pd->ip_sum,
4718 &th->th_sum, &(*state)->gwy.addr,
4719 (*state)->gwy.port, 0, pd->af);
4720 else
4721 pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum,
4722 &th->th_sum, &(*state)->lan.addr,
4723 (*state)->lan.port, 0, pd->af);
4724 m_copyback(m, off, sizeof(*th), (caddr_t)th);
4725 } else if (copyback) {
4726 /* Copyback sequence modulation or stateful scrub changes */
4727 m_copyback(m, off, sizeof(*th), (caddr_t)th);
4728 }
4729
4730 return (PF_PASS);
4731}
4732
4733int
4734pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
4735 struct mbuf *m, int off, void *h, struct pf_pdesc *pd)
4736{
4737 struct pf_state_peer *src, *dst;
4738 struct pf_state key;
4739 struct udphdr *uh = pd->hdr.udp;
4740
4741 key.af = pd->af;
4742 key.proto = IPPROTO_UDP;
4743 if (direction == PF_IN) {
4744 PF_ACPY(&key.ext.addr, pd->src, key.af);
4745 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4746 key.ext.port = uh->uh_sport;
4747 key.gwy.port = uh->uh_dport;
4748 } else {
4749 PF_ACPY(&key.lan.addr, pd->src, key.af);
4750 PF_ACPY(&key.ext.addr, pd->dst, key.af);
4751 key.lan.port = uh->uh_sport;
4752 key.ext.port = uh->uh_dport;
4753 }
4754
4755 STATE_LOOKUP();
4756
4757 if (direction == (*state)->direction) {
4758 src = &(*state)->src;
4759 dst = &(*state)->dst;
4760 } else {
4761 src = &(*state)->dst;
4762 dst = &(*state)->src;
4763 }
4764
4765 /* update states */
4766 if (src->state < PFUDPS_SINGLE)
4767 src->state = PFUDPS_SINGLE;
4768 if (dst->state == PFUDPS_SINGLE)
4769 dst->state = PFUDPS_MULTIPLE;
4770
4771 /* update expire time */
4772 (*state)->expire = time_second;
4773 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE)
4774 (*state)->timeout = PFTM_UDP_MULTIPLE;
4775 else
4776 (*state)->timeout = PFTM_UDP_SINGLE;
4777
4778 /* translate source/destination address, if necessary */
4779 if (STATE_TRANSLATE(*state)) {
4780 if (direction == PF_OUT)
4781 pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum,
4782 &uh->uh_sum, &(*state)->gwy.addr,
4783 (*state)->gwy.port, 1, pd->af);
4784 else
4785 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum,
4786 &uh->uh_sum, &(*state)->lan.addr,
4787 (*state)->lan.port, 1, pd->af);
4788 m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
4789 }
4790
4791 return (PF_PASS);
4792}
4793
4794int
4795pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
4796 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason)
4797{
4798 struct pf_addr *saddr = pd->src, *daddr = pd->dst;
4799 u_int16_t icmpid = 0; /* make the compiler happy */
4800 u_int16_t *icmpsum = NULL; /* make the compiler happy */
4801 u_int8_t icmptype = 0; /* make the compiler happy */
4802 int state_icmp = 0;
4803
4804 switch (pd->proto) {
4805#ifdef INET
4806 case IPPROTO_ICMP:
4807 icmptype = pd->hdr.icmp->icmp_type;
4808 icmpid = pd->hdr.icmp->icmp_id;
4809 icmpsum = &pd->hdr.icmp->icmp_cksum;
4810
4811 if (icmptype == ICMP_UNREACH ||
4812 icmptype == ICMP_SOURCEQUENCH ||
4813 icmptype == ICMP_REDIRECT ||
4814 icmptype == ICMP_TIMXCEED ||
4815 icmptype == ICMP_PARAMPROB)
4816 state_icmp++;
4817 break;
4818#endif /* INET */
4819#ifdef INET6
4820 case IPPROTO_ICMPV6:
4821 icmptype = pd->hdr.icmp6->icmp6_type;
4822 icmpid = pd->hdr.icmp6->icmp6_id;
4823 icmpsum = &pd->hdr.icmp6->icmp6_cksum;
4824
4825 if (icmptype == ICMP6_DST_UNREACH ||
4826 icmptype == ICMP6_PACKET_TOO_BIG ||
4827 icmptype == ICMP6_TIME_EXCEEDED ||
4828 icmptype == ICMP6_PARAM_PROB)
4829 state_icmp++;
4830 break;
4831#endif /* INET6 */
4832 }
4833
4834 if (!state_icmp) {
4835
4836 /*
4837 * ICMP query/reply message not related to a TCP/UDP packet.
4838 * Search for an ICMP state.
4839 */
4840 struct pf_state key;
4841
4842 key.af = pd->af;
4843 key.proto = pd->proto;
4844 if (direction == PF_IN) {
4845 PF_ACPY(&key.ext.addr, pd->src, key.af);
4846 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4847 key.ext.port = 0;
4848 key.gwy.port = icmpid;
4849 } else {
4850 PF_ACPY(&key.lan.addr, pd->src, key.af);
4851 PF_ACPY(&key.ext.addr, pd->dst, key.af);
4852 key.lan.port = icmpid;
4853 key.ext.port = 0;
4854 }
4855
4856 STATE_LOOKUP();
4857
4858 (*state)->expire = time_second;
4859 (*state)->timeout = PFTM_ICMP_ERROR_REPLY;
4860
4861 /* translate source/destination address, if necessary */
4862 if (STATE_TRANSLATE(*state)) {
4863 if (direction == PF_OUT) {
4864 switch (pd->af) {
4865#ifdef INET
4866 case AF_INET:
4867 pf_change_a(&saddr->v4.s_addr,
4868 pd->ip_sum,
4869 (*state)->gwy.addr.v4.s_addr, 0);
4870 pd->hdr.icmp->icmp_cksum =
4871 pf_cksum_fixup(
4872 pd->hdr.icmp->icmp_cksum, icmpid,
4873 (*state)->gwy.port, 0);
4874 pd->hdr.icmp->icmp_id =
4875 (*state)->gwy.port;
4876 m_copyback(m, off, ICMP_MINLEN,
4877 (caddr_t)pd->hdr.icmp);
4878 break;
4879#endif /* INET */
4880#ifdef INET6
4881 case AF_INET6:
4882 pf_change_a6(saddr,
4883 &pd->hdr.icmp6->icmp6_cksum,
4884 &(*state)->gwy.addr, 0);
4885 m_copyback(m, off,
4886 sizeof(struct icmp6_hdr),
4887 (caddr_t)pd->hdr.icmp6);
4888 break;
4889#endif /* INET6 */
4890 }
4891 } else {
4892 switch (pd->af) {
4893#ifdef INET
4894 case AF_INET:
4895 pf_change_a(&daddr->v4.s_addr,
4896 pd->ip_sum,
4897 (*state)->lan.addr.v4.s_addr, 0);
4898 pd->hdr.icmp->icmp_cksum =
4899 pf_cksum_fixup(
4900 pd->hdr.icmp->icmp_cksum, icmpid,
4901 (*state)->lan.port, 0);
4902 pd->hdr.icmp->icmp_id =
4903 (*state)->lan.port;
4904 m_copyback(m, off, ICMP_MINLEN,
4905 (caddr_t)pd->hdr.icmp);
4906 break;
4907#endif /* INET */
4908#ifdef INET6
4909 case AF_INET6:
4910 pf_change_a6(daddr,
4911 &pd->hdr.icmp6->icmp6_cksum,
4912 &(*state)->lan.addr, 0);
4913 m_copyback(m, off,
4914 sizeof(struct icmp6_hdr),
4915 (caddr_t)pd->hdr.icmp6);
4916 break;
4917#endif /* INET6 */
4918 }
4919 }
4920 }
4921
4922 return (PF_PASS);
4923
4924 } else {
4925 /*
4926 * ICMP error message in response to a TCP/UDP packet.
4927 * Extract the inner TCP/UDP header and search for that state.
4928 */
4929
4930 struct pf_pdesc pd2;
4931#ifdef INET
4932 struct ip h2;
4933#endif /* INET */
4934#ifdef INET6
4935 struct ip6_hdr h2_6;
4936 int terminal = 0;
4937#endif /* INET6 */
4938 int ipoff2 = 0; /* make the compiler happy */
4939 int off2 = 0; /* make the compiler happy */
4940
4941 pd2.af = pd->af;
4942 switch (pd->af) {
4943#ifdef INET
4944 case AF_INET:
4945 /* offset of h2 in mbuf chain */
4946 ipoff2 = off + ICMP_MINLEN;
4947
4948 if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2),
4949 NULL, reason, pd2.af)) {
4950 DPFPRINTF(PF_DEBUG_MISC,
4951 ("pf: ICMP error message too short "
4952 "(ip)\n"));
4953 return (PF_DROP);
4954 }
4955 /*
4956 * ICMP error messages don't refer to non-first
4957 * fragments
4958 */
4959 if (h2.ip_off & htons(IP_OFFMASK)) {
4960 REASON_SET(reason, PFRES_FRAG);
4961 return (PF_DROP);
4962 }
4963
4964 /* offset of protocol header that follows h2 */
4965 off2 = ipoff2 + (h2.ip_hl << 2);
4966
4967 pd2.proto = h2.ip_p;
4968 pd2.src = (struct pf_addr *)&h2.ip_src;
4969 pd2.dst = (struct pf_addr *)&h2.ip_dst;
4970 pd2.ip_sum = &h2.ip_sum;
4971 break;
4972#endif /* INET */
4973#ifdef INET6
4974 case AF_INET6:
4975 ipoff2 = off + sizeof(struct icmp6_hdr);
4976
4977 if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6),
4978 NULL, reason, pd2.af)) {
4979 DPFPRINTF(PF_DEBUG_MISC,
4980 ("pf: ICMP error message too short "
4981 "(ip6)\n"));
4982 return (PF_DROP);
4983 }
4984 pd2.proto = h2_6.ip6_nxt;
4985 pd2.src = (struct pf_addr *)&h2_6.ip6_src;
4986 pd2.dst = (struct pf_addr *)&h2_6.ip6_dst;
4987 pd2.ip_sum = NULL;
4988 off2 = ipoff2 + sizeof(h2_6);
4989 do {
4990 switch (pd2.proto) {
4991 case IPPROTO_FRAGMENT:
4992 /*
4993 * ICMPv6 error messages for
4994 * non-first fragments
4995 */
4996 REASON_SET(reason, PFRES_FRAG);
4997 return (PF_DROP);
4998 case IPPROTO_AH:
4999 case IPPROTO_HOPOPTS:
5000 case IPPROTO_ROUTING:
5001 case IPPROTO_DSTOPTS: {
5002 /* get next header and header length */
5003 struct ip6_ext opt6;
5004
5005 if (!pf_pull_hdr(m, off2, &opt6,
5006 sizeof(opt6), NULL, reason,
5007 pd2.af)) {
5008 DPFPRINTF(PF_DEBUG_MISC,
5009 ("pf: ICMPv6 short opt\n"));
5010 return (PF_DROP);
5011 }
5012 if (pd2.proto == IPPROTO_AH)
5013 off2 += (opt6.ip6e_len + 2) * 4;
5014 else
5015 off2 += (opt6.ip6e_len + 1) * 8;
5016 pd2.proto = opt6.ip6e_nxt;
5017 /* goto the next header */
5018 break;
5019 }
5020 default:
5021 terminal++;
5022 break;
5023 }
5024 } while (!terminal);
5025 break;
5026#endif /* INET6 */
5027 }
5028
5029 switch (pd2.proto) {
5030 case IPPROTO_TCP: {
5031 struct tcphdr th;
5032 u_int32_t seq;
5033 struct pf_state key;
5034 struct pf_state_peer *src, *dst;
5035 u_int8_t dws;
5036 int copyback = 0;
5037
5038 /*
5039 * Only the first 8 bytes of the TCP header can be
5040 * expected. Don't access any TCP header fields after
5041 * th_seq, an ackskew test is not possible.
5042 */
5043 if (!pf_pull_hdr(m, off2, &th, 8, NULL, reason,
5044 pd2.af)) {
5045 DPFPRINTF(PF_DEBUG_MISC,
5046 ("pf: ICMP error message too short "
5047 "(tcp)\n"));
5048 return (PF_DROP);
5049 }
5050
5051 key.af = pd2.af;
5052 key.proto = IPPROTO_TCP;
5053 if (direction == PF_IN) {
5054 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
5055 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
5056 key.ext.port = th.th_dport;
5057 key.gwy.port = th.th_sport;
5058 } else {
5059 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
5060 PF_ACPY(&key.ext.addr, pd2.src, key.af);
5061 key.lan.port = th.th_dport;
5062 key.ext.port = th.th_sport;
5063 }
5064
5065 STATE_LOOKUP();
5066
5067 if (direction == (*state)->direction) {
5068 src = &(*state)->dst;
5069 dst = &(*state)->src;
5070 } else {
5071 src = &(*state)->src;
5072 dst = &(*state)->dst;
5073 }
5074
5075 if (src->wscale && dst->wscale &&
5076 !(th.th_flags & TH_SYN))
5077 dws = dst->wscale & PF_WSCALE_MASK;
5078 else
5079 dws = 0;
5080
5081 /* Demodulate sequence number */
5082 seq = ntohl(th.th_seq) - src->seqdiff;
5083 if (src->seqdiff) {
5084 pf_change_a(&th.th_seq, icmpsum,
5085 htonl(seq), 0);
5086 copyback = 1;
5087 }
5088
5089 if (!SEQ_GEQ(src->seqhi, seq) ||
5090 !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws))) {
5091 if (pf_status.debug >= PF_DEBUG_MISC) {
5092 printf("pf: BAD ICMP %d:%d ",
5093 icmptype, pd->hdr.icmp->icmp_code);
5094 pf_print_host(pd->src, 0, pd->af);
5095 printf(" -> ");
5096 pf_print_host(pd->dst, 0, pd->af);
5097 printf(" state: ");
5098 pf_print_state(*state);
5099 printf(" seq=%u\n", seq);
5100 }
5101 REASON_SET(reason, PFRES_BADSTATE);
5102 return (PF_DROP);
5103 }
5104
5105 if (STATE_TRANSLATE(*state)) {
5106 if (direction == PF_IN) {
5107 pf_change_icmp(pd2.src, &th.th_sport,
5108 daddr, &(*state)->lan.addr,
5109 (*state)->lan.port, NULL,
5110 pd2.ip_sum, icmpsum,
5111 pd->ip_sum, 0, pd2.af);
5112 } else {
5113 pf_change_icmp(pd2.dst, &th.th_dport,
5114 saddr, &(*state)->gwy.addr,
5115 (*state)->gwy.port, NULL,
5116 pd2.ip_sum, icmpsum,
5117 pd->ip_sum, 0, pd2.af);
5118 }
5119 copyback = 1;
5120 }
5121
5122 if (copyback) {
5123 switch (pd2.af) {
5124#ifdef INET
5125 case AF_INET:
5126 m_copyback(m, off, ICMP_MINLEN,
5127 (caddr_t)pd->hdr.icmp);
5128 m_copyback(m, ipoff2, sizeof(h2),
5129 (caddr_t)&h2);
5130 break;
5131#endif /* INET */
5132#ifdef INET6
5133 case AF_INET6:
5134 m_copyback(m, off,
5135 sizeof(struct icmp6_hdr),
5136 (caddr_t)pd->hdr.icmp6);
5137 m_copyback(m, ipoff2, sizeof(h2_6),
5138 (caddr_t)&h2_6);
5139 break;
5140#endif /* INET6 */
5141 }
5142 m_copyback(m, off2, 8, (caddr_t)&th);
5143 }
5144
5145 return (PF_PASS);
5146 break;
5147 }
5148 case IPPROTO_UDP: {
5149 struct udphdr uh;
5150 struct pf_state key;
5151
5152 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh),
5153 NULL, reason, pd2.af)) {
5154 DPFPRINTF(PF_DEBUG_MISC,
5155 ("pf: ICMP error message too short "
5156 "(udp)\n"));
5157 return (PF_DROP);
5158 }
5159
5160 key.af = pd2.af;
5161 key.proto = IPPROTO_UDP;
5162 if (direction == PF_IN) {
5163 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
5164 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
5165 key.ext.port = uh.uh_dport;
5166 key.gwy.port = uh.uh_sport;
5167 } else {
5168 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
5169 PF_ACPY(&key.ext.addr, pd2.src, key.af);
5170 key.lan.port = uh.uh_dport;
5171 key.ext.port = uh.uh_sport;
5172 }
5173
5174 STATE_LOOKUP();
5175
5176 if (STATE_TRANSLATE(*state)) {
5177 if (direction == PF_IN) {
5178 pf_change_icmp(pd2.src, &uh.uh_sport,
5179 daddr, &(*state)->lan.addr,
5180 (*state)->lan.port, &uh.uh_sum,
5181 pd2.ip_sum, icmpsum,
5182 pd->ip_sum, 1, pd2.af);
5183 } else {
5184 pf_change_icmp(pd2.dst, &uh.uh_dport,
5185 saddr, &(*state)->gwy.addr,
5186 (*state)->gwy.port, &uh.uh_sum,
5187 pd2.ip_sum, icmpsum,
5188 pd->ip_sum, 1, pd2.af);
5189 }
5190 switch (pd2.af) {
5191#ifdef INET
5192 case AF_INET:
5193 m_copyback(m, off, ICMP_MINLEN,
5194 (caddr_t)pd->hdr.icmp);
5195 m_copyback(m, ipoff2, sizeof(h2),
5196 (caddr_t)&h2);
5197 break;
5198#endif /* INET */
5199#ifdef INET6
5200 case AF_INET6:
5201 m_copyback(m, off,
5202 sizeof(struct icmp6_hdr),
5203 (caddr_t)pd->hdr.icmp6);
5204 m_copyback(m, ipoff2, sizeof(h2_6),
5205 (caddr_t)&h2_6);
5206 break;
5207#endif /* INET6 */
5208 }
5209 m_copyback(m, off2, sizeof(uh),
5210 (caddr_t)&uh);
5211 }
5212
5213 return (PF_PASS);
5214 break;
5215 }
5216#ifdef INET
5217 case IPPROTO_ICMP: {
5218 struct icmp iih;
5219 struct pf_state key;
5220
5221 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN,
5222 NULL, reason, pd2.af)) {
5223 DPFPRINTF(PF_DEBUG_MISC,
5224 ("pf: ICMP error message too short i"
5225 "(icmp)\n"));
5226 return (PF_DROP);
5227 }
5228
5229 key.af = pd2.af;
5230 key.proto = IPPROTO_ICMP;
5231 if (direction == PF_IN) {
5232 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
5233 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
5234 key.ext.port = 0;
5235 key.gwy.port = iih.icmp_id;
5236 } else {
5237 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
5238 PF_ACPY(&key.ext.addr, pd2.src, key.af);
5239 key.lan.port = iih.icmp_id;
5240 key.ext.port = 0;
5241 }
5242
5243 STATE_LOOKUP();
5244
5245 if (STATE_TRANSLATE(*state)) {
5246 if (direction == PF_IN) {
5247 pf_change_icmp(pd2.src, &iih.icmp_id,
5248 daddr, &(*state)->lan.addr,
5249 (*state)->lan.port, NULL,
5250 pd2.ip_sum, icmpsum,
5251 pd->ip_sum, 0, AF_INET);
5252 } else {
5253 pf_change_icmp(pd2.dst, &iih.icmp_id,
5254 saddr, &(*state)->gwy.addr,
5255 (*state)->gwy.port, NULL,
5256 pd2.ip_sum, icmpsum,
5257 pd->ip_sum, 0, AF_INET);
5258 }
5259 m_copyback(m, off, ICMP_MINLEN,
5260 (caddr_t)pd->hdr.icmp);
5261 m_copyback(m, ipoff2, sizeof(h2),
5262 (caddr_t)&h2);
5263 m_copyback(m, off2, ICMP_MINLEN,
5264 (caddr_t)&iih);
5265 }
5266
5267 return (PF_PASS);
5268 break;
5269 }
5270#endif /* INET */
5271#ifdef INET6
5272 case IPPROTO_ICMPV6: {
5273 struct icmp6_hdr iih;
5274 struct pf_state key;
5275
5276 if (!pf_pull_hdr(m, off2, &iih,
5277 sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
5278 DPFPRINTF(PF_DEBUG_MISC,
5279 ("pf: ICMP error message too short "
5280 "(icmp6)\n"));
5281 return (PF_DROP);
5282 }
5283
5284 key.af = pd2.af;
5285 key.proto = IPPROTO_ICMPV6;
5286 if (direction == PF_IN) {
5287 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
5288 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
5289 key.ext.port = 0;
5290 key.gwy.port = iih.icmp6_id;
5291 } else {
5292 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
5293 PF_ACPY(&key.ext.addr, pd2.src, key.af);
5294 key.lan.port = iih.icmp6_id;
5295 key.ext.port = 0;
5296 }
5297
5298 STATE_LOOKUP();
5299
5300 if (STATE_TRANSLATE(*state)) {
5301 if (direction == PF_IN) {
5302 pf_change_icmp(pd2.src, &iih.icmp6_id,
5303 daddr, &(*state)->lan.addr,
5304 (*state)->lan.port, NULL,
5305 pd2.ip_sum, icmpsum,
5306 pd->ip_sum, 0, AF_INET6);
5307 } else {
5308 pf_change_icmp(pd2.dst, &iih.icmp6_id,
5309 saddr, &(*state)->gwy.addr,
5310 (*state)->gwy.port, NULL,
5311 pd2.ip_sum, icmpsum,
5312 pd->ip_sum, 0, AF_INET6);
5313 }
5314 m_copyback(m, off, sizeof(struct icmp6_hdr),
5315 (caddr_t)pd->hdr.icmp6);
5316 m_copyback(m, ipoff2, sizeof(h2_6),
5317 (caddr_t)&h2_6);
5318 m_copyback(m, off2, sizeof(struct icmp6_hdr),
5319 (caddr_t)&iih);
5320 }
5321
5322 return (PF_PASS);
5323 break;
5324 }
5325#endif /* INET6 */
5326 default: {
5327 struct pf_state key;
5328
5329 key.af = pd2.af;
5330 key.proto = pd2.proto;
5331 if (direction == PF_IN) {
5332 PF_ACPY(&key.ext.addr, pd2.dst, key.af);
5333 PF_ACPY(&key.gwy.addr, pd2.src, key.af);
5334 key.ext.port = 0;
5335 key.gwy.port = 0;
5336 } else {
5337 PF_ACPY(&key.lan.addr, pd2.dst, key.af);
5338 PF_ACPY(&key.ext.addr, pd2.src, key.af);
5339 key.lan.port = 0;
5340 key.ext.port = 0;
5341 }
5342
5343 STATE_LOOKUP();
5344
5345 if (STATE_TRANSLATE(*state)) {
5346 if (direction == PF_IN) {
5347 pf_change_icmp(pd2.src, NULL,
5348 daddr, &(*state)->lan.addr,
5349 0, NULL,
5350 pd2.ip_sum, icmpsum,
5351 pd->ip_sum, 0, pd2.af);
5352 } else {
5353 pf_change_icmp(pd2.dst, NULL,
5354 saddr, &(*state)->gwy.addr,
5355 0, NULL,
5356 pd2.ip_sum, icmpsum,
5357 pd->ip_sum, 0, pd2.af);
5358 }
5359 switch (pd2.af) {
5360#ifdef INET
5361 case AF_INET:
5362 m_copyback(m, off, ICMP_MINLEN,
5363 (caddr_t)pd->hdr.icmp);
5364 m_copyback(m, ipoff2, sizeof(h2),
5365 (caddr_t)&h2);
5366 break;
5367#endif /* INET */
5368#ifdef INET6
5369 case AF_INET6:
5370 m_copyback(m, off,
5371 sizeof(struct icmp6_hdr),
5372 (caddr_t)pd->hdr.icmp6);
5373 m_copyback(m, ipoff2, sizeof(h2_6),
5374 (caddr_t)&h2_6);
5375 break;
5376#endif /* INET6 */
5377 }
5378 }
5379
5380 return (PF_PASS);
5381 break;
5382 }
5383 }
5384 }
5385}
5386
5387int
5388pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
5389 struct pf_pdesc *pd)
5390{
5391 struct pf_state_peer *src, *dst;
5392 struct pf_state key;
5393
5394 key.af = pd->af;
5395 key.proto = pd->proto;
5396 if (direction == PF_IN) {
5397 PF_ACPY(&key.ext.addr, pd->src, key.af);
5398 PF_ACPY(&key.gwy.addr, pd->dst, key.af);
5399 key.ext.port = 0;
5400 key.gwy.port = 0;
5401 } else {
5402 PF_ACPY(&key.lan.addr, pd->src, key.af);
5403 PF_ACPY(&key.ext.addr, pd->dst, key.af);
5404 key.lan.port = 0;
5405 key.ext.port = 0;
5406 }
5407
5408 STATE_LOOKUP();
5409
5410 if (direction == (*state)->direction) {
5411 src = &(*state)->src;
5412 dst = &(*state)->dst;
5413 } else {
5414 src = &(*state)->dst;
5415 dst = &(*state)->src;
5416 }
5417
5418 /* update states */
5419 if (src->state < PFOTHERS_SINGLE)
5420 src->state = PFOTHERS_SINGLE;
5421 if (dst->state == PFOTHERS_SINGLE)
5422 dst->state = PFOTHERS_MULTIPLE;
5423
5424 /* update expire time */
5425 (*state)->expire = time_second;
5426 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE)
5427 (*state)->timeout = PFTM_OTHER_MULTIPLE;
5428 else
5429 (*state)->timeout = PFTM_OTHER_SINGLE;
5430
5431 /* translate source/destination address, if necessary */
5432 if (STATE_TRANSLATE(*state)) {
5433 if (direction == PF_OUT)
5434 switch (pd->af) {
5435#ifdef INET
5436 case AF_INET:
5437 pf_change_a(&pd->src->v4.s_addr,
5438 pd->ip_sum, (*state)->gwy.addr.v4.s_addr,
5439 0);
5440 break;
5441#endif /* INET */
5442#ifdef INET6
5443 case AF_INET6:
5444 PF_ACPY(pd->src, &(*state)->gwy.addr, pd->af);
5445 break;
5446#endif /* INET6 */
5447 }
5448 else
5449 switch (pd->af) {
5450#ifdef INET
5451 case AF_INET:
5452 pf_change_a(&pd->dst->v4.s_addr,
5453 pd->ip_sum, (*state)->lan.addr.v4.s_addr,
5454 0);
5455 break;
5456#endif /* INET */
5457#ifdef INET6
5458 case AF_INET6:
5459 PF_ACPY(pd->dst, &(*state)->lan.addr, pd->af);
5460 break;
5461#endif /* INET6 */
5462 }
5463 }
5464
5465 return (PF_PASS);
5466}
5467
5468/*
5469 * ipoff and off are measured from the start of the mbuf chain.
5470 * h must be at "ipoff" on the mbuf chain.
5471 */
5472void *
5473pf_pull_hdr(struct mbuf *m, int off, void *p, int len,
5474 u_short *actionp, u_short *reasonp, sa_family_t af)
5475{
5476 switch (af) {
5477#ifdef INET
5478 case AF_INET: {
5479 struct ip *h = mtod(m, struct ip *);
5480 u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
5481
5482 if (fragoff) {
5483 if (fragoff >= len)
5484 ACTION_SET(actionp, PF_PASS);
5485 else {
5486 ACTION_SET(actionp, PF_DROP);
5487 REASON_SET(reasonp, PFRES_FRAG);
5488 }
5489 return (NULL);
5490 }
5491 if (m->m_pkthdr.len < off + len ||
5492 ntohs(h->ip_len) < off + len) {
5493 ACTION_SET(actionp, PF_DROP);
5494 REASON_SET(reasonp, PFRES_SHORT);
5495 return (NULL);
5496 }
5497 break;
5498 }
5499#endif /* INET */
5500#ifdef INET6
5501 case AF_INET6: {
5502 struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
5503
5504 if (m->m_pkthdr.len < off + len ||
5505 (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) <
5506 (unsigned)(off + len)) {
5507 ACTION_SET(actionp, PF_DROP);
5508 REASON_SET(reasonp, PFRES_SHORT);
5509 return (NULL);
5510 }
5511 break;
5512 }
5513#endif /* INET6 */
5514 }
5515 m_copydata(m, off, len, p);
5516 return (p);
5517}
5518
5519int
5520pf_routable(struct pf_addr *addr, sa_family_t af)
5521{
5522 struct sockaddr_in *dst;
5523#ifdef INET6
5524 struct sockaddr_in6 *dst6;
5525 struct route_in6 ro;
5526#else
5527 struct route ro;
5528#endif
5529
5530 bzero(&ro, sizeof(ro));
5531 switch (af) {
5532 case AF_INET:
5533 dst = satosin(&ro.ro_dst);
5534 dst->sin_family = AF_INET;
5535 dst->sin_len = sizeof(*dst);
5536 dst->sin_addr = addr->v4;
5537 break;
5538#ifdef INET6
5539 case AF_INET6:
5540 dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
5541 dst6->sin6_family = AF_INET6;
5542 dst6->sin6_len = sizeof(*dst6);
5543 dst6->sin6_addr = addr->v6;
5544 break;
5545#endif /* INET6 */
5546 default:
5547 return (0);
5548 }
5549
5550#ifdef __FreeBSD__
5551#ifdef RTF_PRCLONING
5552 rtalloc_ign((struct route *)&ro, (RTF_CLONING | RTF_PRCLONING));
5553#else /* !RTF_PRCLONING */
5554 rtalloc_ign((struct route *)&ro, RTF_CLONING);
5555#endif
5556#else /* ! __FreeBSD__ */
5557 rtalloc_noclone((struct route *)&ro, NO_CLONING);
5558#endif
5559
5560 if (ro.ro_rt != NULL) {
5561 RTFREE(ro.ro_rt);
5562 return (1);
5563 }
5564
5565 return (0);
5566}
5567
5568int
5569pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw)
5570{
5571 struct sockaddr_in *dst;
5572#ifdef INET6
5573 struct sockaddr_in6 *dst6;
5574 struct route_in6 ro;
5575#else
5576 struct route ro;
5577#endif
5578 int ret = 0;
5579
5580 bzero(&ro, sizeof(ro));
5581 switch (af) {
5582 case AF_INET:
5583 dst = satosin(&ro.ro_dst);
5584 dst->sin_family = AF_INET;
5585 dst->sin_len = sizeof(*dst);
5586 dst->sin_addr = addr->v4;
5587 break;
5588#ifdef INET6
5589 case AF_INET6:
5590 dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
5591 dst6->sin6_family = AF_INET6;
5592 dst6->sin6_len = sizeof(*dst6);
5593 dst6->sin6_addr = addr->v6;
5594 break;
5595#endif /* INET6 */
5596 default:
5597 return (0);
5598 }
5599
5600#ifdef __FreeBSD__
5601# ifdef RTF_PRCLONING
5602 rtalloc_ign((struct route *)&ro, (RTF_CLONING|RTF_PRCLONING));
5603# else /* !RTF_PRCLONING */
5604 rtalloc_ign((struct route *)&ro, RTF_CLONING);
5605# endif
5606#else /* ! __FreeBSD__ */
5607 rtalloc_noclone((struct route *)&ro, NO_CLONING);
5608#endif
5609
5610 if (ro.ro_rt != NULL) {
5611#ifdef __FreeBSD__
5612 /* XXX_IMPORT: later */
5613#else
5614 if (ro.ro_rt->rt_labelid == aw->v.rtlabel)
5615 ret = 1;
5616#endif
5617 RTFREE(ro.ro_rt);
5618 }
5619
5620 return (ret);
5621}
5622
5623#ifdef INET
5624
5625void
5626pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
5627 struct pf_state *s)
5628{
5629 struct mbuf *m0, *m1;
5630 struct m_tag *mtag;
5631 struct route iproute;
5632 struct route *ro = NULL; /* XXX: was uninitialized */
5633 struct sockaddr_in *dst;
5634 struct ip *ip;
5635 struct ifnet *ifp = NULL;
5636 struct pf_addr naddr;
5637 struct pf_src_node *sn = NULL;
5638 int error = 0;
5639#ifdef __FreeBSD__
5640 int sw_csum;
5641#endif
5642
5643 if (m == NULL || *m == NULL || r == NULL ||
5644 (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
5645 panic("pf_route: invalid parameters");
5646
5647 if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) {
5648 if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) ==
5649 NULL) {
5650 m0 = *m;
5651 *m = NULL;
5652 goto bad;
5653 }
5654 *(char *)(mtag + 1) = 1;
5655 m_tag_prepend(*m, mtag);
5656 } else {
5657 if (*(char *)(mtag + 1) > 3) {
5658 m0 = *m;
5659 *m = NULL;
5660 goto bad;
5661 }
5662 (*(char *)(mtag + 1))++;
5663 }
5664
5665 if (r->rt == PF_DUPTO) {
5666#ifdef __FreeBSD__
5667 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
5668#else
5669 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
5670#endif
5671 return;
5672 } else {
5673 if ((r->rt == PF_REPLYTO) == (r->direction == dir))
5674 return;
5675 m0 = *m;
5676 }
5677
5678 if (m0->m_len < sizeof(struct ip)) {
5679 DPFPRINTF(PF_DEBUG_URGENT,
5680 ("pf_route: m0->m_len < sizeof(struct ip)\n"));
5681 goto bad;
5682 }
5683
5684 ip = mtod(m0, struct ip *);
5685
5686 ro = &iproute;
5687 bzero((caddr_t)ro, sizeof(*ro));
5688 dst = satosin(&ro->ro_dst);
5689 dst->sin_family = AF_INET;
5690 dst->sin_len = sizeof(*dst);
5691 dst->sin_addr = ip->ip_dst;
5692
5693 if (r->rt == PF_FASTROUTE) {
5694 rtalloc(ro);
5695 if (ro->ro_rt == 0) {
5696 ipstat.ips_noroute++;
5697 goto bad;
5698 }
5699
5700 ifp = ro->ro_rt->rt_ifp;
5701 ro->ro_rt->rt_use++;
5702
5703 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
5704 dst = satosin(ro->ro_rt->rt_gateway);
5705 } else {
5706 if (TAILQ_EMPTY(&r->rpool.list)) {
5707 DPFPRINTF(PF_DEBUG_URGENT,
5708 ("pf_route: TAILQ_EMPTY(&r->rpool.list)\n"));
5709 goto bad;
5710 }
5711 if (s == NULL) {
5712 pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
5713 &naddr, NULL, &sn);
5714 if (!PF_AZERO(&naddr, AF_INET))
5715 dst->sin_addr.s_addr = naddr.v4.s_addr;
5716 ifp = r->rpool.cur->kif ?
5717 r->rpool.cur->kif->pfik_ifp : NULL;
5718 } else {
5719 if (!PF_AZERO(&s->rt_addr, AF_INET))
5720 dst->sin_addr.s_addr =
5721 s->rt_addr.v4.s_addr;
5722 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
5723 }
5724 }
5725 if (ifp == NULL)
5726 goto bad;
5727
5728 if (oifp != ifp) {
5729#ifdef __FreeBSD__
5730 PF_UNLOCK();
5731 if (pf_test(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) {
5732 PF_LOCK();
5733 goto bad;
5734 } else if (m0 == NULL) {
5735 PF_LOCK();
5736 goto done;
5737 }
5738 PF_LOCK();
5739#else
5740 if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS)
5741 goto bad;
5742 else if (m0 == NULL)
5743 goto done;
5744#endif
5745 if (m0->m_len < sizeof(struct ip)) {
5746 DPFPRINTF(PF_DEBUG_URGENT,
5747 ("pf_route: m0->m_len < sizeof(struct ip)\n"));
5748 goto bad;
5749 }
5750 ip = mtod(m0, struct ip *);
5751 }
5752
5753#ifdef __FreeBSD__
5754 /* Copied from FreeBSD 5.1-CURRENT ip_output. */
5755 m0->m_pkthdr.csum_flags |= CSUM_IP;
5756 sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist;
5757 if (sw_csum & CSUM_DELAY_DATA) {
5758 /*
5759 * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least)
5760 */
5761 NTOHS(ip->ip_len);
5762 NTOHS(ip->ip_off); /* XXX: needed? */
5763 in_delayed_cksum(m0);
5764 HTONS(ip->ip_len);
5765 HTONS(ip->ip_off);
5766 sw_csum &= ~CSUM_DELAY_DATA;
5767 }
5768 m0->m_pkthdr.csum_flags &= ifp->if_hwassist;
5769
5770 if (ntohs(ip->ip_len) <= ifp->if_mtu ||
5771 (ifp->if_hwassist & CSUM_FRAGMENT &&
5772 ((ip->ip_off & htons(IP_DF)) == 0))) {
5773 /*
5774 * ip->ip_len = htons(ip->ip_len);
5775 * ip->ip_off = htons(ip->ip_off);
5776 */
5777 ip->ip_sum = 0;
5778 if (sw_csum & CSUM_DELAY_IP) {
5779 /* From KAME */
5780 if (ip->ip_v == IPVERSION &&
5781 (ip->ip_hl << 2) == sizeof(*ip)) {
5782 ip->ip_sum = in_cksum_hdr(ip);
5783 } else {
5784 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
5785 }
5786 }
5787 PF_UNLOCK();
5788 error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro->ro_rt);
5789 PF_LOCK();
5790 goto done;
5791 }
5792
5793#else
5794 /* Copied from ip_output. */
5795#ifdef IPSEC
5796 /*
5797 * If deferred crypto processing is needed, check that the
5798 * interface supports it.
5799 */
5800 if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL))
5801 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) {
5802 /* Notify IPsec to do its own crypto. */
5803 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
5804 goto bad;
5805 }
5806#endif /* IPSEC */
5807
5808 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */
5809 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) {
5810 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) ||
5811 ifp->if_bridge != NULL) {
5812 in_delayed_cksum(m0);
5813 m0->m_pkthdr.csum &= ~M_TCPV4_CSUM_OUT; /* Clear */
5814 }
5815 } else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) {
5816 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) ||
5817 ifp->if_bridge != NULL) {
5818 in_delayed_cksum(m0);
5819 m0->m_pkthdr.csum &= ~M_UDPV4_CSUM_OUT; /* Clear */
5820 }
5821 }
5822
5823 if (ntohs(ip->ip_len) <= ifp->if_mtu) {
5824 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
5825 ifp->if_bridge == NULL) {
5826 m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT;
5827 ipstat.ips_outhwcsum++;
5828 } else {
5829 ip->ip_sum = 0;
5830 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
5831 }
5832 /* Update relevant hardware checksum stats for TCP/UDP */
5833 if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT)
5834 tcpstat.tcps_outhwcsum++;
5835 else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT)
5836 udpstat.udps_outhwcsum++;
5837 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL);
5838 goto done;
5839 }
5840#endif
5841 /*
5842 * Too large for interface; fragment if possible.
5843 * Must be able to put at least 8 bytes per fragment.
5844 */
5845 if (ip->ip_off & htons(IP_DF)) {
5846 ipstat.ips_cantfrag++;
5847 if (r->rt != PF_DUPTO) {
5848#ifdef __FreeBSD__
5849 /* icmp_error() expects host byte ordering */
5850 NTOHS(ip->ip_len);
5851 NTOHS(ip->ip_off);
5852 PF_UNLOCK();
5853 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
5854 ifp->if_mtu);
5855 PF_LOCK();
5856#else
5857 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
5858 ifp);
5859#endif
5860 goto done;
5861 } else
5862 goto bad;
5863 }
5864
5865 m1 = m0;
5866#ifdef __FreeBSD__
5867 /*
5868 * XXX: is cheaper + less error prone than own function
5869 */
5870 NTOHS(ip->ip_len);
5871 NTOHS(ip->ip_off);
5872 error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum);
5873#else
5874 error = ip_fragment(m0, ifp, ifp->if_mtu);
5875#endif
5876 if (error) {
5877#ifndef __FreeBSD__ /* ip_fragment does not do m_freem() on FreeBSD */
5878 m0 = NULL;
5879#endif
5880 goto bad;
5881 }
5882
5883 for (m0 = m1; m0; m0 = m1) {
5884 m1 = m0->m_nextpkt;
5885 m0->m_nextpkt = 0;
5886#ifdef __FreeBSD__
5887 if (error == 0) {
5888 PF_UNLOCK();
5889 error = (*ifp->if_output)(ifp, m0, sintosa(dst),
5890 NULL);
5891 PF_LOCK();
5892 } else
5893#else
5894 if (error == 0)
5895 error = (*ifp->if_output)(ifp, m0, sintosa(dst),
5896 NULL);
5897 else
5898#endif
5899 m_freem(m0);
5900 }
5901
5902 if (error == 0)
5903 ipstat.ips_fragmented++;
5904
5905done:
5906 if (r->rt != PF_DUPTO)
5907 *m = NULL;
5908 if (ro == &iproute && ro->ro_rt)
5909 RTFREE(ro->ro_rt);
5910 return;
5911
5912bad:
5913 m_freem(m0);
5914 goto done;
5915}
5916#endif /* INET */
5917
5918#ifdef INET6
5919void
5920pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
5921 struct pf_state *s)
5922{
5923 struct mbuf *m0;
5924 struct m_tag *mtag;
5925 struct route_in6 ip6route;
5926 struct route_in6 *ro;
5927 struct sockaddr_in6 *dst;
5928 struct ip6_hdr *ip6;
5929 struct ifnet *ifp = NULL;
5930 struct pf_addr naddr;
5931 struct pf_src_node *sn = NULL;
5932 int error = 0;
5933
5934 if (m == NULL || *m == NULL || r == NULL ||
5935 (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
5936 panic("pf_route6: invalid parameters");
5937
5938 if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) {
5939 if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) ==
5940 NULL) {
5941 m0 = *m;
5942 *m = NULL;
5943 goto bad;
5944 }
5945 *(char *)(mtag + 1) = 1;
5946 m_tag_prepend(*m, mtag);
5947 } else {
5948 if (*(char *)(mtag + 1) > 3) {
5949 m0 = *m;
5950 *m = NULL;
5951 goto bad;
5952 }
5953 (*(char *)(mtag + 1))++;
5954 }
5955
5956 if (r->rt == PF_DUPTO) {
5957#ifdef __FreeBSD__
5958 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
5959#else
5960 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
5961#endif
5962 return;
5963 } else {
5964 if ((r->rt == PF_REPLYTO) == (r->direction == dir))
5965 return;
5966 m0 = *m;
5967 }
5968
5969 if (m0->m_len < sizeof(struct ip6_hdr)) {
5970 DPFPRINTF(PF_DEBUG_URGENT,
5971 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n"));
5972 goto bad;
5973 }
5974 ip6 = mtod(m0, struct ip6_hdr *);
5975
5976 ro = &ip6route;
5977 bzero((caddr_t)ro, sizeof(*ro));
5978 dst = (struct sockaddr_in6 *)&ro->ro_dst;
5979 dst->sin6_family = AF_INET6;
5980 dst->sin6_len = sizeof(*dst);
5981 dst->sin6_addr = ip6->ip6_dst;
5982
5983 /* Cheat. */
5984 if (r->rt == PF_FASTROUTE) {
5985#ifdef __FreeBSD__
5986 m0->m_flags |= M_SKIP_FIREWALL;
5987 PF_UNLOCK();
5988 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
5989 PF_LOCK();
5990#else
5991 mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT);
5992 if (mtag == NULL)
5993 goto bad;
5994 m_tag_prepend(m0, mtag);
5995 ip6_output(m0, NULL, NULL, 0, NULL, NULL);
5996#endif
5997 return;
5998 }
5999
6000 if (TAILQ_EMPTY(&r->rpool.list)) {
6001 DPFPRINTF(PF_DEBUG_URGENT,
6002 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n"));
6003 goto bad;
6004 }
6005 if (s == NULL) {
6006 pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
6007 &naddr, NULL, &sn);
6008 if (!PF_AZERO(&naddr, AF_INET6))
6009 PF_ACPY((struct pf_addr *)&dst->sin6_addr,
6010 &naddr, AF_INET6);
6011 ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
6012 } else {
6013 if (!PF_AZERO(&s->rt_addr, AF_INET6))
6014 PF_ACPY((struct pf_addr *)&dst->sin6_addr,
6015 &s->rt_addr, AF_INET6);
6016 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
6017 }
6018 if (ifp == NULL)
6019 goto bad;
6020
6021 if (oifp != ifp) {
6022#ifdef __FreeBSD__
6023 PF_UNLOCK();
6024 if (pf_test6(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) {
6025 PF_LOCK();
6026 goto bad;
6027 } else if (m0 == NULL) {
6028 PF_LOCK();
6029 goto done;
6030 }
6031 PF_LOCK();
6032#else
6033 if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS)
6034 goto bad;
6035 else if (m0 == NULL)
6036 goto done;
6037#endif
6038 if (m0->m_len < sizeof(struct ip6_hdr)) {
6039 DPFPRINTF(PF_DEBUG_URGENT,
6040 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n"));
6041 goto bad;
6042 }
6043 ip6 = mtod(m0, struct ip6_hdr *);
6044 }
6045
6046 /*
6047 * If the packet is too large for the outgoing interface,
6048 * send back an icmp6 error.
6049 */
6050 if (IN6_IS_ADDR_LINKLOCAL(&dst->sin6_addr))
6051 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
6052 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
6053#ifdef __FreeBSD__
6054 PF_UNLOCK();
6055#endif
6056 error = nd6_output(ifp, ifp, m0, dst, NULL);
6057#ifdef __FreeBSD__
6058 PF_LOCK();
6059#endif
6060 } else {
6061 in6_ifstat_inc(ifp, ifs6_in_toobig);
6062#ifdef __FreeBSD__
6063 if (r->rt != PF_DUPTO) {
6064 PF_UNLOCK();
6065 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
6066 PF_LOCK();
6067 } else
6068#else
6069 if (r->rt != PF_DUPTO)
6070 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
6071 else
6072#endif
6073 goto bad;
6074 }
6075
6076done:
6077 if (r->rt != PF_DUPTO)
6078 *m = NULL;
6079 return;
6080
6081bad:
6082 m_freem(m0);
6083 goto done;
6084}
6085#endif /* INET6 */
6086
6087
6088#ifdef __FreeBSD__
6089/*
6090 * FreeBSD supports cksum offloads for the following drivers.
6091 * em(4), fxp(4), ixgb(4), lge(4), ndis(4), nge(4), re(4),
6092 * ti(4), txp(4), xl(4)
6093 *
6094 * CSUM_DATA_VALID | CSUM_PSEUDO_HDR :
6095 * network driver performed cksum including pseudo header, need to verify
6096 * csum_data
6097 * CSUM_DATA_VALID :
6098 * network driver performed cksum, needs to additional pseudo header
6099 * cksum computation with partial csum_data(i.e. lack of H/W support for
6100 * pseudo header, for instance hme(4), sk(4) and possibly gem(4))
6101 *
6102 * After validating the cksum of packet, set both flag CSUM_DATA_VALID and
6103 * CSUM_PSEUDO_HDR in order to avoid recomputation of the cksum in upper
6104 * TCP/UDP layer.
6105 * Also, set csum_data to 0xffff to force cksum validation.
6106 */
6107int
6108pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af)
6109{
6110 u_int16_t sum = 0;
6111 int hw_assist = 0;
6112 struct ip *ip;
6113
6114 if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
6115 return (1);
6116 if (m->m_pkthdr.len < off + len)
6117 return (1);
6118
6119 switch (p) {
6120 case IPPROTO_TCP:
6121 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
6122 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) {
6123 sum = m->m_pkthdr.csum_data;
6124 } else {
6125 ip = mtod(m, struct ip *);
6126 sum = in_pseudo(ip->ip_src.s_addr,
6127 ip->ip_dst.s_addr, htonl((u_short)len +
6128 m->m_pkthdr.csum_data + IPPROTO_TCP));
6129 }
6130 sum ^= 0xffff;
6131 ++hw_assist;
6132 }
6133 break;
6134 case IPPROTO_UDP:
6135 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
6136 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) {
6137 sum = m->m_pkthdr.csum_data;
6138 } else {
6139 ip = mtod(m, struct ip *);
6140 sum = in_pseudo(ip->ip_src.s_addr,
6141 ip->ip_dst.s_addr, htonl((u_short)len +
6142 m->m_pkthdr.csum_data + IPPROTO_UDP));
6143 }
6144 sum ^= 0xffff;
6145 ++hw_assist;
6146 }
6147 break;
6148 case IPPROTO_ICMP:
6149#ifdef INET6
6150 case IPPROTO_ICMPV6:
6151#endif /* INET6 */
6152 break;
6153 default:
6154 return (1);
6155 }
6156
6157 if (!hw_assist) {
6158 switch (af) {
6159 case AF_INET:
6160 if (p == IPPROTO_ICMP) {
6161 if (m->m_len < off)
6162 return (1);
6163 m->m_data += off;
6164 m->m_len -= off;
6165 sum = in_cksum(m, len);
6166 m->m_data -= off;
6167 m->m_len += off;
6168 } else {
6169 if (m->m_len < sizeof(struct ip))
6170 return (1);
6171 sum = in4_cksum(m, p, off, len);
6172 }
6173 break;
6174#ifdef INET6
6175 case AF_INET6:
6176 if (m->m_len < sizeof(struct ip6_hdr))
6177 return (1);
6178 sum = in6_cksum(m, p, off, len);
6179 break;
6180#endif /* INET6 */
6181 default:
6182 return (1);
6183 }
6184 }
6185 if (sum) {
6186 switch (p) {
6187 case IPPROTO_TCP:
6188 tcpstat.tcps_rcvbadsum++;
6189 break;
6190 case IPPROTO_UDP:
6191 udpstat.udps_badsum++;
6192 break;
6193 case IPPROTO_ICMP:
6194 icmpstat.icps_checksum++;
6195 break;
6196#ifdef INET6
6197 case IPPROTO_ICMPV6:
6198 icmp6stat.icp6s_checksum++;
6199 break;
6200#endif /* INET6 */
6201 }
6202 return (1);
6203 } else {
6204 if (p == IPPROTO_TCP || p == IPPROTO_UDP) {
6205 m->m_pkthdr.csum_flags |=
6206 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
6207 m->m_pkthdr.csum_data = 0xffff;
6208 }
6209 }
6210 return (0);
6211}
6212#else
6213/*
6214 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag
6215 * off is the offset where the protocol header starts
6216 * len is the total length of protocol header plus payload
6217 * returns 0 when the checksum is valid, otherwise returns 1.
6218 */
6219int
6220pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,
6221 sa_family_t af)
6222{
6223 u_int16_t flag_ok, flag_bad;
6224 u_int16_t sum;
6225
6226 switch (p) {
6227 case IPPROTO_TCP:
6228 flag_ok = M_TCP_CSUM_IN_OK;
6229 flag_bad = M_TCP_CSUM_IN_BAD;
6230 break;
6231 case IPPROTO_UDP:
6232 flag_ok = M_UDP_CSUM_IN_OK;
6233 flag_bad = M_UDP_CSUM_IN_BAD;
6234 break;
6235 case IPPROTO_ICMP:
6236#ifdef INET6
6237 case IPPROTO_ICMPV6:
6238#endif /* INET6 */
6239 flag_ok = flag_bad = 0;
6240 break;
6241 default:
6242 return (1);
6243 }
6244 if (m->m_pkthdr.csum & flag_ok)
6245 return (0);
6246 if (m->m_pkthdr.csum & flag_bad)
6247 return (1);
6248 if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
6249 return (1);
6250 if (m->m_pkthdr.len < off + len)
6251 return (1);
6252 switch (af) {
6253#ifdef INET
6254 case AF_INET:
6255 if (p == IPPROTO_ICMP) {
6256 if (m->m_len < off)
6257 return (1);
6258 m->m_data += off;
6259 m->m_len -= off;
6260 sum = in_cksum(m, len);
6261 m->m_data -= off;
6262 m->m_len += off;
6263 } else {
6264 if (m->m_len < sizeof(struct ip))
6265 return (1);
6266 sum = in4_cksum(m, p, off, len);
6267 }
6268 break;
6269#endif /* INET */
6270#ifdef INET6
6271 case AF_INET6:
6272 if (m->m_len < sizeof(struct ip6_hdr))
6273 return (1);
6274 sum = in6_cksum(m, p, off, len);
6275 break;
6276#endif /* INET6 */
6277 default:
6278 return (1);
6279 }
6280 if (sum) {
6281 m->m_pkthdr.csum |= flag_bad;
6282 switch (p) {
6283 case IPPROTO_TCP:
6284 tcpstat.tcps_rcvbadsum++;
6285 break;
6286 case IPPROTO_UDP:
6287 udpstat.udps_badsum++;
6288 break;
6289 case IPPROTO_ICMP:
6290 icmpstat.icps_checksum++;
6291 break;
6292#ifdef INET6
6293 case IPPROTO_ICMPV6:
6294 icmp6stat.icp6s_checksum++;
6295 break;
6296#endif /* INET6 */
6297 }
6298 return (1);
6299 }
6300 m->m_pkthdr.csum |= flag_ok;
6301 return (0);
6302}
6303#endif
6304
6305static int
6306pf_add_mbuf_tag(struct mbuf *m, u_int tag)
6307{
6308 struct m_tag *mtag;
6309
6310 if (m_tag_find(m, tag, NULL) != NULL)
6311 return (0);
6312 mtag = m_tag_get(tag, 0, M_NOWAIT);
6313 if (mtag == NULL)
6314 return (1);
6315 m_tag_prepend(m, mtag);
6316 return (0);
6317}
6318
6319#ifdef INET
6320int
6321#ifdef __FreeBSD__
6322pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
6323 struct ether_header *eh, struct inpcb *inp)
6324#else
6325pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
6326 struct ether_header *eh)
6327#endif
6328{
6329 struct pfi_kif *kif;
6330 u_short action, reason = 0, log = 0;
6331 struct mbuf *m = *m0;
6332 struct ip *h = NULL; /* make the compiler happy */
6333 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
6334 struct pf_state *s = NULL;
6335 struct pf_ruleset *ruleset = NULL;
6336 struct pf_pdesc pd;
6337 int off, dirndx, pqid = 0;
6338
6339#ifdef __FreeBSD__
6340 PF_LOCK();
6341#endif
6342 if (!pf_status.running ||
6343#ifdef __FreeBSD__
6344 (m->m_flags & M_SKIP_FIREWALL)) {
6345 PF_UNLOCK();
6346#else
6347 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) {
6348#endif
6349 return (PF_PASS);
6350 }
6351
6352#ifdef __FreeBSD__
6353 /* XXX_IMPORT: later */
6354#else
6355 if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
6356 ifp = ifp->if_carpdev;
6357#endif
6358
6359 kif = pfi_index2kif[ifp->if_index];
6360 if (kif == NULL) {
6361#ifdef __FreeBSD__
6362 PF_UNLOCK();
6363#endif
6364 DPFPRINTF(PF_DEBUG_URGENT,
6365 ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname));
6366 return (PF_DROP);
6367 }
6368 if (kif->pfik_flags & PFI_IFLAG_SKIP) {
6369#ifdef __FreeBSD__
6370 PF_UNLOCK();
6371#endif
6372 return (PF_PASS);
6373 }
6374
6375#ifdef __FreeBSD__
6376 M_ASSERTPKTHDR(m);
6377#else
6378#ifdef DIAGNOSTIC
6379 if ((m->m_flags & M_PKTHDR) == 0)
6380 panic("non-M_PKTHDR is passed to pf_test");
6381#endif /* DIAGNOSTIC */
6382#endif /* __FreeBSD__ */
6383
6384 memset(&pd, 0, sizeof(pd));
6385 if (m->m_pkthdr.len < (int)sizeof(*h)) {
6386 action = PF_DROP;
6387 REASON_SET(&reason, PFRES_SHORT);
6388 log = 1;
6389 goto done;
6390 }
6391
6392 /* We do IP header normalization and packet reassembly here */
6393 if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) {
6394 action = PF_DROP;
6395 goto done;
6396 }
6397 m = *m0;
6398 h = mtod(m, struct ip *);
6399
6400 off = h->ip_hl << 2;
6401 if (off < (int)sizeof(*h)) {
6402 action = PF_DROP;
6403 REASON_SET(&reason, PFRES_SHORT);
6404 log = 1;
6405 goto done;
6406 }
6407
6408 pd.src = (struct pf_addr *)&h->ip_src;
6409 pd.dst = (struct pf_addr *)&h->ip_dst;
6410 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET);
6411 pd.ip_sum = &h->ip_sum;
6412 pd.proto = h->ip_p;
6413 pd.af = AF_INET;
6414 pd.tos = h->ip_tos;
6415 pd.tot_len = ntohs(h->ip_len);
6416 pd.eh = eh;
6417
6418 /* handle fragments that didn't get reassembled by normalization */
6419 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) {
6420 action = pf_test_fragment(&r, dir, kif, m, h,
6421 &pd, &a, &ruleset);
6422 goto done;
6423 }
6424
6425 switch (h->ip_p) {
6426
6427 case IPPROTO_TCP: {
6428 struct tcphdr th;
6429
6430 pd.hdr.tcp = &th;
6431 if (!pf_pull_hdr(m, off, &th, sizeof(th),
6432 &action, &reason, AF_INET)) {
6433 log = action != PF_PASS;
6434 goto done;
6435 }
6436 if (dir == PF_IN && pf_check_proto_cksum(m, off,
6437 ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) {
6438 action = PF_DROP;
6439 goto done;
6440 }
6441 pd.p_len = pd.tot_len - off - (th.th_off << 2);
6442 if ((th.th_flags & TH_ACK) && pd.p_len == 0)
6443 pqid = 1;
6444 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
6445 if (action == PF_DROP)
6446 goto done;
6447 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
6448 &reason);
6449 if (action == PF_PASS) {
6450#if NPFSYNC
6451 pfsync_update_state(s);
6452#endif /* NPFSYNC */
6453 r = s->rule.ptr;
6454 a = s->anchor.ptr;
6455 log = s->log;
6456 } else if (s == NULL)
6457#ifdef __FreeBSD__
6458 action = pf_test_tcp(&r, &s, dir, kif,
6459 m, off, h, &pd, &a, &ruleset, NULL, inp);
6460#else
6461 action = pf_test_tcp(&r, &s, dir, kif,
6462 m, off, h, &pd, &a, &ruleset, &ipintrq);
6463#endif
6464 break;
6465 }
6466
6467 case IPPROTO_UDP: {
6468 struct udphdr uh;
6469
6470 pd.hdr.udp = &uh;
6471 if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
6472 &action, &reason, AF_INET)) {
6473 log = action != PF_PASS;
6474 goto done;
6475 }
6476 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m,
6477 off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) {
6478 action = PF_DROP;
6479 goto done;
6480 }
6481 if (uh.uh_dport == 0 ||
6482 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
6483 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
6484 action = PF_DROP;
6485 goto done;
6486 }
6487 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
6488 if (action == PF_PASS) {
6489#if NPFSYNC
6490 pfsync_update_state(s);
6491#endif /* NPFSYNC */
6492 r = s->rule.ptr;
6493 a = s->anchor.ptr;
6494 log = s->log;
6495 } else if (s == NULL)
6496#ifdef __FreeBSD__
6497 action = pf_test_udp(&r, &s, dir, kif,
6498 m, off, h, &pd, &a, &ruleset, NULL, inp);
6499#else
6500 action = pf_test_udp(&r, &s, dir, kif,
6501 m, off, h, &pd, &a, &ruleset, &ipintrq);
6502#endif
6503 break;
6504 }
6505
6506 case IPPROTO_ICMP: {
6507 struct icmp ih;
6508
6509 pd.hdr.icmp = &ih;
6510 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN,
6511 &action, &reason, AF_INET)) {
6512 log = action != PF_PASS;
6513 goto done;
6514 }
6515 if (dir == PF_IN && pf_check_proto_cksum(m, off,
6516 ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) {
6517 action = PF_DROP;
6518 goto done;
6519 }
6520 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd,
6521 &reason);
6522 if (action == PF_PASS) {
6523#if NPFSYNC
6524 pfsync_update_state(s);
6525#endif /* NPFSYNC */
6526 r = s->rule.ptr;
6527 a = s->anchor.ptr;
6528 log = s->log;
6529 } else if (s == NULL)
6530#ifdef __FreeBSD__
6531 action = pf_test_icmp(&r, &s, dir, kif,
6532 m, off, h, &pd, &a, &ruleset, NULL);
6533#else
6534 action = pf_test_icmp(&r, &s, dir, kif,
6535 m, off, h, &pd, &a, &ruleset, &ipintrq);
6536#endif
6537 break;
6538 }
6539
6540 default:
6541 action = pf_test_state_other(&s, dir, kif, &pd);
6542 if (action == PF_PASS) {
6543#if NPFSYNC
6544 pfsync_update_state(s);
6545#endif /* NPFSYNC */
6546 r = s->rule.ptr;
6547 a = s->anchor.ptr;
6548 log = s->log;
6549 } else if (s == NULL)
6550#ifdef __FreeBSD__
6551 action = pf_test_other(&r, &s, dir, kif, m, off, h,
6552 &pd, &a, &ruleset, NULL);
6553#else
6554 action = pf_test_other(&r, &s, dir, kif, m, off, h,
6555 &pd, &a, &ruleset, &ipintrq);
6556#endif
6557 break;
6558 }
6559
6560done:
6561 if (action == PF_PASS && h->ip_hl > 5 &&
6562 !((s && s->allow_opts) || r->allow_opts)) {
6563 action = PF_DROP;
6564 REASON_SET(&reason, PFRES_IPOPTIONS);
6565 log = 1;
6566 DPFPRINTF(PF_DEBUG_MISC,
6567 ("pf: dropping packet with ip options\n"));
6568 }
6569
6570 if (s && s->tag)
6571 pf_tag_packet(m, pf_get_tag(m), s->tag);
6572
6573#ifdef ALTQ
6574 if (action == PF_PASS && r->qid) {
6575 struct m_tag *mtag;
6576 struct altq_tag *atag;
6577
6578 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
6579 if (mtag != NULL) {
6580 atag = (struct altq_tag *)(mtag + 1);
6581 if (pqid || pd.tos == IPTOS_LOWDELAY)
6582 atag->qid = r->pqid;
6583 else
6584 atag->qid = r->qid;
6585 /* add hints for ecn */
6586 atag->af = AF_INET;
6587 atag->hdr = h;
6588 m_tag_prepend(m, mtag);
6589 }
6590 }
6591#endif /* ALTQ */
6592
6593 /*
6594 * connections redirected to loopback should not match sockets
6595 * bound specifically to loopback due to security implications,
6596 * see tcp_input() and in_pcblookup_listen().
6597 */
6598 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
6599 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
6600 (s->nat_rule.ptr->action == PF_RDR ||
6601 s->nat_rule.ptr->action == PF_BINAT) &&
6602 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET &&
6603 pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) {
6604 action = PF_DROP;
6605 REASON_SET(&reason, PFRES_MEMORY);
6606 }
6607
6608 if (log)
6609 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, a, ruleset);
6610
6611 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
6612 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++;
6613
6614 if (action == PF_PASS || r->action == PF_DROP) {
6615 r->packets++;
6616 r->bytes += pd.tot_len;
6617 if (a != NULL) {
6618 a->packets++;
6619 a->bytes += pd.tot_len;
6620 }
6621 if (s != NULL) {
6622 dirndx = (dir == s->direction) ? 0 : 1;
6623 s->packets[dirndx]++;
6624 s->bytes[dirndx] += pd.tot_len;
6625 if (s->nat_rule.ptr != NULL) {
6626 s->nat_rule.ptr->packets++;
6627 s->nat_rule.ptr->bytes += pd.tot_len;
6628 }
6629 if (s->src_node != NULL) {
6630 s->src_node->packets++;
6631 s->src_node->bytes += pd.tot_len;
6632 }
6633 if (s->nat_src_node != NULL) {
6634 s->nat_src_node->packets++;
6635 s->nat_src_node->bytes += pd.tot_len;
6636 }
6637 }
6638 tr = r;
6639 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
6640 if (nr != NULL) {
6641 struct pf_addr *x;
6642 /*
6643 * XXX: we need to make sure that the addresses
6644 * passed to pfr_update_stats() are the same than
6645 * the addresses used during matching (pfr_match)
6646 */
6647 if (r == &pf_default_rule) {
6648 tr = nr;
6649 x = (s == NULL || s->direction == dir) ?
6650 &pd.baddr : &pd.naddr;
6651 } else
6652 x = (s == NULL || s->direction == dir) ?
6653 &pd.naddr : &pd.baddr;
6654 if (x == &pd.baddr || s == NULL) {
6655 /* we need to change the address */
6656 if (dir == PF_OUT)
6657 pd.src = x;
6658 else
6659 pd.dst = x;
6660 }
6661 }
6662 if (tr->src.addr.type == PF_ADDR_TABLE)
6663 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL ||
6664 s->direction == dir) ? pd.src : pd.dst, pd.af,
6665 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
6666 tr->src.neg);
6667 if (tr->dst.addr.type == PF_ADDR_TABLE)
6668 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL ||
6669 s->direction == dir) ? pd.dst : pd.src, pd.af,
6670 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
6671 tr->dst.neg);
6672 }
6673
6674
6675 if (action == PF_SYNPROXY_DROP) {
6676 m_freem(*m0);
6677 *m0 = NULL;
6678 action = PF_PASS;
6679 } else if (r->rt)
6680 /* pf_route can free the mbuf causing *m0 to become NULL */
6681 pf_route(m0, r, dir, ifp, s);
6682
6683#ifdef __FreeBSD__
6684 PF_UNLOCK();
6685#endif
6686
6687 return (action);
6688}
6689#endif /* INET */
6690
6691#ifdef INET6
6692int
6693#ifdef __FreeBSD__
6694pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
6695 struct ether_header *eh, struct inpcb *inp)
6696#else
6697pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
6698 struct ether_header *eh)
6699#endif
6700{
6701 struct pfi_kif *kif;
6702 u_short action, reason = 0, log = 0;
6703 struct mbuf *m = *m0;
6704 struct ip6_hdr *h = NULL; /* make the compiler happy */
6705 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
6706 struct pf_state *s = NULL;
6707 struct pf_ruleset *ruleset = NULL;
6708 struct pf_pdesc pd;
6709 int off, terminal = 0, dirndx;
6710
6711#ifdef __FreeBSD__
6712 PF_LOCK();
6713#endif
6714
6715 if (!pf_status.running ||
6716#ifdef __FreeBSD__
6717 (m->m_flags & M_SKIP_FIREWALL)) {
6718 PF_UNLOCK();
6719#else
6720 (m_tag_find(m, PACKET_TAG_PF_GENERATED, NULL) != NULL)) {
6721#endif
6722 return (PF_PASS);
6723 }
6724
6725#ifdef __FreeBSD__
6726 /* XXX_IMPORT: later */
6727#else
6728 if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
6729 ifp = ifp->if_carpdev;
6730#endif
6731
6732 kif = pfi_index2kif[ifp->if_index];
6733 if (kif == NULL) {
6734#ifdef __FreeBSD__
6735 PF_UNLOCK();
6736#endif
6737 DPFPRINTF(PF_DEBUG_URGENT,
6738 ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname));
6739 return (PF_DROP);
6740 }
6741 if (kif->pfik_flags & PFI_IFLAG_SKIP) {
6742#ifdef __FreeBSD__
6743 PF_UNLOCK();
6744#endif
6745 return (PF_PASS);
6746 }
6747
6748#ifdef __FreeBSD__
6749 M_ASSERTPKTHDR(m);
6750#else
6751#ifdef DIAGNOSTIC
6752 if ((m->m_flags & M_PKTHDR) == 0)
6753 panic("non-M_PKTHDR is passed to pf_test6");
6754#endif /* DIAGNOSTIC */
6755#endif
6756
6757 memset(&pd, 0, sizeof(pd));
6758 if (m->m_pkthdr.len < (int)sizeof(*h)) {
6759 action = PF_DROP;
6760 REASON_SET(&reason, PFRES_SHORT);
6761 log = 1;
6762 goto done;
6763 }
6764
6765 /* We do IP header normalization and packet reassembly here */
6766 if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) {
6767 action = PF_DROP;
6768 goto done;
6769 }
6770 m = *m0;
6771 h = mtod(m, struct ip6_hdr *);
6772
6773 pd.src = (struct pf_addr *)&h->ip6_src;
6774 pd.dst = (struct pf_addr *)&h->ip6_dst;
6775 PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET6);
6776 pd.ip_sum = NULL;
6777 pd.af = AF_INET6;
6778 pd.tos = 0;
6779 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
6780 pd.eh = eh;
6781
6782 off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr);
6783 pd.proto = h->ip6_nxt;
6784 do {
6785 switch (pd.proto) {
6786 case IPPROTO_FRAGMENT:
6787 action = pf_test_fragment(&r, dir, kif, m, h,
6788 &pd, &a, &ruleset);
6789 if (action == PF_DROP)
6790 REASON_SET(&reason, PFRES_FRAG);
6791 goto done;
6792 case IPPROTO_AH:
6793 case IPPROTO_HOPOPTS:
6794 case IPPROTO_ROUTING:
6795 case IPPROTO_DSTOPTS: {
6796 /* get next header and header length */
6797 struct ip6_ext opt6;
6798
6799 if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6),
6800 NULL, &reason, pd.af)) {
6801 DPFPRINTF(PF_DEBUG_MISC,
6802 ("pf: IPv6 short opt\n"));
6803 action = PF_DROP;
6804 log = 1;
6805 goto done;
6806 }
6807 if (pd.proto == IPPROTO_AH)
6808 off += (opt6.ip6e_len + 2) * 4;
6809 else
6810 off += (opt6.ip6e_len + 1) * 8;
6811 pd.proto = opt6.ip6e_nxt;
6812 /* goto the next header */
6813 break;
6814 }
6815 default:
6816 terminal++;
6817 break;
6818 }
6819 } while (!terminal);
6820
6821 switch (pd.proto) {
6822
6823 case IPPROTO_TCP: {
6824 struct tcphdr th;
6825
6826 pd.hdr.tcp = &th;
6827 if (!pf_pull_hdr(m, off, &th, sizeof(th),
6828 &action, &reason, AF_INET6)) {
6829 log = action != PF_PASS;
6830 goto done;
6831 }
6832 if (dir == PF_IN && pf_check_proto_cksum(m, off,
6833 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
6834 IPPROTO_TCP, AF_INET6)) {
6835 action = PF_DROP;
6836 REASON_SET(&reason, PFRES_PROTCKSUM);
6837 goto done;
6838 }
6839 pd.p_len = pd.tot_len - off - (th.th_off << 2);
6840 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
6841 if (action == PF_DROP)
6842 goto done;
6843 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
6844 &reason);
6845 if (action == PF_PASS) {
6846#if NPFSYNC
6847 pfsync_update_state(s);
6848#endif /* NPFSYNC */
6849 r = s->rule.ptr;
6850 a = s->anchor.ptr;
6851 log = s->log;
6852 } else if (s == NULL)
6853#ifdef __FreeBSD__
6854 action = pf_test_tcp(&r, &s, dir, kif,
6855 m, off, h, &pd, &a, &ruleset, NULL, inp);
6856#else
6857 action = pf_test_tcp(&r, &s, dir, kif,
6858 m, off, h, &pd, &a, &ruleset, &ip6intrq);
6859#endif
6860 break;
6861 }
6862
6863 case IPPROTO_UDP: {
6864 struct udphdr uh;
6865
6866 pd.hdr.udp = &uh;
6867 if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
6868 &action, &reason, AF_INET6)) {
6869 log = action != PF_PASS;
6870 goto done;
6871 }
6872 if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m,
6873 off, ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
6874 IPPROTO_UDP, AF_INET6)) {
6875 action = PF_DROP;
6876 REASON_SET(&reason, PFRES_PROTCKSUM);
6877 goto done;
6878 }
6879 if (uh.uh_dport == 0 ||
6880 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
6881 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
6882 action = PF_DROP;
6883 goto done;
6884 }
6885 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
6886 if (action == PF_PASS) {
6887#if NPFSYNC
6888 pfsync_update_state(s);
6889#endif /* NPFSYNC */
6890 r = s->rule.ptr;
6891 a = s->anchor.ptr;
6892 log = s->log;
6893 } else if (s == NULL)
6894#ifdef __FreeBSD__
6895 action = pf_test_udp(&r, &s, dir, kif,
6896 m, off, h, &pd, &a, &ruleset, NULL, inp);
6897#else
6898 action = pf_test_udp(&r, &s, dir, kif,
6899 m, off, h, &pd, &a, &ruleset, &ip6intrq);
6900#endif
6901 break;
6902 }
6903
6904 case IPPROTO_ICMPV6: {
6905 struct icmp6_hdr ih;
6906
6907 pd.hdr.icmp6 = &ih;
6908 if (!pf_pull_hdr(m, off, &ih, sizeof(ih),
6909 &action, &reason, AF_INET6)) {
6910 log = action != PF_PASS;
6911 goto done;
6912 }
6913 if (dir == PF_IN && pf_check_proto_cksum(m, off,
6914 ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
6915 IPPROTO_ICMPV6, AF_INET6)) {
6916 action = PF_DROP;
6917 REASON_SET(&reason, PFRES_PROTCKSUM);
6918 goto done;
6919 }
6920 action = pf_test_state_icmp(&s, dir, kif,
6921 m, off, h, &pd, &reason);
6922 if (action == PF_PASS) {
6923#if NPFSYNC
6924 pfsync_update_state(s);
6925#endif /* NPFSYNC */
6926 r = s->rule.ptr;
6927 a = s->anchor.ptr;
6928 log = s->log;
6929 } else if (s == NULL)
6930#ifdef __FreeBSD__
6931 action = pf_test_icmp(&r, &s, dir, kif,
6932 m, off, h, &pd, &a, &ruleset, NULL);
6933#else
6934 action = pf_test_icmp(&r, &s, dir, kif,
6935 m, off, h, &pd, &a, &ruleset, &ip6intrq);
6936#endif
6937 break;
6938 }
6939
6940 default:
6941 action = pf_test_state_other(&s, dir, kif, &pd);
6942 if (action == PF_PASS) {
6943#if NPFSYNC
6944 pfsync_update_state(s);
6945#endif /* NPFSYNC */
6946 r = s->rule.ptr;
6947 a = s->anchor.ptr;
6948 log = s->log;
6949 } else if (s == NULL)
6950#ifdef __FreeBSD__
6951 action = pf_test_other(&r, &s, dir, kif, m, off, h,
6952 &pd, &a, &ruleset, NULL);
6953#else
6954 action = pf_test_other(&r, &s, dir, kif, m, off, h,
6955 &pd, &a, &ruleset, &ip6intrq);
6956#endif
6957 break;
6958 }
6959
6960done:
6961 /* XXX handle IPv6 options, if not allowed. not implemented. */
6962
6963 if (s && s->tag)
6964 pf_tag_packet(m, pf_get_tag(m), s->tag);
6965
6966#ifdef ALTQ
6967 if (action == PF_PASS && r->qid) {
6968 struct m_tag *mtag;
6969 struct altq_tag *atag;
6970
6971 mtag = m_tag_get(PACKET_TAG_PF_QID, sizeof(*atag), M_NOWAIT);
6972 if (mtag != NULL) {
6973 atag = (struct altq_tag *)(mtag + 1);
6974 if (pd.tos == IPTOS_LOWDELAY)
6975 atag->qid = r->pqid;
6976 else
6977 atag->qid = r->qid;
6978 /* add hints for ecn */
6979 atag->af = AF_INET6;
6980 atag->hdr = h;
6981 m_tag_prepend(m, mtag);
6982 }
6983 }
6984#endif /* ALTQ */
6985
6986 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
6987 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
6988 (s->nat_rule.ptr->action == PF_RDR ||
6989 s->nat_rule.ptr->action == PF_BINAT) &&
6990 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6) &&
6991 pf_add_mbuf_tag(m, PACKET_TAG_PF_TRANSLATE_LOCALHOST)) {
6992 action = PF_DROP;
6993 REASON_SET(&reason, PFRES_MEMORY);
6994 }
6995
6996 if (log)
6997 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, r, a, ruleset);
6998
6999 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
7000 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++;
7001
7002 if (action == PF_PASS || r->action == PF_DROP) {
7003 r->packets++;
7004 r->bytes += pd.tot_len;
7005 if (a != NULL) {
7006 a->packets++;
7007 a->bytes += pd.tot_len;
7008 }
7009 if (s != NULL) {
7010 dirndx = (dir == s->direction) ? 0 : 1;
7011 s->packets[dirndx]++;
7012 s->bytes[dirndx] += pd.tot_len;
7013 if (s->nat_rule.ptr != NULL) {
7014 s->nat_rule.ptr->packets++;
7015 s->nat_rule.ptr->bytes += pd.tot_len;
7016 }
7017 if (s->src_node != NULL) {
7018 s->src_node->packets++;
7019 s->src_node->bytes += pd.tot_len;
7020 }
7021 if (s->nat_src_node != NULL) {
7022 s->nat_src_node->packets++;
7023 s->nat_src_node->bytes += pd.tot_len;
7024 }
7025 }
7026 tr = r;
7027 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
7028 if (nr != NULL) {
7029 struct pf_addr *x;
7030 /*
7031 * XXX: we need to make sure that the addresses
7032 * passed to pfr_update_stats() are the same than
7033 * the addresses used during matching (pfr_match)
7034 */
7035 if (r == &pf_default_rule) {
7036 tr = nr;
7037 x = (s == NULL || s->direction == dir) ?
7038 &pd.baddr : &pd.naddr;
7039 } else {
7040 x = (s == NULL || s->direction == dir) ?
7041 &pd.naddr : &pd.baddr;
7042 }
7043 if (x == &pd.baddr || s == NULL) {
7044 if (dir == PF_OUT)
7045 pd.src = x;
7046 else
7047 pd.dst = x;
7048 }
7049 }
7050 if (tr->src.addr.type == PF_ADDR_TABLE)
7051 pfr_update_stats(tr->src.addr.p.tbl, (s == NULL ||
7052 s->direction == dir) ? pd.src : pd.dst, pd.af,
7053 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
7054 tr->src.neg);
7055 if (tr->dst.addr.type == PF_ADDR_TABLE)
7056 pfr_update_stats(tr->dst.addr.p.tbl, (s == NULL ||
7057 s->direction == dir) ? pd.dst : pd.src, pd.af,
7058 pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
7059 tr->dst.neg);
7060 }
7061
7062
7063 if (action == PF_SYNPROXY_DROP) {
7064 m_freem(*m0);
7065 *m0 = NULL;
7066 action = PF_PASS;
7067 } else if (r->rt)
7068 /* pf_route6 can free the mbuf causing *m0 to become NULL */
7069 pf_route6(m0, r, dir, ifp, s);
7070
7071#ifdef __FreeBSD__
7072 PF_UNLOCK();
7073#endif
7074 return (action);
7075}
7076#endif /* INET6 */
7077
7078int
7079pf_check_congestion(struct ifqueue *ifq)
7080{
7081#ifdef __FreeBSD__
7082 /* XXX_IMPORT: later */
7083 return (0);
7084#else
7085 if (ifq->ifq_congestion)
7086 return (1);
7087 else
7088 return (0);
7089#endif
7090}