From 2e0c9a406d07fcff42b2e4345bf52600479989d6 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 30 Mar 2022 00:17:09 +0200 Subject: extensions: ipt_DNAT: Combine xlate functions also Make use of the new sprint_range() to introduce a common inner function for both v1 and v2 xlate functions. Also abort translation with shifted port ranges to not hide the missing feature in nftables. Signed-off-by: Phil Sutter --- extensions/libipt_DNAT.c | 88 ++++++++++++------------------------------------ 1 file changed, 21 insertions(+), 67 deletions(-) diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c index b72437d5..9a179919 100644 --- a/extensions/libipt_DNAT.c +++ b/extensions/libipt_DNAT.c @@ -266,47 +266,36 @@ static void DNAT_save(const void *ip, const struct xt_entry_target *target) __DNAT_print(&range, true); } -static void print_range_xlate(const struct nf_nat_ipv4_range *r, - struct xt_xlate *xl) +static int __DNAT_xlate(struct xt_xlate *xl, const struct nf_nat_range2 *r) { - if (r->flags & NF_NAT_RANGE_MAP_IPS) { - struct in_addr a; + char *range_str = sprint_range(r); + const char *sep = " "; - a.s_addr = r->min_ip; - xt_xlate_add(xl, "%s", xtables_ipaddr_to_numeric(&a)); - if (r->max_ip != r->min_ip) { - a.s_addr = r->max_ip; - xt_xlate_add(xl, "-%s", xtables_ipaddr_to_numeric(&a)); - } + /* shifted portmap ranges are not supported by nftables */ + if (r->flags & NF_NAT_RANGE_PROTO_OFFSET) + return 0; + + xt_xlate_add(xl, "dnat"); + if (strlen(range_str)) + xt_xlate_add(xl, " to %s", range_str); + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) { + xt_xlate_add(xl, "%srandom", sep); + sep = ","; } - if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { - xt_xlate_add(xl, ":%hu", ntohs(r->min.tcp.port)); - if (r->max.tcp.port != r->min.tcp.port) - xt_xlate_add(xl, "-%hu", ntohs(r->max.tcp.port)); + if (r->flags & NF_NAT_RANGE_PERSISTENT) { + xt_xlate_add(xl, "%spersistent", sep); + sep = ","; } + return 1; } static int DNAT_xlate(struct xt_xlate *xl, const struct xt_xlate_tg_params *params) { - const struct nf_nat_ipv4_multi_range_compat *mr = - (const void *)params->target->data; - bool sep_need = false; - const char *sep = " "; - - xt_xlate_add(xl, "dnat to "); - print_range_xlate(mr->range, xl); - if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM) { - xt_xlate_add(xl, " random"); - sep_need = true; - } - if (mr->range->flags & NF_NAT_RANGE_PERSISTENT) { - if (sep_need) - sep = ","; - xt_xlate_add(xl, "%spersistent", sep); - } + struct nf_nat_range2 range = + RANGE2_INIT_FROM_IPV4_MRC(params->target->data); - return 1; + return __DNAT_xlate(xl, &range); } static void DNAT_parse_v2(struct xt_option_call *cb) @@ -336,45 +325,10 @@ static void DNAT_save_v2(const void *ip, const struct xt_entry_target *target) __DNAT_print((const void *)target->data, true); } -static void print_range_xlate_v2(const struct nf_nat_range2 *range, - struct xt_xlate *xl) -{ - if (range->flags & NF_NAT_RANGE_MAP_IPS) { - xt_xlate_add(xl, "%s", xtables_ipaddr_to_numeric(&range->min_addr.in)); - if (memcmp(&range->min_addr, &range->max_addr, - sizeof(range->min_addr))) { - xt_xlate_add(xl, "-%s", xtables_ipaddr_to_numeric(&range->max_addr.in)); - } - } - if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { - xt_xlate_add(xl, ":%hu", ntohs(range->min_proto.tcp.port)); - if (range->max_proto.tcp.port != range->min_proto.tcp.port) - xt_xlate_add(xl, "-%hu", ntohs(range->max_proto.tcp.port)); - if (range->flags & NF_NAT_RANGE_PROTO_OFFSET) - xt_xlate_add(xl, ";%hu", ntohs(range->base_proto.tcp.port)); - } -} - static int DNAT_xlate_v2(struct xt_xlate *xl, const struct xt_xlate_tg_params *params) { - const struct nf_nat_range2 *range = (const void *)params->target->data; - bool sep_need = false; - const char *sep = " "; - - xt_xlate_add(xl, "dnat to "); - print_range_xlate_v2(range, xl); - if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) { - xt_xlate_add(xl, " random"); - sep_need = true; - } - if (range->flags & NF_NAT_RANGE_PERSISTENT) { - if (sep_need) - sep = ","; - xt_xlate_add(xl, "%spersistent", sep); - } - - return 1; + return __DNAT_xlate(xl, (const void *)params->target->data); } static struct xtables_target dnat_tg_reg[] = { -- cgit v1.2.3