diff options
author | jasoni <jasoni@cvs.openbsd.org> | 2002-05-09 21:58:13 +0000 |
---|---|---|
committer | jasoni <jasoni@cvs.openbsd.org> | 2002-05-09 21:58:13 +0000 |
commit | 321f9cba7df95fec45615a4f5f6f9b995a0edb05 (patch) | |
tree | 7c75c542368976d3eb47e322dc7ce49631c44953 /sys/net | |
parent | 676b7110b9008420e77ca52e8ed54111e3659e23 (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.c | 53 | ||||
-rw-r--r-- | sys/net/pfvar.h | 3 |
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; |