diff options
Diffstat (limited to 'sys')
-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 */ |