{
struct expr *one, *two, *data, *tmp;
const struct datatype *dtype;
- int err;
+ int addr_type, err;
- dtype = get_addr_dtype(stmt->nat.family);
+ if (stmt->nat.ipportmap) {
+ switch (stmt->nat.family) {
+ case NFPROTO_IPV4:
+ addr_type = TYPE_IPADDR;
+ break;
+ case NFPROTO_IPV6:
+ addr_type = TYPE_IP6ADDR;
+ break;
+ default:
+ return -1;
+ }
+ dtype = concat_type_alloc((addr_type << TYPE_BITS) |
+ TYPE_INET_SERVICE);
+ } else {
+ dtype = get_addr_dtype(stmt->nat.family);
+ }
expr_set_context(&ctx->ectx, dtype, dtype->size);
if (expr_evaluate(ctx, &stmt->nat.addr))
return -1;
data = stmt->nat.addr->mappings->set->data;
+ datatype_set(data, dtype);
+
if (expr_ops(data)->type != EXPR_CONCAT)
return __stmt_evaluate_arg(ctx, stmt, dtype, dtype->size,
BYTEORDER_BIG_ENDIAN,
BYTEORDER_BIG_ENDIAN,
&stmt->nat.addr);
+ dtype = get_addr_dtype(stmt->nat.family);
tmp = one;
err = __stmt_evaluate_arg(ctx, stmt, dtype, dtype->size,
BYTEORDER_BIG_ENDIAN,
if (tmp != two)
BUG("Internal error: Unexpected alteration of l4 expression");
- stmt->nat.ipportmap = true;
return err;
}
%token FLAGS "flags"
%token CPI "cpi"
+%token PORT "port"
%token UDP "udp"
%token SPORT "sport"
%token DPORT "dport"
{
$<stmt>0->nat.flags = $2;
}
+ | nf_key_proto ADDR DOT PORT TO stmt_expr
+ {
+ $<stmt>0->nat.family = $1;
+ $<stmt>0->nat.addr = $6;
+ $<stmt>0->nat.ipportmap = true;
+ }
;
masq_stmt : masq_stmt_alloc masq_stmt_args