Merge the handlers of O_IP_SRC_MASK and O_IP_DST_MASK opcodes, and

support matching a list of addr/mask pairs so one can write
more efficient rulesets which were not possible before e.g.

    add 100 skipto 1000 not src-ip 10.0.0.0/8,127.0.0.1/8,192.168.0.0/16

The change is fully backward compatible.
ipfw2 and manpage commit to follow.

MFC after: 3 days
This commit is contained in:
luigi 2003-07-08 07:44:42 +00:00
parent f90fe69bb8
commit cbd03d1b67

View File

@ -1644,10 +1644,17 @@ ipfw_chk(struct ip_fw_args *args)
break;
case O_IP_SRC_MASK:
match = (hlen > 0 &&
((ipfw_insn_ip *)cmd)->addr.s_addr ==
(src_ip.s_addr &
((ipfw_insn_ip *)cmd)->mask.s_addr));
case O_IP_DST_MASK:
if (hlen > 0) {
uint32_t a =
(cmd->opcode == O_IP_DST_MASK) ?
dst_ip.s_addr : src_ip.s_addr;
uint32_t *p = ((ipfw_insn_u32 *)cmd)->d;
int i = cmdlen-1;
for (; !match && i>0; i-= 2, p+= 2)
match = (p[0] == (a & p[1]));
}
break;
case O_IP_SRC_ME:
@ -1683,13 +1690,6 @@ ipfw_chk(struct ip_fw_args *args)
dst_ip.s_addr);
break;
case O_IP_DST_MASK:
match = (hlen > 0) &&
(((ipfw_insn_ip *)cmd)->addr.s_addr ==
(dst_ip.s_addr &
((ipfw_insn_ip *)cmd)->mask.s_addr));
break;
case O_IP_DST_ME:
if (hlen > 0) {
struct ifnet *tif;
@ -2440,13 +2440,9 @@ check_ipfw_struct(struct ip_fw *rule, int size)
case O_IP_SRC_MASK:
case O_IP_DST_MASK:
if (cmdlen != F_INSN_SIZE(ipfw_insn_ip))
/* only odd command lengths */
if ( !(cmdlen & 1) || cmdlen > 31)
goto bad_size;
if (((ipfw_insn_ip *)cmd)->mask.s_addr == 0) {
printf("ipfw: opcode %d, useless rule\n",
cmd->opcode);
return EINVAL;
}
break;
case O_IP_SRC_SET: