Bug 161986

Summary: [patch] netstat(1): Interface auto-width in "netstat -rn"
Product: Base System Reporter: Dennis Yusupoff <dyr>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Open ---    
Severity: Affects Only Me CC: yaroslav.shvets
Priority: Normal Keywords: patch
Version: Unspecified   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
There are two patches that use IFNAMSIZ from <net/if.h> instead of fixed values
none
There are two patches that use IFNAMSIZ from <net/if.h> instead of fixed values none

Description Dennis Yusupoff 2011-10-25 10:10:01 UTC
Currently there are two version of "netstat -rn" - "wide" and "usual". Wide is turning on by option "-W" and show additional information about routes (only for IPv4 family, as I understand route.c) - MTU and the full interface name(limited, however, by 8 symbols). In "usual" mode Netif limited by 6 symbols, which definitly isn't enough for VLAN interfaces:

===
netstat  -rn| head -n6
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            217.119.16.33      UGS         0 2147187618    em0
10.1.0.0/16        10.78.77.9         UG1         0        0 vlan30
===


===
netstat  -Wrn| head -n6
Routing tables

Internet:
Destination        Gateway            Flags    Refs        Use    Mtu    Netif Expire
default            217.119.16.33      UGS         0 2147115775   1500      em0
10.1.0.0/16        10.78.77.9         UG1         0          0   1500 vlan3050
===

I think, that truncating Netif is absolutely incorrect and easily confusing most FreeBSD users. 

So I propose:
1. Limit wid_if by getting width of longest netif name (i.e. automatically, on-the-fly)
2.1 Show full netif by default or:
2.2 Add special "truncated" symbol at the end of Netif, for example ">", like that:
===
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            217.119.16.33      UGS         0 2147187618    em0
10.1.0.0/16        10.78.77.9         UG1         0        0 vlan30>
===

Fix: 

Don't know C as should, but it looks like it might be easily patch route.c
Comment 1 pershin87 2011-11-09 02:56:32 UTC
I wrote small patch.
Tested patch on 8.2-RELEASE-p3

--- route.c     2010-12-21 23:09:25.000000000 +0600
+++ route_n.c   2011-11-04 23:01:33.000000000 +0600
@@ -264,13 +264,11 @@
 #ifndef INET6
 #define        WID_DST_DEFAULT(af)     18      /* width of destination column */
 #define        WID_GW_DEFAULT(af)      18      /* width of gateway column */
-#define        WID_IF_DEFAULT(af)      (Wflag ? 8 : 6) /* width of netif column */
 #else
 #define        WID_DST_DEFAULT(af) \
        ((af) == AF_INET6 ? (numeric_addr ? 33: 18) : 18)
 #define        WID_GW_DEFAULT(af) \
        ((af) == AF_INET6 ? (numeric_addr ? 29 : 18) : 18)
-#define        WID_IF_DEFAULT(af)      ((af) == AF_INET6 ? 8 : (Wflag ? 8 : 6))
 #endif /*INET6*/

 static int wid_dst;
@@ -291,11 +289,10 @@
        wid_refs = 6;
        wid_use = 8;
        wid_mtu = 6;
-       wid_if = WID_IF_DEFAULT(ef);
+       wid_if = 8;
        wid_expire = 6;

-       if (Wflag)
-               size_cols_tree(rn);
+       size_cols_tree(rn);
 }

 static void
@@ -781,7 +778,7 @@
                        if (rt->rt_rmx.rmx_mtu != 0)
                                printf("%*lu ", wid_mtu, rt->rt_rmx.rmx_mtu);
                        else
-                               printf("%*s ", wid_mtu, "");
+                               printf("%*s ", wid_mtu, "");
                }
        }
        if (rt->rt_ifp) {
Comment 2 Dennis Yusupoff 2011-11-18 10:21:32 UTC
Thank you for your patch, it works excellent, what I really wanted to
see al this years! :)

Example after patch:
===
 netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use    Netif Expire
default            10.78.77.35        UGS         0     2538      em0
1.1.1.0/30         link#7             U           0        0 em0.3050
1.1.1.1            link#7             UHS         0        0      lo0
127.0.0.1          link#6             UH          0        1      lo0
===
It's even works with renamed interfaces also:
===
# ifconfig em0.3050 name eth0.tag.3050
# netstat -rn|grep eth0
1.1.1.0/30         link#7             U           0        0 eth0.tag.3050
#
===
Brilliant!

