summaryrefslogtreecommitdiffstats
path: root/src/evaluate.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2015-09-29 18:21:54 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2015-09-30 17:32:10 +0200
commitb870b949470af0b1b578590b38efdd80048b539e (patch)
tree21fbd7c71aa63e3a95b0d4be80d56664b17b2cb7 /src/evaluate.c
parentde2ebd0e1d43361ecd879170b40bac76a503aa65 (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.c33
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: