#!/usr/bin/perl
# (C) 1994 Ulrich Callmeier
# Slip To Readable
# Converts output of nacctd to a somewhat more readable form

require "ctime.pl";
require "ptime.pl";

$AF_INET = 2;
	
open(TABLE, "<german-IP-networks");
while(<TABLE>)
{
    chop;
    $german_net{$_} = 1;
}
close(TABLE);

setservent(1);
while(($na, $al, $po, $pr) = getservent)
{
	if($pr eq "udp")
	{
		$udp[$po] = $na;

	}
	elsif($pr eq "tcp")
	{
		$tcp[$po] = $na;
	}

}
endservent;

while(<>)
{
    chop;
    ($x_time, $x_proto, $x_from, $x_fromport, $x_to, $x_toport, $x_size, $dev) = split;
    $date = &ptime("%a %d.%m.%y %T",$x_time);	

    $h1 = &hbyaddr($x_from);
    $h2 = &hbyaddr($x_to);
    $g1 = &is_german($x_from) ? "G" : "I";
    $g2 = &is_german($x_to) ? "G" : "I";
    if(!(($proto) = getprotobynumber($x_proto))) {$proto = $x_proto;};

    if($proto eq 'udp')
    {
	if(!($port1 = $udp[$x_fromport])) {$port1 = $x_fromport;};
	if(!($port2 = $udp[$x_toport])) {$port2 = $x_toport;};
    } 
	elsif($proto eq 'tcp')
    {

	if(!($port1 = $tcp[$x_fromport])) {$port1 = $x_fromport;};
	if(!($port2 = $tcp[$x_toport])) {$port2 = $x_toport;};
    }  
	else
    {
	$port1 = $x_fromport;
	$port2 = $x_toport;
    } 
#print "$date\t$proto\t$h1\t$port1\t$h2\t$port2\t$x_size\t$g1\t$g2\n";
printf ("%21s %-4s %-4s %1s %1s %8d %8s -> %-8s %s -> %s\n",$date, $dev, $proto, $g1, $g2, $x_size, $port1, $port2, $h1, $h2);
}

sub hbyaddr
{
    local($addr) = @_;
    local($ipaddr, $host_name);
    if(! ($host_name = $ip_cache{$addr}))
    {	
	print "[lookup] " if $debug;	
	$ipaddr=pack("C4",split(/\./,$addr));
	if (!(($host_name, $aliases, $addrtype, $length, @addrs) = gethostbyaddr($ipaddr,$AF_INET)))
	{
	    print "[lookup failed] " if $debug;
	    $host_name = $addr;
	}
	$ip_cache{$addr} = $host_name;
    }
    print ">>>\"$host_name\"<<< " if $debug;
    $host_name;   
}

sub is_german
{
	# Algorithmus:
	# Wir schneiden jeweils das letzte Adress-Byte ab und schauen nach, ob
	# das Resultat in der Liste der deutschen Netze vorkommt. Es wird
	# höchstens 3mal abgeschnitten (class-A Netz).
	
    local($ipaddr) = @_;

    $cuts = 1;
    while($cuts < 4)
    {
	$ipaddr =~ s/(.*)\.[0-9]{1,3}$/$1/;
	$cuts++;
	if(defined($german_net{$ipaddr}))
	{
	    return 1;
	}
    }
    return 0;
}


sub i2s
{
    local($zahl) = @_;
    local($s) = "$zahl";
    while ($s =~ s/(.*\d)(\d\d\d)/$1.$2/)
    {
    }
    $s;
}
