netstat default if

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

netstat default if

Ted Unangst-2
i like to run netstat -w 1 -b to watch the bytes.  however, netstat
defaults to picking the last interface if you don't specify -I.  on my
system, that happens to be pflog.  not helpful.

the diff below makes some attempt at picking an interesting interface by
selecting the one with the most traffic.

Index: if.c
===================================================================
RCS file: /home/tedu/cvs/src/usr.bin/netstat/if.c,v
retrieving revision 1.62
diff -u -r1.62 if.c
--- if.c 22 Nov 2009 22:22:14 -0000 1.62
+++ if.c 8 Jan 2011 00:32:41 -0000
@@ -500,6 +500,7 @@
  char *buf, *next, *lim;
  char name[IFNAMSIZ];
  size_t len;
+ int takeit = 0;
 
  if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
  err(1, "sysctl");
@@ -508,6 +509,7 @@
  if (sysctl(mib, 6, buf, &len, NULL, 0) == -1)
  err(1, "sysctl");
 
+ memset(&ip_cur, 0, sizeof(ip_cur));
  lim = buf + len;
  for (next = buf; next < lim; next += rtm->rtm_msglen) {
  rtm = (struct rt_msghdr *)next;
@@ -531,6 +533,14 @@
  memcpy(name, sdl->sdl_data, sdl->sdl_nlen);
 
  if (interface != NULL && !strcmp(name, interface)) {
+ takeit = 1;
+ } else if (interface == NULL &&
+    ifd->ifi_ibytes + ifd->ifi_obytes >=
+    ip_cur.ift_ib + ip_cur.ift_ob) {
+ takeit = 1;
+ } else
+ takeit = 0;
+ if (takeit) {
  strlcpy(ip_cur.ift_name, name,
     sizeof(ip_cur.ift_name));
  ip_cur.ift_ip = ifd->ifi_ipackets;
@@ -554,19 +564,6 @@
  sum_cur.ift_dr += 0; /* XXX ifnet.if_snd.ifq_drops */
  break;
  }
- }
- if (interface == NULL) {
- strlcpy(ip_cur.ift_name, name,
-    sizeof(ip_cur.ift_name));
- ip_cur.ift_ip = ifd->ifi_ipackets;
- ip_cur.ift_ib = ifd->ifi_ibytes;
- ip_cur.ift_ie = ifd->ifi_ierrors;
- ip_cur.ift_op = ifd->ifi_opackets;
- ip_cur.ift_ob = ifd->ifi_obytes;
- ip_cur.ift_oe = ifd->ifi_oerrors;
- ip_cur.ift_co = ifd->ifi_collisions;
- ip_cur.ift_dr = 0;
-    /* XXX ifnet.if_snd.ifq_drops */
  }
  free(buf);
 }

Reply | Threaded
Open this post in threaded view
|

Re: netstat default if

Nicholas Marriott-2
Hi

Nice idea, but maybe it could pick the same one that the interface group
"egress" defaults to?


On Fri, Jan 07, 2011 at 07:36:08PM -0500, Ted Unangst wrote:

> i like to run netstat -w 1 -b to watch the bytes.  however, netstat
> defaults to picking the last interface if you don't specify -I.  on my
> system, that happens to be pflog.  not helpful.
>
> the diff below makes some attempt at picking an interesting interface by
> selecting the one with the most traffic.
>
> Index: if.c
> ===================================================================
> RCS file: /home/tedu/cvs/src/usr.bin/netstat/if.c,v
> retrieving revision 1.62
> diff -u -r1.62 if.c
> --- if.c 22 Nov 2009 22:22:14 -0000 1.62
> +++ if.c 8 Jan 2011 00:32:41 -0000
> @@ -500,6 +500,7 @@
>   char *buf, *next, *lim;
>   char name[IFNAMSIZ];
>   size_t len;
> + int takeit = 0;
>  
>   if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
>   err(1, "sysctl");
> @@ -508,6 +509,7 @@
>   if (sysctl(mib, 6, buf, &len, NULL, 0) == -1)
>   err(1, "sysctl");
>  
> + memset(&ip_cur, 0, sizeof(ip_cur));
>   lim = buf + len;
>   for (next = buf; next < lim; next += rtm->rtm_msglen) {
>   rtm = (struct rt_msghdr *)next;
> @@ -531,6 +533,14 @@
>   memcpy(name, sdl->sdl_data, sdl->sdl_nlen);
>  
>   if (interface != NULL && !strcmp(name, interface)) {
> + takeit = 1;
> + } else if (interface == NULL &&
> +    ifd->ifi_ibytes + ifd->ifi_obytes >=
> +    ip_cur.ift_ib + ip_cur.ift_ob) {
> + takeit = 1;
> + } else
> + takeit = 0;
> + if (takeit) {
>   strlcpy(ip_cur.ift_name, name,
>      sizeof(ip_cur.ift_name));
>   ip_cur.ift_ip = ifd->ifi_ipackets;
> @@ -554,19 +564,6 @@
>   sum_cur.ift_dr += 0; /* XXX ifnet.if_snd.ifq_drops */
>   break;
>   }
> - }
> - if (interface == NULL) {
> - strlcpy(ip_cur.ift_name, name,
> -    sizeof(ip_cur.ift_name));
> - ip_cur.ift_ip = ifd->ifi_ipackets;
> - ip_cur.ift_ib = ifd->ifi_ibytes;
> - ip_cur.ift_ie = ifd->ifi_ierrors;
> - ip_cur.ift_op = ifd->ifi_opackets;
> - ip_cur.ift_ob = ifd->ifi_obytes;
> - ip_cur.ift_oe = ifd->ifi_oerrors;
> - ip_cur.ift_co = ifd->ifi_collisions;
> - ip_cur.ift_dr = 0;
> -    /* XXX ifnet.if_snd.ifq_drops */
>   }
>   free(buf);
>  }