And, there is also same problem with interface counters view (netstat
-i). Moreover, it doesn't viewed correctly even in wide mode!
See:
===
root@exBastinda:/usr/src/usr.bin/netstat (387) netstat -inW|grep em0
em0      1500 <Link#3>      00:30:48:64:e9:4a   133090     0     0   
18862     0     0
em0      1500 10.78.77.0/24 10.78.77.22          23468     -     -   
16827     -     -
em0.305  1500 <Link#7>      00:30:48:64:e9:4a        0     0    
0        2     0     0
em0.305  1500 1.1.1.0/30    1.1.1.1                  0     -    
-        0     -     -
root@exBastinda:/usr/src/usr.bin/netstat (388) netstat -in|grep em0
em0    1500 <Link#3>      00:30:48:64:e9:4a   133117     0     0   
18889     0     0
em0    1500 10.78.77.0/24 10.78.77.22          23495     -     -   
16854     -     -
em0.3  1500 <Link#7>      00:30:48:64:e9:4a        0     0     0       
2     0     0
em0.3  1500 1.1.1.0/30    1.1.1.1                  0     -     -       
0     -     -
===

So would you be so kind to fix this behavior also?

-- 
With best regards,
Dennis Yusupoff,
network engineer of
Smart-Telecom ISP
Russia, Saint-Petersburg 

Comment 3 pershin87 2012-02-23 10:53:06 UTC
I wrote small patch.
By default the width equal 10, if you use -W then width equal 16.

