diff mbox

ss: Enclose IPv6 address in brackets

Message ID fc81757c-8dbb-dbed-7a24-7011cb8bb9e0@der-flo.net
State Changes Requested, archived
Delegated to: stephen hemminger
Headers show

Commit Message

Florian Lehner July 29, 2017, 12:29 p.m. UTC
This patch adds support for RFC2732 IPv6 address format with brackets
for the tool ss. So output for ss changes from
2a00:1450:400a:804::200e:443 to [2a00:1450:400a:804::200e]:443 for IPv6
addresses with attached port number.

Signed-off-by: Lehner Florian <dev@der-flo.net>
---
 misc/ss.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

 			est_len = addr_width;

Comments

Stephen Hemminger July 29, 2017, 3:26 p.m. UTC | #1
On Sat, 29 Jul 2017 14:29:10 +0200
Florian Lehner <dev@der-flo.net> wrote:

> This patch adds support for RFC2732 IPv6 address format with brackets
> for the tool ss. So output for ss changes from
> 2a00:1450:400a:804::200e:443 to [2a00:1450:400a:804::200e]:443 for IPv6
> addresses with attached port number.
> 
> Signed-off-by: Lehner Florian <dev@der-flo.net>
> ---

This is the right solution but it might break someone parsing the output of ss
command. Will apply it anyway unless someone has an objection.
Phil Sutter July 31, 2017, 10:30 a.m. UTC | #2
On Sat, Jul 29, 2017 at 02:29:10PM +0200, Florian Lehner wrote:
> This patch adds support for RFC2732 IPv6 address format with brackets
> for the tool ss. So output for ss changes from
> 2a00:1450:400a:804::200e:443 to [2a00:1450:400a:804::200e]:443 for IPv6
> addresses with attached port number.
> 
> Signed-off-by: Lehner Florian <dev@der-flo.net>
> ---
>  misc/ss.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/misc/ss.c b/misc/ss.c
> index 12763c9..db39c93 100644
> --- a/misc/ss.c
> +++ b/misc/ss.c
> @@ -1059,7 +1059,11 @@ static void inet_addr_print(const inet_prefix *a,
> int port, unsigned int ifindex
>  			ap = format_host(AF_INET, 4, a->data);
>  		}
>  	} else {
> -		ap = format_host(a->family, 16, a->data);
> +		if (a->family == AF_INET6) {
> +			sprintf(buf, "[%s]", format_host(a->family, 16, a->data));
> +		} else {
> +			ap = format_host(a->family, 16, a->data);
> +		}
>  		est_len = strlen(ap);
>  		if (est_len <= addr_width)
>  			est_len = addr_width;

Note that this will enclosed resolved hostnames in brackets as well, not
sure if that's intended. Looks like fixing that is not exactly trivial:
Hostname resolution is buried in format_host() which resides in
lib/utils.c so is shared code with ip, tc, etc. Hence, adding the
brackets in rt_addr_n2a_r() is not an option, either. Adding a 'bool *'
param to format_host() and format_host_r() indicating that name
resolution has happened might help here.

Cheers, Phil
Stephen Hemminger July 31, 2017, 4:27 p.m. UTC | #3
On Mon, 31 Jul 2017 12:30:10 +0200
Phil Sutter <phil@nwl.cc> wrote:

> On Sat, Jul 29, 2017 at 02:29:10PM +0200, Florian Lehner wrote:
> > This patch adds support for RFC2732 IPv6 address format with brackets
> > for the tool ss. So output for ss changes from
> > 2a00:1450:400a:804::200e:443 to [2a00:1450:400a:804::200e]:443 for IPv6
> > addresses with attached port number.
> > 
> > Signed-off-by: Lehner Florian <dev@der-flo.net>
> > ---
> >  misc/ss.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/misc/ss.c b/misc/ss.c
> > index 12763c9..db39c93 100644
> > --- a/misc/ss.c
> > +++ b/misc/ss.c
> > @@ -1059,7 +1059,11 @@ static void inet_addr_print(const inet_prefix *a,
> > int port, unsigned int ifindex
> >  			ap = format_host(AF_INET, 4, a->data);
> >  		}
> >  	} else {
> > -		ap = format_host(a->family, 16, a->data);
> > +		if (a->family == AF_INET6) {
> > +			sprintf(buf, "[%s]", format_host(a->family, 16, a->data));
> > +		} else {
> > +			ap = format_host(a->family, 16, a->data);
> > +		}
> >  		est_len = strlen(ap);
> >  		if (est_len <= addr_width)
> >  			est_len = addr_width;  
> 
> Note that this will enclosed resolved hostnames in brackets as well, not
> sure if that's intended. Looks like fixing that is not exactly trivial:
> Hostname resolution is buried in format_host() which resides in
> lib/utils.c so is shared code with ip, tc, etc. Hence, adding the
> brackets in rt_addr_n2a_r() is not an option, either. Adding a 'bool *'
> param to format_host() and format_host_r() indicating that name
> resolution has happened might help here.
> 
> Cheers, Phil

Also, this code should return "*" for IN6ADDR_ANY
Phil Sutter July 31, 2017, 4:43 p.m. UTC | #4
On Mon, Jul 31, 2017 at 09:27:55AM -0700, Stephen Hemminger wrote:
> On Mon, 31 Jul 2017 12:30:10 +0200
> Phil Sutter <phil@nwl.cc> wrote:
> 
> > On Sat, Jul 29, 2017 at 02:29:10PM +0200, Florian Lehner wrote:
> > > This patch adds support for RFC2732 IPv6 address format with brackets
> > > for the tool ss. So output for ss changes from
> > > 2a00:1450:400a:804::200e:443 to [2a00:1450:400a:804::200e]:443 for IPv6
> > > addresses with attached port number.
> > > 
> > > Signed-off-by: Lehner Florian <dev@der-flo.net>
> > > ---
> > >  misc/ss.c | 6 +++++-
> > >  1 file changed, 5 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/misc/ss.c b/misc/ss.c
> > > index 12763c9..db39c93 100644
> > > --- a/misc/ss.c
> > > +++ b/misc/ss.c
> > > @@ -1059,7 +1059,11 @@ static void inet_addr_print(const inet_prefix *a,
> > > int port, unsigned int ifindex
> > >  			ap = format_host(AF_INET, 4, a->data);
> > >  		}
> > >  	} else {
> > > -		ap = format_host(a->family, 16, a->data);
> > > +		if (a->family == AF_INET6) {
> > > +			sprintf(buf, "[%s]", format_host(a->family, 16, a->data));
> > > +		} else {
> > > +			ap = format_host(a->family, 16, a->data);
> > > +		}
> > >  		est_len = strlen(ap);
> > >  		if (est_len <= addr_width)
> > >  			est_len = addr_width;  
> > 
> > Note that this will enclosed resolved hostnames in brackets as well, not
> > sure if that's intended. Looks like fixing that is not exactly trivial:
> > Hostname resolution is buried in format_host() which resides in
> > lib/utils.c so is shared code with ip, tc, etc. Hence, adding the
> > brackets in rt_addr_n2a_r() is not an option, either. Adding a 'bool *'
> > param to format_host() and format_host_r() indicating that name
> > resolution has happened might help here.
> > 
> > Cheers, Phil
> 
> Also, this code should return "*" for IN6ADDR_ANY

Oh, really? It doesn't do that currently, and I always thought the IPv6
all-zero address was written '::' (or '[::]:1234' if a port is present).

Cheers, Phil
Florian Lehner July 31, 2017, 6:17 p.m. UTC | #5
On 07/31/2017 12:30 PM, Phil Sutter wrote:
> On Sat, Jul 29, 2017 at 02:29:10PM +0200, Florian Lehner wrote:
>> This patch adds support for RFC2732 IPv6 address format with brackets
>> for the tool ss. So output for ss changes from
>> 2a00:1450:400a:804::200e:443 to [2a00:1450:400a:804::200e]:443 for IPv6
>> addresses with attached port number.
>>
>> Signed-off-by: Lehner Florian <dev@der-flo.net>
>> ---
>>  misc/ss.c | 6 +++++-
>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/misc/ss.c b/misc/ss.c
>> index 12763c9..db39c93 100644
>> --- a/misc/ss.c
>> +++ b/misc/ss.c
>> @@ -1059,7 +1059,11 @@ static void inet_addr_print(const inet_prefix *a,
>> int port, unsigned int ifindex
>>  			ap = format_host(AF_INET, 4, a->data);
>>  		}
>>  	} else {
>> -		ap = format_host(a->family, 16, a->data);
>> +		if (a->family == AF_INET6) {
>> +			sprintf(buf, "[%s]", format_host(a->family, 16, a->data));
>> +		} else {
>> +			ap = format_host(a->family, 16, a->data);
>> +		}
>>  		est_len = strlen(ap);
>>  		if (est_len <= addr_width)
>>  			est_len = addr_width;
> 
> Note that this will enclosed resolved hostnames in brackets as well, not
> sure if that's intended. Looks like fixing that is not exactly trivial:
> Hostname resolution is buried in format_host() which resides in
> lib/utils.c so is shared code with ip, tc, etc. Hence, adding the
> brackets in rt_addr_n2a_r() is not an option, either. Adding a 'bool *'
> param to format_host() and format_host_r() indicating that name
> resolution has happened might help here.
> 
> Cheers, Phil
> 

By adding a check in the if statement on the global variable
$resolve_hosts the resolved hostnames will not enclosed with brackets.
David Laight Aug. 1, 2017, 11:11 a.m. UTC | #6
From: Florian Lehner

> Sent: 29 July 2017 13:29

> This patch adds support for RFC2732 IPv6 address format with brackets

> for the tool ss. So output for ss changes from

> 2a00:1450:400a:804::200e:443 to [2a00:1450:400a:804::200e]:443 for IPv6

> addresses with attached port number.

> 

> Signed-off-by: Lehner Florian <dev@der-flo.net>

> ---

>  misc/ss.c | 6 +++++-

>  1 file changed, 5 insertions(+), 1 deletion(-)

> 

> diff --git a/misc/ss.c b/misc/ss.c

> index 12763c9..db39c93 100644

> --- a/misc/ss.c

> +++ b/misc/ss.c

> @@ -1059,7 +1059,11 @@ static void inet_addr_print(const inet_prefix *a,

> int port, unsigned int ifindex

>  			ap = format_host(AF_INET, 4, a->data);

>  		}

>  	} else {

> -		ap = format_host(a->family, 16, a->data);

> +		if (a->family == AF_INET6) {

> +			sprintf(buf, "[%s]", format_host(a->family, 16, a->data));

> +		} else {

> +			ap = format_host(a->family, 16, a->data);

> +		}

>  		est_len = strlen(ap);

...

There are some strange things going on with global variables if this works at all.
The text form of the address is in buf[] in one path and *ap in the other.

One option might be to call format_host() then use strchr(ap, ':')
to add [] if the string contains any ':'.

	David
Stephen Hemminger Aug. 1, 2017, 2:41 p.m. UTC | #7
On Tue, 1 Aug 2017 11:11:03 +0000
David Laight <David.Laight@ACULAB.COM> wrote:

> From: Florian Lehner
> > Sent: 29 July 2017 13:29
> > This patch adds support for RFC2732 IPv6 address format with brackets
> > for the tool ss. So output for ss changes from
> > 2a00:1450:400a:804::200e:443 to [2a00:1450:400a:804::200e]:443 for IPv6
> > addresses with attached port number.
> > 
> > Signed-off-by: Lehner Florian <dev@der-flo.net>
> > ---
> >  misc/ss.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/misc/ss.c b/misc/ss.c
> > index 12763c9..db39c93 100644
> > --- a/misc/ss.c
> > +++ b/misc/ss.c
> > @@ -1059,7 +1059,11 @@ static void inet_addr_print(const inet_prefix *a,
> > int port, unsigned int ifindex
> >  			ap = format_host(AF_INET, 4, a->data);
> >  		}
> >  	} else {
> > -		ap = format_host(a->family, 16, a->data);
> > +		if (a->family == AF_INET6) {
> > +			sprintf(buf, "[%s]", format_host(a->family, 16, a->data));
> > +		} else {
> > +			ap = format_host(a->family, 16, a->data);
> > +		}
> >  		est_len = strlen(ap);  
> ...
> 
> There are some strange things going on with global variables if this works at all.
> The text form of the address is in buf[] in one path and *ap in the other.
> 
> One option might be to call format_host() then use strchr(ap, ':')
> to add [] if the string contains any ':'.
> 
> 	David
> 

That sounds like a better solution.

Also what about IN6ADDR_ANY
diff mbox

Patch

diff --git a/misc/ss.c b/misc/ss.c
index 12763c9..db39c93 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -1059,7 +1059,11 @@  static void inet_addr_print(const inet_prefix *a,
int port, unsigned int ifindex
 			ap = format_host(AF_INET, 4, a->data);
 		}
 	} else {
-		ap = format_host(a->family, 16, a->data);
+		if (a->family == AF_INET6) {
+			sprintf(buf, "[%s]", format_host(a->family, 16, a->data));
+		} else {
+			ap = format_host(a->family, 16, a->data);
+		}
 		est_len = strlen(ap);
 		if (est_len <= addr_width)