diff options
author | green <green@FreeBSD.org> | 2004-10-03 00:47:15 +0000 |
---|---|---|
committer | green <green@FreeBSD.org> | 2004-10-03 00:47:15 +0000 |
commit | cb606898b9f83045c54ca6796b13313487916ac0 (patch) | |
tree | ed21a6bab51547d776061c9da2318f199ee4ea14 /sys/netinet | |
parent | cdf18c02e63403bcc3ca98fc618b46d5868cd2d3 (diff) | |
download | FreeBSD-src-cb606898b9f83045c54ca6796b13313487916ac0.zip FreeBSD-src-cb606898b9f83045c54ca6796b13313487916ac0.tar.gz |
Add support to IPFW for matching by TCP data length.
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ip_fw.h | 1 | ||||
-rw-r--r-- | sys/netinet/ip_fw2.c | 23 |
2 files changed, 24 insertions, 0 deletions
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h index 15ce84b..9771189 100644 --- a/sys/netinet/ip_fw.h +++ b/sys/netinet/ip_fw.h @@ -136,6 +136,7 @@ enum ipfw_opcodes { /* arguments (4 byte each) */ O_JAIL, /* u32 = id */ O_ALTQ, /* u32 = altq classif. qid */ O_DIVERTED, /* arg1=bitmap (1:loop, 2:out) */ + O_TCPDATALEN, /* arg1 = tcp data len */ O_LAST_OPCODE /* not an opcode! */ }; diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c index 854e2d9..c45a04f 100644 --- a/sys/netinet/ip_fw2.c +++ b/sys/netinet/ip_fw2.c @@ -2203,6 +2203,28 @@ check_body: flags_match(cmd, ip->ip_tos)); break; + case O_TCPDATALEN: + if (proto == IPPROTO_TCP && offset == 0) { + struct tcphdr *tcp; + uint16_t x; + uint16_t *p; + int i; + + tcp = L3HDR(struct tcphdr,ip); + x = ip_len - + ((ip->ip_hl + tcp->th_off) << 2); + if (cmdlen == 1) { + match = (cmd->arg1 == x); + break; + } + /* otherwise we have ranges */ + p = ((ipfw_insn_u16 *)cmd)->ports; + i = cmdlen - 1; + for (; !match && i>0; i--, p += 2) + match = (x >= p[0] && x <= p[1]); + } + break; + case O_TCPFLAGS: match = (proto == IPPROTO_TCP && offset == 0 && flags_match(cmd, @@ -3014,6 +3036,7 @@ check_ipfw_struct(struct ip_fw *rule, int size) case O_IPID: case O_IPTTL: case O_IPLEN: + case O_TCPDATALEN: if (cmdlen < 1 || cmdlen > 31) goto bad_size; break; |