#!/usr/bin/perl -w
#
# (C) 2009, W. Dean Freeman //bsDaemon (Slashdot ID 83707)
# 
# It's nothing special, but it makes my life easier.  It's good for
# getting info out of logs of various network-related services such as
# ftp, mail or dom logs.  Also I find it fairly handy for parsing out netstat as well.
# 
# Any suggestions are welcome.

#I'm on a "let's not be [too] sloppy kick lately
use strict;

# This comes from CPAN, but still you need to separately fetch and install the dat file
use Geo::IP::PurePerl;

# Initialize our empty hash that does all the work
my %hosts;

# Take everything from standard input and grab all of the IP addresses out each line
# then store them in a hash where $key = IP and $value = the number of occurrances in the count
while (<>) {
	foreach(/(\d+\.\d+\.\d+.\d+)/g) {
		$hosts{$_}++;
	}
}

# The other way might be to pipe sort -n and then have it go bottom-heavy... this is fine though
# and it's probably best fed to head on the command line anyway
open (SORT, "|sort -rn");

# And now for the interesting parts...
foreach my $host (sort keys %hosts) {
	# create a new geoip object
	my $gi = Geo::IP::PurePerl->new(GEOIP_STANDARD);
	
	# find out where the I is from
	my $country = $gi->country_name_by_name($host);
	
	# you can't get a geoip lookup on 'localhost', so lets take care of that.
	if (!$country) {
		$country = "unkown";
	}
	
	# Apparnetly gethostbyaddr() likes pack()'d input.  Let's feed it what it wants.
	my @ip = split(/\./, $host);
	my $ip = pack("C4", @ip);
	# Not having to copy and paste the output of `cat $log |awk '{print $1}'|sort -r|uniq -c|sort -rn`
	# to find out of the IP was worth calling an attacker and kicking out is, quite frankly, the reason
	# I wrote this, so its the most important part (to me).
	my $hname = gethostbyaddr($ip,2);
	
	# Where `host` would give us NXDOMAIN or SERVFAIL, gethostbyaddr() prints a crappy message when -w
	# is on, so let us avoid that.
	if (!$hname) {
		$hname = "NXDOMAIN";
	}
	
	# print out our super awesome, formatted, sorted output
	printf SORT "$hosts{$host}\t%16s\t%50s\t$country\n", $host,$hname;
}
# Just to be tidy...
close SORT;

=head1 NAME
	
ipparse.pl

=head1 CONTACT

!spam-dean@14thanddock.com

=pod OSNAMES

Linux, BSD

=pod SCRIPT CATEGORIES

Networking, UNIX: System Administration

=cut
