summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_fw2.c
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2003-06-22 17:33:19 +0000
committerluigi <luigi@FreeBSD.org>2003-06-22 17:33:19 +0000
commita2349d529836463f5ee1d4f893837c60d23b15d2 (patch)
tree251b5628acca6e45e20706ada46448a593db65d7 /sys/netinet/ip_fw2.c
parent5fb2bd5499547bb2e47eff4132443da417a41139 (diff)
downloadFreeBSD-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.c41
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 */
OpenPOWER on IntegriCloud