diff options
author | luigi <luigi@FreeBSD.org> | 2003-06-22 17:33:19 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 2003-06-22 17:33:19 +0000 |
commit | a2349d529836463f5ee1d4f893837c60d23b15d2 (patch) | |
tree | 251b5628acca6e45e20706ada46448a593db65d7 /sys/netinet/ip_fw2.c | |
parent | 5fb2bd5499547bb2e47eff4132443da417a41139 (diff) | |
download | FreeBSD-src-a2349d529836463f5ee1d4f893837c60d23b15d2.zip FreeBSD-src-a2349d529836463f5ee1d4f893837c60d23b15d2.tar.gz |
Add support for multiple values and ranges for the "iplen", "ipttl",
"ipid" options. This feature has been requested by several users.
On passing, fix some minor bugs in the parser. This change is fully
backward compatible so if you have an old /sbin/ipfw and a new
kernel you are not in trouble (but you need to update /sbin/ipfw
if you want to use the new features).
Document the changes in the manpage.
Now you can write things like
ipfw add skipto 1000 iplen 0-500
which some people were asking to give preferential treatment to
short packets.
The 'MFC after' is just set as a reminder, because I still need
to merge the Alpha/Sparc64 fixes for ipfw2 (which unfortunately
change the size of certain kernel structures; not that it matters
a lot since ipfw2 is entirely optional and not the default...)
PR: bin/48015
MFC after: 1 week
Diffstat (limited to 'sys/netinet/ip_fw2.c')
-rw-r--r-- | sys/netinet/ip_fw2.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c index 95a153e..1af01da 100644 --- a/sys/netinet/ip_fw2.c +++ b/sys/netinet/ip_fw2.c @@ -1730,17 +1730,30 @@ check_body: match = (hlen > 0 && cmd->arg1 == ip->ip_v); break; - case O_IPTTL: - match = (hlen > 0 && cmd->arg1 == ip->ip_ttl); - break; - case O_IPID: - match = (hlen > 0 && - cmd->arg1 == ntohs(ip->ip_id)); - break; - case O_IPLEN: - match = (hlen > 0 && cmd->arg1 == ip_len); + case O_IPTTL: + if (hlen > 0) { /* only for IP packets */ + uint16_t x; + uint16_t *p; + int i; + + if (cmd->opcode == O_IPLEN) + x = ip_len; + else if (cmd->opcode == O_IPTTL) + x = ip->ip_ttl; + else /* must be IPID */ + x = ntohs(ip->ip_id); + 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_IPPRECEDENCE: @@ -2371,11 +2384,8 @@ check_ipfw_struct(struct ip_fw *rule, int size) case O_IN: case O_FRAG: case O_IPOPT: - case O_IPLEN: - case O_IPID: case O_IPTOS: case O_IPPRECEDENCE: - case O_IPTTL: case O_IPVER: case O_TCPWIN: case O_TCPFLAGS: @@ -2440,6 +2450,13 @@ check_ipfw_struct(struct ip_fw *rule, int size) goto bad_size; break; + case O_IPID: + case O_IPTTL: + case O_IPLEN: + if (cmdlen < 1 || cmdlen > 31) + goto bad_size; + break; + case O_MAC_TYPE: case O_IP_SRCPORT: case O_IP_DSTPORT: /* XXX artificial limit, 30 port pairs */ |