syntactic sugar: support range notation such as

1.2.3.4/24{5,6,7,10-20,60-90}
for set of ip addresses.
Previously you needed to specify every address in the range, which
was unconvenient and lead to very long lines.
Internally the set is still stored in the same way, just the
input and output routines are modified.

Manpage update still missing.

Perhaps a similar preprocessing step would be useful for port ranges.

MFC after: 3 days
This commit is contained in:
Luigi Rizzo 2003-06-23 08:20:28 +00:00
parent 064d54a248
commit 9ef3f16d08
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=116716

View File

@ -687,7 +687,7 @@ print_ip(ipfw_insn_ip *cmd, char *s)
}
if (cmd->o.opcode == O_IP_SRC_SET || cmd->o.opcode == O_IP_DST_SET) {
u_int32_t x, *d;
int i;
int i, j;
char comma = '{';
x = cmd->o.arg1 - 1;
@ -698,9 +698,22 @@ print_ip(ipfw_insn_ip *cmd, char *s)
x = cmd->addr.s_addr = htonl(cmd->addr.s_addr);
x &= 0xff; /* base */
d = (u_int32_t *)&(cmd->mask);
/*
* Print bits and ranges.
* Locate first bit set (i), then locate first bit unset (j).
* If we have 3+ consecutive bits set, then print them as a
* range, otherwise only print the initial bit and rescan.
*/
for (i=0; i < cmd->o.arg1; i++)
if (d[ i/32] & (1<<(i & 31))) {
if (d[i/32] & (1<<(i & 31))) {
for (j=i+1; j < cmd->o.arg1; j++)
if (!(d[ j/32] & (1<<(j & 31))))
break;
printf("%c%d", comma, i+x);
if (j>i+2) { /* range has at least 3 elements */
printf("-%d", j-1+x);
i = j-1;
}
comma = ',';
}
printf("}");
@ -1906,6 +1919,7 @@ fill_ip(ipfw_insn_ip *cmd, char *av)
av = p+1;
low = cmd->addr.s_addr & 0xff;
high = low + cmd->o.arg1 - 1;
i = -1; /* previous value in a range */
while (isdigit(*av)) {
char *s;
u_int16_t a = strtol(av, &s, 0);
@ -1918,9 +1932,22 @@ fill_ip(ipfw_insn_ip *cmd, char *av)
exit(0);
}
a -= low;
d[ a/32] |= 1<<(a & 31);
if (*s != ',')
break;
if (i == -1) /* no previous in range */
i = a;
else { /* check that range is valid */
if (i > a)
errx(EX_DATAERR, "invalid range %d-%d",
i+low, a+low);
if (*s == '-')
errx(EX_DATAERR, "double '-' in range");
}
for (; i <= a; i++)
d[i/32] |= 1<<(i & 31);
i = -1;
if (*s == '-')
i = a;
else if (*s != ',')
break;
av = s+1;
}
return;