#!/usr/bin/perl -w

use Time::HiRes qw(time);
use strict;

sub rateformat($$);

my $ifconfig = '/sbin/ifconfig';

my $update = 2;

my $t0 = 0;
my ($t1, $out1, $out2, $RxBytes, $RxDropped, $Tx, $dev, $IP, $mtu, $type);

my %saved = ();

while (1) {

  $out1 = $out2 = `$ifconfig`;

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

  my $first = 1;
  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;
      $RxDropped = $7;
      $RxBytes = $16;
      $Tx = $17;
    } elsif ($out2 =~ /^(\S+):\s+flags=\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+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 Rx bytes
                        \s+RX\serrors\s\d+\s+dropped\s(\d+)\s+overruns\s\d+\s+frame\s\d+ # $7 Rx dropped
                        \s+TX\spackets\s\d+\s+bytes\s+(\d+)\s+\(\S+\s\S+\)  # $8 Tx 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";
      $RxBytes = $6;
      $RxDropped = $7;
      $Tx = $8;
      $IP = 'q' if (!defined $IP);
    } else {
      $ok = 0;
    }
    last if (!$ok);

    next if ($dev eq 'lo');

    if (exists $saved{$dev}) {
      if ($first) {
        print("\033[H\033[2J"); # Clear screen
	$first = 0;
      }

      print("$dev $IP $type $mtu\n");

      printf("   Rx %s   Tx %s  Dropped %d\n\n", 
	     rateformat($t1-$t0, $RxBytes-$saved{$dev}->{RxBytes}),
	     rateformat($t1-$t0, $Tx-$saved{$dev}->{Tx}), $RxDropped-$saved{$dev}->{RxDropped});
    } else {
      $saved{$dev} = {};
    }
    $saved{$dev}->{RxBytes} = $RxBytes;
    $saved{$dev}->{RxDropped} = $RxDropped;
    $saved{$dev}->{Tx} = $Tx;
}

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

}


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

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

  if ($rate<900000) {
    return sprintf "%6.2f Kbps",$rate/1000;
  } elsif ($rate<900000000) {
    return sprintf "%6.2f Mbps",$rate/1e6;
  } else {
    return sprintf "%6.2f Gbps",$rate/1e9;
  }
}
