#!/usr/bin/perl -w

use strict;

sub ifconfig2list()
{
    my(@configList) = `/sbin/ifconfig`;
    return(@configList);
}

sub newInterface(\%$)
{
    %{$_[0]} = (); 
    %{$_[0]} =  
      (
	  "a_bcast"      => "",
	  "a_inet"       => "",
	  "a_mask"       => "",
	  "hw_addr"      => "",
	  "hw_irq"       => "",
	  "i_mac"        => "",
	  "i_name"       => $_[1],
	  "i_type"       => "",
	  "n_collide"    => "",
	  "n_txqlen"     => "",
	  "rx_bytes"     => "",
	  "rx_drop"      => "",
	  "rx_errs"      => "",
	  "rx_frame"     => "",
	  "rx_overrun"   => "",
	  "rx_packets"   => "",
	  "tx_carrier"   => "",
	  "tx_bytes"     => "",
	  "tx_drop"      => "",
	  "tx_errs"      => "",
	  "tx_overrun"   => "",
	  "tx_packets"   => ""
      );
} 

sub isValidField(\%$)
{
    return(defined(${$_[0]}{$_[1]}))
}

sub setField(\%$$)
{
    isValidField(%{$_[0]}, $_[1]) or
      die "\n\nInternal programming error, illegal field name >$_[1]<\n";
    ${$_[0]}{$_[1]} = $_[2]; 
}

sub parseIfconfig(\@)
{
    my ($arrayPtr) = $_[0];
    my(@ifconfigMemoryImage) = (@ {$arrayPtr});
    
    my($state) = "init";
    my(%allInterfaces);
    
    my(%interface);
    my($ifconfigLine);
    foreach $ifconfigLine (@ifconfigMemoryImage)
    {
	if($ifconfigLine =~ /^\s*$/) {next;}; #Blow off blank lines
	  chomp($ifconfigLine);
	$ifconfigLine =~ s/\s+$//;              #Delete trailing blanks
	  if($ifconfigLine =~ /^(\S+)/)            #if new interface 
	{
	    my($newName) = $1;
	    if($state ne "init")
	    {
		### RECORD PRIOR INTERFACE IN %allInterfaces ###
		$allInterfaces{$interface{"i_name"}} = {%interface};
	    }
	    newInterface(%interface, $newName); 
	    newInterface(%interface, $newName); 
	    if($ifconfigLine =~ /Link encap:(.+)\s+HWaddr\s+(\S+)/)
	    {
		setField(%interface, "i_type", $1);
		setField(%interface, "i_mac", $2);
	    }
	    elsif($ifconfigLine =~ /Link encap:(.+)/)
	    {
		$interface{"i_type"} = $1;
		setField(%interface, "i_type", $1);
	    }
	    $state = "finishedfirstline";
	}
	elsif($ifconfigLine =~ /^\s+inet addr:(\S+)/)
	{
	    $interface{"a_inet"} = $1;
	    setField(%interface, "a_inet", $1);
	    if($ifconfigLine =~ /Bcast:(\S+)/)
	    {setField(%interface, "a_bcast", $1);}
	    if($ifconfigLine =~ /Mask:(\S+)/)
	    {setField(%interface, "a_mask", $1);}
	    $state = "finishedinetaddr";
	}
	elsif($ifconfigLine =~ /^\s+RX packets:(\S+)/)
	{
	    $interface{"rx_packets"} = $1;
	    if($ifconfigLine =~ /\berrors:(\S+)/)
	    {setField(%interface, "rx_errs", $1);}
	    if($ifconfigLine =~ /\bdropped:(\S+)/)
	    {setField(%interface, "rx_drop", $1);}
	    if($ifconfigLine =~ /\boverruns:(\S+)/)
	    {setField(%interface, "rx_overrun", $1);}
	    if($ifconfigLine =~ /\bframe:(\S+)/)
	    {setField(%interface, "rx_frame", $1);}
	    $state = "finished_rx";
	}
	elsif($ifconfigLine =~ /^\s+TX packets:(.+?)\s+/)
	{
	    setField(%interface, "tx_packets", $1);
	    if($ifconfigLine =~ /\berrors:(\S+)/)
	    {setField(%interface, "tx_errs", $1);}
	    if($ifconfigLine =~ /\bdropped:(\S+)/)
	    {setField(%interface, "tx_drop", $1);}
	    if($ifconfigLine =~ /\boverruns:(\S+)/)
	    {setField(%interface, "tx_overrun", $1);}
	    if($ifconfigLine =~ /\bcarrier:(\S+)/)
	    {setField(%interface, "tx_carrier", $1);}
	    $state = "finished_tx";
	}
	elsif($ifconfigLine =~ /^\s+Metric:(.+?)\b/)
	{
	    setField(%interface, "z_metric", $1);
	    if($ifconfigLine =~ /^\bMTU:(.+?)\b/)
	    {setField(%interface, "z_mtu", $1);}
	    ## "UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1" unimplemented
	    $state = "finished_state";
	}
	else
	{
	    if($ifconfigLine =~ /\bcollisions:(\S+)/)
	    {setField(%interface, "n_collide", $1);}
	    if($ifconfigLine =~ /\btxqueuelen:(\S+)/)
	    {setField(%interface, "n_txqlen", $1);}
	    if($ifconfigLine =~ /\bInterrupt:(\S+)/)
	    {setField(%interface, "hw_irq", $1);}
	    if($ifconfigLine =~ /\bRX bytes:(\S+)/)
	    {setField(%interface, "rx_bytes", $1);}
	    if($ifconfigLine =~ /\bTX bytes:(\S+)/)
	    {setField(%interface, "tx_bytes", $1);}
	    $state = "finished_misc";
	}
    }
    ### ADD FINAL INTERFACE TO %allInterfaces ###
    $allInterfaces{$interface{"i_name"}} = {%interface};
    return(%allInterfaces);
}

sub displayOneInterface(\%$)
{
    my(%allInterfaces) = %{(shift)};
    my($interfaceName) = shift;
    my(%interface) = %{$allInterfaces{$interfaceName}}; 
    my($key,$value);
    print "\n\n[$interfaceName]======================================\n";
    foreach $key (sort(keys(%interface)))
    {
	print "$key=" . $interface{$key} . "\n";
    }
}

sub displayAll(\%)
{
    my(%allInterfaces) = %{(shift)};
    my($key,$value);
    foreach $key (sort(keys(%allInterfaces)))
    {
	displayOneInterface(%allInterfaces, $key)
    }
}

sub printRXTX(\%$)
{
    my ($theInterfacesPtr, $theInterfaceName) = @_;
    my (%theInterfaces) = (% {$theInterfacesPtr});
    my (%theInterface) = %{$theInterfaces{$theInterfaceName}};

    my $theTime = time();
    my $theRXBytes = $theInterface{"rx_bytes"};
    my $theTXBytes = $theInterface{"tx_bytes"};
    
    printf "$theTime, $theRXBytes, $theTXBytes\n";
}

sub main()
{
    my(@lines) = <STDIN>;
    my(%interfaces) = parseIfconfig(@lines);
    #displayAll(%interfaces);

    my $theNumArgs = $#ARGV + 1;
    my $theIF = "lo";

    if ($theNumArgs == 1)
    {
	$theIF = $ARGV[0];
    }
    
    printRXTX(%interfaces, $theIF);
}

main();

