summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorjasoni <jasoni@cvs.openbsd.org>2002-05-09 21:58:13 +0000
committerjasoni <jasoni@cvs.openbsd.org>2002-05-09 21:58:13 +0000
commit321f9cba7df95fec45615a4f5f6f9b995a0edb05 (patch)
tree7c75c542368976d3eb47e322dc7ce49631c44953 /sys/net
parent676b7110b9008420e77ca52e8ed54111e3659e23 (diff)
Add a max-mss option to the scrub rule which will enforce a maximum mss
by lowering it to the given value. - ok dhartmei@, provos@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/pf_norm.c53
-rw-r--r--sys/net/pfvar.h3
2 files changed, 54 insertions, 2 deletions
diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c
index a525259d4fb..0ca14a4ffe2 100644
--- a/sys/net/pf_norm.c
+++ b/sys/net/pf_norm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_norm.c,v 1.25 2002/05/06 15:49:54 jasoni Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.26 2002/05/09 21:58:12 jasoni Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
@@ -89,6 +89,8 @@ struct mbuf *pf_reassemble(struct mbuf **, struct pf_fragment *,
u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t);
int pf_normalize_tcp(int, struct ifnet *, struct mbuf *,
int, int, void *, struct pf_pdesc *);
+int pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
+ struct tcphdr *, int);
#define DPFPRINTF(x) if (pf_status.debug >= PF_DEBUG_MISC) printf x
@@ -658,6 +660,10 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff,
rewrite = 1;
}
+ /* Process options */
+ if (r->max_mss && pf_normalize_tcpopt(r, m, th, off))
+ rewrite = 1;
+
/* copy back packet headers if we sanitized */
if (rewrite)
m_copyback(m, off, sizeof(*th), (caddr_t)th);
@@ -670,3 +676,48 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff,
PFLOG_PACKET(ifp, h, m, AF_INET, dir, reason, rm);
return (PF_DROP);
}
+
+int
+pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
+ int off)
+{
+ u_int16_t *mss;
+ int thoff;
+ int opt, cnt, optlen = 0;
+ int rewrite = 0;
+ u_char *optp;
+
+ thoff = th->th_off << 2;
+ cnt = thoff - sizeof(struct tcphdr);
+ optp = mtod(m, caddr_t) + off + sizeof(struct tcphdr);
+
+ for (; cnt > 0; cnt -= optlen, optp += optlen) {
+ opt = optp[0];
+ if (opt == TCPOPT_EOL)
+ break;
+ if (opt == TCPOPT_NOP)
+ optlen = 1;
+ else {
+ if (cnt < 2)
+ break;
+ optlen = optp[1];
+ if (optlen < 2 || optlen > cnt)
+ break;
+ }
+ switch (opt) {
+ case TCPOPT_MAXSEG:
+ mss = (u_int16_t *)(optp + 2);
+ if ((ntohs(*mss)) > r->max_mss) {
+ th->th_sum = pf_cksum_fixup(th->th_sum,
+ *mss, htons(r->max_mss));
+ *mss = htons(r->max_mss);
+ rewrite = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ return (rewrite);
+}
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 5b3ddcf9c0b..d6a7726144f 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.70 2002/05/09 19:58:42 dhartmei Exp $ */
+/* $OpenBSD: pfvar.h,v 1.71 2002/05/09 21:58:12 jasoni Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -240,6 +240,7 @@ struct pf_rule {
u_int16_t nr;
u_int16_t return_icmp;
+ u_int16_t max_mss;
struct pf_rule_uid ruid;
struct pf_rule_uid euid;