Author: melifaro
Date: Wed Feb 20 13:47:05 2013
New Revision: 247036
URL: http://svnweb.freebsd.org/changeset/base/247036

Log:
  Add interface name filtering via 'match' cmd.
  Add 'pps' cmd for switching beetween interface packets/bytes statistics.
  
  Submitted by: vsevolod
  MFC after:    2 weeks

Modified:
  head/usr.bin/systat/ifcmds.c
  head/usr.bin/systat/ifstat.c
  head/usr.bin/systat/systat.1

Modified: head/usr.bin/systat/ifcmds.c
==============================================================================
--- head/usr.bin/systat/ifcmds.c        Wed Feb 20 12:59:21 2013        
(r247035)
+++ head/usr.bin/systat/ifcmds.c        Wed Feb 20 13:47:05 2013        
(r247036)
@@ -28,11 +28,19 @@
  * $FreeBSD$
  */
 
+#include <sys/types.h>
+
 #include "systat.h"
 #include "extern.h"
 #include "convtbl.h"
 
+#include <stdlib.h>
+#include <string.h>
+
 int curscale = SC_AUTO;
+char *matchline = NULL;
+int showpps = 0;
+int needsort = 0;
 
 int
 ifcmd(const char *cmd, const char *args)
@@ -48,6 +56,24 @@ ifcmd(const char *cmd, const char *args)
                        addstr("what scale? ");
                        addstr(get_helplist());
                }
-       }
+       } else if (prefix(cmd, "match")) {
+               if (args != NULL && *args != '\0' && memcmp(args, "*", 2) != 0) 
{
+                       /* We got a valid match line */
+                       if (matchline != NULL) {
+                               free(matchline);
+                       }
+                       needsort = 1;
+                       matchline = strdup(args);
+               } else {
+                       /* Empty or * pattern, turn filtering off */
+                       if (matchline != NULL) {
+                               free(matchline);
+                       }
+                       needsort = 1;
+                       matchline = NULL;
+               }
+       } else if (prefix(cmd, "pps"))
+               showpps = !showpps;
+
        return (1);
 }

Modified: head/usr.bin/systat/ifstat.c
==============================================================================
--- head/usr.bin/systat/ifstat.c        Wed Feb 20 12:59:21 2013        
(r247035)
+++ head/usr.bin/systat/ifstat.c        Wed Feb 20 13:47:05 2013        
(r247036)
@@ -38,6 +38,7 @@
 #include <string.h>
 #include <err.h>
 #include <errno.h>
+#include <fnmatch.h>
 
 #include "systat.h"
 #include "extern.h"
@@ -71,12 +72,22 @@ struct if_stat {
        u_long  if_out_curtraffic;
        u_long  if_in_traffic_peak;
        u_long  if_out_traffic_peak;
+       u_long  if_in_curpps;
+       u_long  if_out_curpps;
+       u_long  if_in_pps_peak;
+       u_long  if_out_pps_peak;
        u_int   if_row;                 /* Index into ifmib sysctl */
        u_int   if_ypos;                /* 0 if not being displayed */
        u_int   display;
+       u_int   match;
 };
 
-extern  u_int curscale;
+extern  int curscale;
+extern  char *matchline;
+extern  int showpps;
+extern  int needsort;
+
+static  int needclear = 0;
 
 static  void  right_align_string(struct if_stat *);
 static  void  getifmibdata(const int, struct ifmibdata *);
@@ -96,34 +107,48 @@ static      u_int getifnum(void);
 #define STARTING_ROW   (TOPLINE + 1)
 #define ROW_SPACING    (3)
 
-#define CLEAR_LINE(y, x)       do {                                    \
-       wmove(wnd, y, x);                                               \
-       wclrtoeol(wnd);                                                 \
-} while (0)
-
-#define IN_col2                (ifp->if_in_curtraffic)
-#define OUT_col2       (ifp->if_out_curtraffic)
-#define IN_col3                (ifp->if_in_traffic_peak)
-#define OUT_col3       (ifp->if_out_traffic_peak)
-#define IN_col4                (ifp->if_mib.ifmd_data.ifi_ibytes)
-#define OUT_col4       (ifp->if_mib.ifmd_data.ifi_obytes)
+#define IN_col2                (showpps ? ifp->if_in_curpps : 
ifp->if_in_curtraffic)
+#define OUT_col2       (showpps ? ifp->if_out_curpps : ifp->if_out_curtraffic)
+#define IN_col3                (showpps ? \
+               ifp->if_in_pps_peak : ifp->if_in_traffic_peak)
+#define OUT_col3       (showpps ? \
+               ifp->if_out_pps_peak : ifp->if_out_traffic_peak)
+#define IN_col4                (showpps ? \
+       ifp->if_mib.ifmd_data.ifi_ipackets : ifp->if_mib.ifmd_data.ifi_ibytes)
+#define OUT_col4       (showpps ? \
+       ifp->if_mib.ifmd_data.ifi_opackets : ifp->if_mib.ifmd_data.ifi_obytes)
 
 #define EMPTY_COLUMN   "                    "
 #define CLEAR_COLUMN(y, x)     mvprintw((y), (x), "%20s", EMPTY_COLUMN);
 
 #define DOPUTRATE(c, r, d)     do {                                    \
        CLEAR_COLUMN(r, c);                                             \
