diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2015-09-29 18:21:54 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2015-09-30 17:32:10 +0200 |
commit | b870b949470af0b1b578590b38efdd80048b539e (patch) | |
tree | 21fbd7c71aa63e3a95b0d4be80d56664b17b2cb7 /src/evaluate.c | |
parent | de2ebd0e1d43361ecd879170b40bac76a503aa65 (diff) |
src: add dup statement support
This allows you to clone packets to destination address, eg.
... dup to 172.20.0.2
... dup to 172.20.0.2 device eth1
... dup to ip saddr map { 192.168.0.2 : 172.20.0.2, ... } device eth1
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r-- | src/evaluate.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index 581f3641..e8eafc64 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -20,6 +20,7 @@ #include <netinet/ip_icmp.h> #include <netinet/icmp6.h> #include <net/ethernet.h> +#include <net/if.h> #include <expression.h> #include <statement.h> @@ -1617,7 +1618,7 @@ static int nat_evaluate_family(struct eval_ctx *ctx, struct stmt *stmt) } } -static int nat_evaluate_addr(struct eval_ctx *ctx, struct stmt *stmt, +static int evaluate_addr(struct eval_ctx *ctx, struct stmt *stmt, struct expr **expr) { struct proto_ctx *pctx = &ctx->pctx; @@ -1659,7 +1660,7 @@ static int stmt_evaluate_nat(struct eval_ctx *ctx, struct stmt *stmt) return err; if (stmt->nat.addr != NULL) { - err = nat_evaluate_addr(ctx, stmt, &stmt->nat.addr); + err = evaluate_addr(ctx, stmt, &stmt->nat.addr); if (err < 0) return err; } @@ -1703,6 +1704,32 @@ static int stmt_evaluate_redir(struct eval_ctx *ctx, struct stmt *stmt) return 0; } +static int stmt_evaluate_dup(struct eval_ctx *ctx, struct stmt *stmt) +{ + int err; + + switch (ctx->pctx.family) { + case NFPROTO_IPV4: + case NFPROTO_IPV6: + if (stmt->dup.to == NULL) + return stmt_error(ctx, stmt, + "missing destination address"); + err = evaluate_addr(ctx, stmt, &stmt->dup.to); + if (err < 0) + return err; + + if (stmt->dup.dev != NULL) { + err = stmt_evaluate_arg(ctx, stmt, &ifindex_type, + sizeof(uint32_t) * BITS_PER_BYTE, + &stmt->dup.dev); + if (err < 0) + return err; + } + break; + } + return 0; +} + static int stmt_evaluate_queue(struct eval_ctx *ctx, struct stmt *stmt) { if (stmt->queue.queue != NULL) { @@ -1786,6 +1813,8 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt) return stmt_evaluate_redir(ctx, stmt); case STMT_QUEUE: return stmt_evaluate_queue(ctx, stmt); + case STMT_DUP: + return stmt_evaluate_dup(ctx, stmt); case STMT_SET: return stmt_evaluate_set(ctx, stmt); default: |