packets per second tool for CLI - and question about checksum_errs

Rudy crapsh at monkeybrains.net
Wed Aug 21 05:34:49 UTC 2019


Here is a quick tool so show Packets Per Second on the CLI for all your 
interfaces (only tested with ix and igb).
It uses the output of sysctl every second.  If you like it, great!

Quick question, why am I seeing checksum_errs around 1k on a link doing 
3Gbps?

*
**Sample output of script:*

Tue Aug 20 22:28:16 2019                          00:00:01
      Dev RX bits   TX bits    RX PPS    TX PPS  CK Error
     igb0                 0         2         0
     igb1                 0         0         0
      ix0    2589 M     415 M     311 k     171 k      11
      ix1     254 M    2120 M     108 k     248 k       1 k
      ix2     171 M     508 M      62 k      63 k     385
      ix3       1 k       1 k       0         0         0
  Host: yourbox.example.com

Rudy



#!/usr/local/bin/perl
#
# pps - Packets Per Second tool like top
#
# Tue Aug 20 22:09:25 PDT 2019, MonkeyBrains.NET
#

my $SAMPLETIME = shift || 4;
my $DAMPEN = undef;  # set to 1 to make Mbps be an average

$SAMPLETIME =~ /^\d{1,4}$/ or die "Usage: $0 [delay]\n";

use Term::ANSIScreen qw/:color :cursor :screen :keyboard/;

#  footer text
my $hostname = `hostname`;
chomp($hostname);
my $footer = "Host: $hostname";

# colors in the table
my @c = ('bold white on black', 'green', 'cyan', 'bold green', 'bold 
blue', 'bold red'); # columns in table
my @c2 = ('bold yellow on black', 'black on yellow', 'black on yellow'); 
# header and footer

my @w = (8);  # width for columns (decided on 10 for all but first...)
my $totalWidth = $w[0] + 50;
my $width1 = $totalWidth-30;
my $width2 = $totalWidth-$w[0];

# some variables
my %info;
my %avg;  # tamper Mbps fluctations...

print cls(); #clear screen
my $s = 0;  # number of sysctl runs
while (1) {
     open STATS, "sysctl dev | " or die;
     my %sum;
     while (<STATS>) {
         my ($dev,$p1,$p2,$v,$delta);
         if (s/^dev\.([a-z]+)\.(\d+)\.//) {
             $dev = $1.$2;
         } else {
             next;
         }
         if (/^(mac_stats).good_(octets_.*): *(\d+)$/o) {
             ($p1,$p2,$v) = ($1,$2,$3*8);  # bytes * 8
             # use a rolling 'last 4 data points' average
             $delta=$v-$info{$dev}{$p1}{$p2}{'last'} if 
$info{$dev}{$p1}{$p2}{'last'};
             $info{$dev}{$p1}{$p2}{'last'}=$v;
             if ($DAMPEN) {
                 # keep a running average...
                 if ($avg{$dev}{$p2} && $delta) {
                     # add t0 average over past 2 cycles
                     $avg{$dev}{$p2} = ($delta + $avg{$dev}{$p2} * 2)/ 3;
                     $delta = $avg{$dev}{$p2} unless ($delta = 0);  # 
hard zero at 0
                 } else {
                     # first time through
                     $avg{$dev}{$p2} = 0; # init
                 }
             }
         } elsif (/^(mac_stats|queue.*)\.(.*): *(\d+)$/o) {
             ($p1,$p2,$v) = ($1,$2,$3);
             $delta=$v-$info{$dev}{$p1}{$p2}{'last'} if 
$info{$dev}{$p1}{$p2}{'last'};
             $info{$dev}{$p1}{$p2}{'last'}=$v;
         } else {
             next;
         }
         $sum{$dev}{$p2} += $delta;  # will aggregate all queues
     }
     locate 1, 1;  # move cursor to top left
     my $seconds = time-$^T;
     my $hours = int( $seconds / (60*60) );
     my $mins = ( $seconds / 60 ) % 60;
     my $secs = $seconds % 60;
     my $elapsed = sprintf("%02d:%02d:%02d", $hours,$mins,$secs);
     print colored 
[$c2[0]],sprintf("%-30s%${width1}s\n",scalar(localtime),$elapsed); # 
clear line, and return
     print colored [$c2[1]],sprintf("%$w[0]s%-${width2}s\n", "Dev"," RX 
bits   TX bits    RX PPS    TX PPS  CK Error ");
     $s++;

     foreach my $dev (sort keys %sum) {
         my $i = 0;
         print colored [$c[0]], sprintf("%$w[$i]s",$dev);
         foreach my $p2 (qw(octets_rcvd octets_txd rx_packets tx_packets 
checksum_errs)) {
             $i++;
             my $v = $sum{$dev}{$p2};
             $v /= $SAMPLETIME if $s > 2; # need two values
             $v =~ s/\..*//; # floor
             # conver to M and k for Mega and Kilo
             if ($v >  1000000) {
                 $v /= 1000000;
                 $v =~ s/\.\d+//;
                 $v .= ' M';
             } elsif ($v >  1000) {
                 $v /= 1000;
                 $v =~ s/\.\d+//;
                 $v .= ' k';
             } else {
                 $v .= '  ';  # some padding for alignment
             }
             my $width = $w[$i] || 10;
             print colored [$c[$i]],sprintf("%${width}s",$v);
         }
         print "\n";
     }
     print colored [$c2[2]],sprintf("%-${totalWidth}s\n", " $footer");
     close STATS;
     if ($s == 1) {
         sleep 1;  # only sleep 1 on startup
         next;
     }
     sleep $SAMPLETIME;
}


More information about the freebsd-net mailing list