diff options
author | luigi <luigi@FreeBSD.org> | 2009-12-15 09:46:27 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 2009-12-15 09:46:27 +0000 |
commit | 84d17b9dde0bca3ba11491efd293d666259c204f (patch) | |
tree | 6801a26cde90c352ef557ec26fb56589ca42c654 /sbin/ipfw/ipfw2.c | |
parent | 507718c519a5c35f2ef041763a9715b79c33b177 (diff) | |
download | FreeBSD-src-84d17b9dde0bca3ba11491efd293d666259c204f.zip FreeBSD-src-84d17b9dde0bca3ba11491efd293d666259c204f.tar.gz |
implement a new match option,
lookup {dst-ip|src-ip|dst-port|src-port|uid|jail} N
which searches the specified field in table N and sets tablearg
accordingly.
With dst-ip or src-ip the option replicates two existing options.
When used with other arguments, the option can be useful to
quickly dispatch traffic based on other fields.
Work supported by the Onelab project.
MFC after: 1 week
Diffstat (limited to 'sbin/ipfw/ipfw2.c')
-rw-r--r-- | sbin/ipfw/ipfw2.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c index 7edfbd5..d4740c9 100644 --- a/sbin/ipfw/ipfw2.c +++ b/sbin/ipfw/ipfw2.c @@ -224,6 +224,15 @@ static struct _s_x rule_action_params[] = { { NULL, 0 } /* terminator */ }; +/* + * The 'lookup' instruction accepts one of the following arguments. + * -1 is a terminator for the list. + * Arguments are passed as v[1] in O_DST_LOOKUP options. + */ +static int lookup_key[] = { + TOK_DSTIP, TOK_SRCIP, TOK_DSTPORT, TOK_SRCPORT, + TOK_UID, TOK_JAIL, -1 }; + static struct _s_x rule_options[] = { { "tagged", TOK_TAGGED }, { "uid", TOK_UID }, @@ -290,6 +299,7 @@ static struct _s_x rule_options[] = { { "dst-ip6", TOK_DSTIP6}, { "src-ipv6", TOK_SRCIP6}, { "src-ip6", TOK_SRCIP6}, + { "lookup", TOK_LOOKUP}, { "//", TOK_COMMENT }, { "not", TOK_NOT }, /* pseudo option */ @@ -742,6 +752,16 @@ print_ip(ipfw_insn_ip *cmd, char const *s) int len = F_LEN((ipfw_insn *)cmd); uint32_t *a = ((ipfw_insn_u32 *)cmd)->d; + if (cmd->o.opcode == O_IP_DST_LOOKUP && len > F_INSN_SIZE(ipfw_insn_u32)) { + uint32_t d = a[1]; + const char *arg = "<invalid>"; + + if (d < sizeof(lookup_key)/sizeof(lookup_key[0])) + arg = match_value(rule_options, lookup_key[d]); + printf("%s lookup %s %d", cmd->o.len & F_NOT ? " not": "", + arg, cmd->o.arg1); + return; + } printf("%s%s ", cmd->o.len & F_NOT ? " not": "", s); if (cmd->o.opcode == O_IP_SRC_ME || cmd->o.opcode == O_IP_DST_ME) { @@ -3479,6 +3499,31 @@ read_options: ac--; av++; break; + case TOK_LOOKUP: { + ipfw_insn_u32 *c = (ipfw_insn_u32 *)cmd; + char *p; + int j; + + if (ac < 2) + errx(EX_USAGE, "format: lookup argument tablenum"); + cmd->opcode = O_IP_DST_LOOKUP; + cmd->len |= F_INSN_SIZE(ipfw_insn) + 2; + i = match_token(rule_options, *av); + for (j = 0; lookup_key[j] >= 0 ; j++) { + if (i == lookup_key[j]) + break; + } + if (lookup_key[j] <= 0) + errx(EX_USAGE, "format: cannot lookup on %s", *av); + c->d[1] = j; // i converted to option + ac--; av++; + cmd->arg1 = strtoul(*av, &p, 0); + if (p && *p) + errx(EX_USAGE, "format: lookup argument tablenum"); + ac--; av++; + } + break; + default: errx(EX_USAGE, "unrecognised option [%d] %s\n", i, s); } |