#!/usr/bin/perl -w
#
# Copyright 2003 Stephen Hahn.  
# Licensed for use under the same terms as Perl itself.
#
#ident "@(#)cachedns.pl	1.3	03/11/22"
#
# [ Derived from minidns.pl by Michael Kennedy, michael@toronto.com
#   His terms are:  Use or modify as you wish, but no warranty. ]
#

use strict;
use Getopt::Std;
use Storable qw(nstore retrieve);

my %opts = ();
my %cache = ();

my $cache_lkup = 0;
my $cache_hit = 0;
my $cache_entry = 0;

sub usage () {
	print  STDERR <<EOU;
Usage: minidns [-hs] [-c cachefile]
EOU
	exit 2;
}

getopts("c:hs", \%opts);

usage if (defined($opts{h}));

if (defined($opts{c}) && -f $opts{c}) {
	my $hashref = retrieve($opts{c});
	%cache = %$hashref;
}

sub cached_gethostbyaddr ($$) {
	my ($txtip, $ip) = @_;

	$cache_lkup++;

	if (exists($cache{"$txtip"}) &&
	    defined($cache{"$txtip"}->{host})) {
		$cache_hit++;
		return ($cache{"$txtip"}->{host});
	}

	my $result = (gethostbyaddr($ip, 2));

	$result = "" if (!defined($result));

	$cache{"$txtip"}->{host} = $result;

	return ($result);
}

while (<>) {
	my $line;
	if (/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/) {
		if ($1 <= 255 && $2 <= 255 && $3 <= 255 && $4 <= 255) {
			$line = $_;
			my $txtip = "$1.$2.$3.$4";
			my $ip = pack 'C4',$1,$2,$3,$4;
			my $hostname = (cached_gethostbyaddr($txtip, $ip));
			$line =~ s/$txtip/$hostname/ if ($hostname ne "");
		}
	}
	print $line;
}

if (defined($opts{c})) {
	nstore \%cache, $opts{c};
}

if (defined($opts{s})) {
	print STDERR <<EOS;
	cache lookups: $cache_lkup
	cache hits:    $cache_hit
EOS
}
