iptables: allow IPv6 port NAT without address NAT
PATCH 1/1 iptables: allow IPv6 port NAT without address NAT
correct parsing of IPv6 port NAT without address NAT and also print brackets for port only IPv6 NAT.
--- extensions/libip6t_DNAT.c | 12 +++++------- extensions/libip6t_SNAT.c | 12 +++++------- 2 files changed, 10 insertions(+), 14 deletions(-)
extensions/libip6t_DNAT.c +5 -7
@@ -105,8 +105,8 @@ parse_to(const char *orig_arg, int portok, struct nf_nat_range *range) range->min_proto.tcp.port =htons (port); range->max_proto.tcp.port =htons (maxport); } -/* Starts with a colon? No IP info...*/ -if (colon == arg) { +/* Starts with [] colon? No IP info...*/ +if (colon == arg+2 ) {free (arg);return ; }
@@ -183,18 +183,16 @@ static void DNAT_fcheck(struct xt_fcheck_call *cb)static void print_range (const struct nf_nat_range *range) { +if (range->flags &NF_NAT_RANGE_PROTO_SPECIFIED ) +printf ("[" );if (range->flags &NF_NAT_RANGE_MAP_IPS ) { -if (range->flags &NF_NAT_RANGE_PROTO_SPECIFIED ) -printf ("[" );printf ("%s" ,xtables_ip6addr_to_numeric (&range->min_addr.in6));if (memcmp (&range->min_addr, &range->max_addr,sizeof (range->min_addr)))printf ("-%s" ,xtables_ip6addr_to_numeric (&range->max_addr.in6)); -if (range->flags &NF_NAT_RANGE_PROTO_SPECIFIED ) -printf ("]" ); }if (range->flags &NF_NAT_RANGE_PROTO_SPECIFIED ) { -printf (":" ); +printf ("]:" );printf ("%hu" ,ntohs (range->min_proto.tcp.port));if (range->max_proto.tcp.port != range->min_proto.tcp.port)printf ("-%hu" ,ntohs (range->max_proto.tcp.port));
extensions/libip6t_SNAT.c +5 -7
@@ -105,8 +105,8 @@ parse_to(const char *orig_arg, int portok, struct nf_nat_range *range) range->min_proto.tcp.port =htons (port); range->max_proto.tcp.port =htons (maxport); } -/* Starts with a colon? No IP info...*/ -if (colon == arg) { +/* Starts with [] colon? No IP info...*/ +if (colon == arg+2 ) {free (arg);return ; }
@@ -183,18 +183,16 @@ static void SNAT_fcheck(struct xt_fcheck_call *cb)static void print_range (const struct nf_nat_range *range) { +if (range->flags &NF_NAT_RANGE_PROTO_SPECIFIED ) +printf ("[" );if (range->flags &NF_NAT_RANGE_MAP_IPS ) { -if (range->flags &NF_NAT_RANGE_PROTO_SPECIFIED ) -printf ("[" );printf ("%s" ,xtables_ip6addr_to_numeric (&range->min_addr.in6));if (memcmp (&range->min_addr, &range->max_addr,sizeof (range->min_addr)))printf ("-%s" ,xtables_ip6addr_to_numeric (&range->max_addr.in6)); -if (range->flags &NF_NAT_RANGE_PROTO_SPECIFIED ) -printf ("]" ); }if (range->flags &NF_NAT_RANGE_PROTO_SPECIFIED ) { -printf (":" ); +printf ("]:" );printf ("%hu" ,ntohs (range->min_proto.tcp.port));if (range->max_proto.tcp.port != range->min_proto.tcp.port)printf ("-%hu" ,ntohs (range->max_proto.tcp.port));
Signature · 1 line
1.8.0.2
Pablo Neira Ayuso
maintainerHi Ulrich,
Quoted 2 lines · Ulrich Weber
correct parsing of IPv6 port NAT without address NAT and also print brackets for port only IPv6 NAT.
I think we can go further with some extra sanity checkings, something like:
parse_to(...)
[...]
start = strchr(arg, '[');
if (start == NULL)
xtables_error(PARAMETER_PROBLEM,
"IPv6 address has to be enclosed in brackets");That will help users that expect a similar syntax than IPv4 DNAT.
The current error shows misleading error reporting if brackets are missing:
# ip6tables -D PREROUTING -p tcp -t nat -j DNAT --to :80-110 ip6tables v1.4.17: Bad IP address ":80"
Would you send me a new version of this patch?
Thanks.
Hi Pablo,
Quoted 8 lines · Pablo Neira Ayuso
Hi Ulrich,
Quoted 2 lines · Ulrich Weber
correct parsing of IPv6 port NAT without address NAT and also print brackets for port only IPv6 NAT.
I think we can go further with some extra sanity checkings, something like:
Quoted 6 lines
parse_to(...)
[...]start = strchr(arg, '['); if (start == NULL) xtables_error(PARAMETER_PROBLEM, "IPv6 address has to be enclosed in brackets");
That will force the use of [] and might break existing scripts. Lets try another way and relax the parsing,
by assuming one colon as port only information.
Will send another patch...
Cheers
Ulrich
Signature · 8 lines
Ulrich Weber | [email protected] | Senior Software Engineer Astaro - a Sophos company | Amalienbadstr 41 | 76227 Karlsruhe | Germany Phone +49-721-25516-0 | Fax –200 | www.astaro.com -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 1/1 iptables: allow IPv6 port NAT without address NAT
In reply to Pablo Neira Ayusocorrect parsing of IPv6 port NAT without address NAT, assume one colon as port information.
Allows:
* address only:
-j DNAT --to affe::1
-j DNAT --to [affe::1]
* port only
-j DNAT --to :80
-j DNAT --to :80-110
-j DNAT --to []:80
-j DNAT --to []:80-110
* address and port
-j DNAT --to [affe::1]:80
-j DNAT --to [affe::1]:80-110
--- extensions/libip6t_DNAT.c | 11 ++++++++--- extensions/libip6t_SNAT.c | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-)
extensions/libip6t_DNAT.c +8 -3
@@ -54,8 +54,13 @@ parse_to(const char *orig_arg, int portok, struct nf_nat_range *range)xtables_error (RESOURCE_PROBLEM ,"strdup" ); start =strchr (arg,'[' ); -if (start ==NULL ) +if (start ==NULL ) { start = arg; +/* Lets assume one colon is port information. Otherwise its an IPv6 address */ + colon =strchr (arg,':' ); +if (colon &&strchr (colon+1 ,':' )) + colon =NULL ; + }else { start++; end =strchr (start,']' );
@@ -105,8 +110,8 @@ parse_to(const char *orig_arg, int portok, struct nf_nat_range *range) range->min_proto.tcp.port =htons (port); range->max_proto.tcp.port =htons (maxport); } -/* Starts with a colon? No IP info...*/ -if (colon == arg) { +/* Starts with colon or [] colon? No IP info...*/ +if (colon == arg || colon == arg+2 ) {free (arg);return ; }
extensions/libip6t_SNAT.c +8 -3
@@ -54,8 +54,13 @@ parse_to(const char *orig_arg, int portok, struct nf_nat_range *range)xtables_error (RESOURCE_PROBLEM ,"strdup" ); start =strchr (arg,'[' ); -if (start ==NULL ) +if (start ==NULL ) { start = arg; +/* Lets assume one colon is port information. Otherwise its an IPv6 address */ + colon =strchr (arg,':' ); +if (colon &&strchr (colon+1 ,':' )) + colon =NULL ; + }else { start++; end =strchr (start,']' );
@@ -105,8 +110,8 @@ parse_to(const char *orig_arg, int portok, struct nf_nat_range *range) range->min_proto.tcp.port =htons (port); range->max_proto.tcp.port =htons (maxport); } -/* Starts with a colon? No IP info...*/ -if (colon == arg) { +/* Starts with colon or [] colon? No IP info...*/ +if (colon == arg || colon == arg+2 ) {free (arg);return ; }
Signature · 1 line
1.8.0.2
Quoted 14 lines · Ulrich Weber
correct parsing of IPv6 port NAT without address NAT, assume one colon as port information.
Allows:
* address only:
-j DNAT --to affe::1
-j DNAT --to [affe::1]* port only
-j DNAT --to :80
-j DNAT --to :80-110
-j DNAT --to []:80
-j DNAT --to []:80-110
Quoted 3 lines
* address and port
-j DNAT --to [affe::1]:80
-j DNAT --to [affe::1]:80-110
Applied, thanks Ulrich.