#!/usr/local/bin/perl -w
#---------------------------------------------------------------------------
#
#	print freebsd TCP hostcache formatted
#
#	last edit-date: [Wed Feb 22 10:22:59 2017]
#
#	Hellmuth Michaelis, hm@hellmuth-michaelis.de
#
#---------------------------------------------------------------------------
use Getopt::Std;
use Net::IP qw(:PROC);

$opt_4 = 0;
$opt_6 = 0;
$opt_n = 0;
$opt_d = 0;
$opt_h = 0;
$opt_R = 0;

$dod = 0;

format STDOUT_TOP =
                       IP address  MTU  SSTRESH      RTT   RTTVAR BANDWIDTH     CWND SENDPIPE RECVPIPE HITS  UPD  EXP
---------------------------------------------------------------------------------------------------------------------
.

format STDOUT =
@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  @<<< @<<<<<<<<<<< @<<<< @<<<<< @<<<<<<<<<<<< @<<< @<<<<<<< @<<<<<<< @<<<< @<<< @<<<
$C[0]||'', $C[1]||0, $C[2]||0, $C[3]||0, $C[4]||0, $C[5]||0, $C[6]||0, $C[7]||0, $C[8]||0, $C[9]||0,$C[10]||0,$C[11]||0
.

sub usage()
{
	print STDERR << "EOF";

usage: $0 [-46dhnR]
-4     display IPv4 only
-6     display IPv6 only
-d     try to resolve FQDN
-h     print this usage message
-n     print line only if MTU != 0
-R     reset the TCP hostcache immediately

EOF
        exit;
}

getopts("46dhnR")
	or usage();

if($opt_h == 1)
{
	usage();
}

if($opt_R == 1)
{
	system("sysctl net.inet.tcp.hostcache.purgenow=1") == 0
        	or die "system sysctl net.inet.tcp.hostcache.purgenow=1 failed: $?";
	exit;
}

open(LIST,"sysctl -o net.inet.tcp.hostcache.list |") 
	or die "sysctl -o net.inet.tcp.hostcache.list failed: $?\n";

select(STDOUT);

while(<LIST>)
{
	@C = split(/ +/);

	if(($opt_n == 1) && ($C[1] == "0"))
	{
		next;
	}

	if($opt_4 == 1)
	{
		if(ip_is_ipv4($C[0]))
		{
			write;	
			$dod = 1;
		}
	}
	elsif($opt_6 == 1)
	{
		if(ip_is_ipv6($C[0]))
		{
			write;
			$dod = 1;
		}
	}
	else
	{
		if(ip_is_ipv6($C[0]) || ip_is_ipv4($C[0]))
		{
			write;
			$dod = 1;
		}
	}
	
	if( ($dod == 1 ) && ($opt_d == 1) && (ip_is_ipv6($C[0]) || ip_is_ipv4($C[0])) )
	{
		open(NAME, "host $C[0] |") 
			or die "host $C[0] failed: $?\n";

		while(<NAME>)
		{
			my @N = split(/ +/);
			my $name=$N[4];
			if($name =~ m/\./i)
			{
				chomp($name);
				print "                                 \\-> $name\n";
			}
		}
		close(NAME);
		$dod = 0;
	}
}
close(LIST);

# EOF