Reply | Threaded
Open this post in threaded view
|

Re: netstat default if

Theo de Raadt
> Nice idea, but maybe it could pick the same one that the interface group
> "egress" defaults to?

Ooooh, that is even better than what I suggested to tedu.

Right on the money, that is exactly what I would like it to default to!

Reply | Threaded
Open this post in threaded view
|

Re: netstat default if

Ted Unangst-2
In reply to this post by Nicholas Marriott-2
On Sat, 8 Jan 2011, Nicholas Marriott wrote:

> Nice idea, but maybe it could pick the same one that the interface group
> "egress" defaults to?

You're lucky that gives me the same answer. :)

Index: if.c
===================================================================
RCS file: /home/tedu/cvs/src/usr.bin/netstat/if.c,v
retrieving revision 1.62
diff -u -r1.62 if.c
--- if.c 22 Nov 2009 22:22:14 -0000 1.62
+++ if.c 8 Jan 2011 02:34:33 -0000
@@ -32,6 +32,7 @@
 
 #include <sys/param.h>
 #include <sys/types.h>
+#include <sys/ioctl.h>
 #include <sys/protosw.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
@@ -488,6 +489,46 @@
  }
 }
 
+
+static int
+isegress(char *name)
+{
+ static int s = -1;
+ int len;
+ struct ifgroupreq ifgr;
+ struct ifg_req *ifg;
+ int rv = 0;
+
+ if (s == -1) {
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ return 0;
+ }
+
+ memset(&ifgr, 0, sizeof(ifgr));
+ strlcpy(ifgr.ifgr_name, name, IFNAMSIZ);
+
+ if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) {
+ return 0;
+ }
+
+ len = ifgr.ifgr_len;
+ ifgr.ifgr_groups = calloc(len, 1);
+ if (ifgr.ifgr_groups == NULL)
+ err(1, "getifgroups");
+ if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
+ err(1, "SIOCGIFGROUP");
+
+ ifg = ifgr.ifgr_groups;
+ for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
+ len -= sizeof(struct ifg_req);
+ if (strcmp(ifg->ifgrq_group, "egress") == 0)
+ rv = 1;
+ }
+
+ free(ifgr.ifgr_groups);
+ return rv;
+}
+
 static void
 fetchifs(void)
 {
@@ -500,6 +541,8 @@
  char *buf, *next, *lim;
  char name[IFNAMSIZ];
  size_t len;
+ int takeit = 0;
+ int foundone = 0;
 
  if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
  err(1, "sysctl");
@@ -508,6 +551,7 @@
  if (sysctl(mib, 6, buf, &len, NULL, 0) == -1)
  err(1, "sysctl");
 
+ memset(&ip_cur, 0, sizeof(ip_cur));
  lim = buf + len;
  for (next = buf; next < lim; next += rtm->rtm_msglen) {
  rtm = (struct rt_msghdr *)next;
@@ -531,6 +575,14 @@
  memcpy(name, sdl->sdl_data, sdl->sdl_nlen);
 
  if (interface != NULL && !strcmp(name, interface)) {
+ takeit = 1;
+ } else if (interface == NULL && foundone == 0 &&
+    isegress(name)) {
+ takeit = 1;
+ foundone = 1;
+ } else
+ takeit = 0;
+ if (takeit) {
  strlcpy(ip_cur.ift_name, name,
     sizeof(ip_cur.ift_name));
  ip_cur.ift_ip = ifd->ifi_ipackets;
@@ -555,7 +607,7 @@
  break;
  }
  }
- if (interface == NULL) {
+ if (interface == NULL && foundone == 0) {
  strlcpy(ip_cur.ift_name, name,
     sizeof(ip_cur.ift_name));
  ip_cur.ift_ip = ifd->ifi_ipackets;

Reply | Threaded
Open this post in threaded view
|

Re: netstat default if

Christian Weisgerber
In reply to this post by Nicholas Marriott-2
Nicholas Marriott <[hidden email]> wrote:

> Nice idea, but maybe it could pick the same one that the interface group
> "egress" defaults to?

You can have more than one interface in group egress.

--
Christian "naddy" Weisgerber                          [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: netstat default if

Bob Beck-4
>> Nice idea, but maybe it could pick the same one that the interface group
>> "egress" defaults to?
>
> You can have more than one interface in group egress.

Perhaps the one in egress with the most traffic?

Reply | Threaded
Open this post in threaded view
|

Re: netstat default if

Theo de Raadt
> >> Nice idea, but maybe it could pick the same one that the interface group
> >> "egress" defaults to?
> >
> > You can have more than one interface in group egress.
>
> Perhaps the one in egress with the most traffic?

First egress will be fine.

The semantic of "most" is troubling; run it two times and it is watching a
different interface.  Who wants that?

Reply | Threaded
Open this post in threaded view
|

Re: netstat default if

Henning Brauer-5
In reply to this post by Bob Beck-4
* Bob Beck <[hidden email]> [2011-01-08 18:10]:
> >> Nice idea, but maybe it could pick the same one that the interface group
> >> "egress" defaults to?
> >
> > You can have more than one interface in group egress.

but that is rather the exception.

> Perhaps the one in egress with the most traffic?

so i get a different interface the next time i run it?

seriously, the first is fine and covers almost all cases. don't
overengineer.

--
Henning Brauer, [hidden email], [hidden email]
BS Web Services, http://bsws.de
Full-Service ISP - Secure Hosting, Mail and DNS Services
Dedicated Servers, Rootservers, Application Hosting

Reply | Threaded
Open this post in threaded view
|

Re: netstat default if

Nicholas Marriott-2
In reply to this post by Ted Unangst-2
Maybe want to use IFG_EGRESS instead of "egress" but otherwise reads
fine and works great, ok nicm.



On Fri, Jan 07, 2011 at 09:36:23PM -0500, Ted Unangst wrote:

> On Sat, 8 Jan 2011, Nicholas Marriott wrote:
>
> > Nice idea, but maybe it could pick the same one that the interface group
> > "egress" defaults to?
>
> You're lucky that gives me the same answer. :)
>
> Index: if.c
> ===================================================================
> RCS file: /home/tedu/cvs/src/usr.bin/netstat/if.c,v
> retrieving revision 1.62
> diff -u -r1.62 if.c
> --- if.c 22 Nov 2009 22:22:14 -0000 1.62
> +++ if.c 8 Jan 2011 02:34:33 -0000
> @@ -32,6 +32,7 @@
>  
>  #include <sys/param.h>
>  #include <sys/types.h>
> +#include <sys/ioctl.h>
>  #include <sys/protosw.h>
>  #include <sys/socket.h>
>  #include <sys/sysctl.h>
> @@ -488,6 +489,46 @@
>   }
>  }
>  
> +
> +static int
> +isegress(char *name)
> +{
> + static int s = -1;
> + int len;
> + struct ifgroupreq ifgr;
> + struct ifg_req *ifg;
> + int rv = 0;
> +
> + if (s == -1) {
> + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
> + return 0;
> + }
> +
> + memset(&ifgr, 0, sizeof(ifgr));
> + strlcpy(ifgr.ifgr_name, name, IFNAMSIZ);
> +
> + if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) {
> + return 0;
> + }
> +
> + len = ifgr.ifgr_len;
> + ifgr.ifgr_groups = calloc(len, 1);
> + if (ifgr.ifgr_groups == NULL)
> + err(1, "getifgroups");
> + if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
> + err(1, "SIOCGIFGROUP");
> +
> + ifg = ifgr.ifgr_groups;
> + for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
> + len -= sizeof(struct ifg_req);
> + if (strcmp(ifg->ifgrq_group, "egress") == 0)
> + rv = 1;
> + }
> +
> + free(ifgr.ifgr_groups);
> + return rv;
> +}
> +
>  static void
>  fetchifs(void)
>  {
> @@ -500,6 +541,8 @@
>   char *buf, *next, *lim;
>   char name[IFNAMSIZ];
>   size_t len;
> + int takeit = 0;
> + int foundone = 0;
>  
>   if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
>   err(1, "sysctl");
> @@ -508,6 +551,7 @@
>   if (sysctl(mib, 6, buf, &len, NULL, 0) == -1)
>   err(1, "sysctl");
>  
> + memset(&ip_cur, 0, sizeof(ip_cur));
>   lim = buf + len;
>   for (next = buf; next < lim; next += rtm->rtm_msglen) {
>   rtm = (struct rt_msghdr *)next;
> @@ -531,6 +575,14 @@
>   memcpy(name, sdl->sdl_data, sdl->sdl_nlen);
>  
>   if (interface != NULL && !strcmp(name, interface)) {
> + takeit = 1;
> + } else if (interface == NULL && foundone == 0 &&
> +    isegress(name)) {
> + takeit = 1;
> + foundone = 1;
> + } else
> + takeit = 0;
> + if (takeit) {
>   strlcpy(ip_cur.ift_name, name,
>      sizeof(ip_cur.ift_name));
>   ip_cur.ift_ip = ifd->ifi_ipackets;
> @@ -555,7 +607,7 @@
>   break;
>   }
>   }
> - if (interface == NULL) {
> + if (interface == NULL && foundone == 0) {
>   strlcpy(ip_cur.ift_name, name,
>      sizeof(ip_cur.ift_name));
>   ip_cur.ift_ip = ifd->ifi_ipackets;