#!/usr/bin/perl -w
#$CVERS="0.0.1 [testing]";

# load default variables
# ==========================================================
$COUNTERMAX = 5;
my $TMPFILE = "/var/tmp/pinger_$$.tmp";
my $conf = "/etc/default/pinger";
open F, $conf or exit 0;
while (<F>) {
    my $line = $_;
    chomp $line;
    my ($name, $value) = $line =~ /([A-Za-z0-9_]+)\s*=(.*)$/;
    next if not defined $name or not defined $value;
    $value =~ s/^\s*\"?(.*?)\"?\s*$/$1/;
    $$name = $value;
}
close F;
# ==========================================================



sub get_up_face {
    return "imq0";
}

sub parse_config {
    %CFG = ();
    
    if (open IF, "$CFGFILE") {
	if ($verbosemode) {
	    print "reading cfg data\n";
	}
	my $cnt = 0;
        while (<IF>) {
    	    $line = $_;
	    #data ve formatu
	    #PROBE="<IP>,<id>,<group>,<descript>"
	    #PROBE="10.102.84.194,skudlik,wlan0,165 - skudlik"
	    my ($cmd,$data) = split ("=", $line);
	    if ($cmd eq "PROBE") {
		chomp($data);
		$data =~ s/\"//g;
		if ($verbosemode) {
		    print "  $data.\n";
		}
		$cnt++;
		my ($ip,$id,$group,$descr) = split (",",$data);
		$CFG{"$ip"} = join ("::", ($id,$group,$descr));
		
	    }
	}
	print "$cnt config lines read\n";
	close IF;
    } else {
	print "No config file $CFGFILE .. exiting\n";
	exit 0;
    }
}	


sub perform_ping {
    my $results = { };

    my %HOSTS = ();
    my %dupici = ();
    while (my ($ip,$data) = each %CFG) {
	my ($id, $group, $descr) = split("::",$data);
	if (exists($HOSTS{"$group"})) {
	    $HOSTS{$group} .= " $ip";
	} else {
	    $HOSTS{$group}=$ip;
	}
    }
    while (my ($group, $hosts)= each(%HOSTS)) {
	my $command ="fping -b $PACKETSIZE -c $PACKETCOUNT -p $PACKETDELAY -i $PACKETDELAY -q $hosts 2>\&1";
        print "Executing ping (size:$PACKETSIZE count:$PACKETCOUNT delay:$PACKETDELAY) .. group $group\n";
	open FILE, "$command |";

	while (<FILE>) {
    	    chomp;$line=$_;
    	    if ($line =~ /duplicate/ ) {
		my ($host) = split(":", $line);
		$host =~s/ //g; chomp $host;
		if (exists($dupici{"$host"})) {
	    	    $dupici{"$host"} = $dupici {"$host"}+1;
		} else { $dupici{"$host"} = 1; }
	    } elsif ($line =~ /xmt/ ) {
		my ($host) = split(":", $line);
		$host =~s/ //g; chomp $host;
		my (undef, $val1, $val2) = split("=", $line);
		(undef, $val1) = split("/", $val1);
		my ($val3, $val4, $val5) = ("U", "U", "U");
		if (defined ($val2)) {
	    	    ($val3, $val4, $val5)= split ("/", $val2);
		}
		$val3 =~ s/ //g;
		my $val6 = 0;
		if (exists($dupici{"$host"})) {
	    	    $val6 = $dupici{"$host"}
	        }
		#print "$host:$val1, $val3, $val4, $val5, $val6 \n";
		my $pl = $PACKETCOUNT - ($val1-$val6);
		$pl = $pl / ($PACKETCOUNT / 100);
		${$results}{"$host"}=join("::",$pl,$val6,$val3,$val4,$val5);
#	    print "$host : ".join("::",$pl,$val6,$val3,$val4,$val5)."\n";

	    }
	}
	close FILE;
    }
    return $results;
    print ("OK\n");

}

