#!/usr/bin/perl -w

use Time::HiRes qw(time);
use POSIX qw(strftime);


use strict;

sub rateformat($$$);

my $ifconfig = '/sbin/ifconfig';

my $update = 2;

my $t0 = 0;
my ($t1, $out1, $out2, $RxBytes, $RxDropped, $TxBytes, $dev, $IP, $mtu, $type, $RxPackets, $TxPackets);
my ($utTime);

my %saved = ();

my $rateType = 'Mbps';

print("                                  Rx            Tx           Rx    Tx  Dropped\n");

while (1) {

  $out1 = $out2 = `$ifconfig`;

  die "$ifconfig failed: $!\n" if (!defined $out1);
  $t1 = time();

  my $ok = 1;
  while ($ok) {
    if ($out1 =~ /^(\S+)\s+              # $1 interface
		 Link\sencap:(.*)$       # $2 Link type
		 \s+inet\saddr:(\S+).*$  # $3 IP4 address
		 (?:\s+inet6\saddr:.*$)? # IP6 address
		 (?:\s+inet6.*$)? # IP6 address
		 (?:\s+inet6.*$)? # IP6 address
		 \s+.*MTU:(\d+).*$       # $4 MTU
		 \s+RX\spackets:(\d+)\s+errors:(\d+)\sdropped:(\d+)
		 \s+overruns:(\d+)\s+frame:(\d+)\s*$ # $5-$9
		 \s+TX\spackets:(\d+)\s+errors:(\d+)\s+dropped:(\d+)
		 \s+overruns:(\d+)\s+carrier:(\d+)\s*$ # $10-$14
		 \s+collisions:(\d+)\s+txqueuelen:\d+\s*$ # $15 collisions
		 \s+RX\s+bytes:(\d+).*TX\sbytes:(\d+).* # $16,$17 RX, TX bytes
		/gmx) {

      $dev = $1;
      $type = $2;
      $IP = $3;
      $mtu = $4;
      $RxPackets = $5;
      $RxDropped = $7;
      $TxPackets = $10;
      $RxBytes = $16;
      $TxBytes = $17;
    } elsif ($out2 =~ /^(\S+):\sflags=\d+\<.*\>\s+mtu\s(\d+)                 # $1 interface, $2 MTU
                        \s+inet\s(\S+)\s+netmask\s\S+\s+broadcast\s\S+       # $3 IP4 address
                        (?:\s+inet6\s\S+\s+prefixlen\s+\S+\s+scopeid\s+\S+)? # 
                        \s+ether\s(\S+)\s+txqueuelen\s\d+\s+\((\S+)\)        # $4 MAC, $5 type
                        \s+RX\spackets\s(\d+)\s+bytes\s(\S+)\s+\(\S+\s\S+\)  # $6, $7 Rx packets, bytes
                        \s+RX\serrors\s\d+\s+dropped\s(\d+)\s+overruns\s\d+\s+frame\s\d+ # $8 Rx dropped
                        \s+TX\spackets\s(\d+)\s+bytes\s+(\d+)\s+\(\S+\s\S+B\)  # $9, $10 Tx packets, bytes
                        \s+TX\serrors\s\d+\s+dropped\s\d+\s+overruns\s\d+\s+carrier\s\d+\s+collisions\s\d+
		      /gmx) {
      $dev = $1;
      $mtu = $2;
      $IP = $3;
      $type = "$5  HWaddr $4";
      $RxPackets = $6;
      $RxBytes = $7;
      $RxDropped = $8;
      $TxPackets = $9;
      $TxBytes = $10;
    } else {
      $ok = 0;
    }
    last if (!$ok);

    next if ($dev eq 'lo');

    if (exists $saved{$dev}) {
      $utTime = strftime "%j/%Y %H:%M:%S %Y", gmtime;

      printf("$utTime $dev  %s   %s  %6d %6d %5d\n", 
	     rateformat($t1-$t0, $RxBytes-$saved{$dev}->{RxBytes}, $rateType),
	     rateformat($t1-$t0, $TxBytes-$saved{$dev}->{TxBytes}, $rateType), $RxPackets-$saved{$dev}->{RxPackets}, $TxPackets-$saved{$dev}->{TxPackets}, $RxDropped-$saved{$dev}->{RxDropped});
    } else {
      $saved{$dev} = {};
    }
    $saved{$dev}->{RxPackets} = $RxPackets;
    $saved{$dev}->{RxBytes} = $RxBytes;
    $saved{$dev}->{RxDropped} = $RxDropped;
    $saved{$dev}->{TxPackets} = $TxPackets;
    $saved{$dev}->{TxBytes} = $TxBytes;
}

  $t0 = $t1;
  sleep($update);

}


sub rateformat($$$) {
  my ($time, $bytes, $rateType) = @_;

  my $rate = $bytes/$time*8;

  if ($rateType eq 'Mbps') {
    return sprintf "%7.2f Mbps",$rate/1e6;
  } elsif ($rateType eq 'Gbps') {
    return sprintf "%6.2f Gbps",$rate/1e9;
  } else {
    return sprintf "%7.2f Kbps",$rate/1e3;
  }
}