-       mvprintw(r, (c), "%10.3f %s%s  ",                               \
-                convert(d##_##c, curscale),                            \
-                get_string(d##_##c, curscale),                         \
-                "/s");                                                 \
+       if (showpps) {                                                  \
+               mvprintw(r, (c), "%10.3f %cp%s  ",                      \
+                        convert(d##_##c, curscale),                    \
+                        *get_string(d##_##c, curscale),                \
+                        "/s");                                         \
+       }                                                               \
+       else {                                                          \
+               mvprintw(r, (c), "%10.3f %s%s  ",                       \
+                        convert(d##_##c, curscale),                    \
+                        get_string(d##_##c, curscale),                 \
+                        "/s");                                         \
+       }                                                               \
 } while (0)
 
 #define DOPUTTOTAL(c, r, d)    do {                                    \
        CLEAR_COLUMN((r), (c));                                         \
-       mvprintw((r), (c), "%12.3f %s  ",                               \
-                convert(d##_##c, SC_AUTO),                             \
-                get_string(d##_##c, SC_AUTO));                         \
+       if (showpps) {                                                  \
+               mvprintw((r), (c), "%12.3f %cp  ",                      \
+                        convert(d##_##c, SC_AUTO),                     \
+                        *get_string(d##_##c, SC_AUTO));                \
+       }                                                               \
+       else {                                                          \
+               mvprintw((r), (c), "%12.3f %s  ",                       \
+                        convert(d##_##c, SC_AUTO),                     \
+                        get_string(d##_##c, SC_AUTO));                 \
+       }                                                               \
 } while (0)
 
 #define PUTRATE(c, r)  do {                                            \
@@ -183,8 +208,10 @@ void
 showifstat(void)
 {
        struct  if_stat *ifp = NULL;
+       
        SLIST_FOREACH(ifp, &curlist, link) {
-               if (ifp->display == 0)
+               if (ifp->display == 0 || (ifp->match == 0) ||
+                       ifp->if_ypos > LINES - 3 - 1)
                        continue;
                PUTNAME(ifp);
                PUTRATE(col2, ifp->if_ypos);
@@ -215,6 +242,7 @@ initifstat(void)
                p->if_row = i+1;
                getifmibdata(p->if_row, &p->if_mib);
                right_align_string(p);
+               p->match = 1;
 
                /*
                 * Initially, we only display interfaces that have
@@ -236,7 +264,7 @@ fetchifstat(void)
        struct  timeval tv, new_tv, old_tv;
        double  elapsed = 0.0;
        u_int   new_inb, new_outb, old_inb, old_outb = 0;
-       u_int   we_need_to_sort_interface_list = 0;
+       u_int   new_inp, new_outp, old_inp, old_outp = 0;
 
        SLIST_FOREACH(ifp, &curlist, link) {
                /*
@@ -245,6 +273,8 @@ fetchifstat(void)
                 */
                old_inb = ifp->if_mib.ifmd_data.ifi_ibytes;
                old_outb = ifp->if_mib.ifmd_data.ifi_obytes;
+               old_inp = ifp->if_mib.ifmd_data.ifi_ipackets;
+               old_outp = ifp->if_mib.ifmd_data.ifi_opackets;
                ifp->tv_lastchanged = ifp->if_mib.ifmd_data.ifi_lastchange;
 
                (void)gettimeofday(&new_tv, NULL);
@@ -252,11 +282,13 @@ fetchifstat(void)
 
                new_inb = ifp->if_mib.ifmd_data.ifi_ibytes;
                new_outb = ifp->if_mib.ifmd_data.ifi_obytes;
+               new_inp = ifp->if_mib.ifmd_data.ifi_ipackets;
+               new_outp = ifp->if_mib.ifmd_data.ifi_opackets;
 
                /* Display interface if it's received some traffic. */
                if (new_inb > 0 && old_inb == 0) {
                        ifp->display = 1;
-                       we_need_to_sort_interface_list++;
+                       needsort = 1;
                }
 
                /*
@@ -271,6 +303,9 @@ fetchifstat(void)
                ifp->if_in_curtraffic = new_inb - old_inb;
                ifp->if_out_curtraffic = new_outb - old_outb;
 
+               ifp->if_in_curpps = new_inp - old_inp;
+               ifp->if_out_curpps = new_outp - old_outp;
+
                /*
                 * Rather than divide by the time specified on the comm-
                 * and line, we divide by ``elapsed'' as this is likely
@@ -278,6 +313,8 @@ fetchifstat(void)
                 */
                ifp->if_in_curtraffic /= elapsed;
                ifp->if_out_curtraffic /= elapsed;
+               ifp->if_in_curpps /= elapsed;
+               ifp->if_out_curpps /= elapsed;
 
                if (ifp->if_in_curtraffic > ifp->if_in_traffic_peak)
                        ifp->if_in_traffic_peak = ifp->if_in_curtraffic;
@@ -285,12 +322,18 @@ fetchifstat(void)
                if (ifp->if_out_curtraffic > ifp->if_out_traffic_peak)
                        ifp->if_out_traffic_peak = ifp->if_out_curtraffic;
 
+               if (ifp->if_in_curpps > ifp->if_in_pps_peak)
+                       ifp->if_in_pps_peak = ifp->if_in_curpps;
+
+               if (ifp->if_out_curpps > ifp->if_out_pps_peak)
+                       ifp->if_out_pps_peak = ifp->if_out_curpps;
+
                ifp->tv.tv_sec = new_tv.tv_sec;
                ifp->tv.tv_usec = new_tv.tv_usec;
 
        }
 
-       if (we_need_to_sort_interface_list)
+       if (needsort)
                sort_interface_list();
 
        return;
@@ -323,6 +366,40 @@ right_align_string(struct if_stat *ifp)
        return;
 }
 
+static int
+check_match(const char *ifname) 
+{
+       char *p = matchline, *c, t;
+       int match = 0, mlen;
+       
+       if (matchline == NULL) {
+               return 0;
+       }
+       /* Strip leading whitespaces */
+       while (*p == ' ')
+               p ++;
+
+       c = p;
+       while ((mlen = strcspn(c, " ;,")) != 0) {
+               p = c + mlen;
+               t = *p;
+               if (p - c > 0) {
+                       *p = '\0';
+                       if (fnmatch(c, ifname, FNM_CASEFOLD) == 0) {
+                               *p = t;
+                               return 1;
+                       }
+                       *p = t;
+                       c = p + strspn(p, " ;,");
+               }
+               else {
+                       c = p + strspn(p, " ;,");
+               }
+       }
+
+       return match;
+}
+
 /*
  * This function iterates through our list of interfaces, identifying
  * those that are to be displayed (ifp->display = 1).  For each interf-
@@ -340,11 +417,18 @@ sort_interface_list(void)
 
        y = STARTING_ROW;
        SLIST_FOREACH(ifp, &curlist, link) {
-               if (ifp->display) {
+               if (matchline && !check_match(ifp->if_mib.ifmd_name))
+                       ifp->match = 0;
+               else
+                       ifp->match = 1;
+               if (ifp->display && ifp->match) {
                        ifp->if_ypos = y;
                        y += ROW_SPACING;
                }
        }
+       
+       needsort = 0;
+       needclear = 1;
 }
 
 static
@@ -394,6 +478,11 @@ cmdifstat(const char *cmd, const char *a
        if (retval == 1) {
                showifstat();
                refresh();
+               if (needclear) {
+                       werase(wnd);
+                       labelifstat();
+                       needclear = 0;
+               }
        }
 
        return retval;

Modified: head/usr.bin/systat/systat.1
==============================================================================
--- head/usr.bin/systat/systat.1        Wed Feb 20 12:59:21 2013        
(r247035)
+++ head/usr.bin/systat/systat.1        Wed Feb 20 13:47:05 2013        
(r247036)
@@ -511,6 +511,28 @@ Modify the scale used to display the cur
 interfaces.
 The following units are recognised: kbit, kbyte, mbit,
 mbyte, gbit, gbyte and auto.
+.It Cm pps
+Show statistics in packets per second instead of bytes/bits per second.
+A subsequent call of 
+.Ic pps 
+switches this mode off.
+.It Cm match Op Ar patterns
+Display only interfaces that match pattern provided as an argument. 
+Patterns should be in shell syntax separated by whitespaces or commas. 
+If this command is called without arguments then all interfaces are displayed.
+For example:
+.Pp
+.Dl match em0, bge1
+.Pp
+This will display em0 and bge1 interfaces.
+.Pp
+.Dl match em*, bge*, lo0
+.Pp
+This will display all 
+.Ic em 
+interfaces, all
+.Ic bge
+interfaces and the loopback interface.
 .El
 .El
 .Pp
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to