summaryrefslogtreecommitdiffstats
path: root/sys/contrib/pf/net/pf_norm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/pf/net/pf_norm.c')
-rw-r--r--sys/contrib/pf/net/pf_norm.c122
1 files changed, 75 insertions, 47 deletions
diff --git a/sys/contrib/pf/net/pf_norm.c b/sys/contrib/pf/net/pf_norm.c
index 0153644..32ba9f4 100644
--- a/sys/contrib/pf/net/pf_norm.c
+++ b/sys/contrib/pf/net/pf_norm.c
@@ -1,6 +1,4 @@
-/* $FreeBSD$ */
-/* $OpenBSD: pf_norm.c,v 1.97 2004/09/21 16:59:12 aaron Exp $ */
-/* add: $OpenBSD: pf_norm.c,v 1.106 2006/03/25 20:55:24 dhartmei Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.107 2006/04/16 00:59:52 pascoe Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
@@ -31,6 +29,10 @@
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_pf.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#ifdef DEV_PFLOG
#define NPFLOG DEV_PFLOG
#else
@@ -493,7 +495,7 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
break;
}
- /* This fragment is completely overlapped, loose it */
+ /* This fragment is completely overlapped, lose it */
next = LIST_NEXT(frea, fr_next);
m_freem(frea->fr_m);
LIST_REMOVE(frea, fr_next);
@@ -966,8 +968,7 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
while (r != NULL) {
r->evaluations++;
- if (r->kif != NULL &&
- (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP].ptr;
else if (r->direction && r->direction != dir)
r = r->skip[PF_SKIP_DIR].ptr;
@@ -976,19 +977,23 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
else if (r->proto && r->proto != h->ip_p)
r = r->skip[PF_SKIP_PROTO].ptr;
else if (PF_MISMATCHAW(&r->src.addr,
- (struct pf_addr *)&h->ip_src.s_addr, AF_INET, r->src.neg))
+ (struct pf_addr *)&h->ip_src.s_addr, AF_INET,
+ r->src.neg, kif))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
else if (PF_MISMATCHAW(&r->dst.addr,
- (struct pf_addr *)&h->ip_dst.s_addr, AF_INET, r->dst.neg))
+ (struct pf_addr *)&h->ip_dst.s_addr, AF_INET,
+ r->dst.neg, NULL))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else
break;
}
- if (r == NULL)
+ if (r == NULL || r->action == PF_NOSCRUB)
return (PF_PASS);
- else
- r->packets++;
+ else {
+ r->packets[dir == PF_OUT]++;
+ r->bytes[dir == PF_OUT] += pd->tot_len;
+ }
/* Check for illegal packets */
if (hlen < (int)sizeof(struct ip))
@@ -1061,6 +1066,18 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
if (m == NULL)
return (PF_DROP);
+ /* use mtag from concatenated mbuf chain */
+ pd->pf_mtag = pf_find_mtag(m);
+#ifdef DIAGNOSTIC
+ if (pd->pf_mtag == NULL) {
+ printf("%s: pf_find_mtag returned NULL(1)\n", __func__);
+ if ((pd->pf_mtag = pf_get_mtag(m)) == NULL) {
+ m_freem(m);
+ *m0 = NULL;
+ goto no_mem;
+ }
+ }
+#endif
if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
goto drop;
@@ -1069,15 +1086,13 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
/* non-buffering fragment cache (drops or masks overlaps) */
int nomem = 0;
- if (dir == PF_OUT) {
- if (m_tag_find(m, PACKET_TAG_PF_FRAGCACHE, NULL) !=
- NULL) {
- /* Already passed the fragment cache in the
- * input direction. If we continued, it would
- * appear to be a dup and would be dropped.
- */
- goto fragment_pass;
- }
+ if (dir == PF_OUT && pd->pf_mtag->flags & PF_TAG_FRAGCACHE) {
+ /*
+ * Already passed the fragment cache in the
+ * input direction. If we continued, it would
+ * appear to be a dup and would be dropped.
+ */
+ goto fragment_pass;
}
frag = pf_find_fragment(h, &pf_cache_tree);
@@ -1098,14 +1113,21 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
goto drop;
}
- if (dir == PF_IN) {
- struct m_tag *mtag;
-
- mtag = m_tag_get(PACKET_TAG_PF_FRAGCACHE, 0, M_NOWAIT);
- if (mtag == NULL)
+ /* use mtag from copied and trimmed mbuf chain */
+ pd->pf_mtag = pf_find_mtag(m);
+#ifdef DIAGNOSTIC
+ if (pd->pf_mtag == NULL) {
+ printf("%s: pf_find_mtag returned NULL(2)\n", __func__);
+ if ((pd->pf_mtag = pf_get_mtag(m)) == NULL) {
+ m_freem(m);
+ *m0 = NULL;
goto no_mem;
- m_tag_prepend(m, mtag);
+ }
}
+#endif
+ if (dir == PF_IN)
+ pd->pf_mtag->flags |= PF_TAG_FRAGCACHE;
+
if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
goto drop;
goto fragment_pass;
@@ -1154,13 +1176,13 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
no_mem:
REASON_SET(reason, PFRES_MEMORY);
if (r != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
+ PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
return (PF_DROP);
drop:
REASON_SET(reason, PFRES_NORM);
if (r != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
+ PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
return (PF_DROP);
bad:
@@ -1172,7 +1194,7 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
REASON_SET(reason, PFRES_FRAG);
if (r != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
+ PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
return (PF_DROP);
}
@@ -1200,8 +1222,7 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
while (r != NULL) {
r->evaluations++;
- if (r->kif != NULL &&
- (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP].ptr;
else if (r->direction && r->direction != dir)
r = r->skip[PF_SKIP_DIR].ptr;
@@ -1212,19 +1233,23 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
r = r->skip[PF_SKIP_PROTO].ptr;
#endif
else if (PF_MISMATCHAW(&r->src.addr,
- (struct pf_addr *)&h->ip6_src, AF_INET6, r->src.neg))
+ (struct pf_addr *)&h->ip6_src, AF_INET6,
+ r->src.neg, kif))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
else if (PF_MISMATCHAW(&r->dst.addr,
- (struct pf_addr *)&h->ip6_dst, AF_INET6, r->dst.neg))
+ (struct pf_addr *)&h->ip6_dst, AF_INET6,
+ r->dst.neg, NULL))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else
break;
}
- if (r == NULL)
+ if (r == NULL || r->action == PF_NOSCRUB)
return (PF_PASS);
- else
- r->packets++;
+ else {
+ r->packets[dir == PF_OUT]++;
+ r->bytes[dir == PF_OUT] += pd->tot_len;
+ }
/* Check for illegal packets */
if (sizeof(struct ip6_hdr) + IPV6_MAXPACKET < m->m_pkthdr.len)
@@ -1336,19 +1361,19 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
shortpkt:
REASON_SET(reason, PFRES_SHORT);
if (r != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
+ PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
return (PF_DROP);
drop:
REASON_SET(reason, PFRES_NORM);
if (r != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
+ PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
return (PF_DROP);
badfrag:
REASON_SET(reason, PFRES_FRAG);
if (r != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
+ PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
return (PF_DROP);
}
#endif /* INET6 */
@@ -1367,8 +1392,7 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
while (r != NULL) {
r->evaluations++;
- if (r->kif != NULL &&
- (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
r = r->skip[PF_SKIP_IFP].ptr;
else if (r->direction && r->direction != dir)
r = r->skip[PF_SKIP_DIR].ptr;
@@ -1376,12 +1400,14 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != pd->proto)
r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.neg))
+ else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
+ r->src.neg, kif))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
else if (r->src.port_op && !pf_match_port(r->src.port_op,
r->src.port[0], r->src.port[1], th->th_sport))
r = r->skip[PF_SKIP_SRC_PORT].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.neg))
+ else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
+ r->dst.neg, NULL))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
r->dst.port[0], r->dst.port[1], th->th_dport))
@@ -1398,8 +1424,10 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
if (rm == NULL || rm->action == PF_NOSCRUB)
return (PF_PASS);
- else
- r->packets++;
+ else {
+ r->packets[dir == PF_OUT]++;
+ r->bytes[dir == PF_OUT] += pd->tot_len;
+ }
if (rm->rule_flag & PFRULE_REASSEMBLE_TCP)
pd->flags |= PFDESC_TCP_NORM;
@@ -1461,7 +1489,7 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
tcp_drop:
REASON_SET(&reason, PFRES_NORM);
if (rm != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, NULL, NULL);
+ PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, NULL, NULL, pd);
return (PF_DROP);
}
@@ -1931,7 +1959,7 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
* timestamps. And require all data packets to contain a timestamp
* if the first does. PAWS implicitly requires that all data packets be
* timestamped. But I think there are middle-man devices that hijack
- * TCP streams immedietly after the 3whs and don't timestamp their
+ * TCP streams immediately after the 3whs and don't timestamp their
* packets (seen in a WWW accelerator or cache).
*/
if (pd->p_len > 0 && src->scrub && (src->scrub->pfss_flags &
OpenPOWER on IntegriCloud