--- if_old.c	2010-12-21 23:09:25.000000000 +0600
+++ if.c	2012-02-23 16:47:58.000000000 +0600
@@ -223,9 +223,9 @@
 
 	if (!pfunc) {
 		if (Wflag)
-			printf("%-7.7s", "Name");
+			printf("%-16.16s", "Name");
 		else
-			printf("%-5.5s", "Name");
+			printf("%-10.10s", "Name");
 		printf(" %5.5s %-13.13s %-17.17s %8.8s %5.5s %5.5s",
 		    "Mtu", "Network", "Address", "Ipkts", "Ierrs", "Idrop");
 		if (bflag)
@@ -293,9 +293,9 @@
 
 		if (ifaddraddr == 0) {
 			if (Wflag)
-				printf("%-7.7s", name);
+				printf("%-16.16s", name);
 			else
-				printf("%-5.5s", name);
+				printf("%-10.10s", name);
 			printf(" %5lu ", ifnet.if_mtu);
 			printf("%-13.13s ", "none");
 			printf("%-17.17s ", "none");
@@ -315,9 +315,9 @@
 				continue;
 			}
 			if (Wflag)
-				printf("%-7.7s", name);
+				printf("%-16.16s", name);
 			else
-				printf("%-5.5s", name);
+				printf("%-10.10s", name);
 			printf(" %5lu ", ifnet.if_mtu);
 			switch (sa->sa_family) {
 			case AF_UNSPEC:
Comment 4 Yaroslav Shvets 2016-03-19 20:56:35 UTC
I prefer to rename interfaces for convenient operation in ipfw by masks:
# ipfw add allow ... in via if_wan*
# ipfw add deny ... out via if_vpn*
etc

I also observe the effect of trimming interface names after the renaming ones:

# ifconfig lagg0.17 name if_wan_kav_bgp

$ netstat -i | head -2
Name    Mtu Network       Address              Ipkts Ierrs Idrop    Opkts Oerrs  Coll
if_wa  1500 <Link#1>      00:0c:29:6a:c0:7f   119703     0     0    88432  1027     0
^^^^^
if_wa instead if_wan_kav_bgp

$ netstat -iW | head -2
Name      Mtu Network       Address              Ipkts Ierrs Idrop    Opkts Oerrs  Coll
if_wan_  1500 <Link#1>      00:0c:29:6a:c0:7f   119713     0     0    88440  1027     0
^^^^^^^
if_wan_ instead if_wan_kav_bgp

$ netstat -r | head -5 | tail -2
Destination        Gateway            Flags      Netif Expire
default            gw-kav             UGS    if_wan_k
                                             ^^^^^^^^
if_wan_k instead if_wan_kav_bgp

$ netstat -rW | head -5 | tail -2
Destination        Gateway            Flags       Use    Mtu      Netif Expire
default            gw-kav-bgp         UGS      762465   1500 if_wan_kav
                                                             ^^^^^^^^^^
if_wan_kav instead if_wan_kav_bgp

The problem of trimmed interface names in the output of netstat
is to use uncorrectly hardcoded length interface names.

There are two patches that use IFNAMSIZ from <net/if.h> instead of fixed values.
$ cd /usr/src/usr.bin/netstat

$ cat patch-if.c
--- if.c.orig   2016-03-19 15:05:31.758234000 +0200
+++ if.c        2016-03-19 21:10:58.987339000 +0200
@@ -240,9 +240,9 @@

        if (!pfunc) {
                if (Wflag)
-                       printf("%-7.7s", "Name");
+                       printf("%-*.*s", IFNAMSIZ-1, IFNAMSIZ-1, "Name");
                else
-                       printf("%-5.5s", "Name");
+                       printf("%-*.*s", IFNAMSIZ-1, IFNAMSIZ-1, "Name");
                printf(" %5.5s %-13.13s %-17.17s %8.8s %5.5s %5.5s",
                    "Mtu", "Network", "Address", "Ipkts", "Ierrs", "Idrop");
                if (bflag)
@@ -282,9 +282,9 @@
                        continue;

                if (Wflag)
-                       printf("%-7.7s", ifa->ifa_name);
+                       printf("%-*.*s", IFNAMSIZ-1, IFNAMSIZ-1, ifa->ifa_name);
                else
-                       printf("%-5.5s", ifa->ifa_name);
+                       printf("%-*.*s", IFNAMSIZ-1, IFNAMSIZ-1, ifa->ifa_name);

 #define IFA_MTU(ifa)   (((struct if_data *)(ifa)->ifa_data)->ifi_mtu)
                show_stat("lu", 6, IFA_MTU(ifa), IFA_MTU(ifa));

$ cat patch-route.c
--- route.c.orig        2016-03-19 15:05:31.783407000 +0200
+++ route.c     2016-03-19 21:09:28.400830000 +0200
@@ -238,13 +238,13 @@
 #ifndef INET6
 #define        WID_DST_DEFAULT(af)     18      /* width of destination column */
 #define        WID_GW_DEFAULT(af)      18      /* width of gateway column */
-#define        WID_IF_DEFAULT(af)      (Wflag ? 10 : 8) /* width of netif column */
+#define        WID_IF_DEFAULT(af)      IFNAMSIZ-1      /* width of netif column */
 #else
 #define        WID_DST_DEFAULT(af) \
        ((af) == AF_INET6 ? (numeric_addr ? 33: 18) : 18)
 #define        WID_GW_DEFAULT(af) \
        ((af) == AF_INET6 ? (numeric_addr ? 29 : 18) : 18)
-#define        WID_IF_DEFAULT(af)      ((af) == AF_INET6 ? 8 : (Wflag ? 10 : 8))
+#define        WID_IF_DEFAULT(af)      ((af) == AF_INET6 ? 8 : IFNAMSIZ-1)
 #endif /*INET6*/

 static int wid_dst;
Comment 5 Yaroslav Shvets 2016-03-19 21:00:36 UTC
Created attachment 168400 [details]
There are two patches that use IFNAMSIZ from <net/if.h> instead of fixed values

There are two patches that use IFNAMSIZ from <net/if.h> instead of fixed values
Comment 6 Yaroslav Shvets 2016-03-19 21:01:25 UTC
Created attachment 168401 [details]
There are two patches that use IFNAMSIZ from <net/if.h> instead of fixed values
Comment 7 Eitan Adler freebsd_committer freebsd_triage 2018-05-20 23:52:09 UTC
For bugs matching the following conditions:
- Status == In Progress
- Assignee == "bugs@FreeBSD.org"
- Last Modified Year <= 2017

Do
- Set Status to "Open"
Comment 8 Graham Perrin freebsd_committer freebsd_triage 2022-10-17 12:39:17 UTC
Keyword: 

    patch
or  patch-ready

– in lieu of summary line prefix: 

    [patch]

* bulk change for the keyword
* summary lines may be edited manually (not in bulk). 

Keyword descriptions and search interface: 

    <https://bugs.freebsd.org/bugzilla/describekeywords.cgi>