sub get_traffic {
    if (open IF, "$TRAFFICDIR/tc_dump.xml") {
	if ($verbosemode) {print "loading data from shaper ($TRAFFICDIR/counter.xml)";}
	my $cnt =0;
	while (<IF>) {
	    $line = $_;
	    if ($line =~ /interfacesumdata/ ) {
		while (<IF>) {
		    $line = $_;
		    if ($line =~ /\/interfacesumdata/ ) {
			last;
		    } 
		    if ($line =~ /user id/ ) {
			my (undef,$uid,undef,$dev,$rest) = split ("'", $line);
			if ($uid == 0) {
			    next;
			}
			my ($sval) = split("<", $rest);
			my (undef,$send) = split(">",$sval);
			$cnt++;
			$tdatas{"$uid:$dev"}=$send;
			#print "data:$uid:$dev:$send\n";
		    }
		}
	    }
	}
	if ($verbosemode) {print " $cnt entries.\n";}
	close IF;
    } else {
	print "W: cannot open traffic stat file!\n";
    }
}
sub gen_stats {
    my ($pings) = @_;
    `touch $TMPFILE`;
    if ($DATAOUT_ENABLED) { 
	open OF,">$TMPFILE"; 
	print OF time()."\n";	
    }
    while (my($host,$result)= each %{$pings}) {
	my $datas = $CFG{"$host"};
	print "$host==$datas==$result\n";
	my $ppl = 0;
	my $pdup = 0;
	my $pmin = U;
	my $pavg = 0;
	my $pmax = 0;
	my $pcnt = 0;
	for (my $i = 0;$i < $COUNTERMAX; $i ++) {
	    my $tmp_res = $results[$i]{"$host"};
	    if (defined ($tmp_res)) {
		$pcnt++;
		if ($verbosemode) { print "$i : $tmp_res \n"; }
		my ($tmppl, $tmpdup, $tmpmin, $tmpavg, $tmpmax) = split ("::", $tmp_res);
		$ppl += $tmppl;
		$pdup += $tmpdup;
		if ($tmpavg ne "U" && $pavg ne "U") {
		    $pavg += $tmpavg;
		} else {
		    $pavg = "U";
		}
		if ($tmpmin ne "U") {
		    if ($pmin eq "U" || $tmpmin < $pmin) { $pmin = $tmpmin; }
		}
		if ($tmpmax ne "U" && $pmax ne "U") {
		    if ($tmpmax > $pmax) { $pmax = $tmpmax; }
		} else {
		    $pmax = "U";
		}
	    }
	}
	$ppl = $ppl / $pcnt;
	if ($pavg ne "U") {
	    $pavg = $pavg / $pcnt;
	}
	my $presult = join ("::", ($ppl,$pdup,$pmin,$pavg,$pmax));
	if ($verbosemode) { print "sum: $ppl $pdup $pmin $pavg $pmax\n"; }
	if ($DATAOUT_ENABLED) { print OF "ping==$host==$datas==$result==$presult\n"; }
    }

    if ($DATAOUT_ENABLED) {close OF; };
    if ($verbosemode) {print "dumping results to $DATAOUTFILE \n"; }
    `mv $TMPFILE $DATAOUTFILE`;

    if (defined($HTMLOUT_ENABLED) && $HTMLOUT_ENABLED) {
	if ($verbosemode) {print "converting results to html \n"; }
	`sleep 60; /etc/pinger/gensystem.pl`;
    }	
}

# ==========================================================
`mkdir /var/www/state/ &>/dev/null`; #prasarna no :) 

$loopmode = 0;
$verbosemode = 0;
$counter = 0;

foreach (@ARGV) {
    if ($_ eq "-l") { $loopmode=1;}
    if ($_ eq "-v") { $verbosemode=1;}
    if ($_ eq "--help" || $_ eq "-h") {
	print "usage ./pinger.pl [-v] [-l]\n  -v  activates verbose mode\n  -l  activates loop mode\n";
	exit 0;
    }
}

#parse_config();

if ($loopmode) {
    print "Starting pinger in loop mode with period:$UPERIOD \n";
    while (1) {
	parse_config();
	#delay
	if ( -e $TMPFILE) {
	    my $mtime=(stat("$TMPFILE"))[9];
	    $| = 1;
	    while (time < $mtime + $UPERIOD) {
		print ".";
		sleep 10;
	    }
	    print "\n";
	}
	if ($TRAFFIC_ENABLED) {get_traffic;}
        my $act_res = perform_ping();
	$results[$counter] = $act_res;
	$counter++;
	gen_stats($act_res);
	if ($counter == $COUNTERMAX) {
	    $counter = 0;
	}
    }
} else {
    parse_config();
    if ($TRAFFIC_ENABLED) {get_traffic;}
    gen_stats(perform_ping);
}

# ==========================================================
