#!/usr/bin/perl -w

# use strict;
use IO::Socket;

#################################################################
#  This is the recieving script  for the ip reporter.
#   This should be ran on a server with a known IP that the
#   reporter.pl script can talk to.
#################################################################

my $port = 4010;		# The port to listen on

my $dbfilename = "IpDb";	# The filename of the db file
				# (created if does not exist.)

my $htmlfilename = "test.html"; # The filename of the output
				#   html file.

#################################################################

##########################################################
#######         End Of Modifiable Variables.       #######
##########################################################

local (%ips,%names,%desc);
readdb($dbfilename);

# Create the socket
my $server = IO::Socket::INET->new(
    LocalPort => $port,
    Type      => SOCK_STREAM,
    Reuse     => 1,
    Listen    => 3 # or maximumlength of waitng queus of remote clients
    ) or die "Could not create a TCP/IP server socket here!\n";

my ($client,$addr,$uniid);

# Accept Connections
while ( ($client,$addr) = $server->accept() ){
	my $line = <$client>; 		#Read a line if it sends it, then validate
	if(!defined($line)){$line=" ";}
	$uniid = "0";			#Parse out the sent line
	if($line =~ m/(.*?)\t(.*?)/){
		$uniid = $1;
		$line = $2;
		}
					#Get,Parse, and validate the remote IP
	my ($port,$ad) = sockaddr_in($addr);
	my $ip=inet_ntoa($ad);
	my $name=gethostbyaddr($ad,AF_INET);
	if(!defined($name)){$name = " ";}
	
	sleep(1); #sleep for good measure
	
	close($client);			#We're done with the connection here
	################################################################################
	
	if ($uniid eq "0"){		# This means that someone didn't assign a unique Id
		my $key;		#   I thought I'd be nice and handle it and check by ip
		foreach $key (keys(%ips)){
			if($ips{$key} eq $ip){
				$uniid=$key;
				last;
				}
			}
		if ($uniid eq "0"){
			my $cnt = 0;
			while(defined($ips{"- $cnt"})){$cnt++;}
			$uniid="- ".$cnt;
			}
		}
	
	# Now let's see if it already exists and hasn't changed (why do anything if it hasn't)
	#      changed?)	
	if((!defined($ips{$uniid})) || ($ips{$uniid} ne inet_ntoa($ad)) || ($desc{$uniid} ne $line) || ($names{$uniid} ne $name)){
                $ips{$uniid}=$ip;		#set the IP
                $desc{$uniid}=$line;		#set the desc
                $names{$uniid}=$name;		#set the name
		writehtml($htmlfilename);	#Write out the Html File (updated)
		writedb($dbfilename);		#Write out a new DB FIle (updated)
		}
	}

# If we ever go here then for some reason we can't accept connections !?!?!?! (i.e. I don't know why)
#   so try and close I guess and exit.
close ($server);	


# Write out the html file with all the data.
sub writehtml{
	my ($filename) = @_;
	open(HTML,">$filename") || die("Counldnt open $filename for write");
	print HTML "<HEAD><TITLE>IPs<\/TITLE><\/HEAD><BODY><H2>Reported Ips<\/H2>\n<TABLE border=1>";
	my $uid;
	foreach $uid (keys(%ips)){
		print HTML "<TR><TD>$ips{$uid}<\/TD><TD>$names{$uid}<\/TD><TD>$desc{$uid}<\/TD><\/TR>\n";
		}
	print HTML "<\/TABLE><\/BODY>";
	close (HTML);
	}

# Write Out the DB File (: delimited, 1 record per line)
sub writedb{
	my ($filename) = @_;
	open(DB,">".$filename)||die "Couldn't Open $filename for writing.";
	my $uid;
	foreach $uid (keys(%ips)){
		if($uid =~ m/-/){
			print DB "0:".$ips{$uid}.":".$names{$uid}.":".$desc{$uid}."\n";
			}
		else{
			print DB $uid.":".$ips{$uid}.":".$names{$uid}.":".$desc{$uid}."\n";
			}
		}
	close(DB);
	}

# Read In the DB File (same as above)
sub readdb{
	my ($filename) = @_;
	if(open(IPDB,"<$filename")){
        	my $cnt = 0;
	        my ($uid,$ip,$name,$descri);
        	while(<IPDB>){
                	if(m/^(\d+):(.*?):(.*?):(.*?)$/){
                        	($uid,$ip,$name,$descri) = ($1,$2,$3,$4);
	                        if($uid eq "0"){
        	                        $uid = "- ".$cnt;
                	                $cnt++;
                        	        }
	                        $ips{$uid}=$ip;
        	                $names{$uid}=$name;
                	        $desc{$uid}=$descri;
				}
	                }
        	close(IPDB);
	        }
	}
