#!/usr/bin/perl -w
# Note: Some lines have been wrapped for readability
# names of the input log file / output hostnames file
#

$log_in_file       = "log.txt";
$html_results_file = "hostnames_out.htm";

# run parts of the program
&get_hostnames;
&html;
&save_html_page;

# template for displaying hostnames
sub html {
    $html_page = <<__READ_HTML__;
<html>
<head>
<meta http-equiv="Content-Language" content="en-gb">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Hostnames</title>
</head>
<body>
<table border="O" cellpadding="O" cellspacing="O" style="border-collapse: collapse" bordercolor="#111111" width="1OO%">
<tr>
<td width="100%" bgcolor="#OOOOOO" height="50">&nbsp;</td>
</tr>
<tr>
<td width="100%">
<pre>
&all_hn_i p
</pre>
</td>
</tr>
<tr>
<td width="100%" bgcolor="#OOOOOO" height="50">&nbsp;</td>
</tr>
</table>
</body>
</html>
__READ_HTML__
}    ### end sub html

sub get_hostnames {

    # read in the raw log file to @data
    open( DAT, $log_in_file ) || die("Error log file must be \"$log_in_file\"");
    @data = <DAT>;
    close(DAT);

    # initialise a variable to strip new line characters from a string
    use vars qw/$NLT/;
    $NLT = qr/(?:\r|\n|\t)/;

    # prevent un-initialised errors
    $all_ip    = '';
    $all_hn_ip = '';
    $all_sp_ip = '';
    $hn_ip     = '';
    $sp_hn_ip  = '';
    $sp_lines  = '';

# if a line number was entered on the command line e.g. perl ip_resolver.pl 1724
# start resolving IPs from this point on
    if ( $ARGV[0] ) { $in_line_from = $ARGV[0]; }

    else { $in_line_from = 0; }

    foreach $line (@data) {

        $line_no++;

        if ( $line_no >= $in_line_from ) {

            if ($line) {

                $line =~ s/$NLT//g;

                ($ip) = split( /\ /, $line );

                # if IP is a number in the format ***.***.***.*** then
                if ( $ip =~ m!(\d+)\.(\d+)\.(\d+)\.(\d+)! ) {

                    # if the IP has allready been resolved then skip this part
                    unless ( $all_ip =~ /$ip/ ) {
                        $all_ip   = $all_ip . "$ip ";
                        $hostname = '';

                        # resolve the actual IP address
                        $hostname =
                          ( gethostbyaddr( pack( 'C4', $1, $2, $3, $4 ), 2 ) )
                          [0];
                        $hostname = $hostname || 'no reverse DNS';

                        # get the length of the hostname to line up the columns
                        $ocharno = length($hostname);
                        if   ( $ocharno > 50 ) { $charno = 1; }
                        else                   { $charno = 50 - $ocharno; }

                        # add this amount of space characters to make up the
                        # rest of the line untill the start of the IP address
                        $addspace = " " x $charno;
                        print $hostname . $addspace . $ip . "\n";

                        # use various colours for the various hostnames
                        $line_start = '<font color="#OOOOOO">';
                        $line_end   = '</font>';
                        if ( $hostname =~ /edu/i ) {
                            $line_start = '<font color="#008000">';
                        }
                        if ( $hostname =~ /(com|net|org)/i ) {
                            $line_start = '<font color="#OOOOFF">';
                        }
                        if ( $hostname =~ /(gov|mil)/i ) {
                            $line_start = '<font color="#FFOOOO">';
                        }

                        # compile the finished hostname / IP line complete with
                        # font colour
                        $hn_ip =
                            $line_start
                          . $hostname
                          . $addspace
                          . $ip
                          . $line_end . "\n";

                        #add this line to the rest
                        $all_hn_ip = $all_hn_ip . $hn_ip;

                        # if the hostname is a special one (gov/mil) then add
                        # it to a special store of its own to be displaye d at
                        # the top of the page and also add the coresponding raw
                        # log lines to a special store
                        if ( $hostname =~ /(gov|mil)/i ) {
                            $sp_hn_ip     = $sp_hn_ip . $hn_ip;
                            $addunderline = "-" x $ocharno;
                            $sp_lines =
                              $sp_lines . "\n$hostname\n$addunderline\n";
                            $all_sp_ip = $all_sp_ip . "$ip ";
                        }
                    }

                    # if we have a special IP then store the log lines for it
                    if ( $all_sp_ip =~ /$ip/ ) {
                        $sp_lines = $sp_lines . " " . $line . "\n";
                    }
                }
            }
        }
    }

    # if there are special hostnames present then sort out the line spacing
    if ($sp_hn_ip) {
        $all_hn_ip =
            $all_hn_ip . "\n"
          . "============================*.GOV / *.MIL============================\n\n"
          . $sp_hn_ip
          . $sp_lines;
    }
}

sub save_html_page {

    # save the finished html page to a file ready for viewing
    open( DAT, ">$html_results_file" )
      || die(
        "Error ensure this script has write permissions \"$html_results_file\""
      );
    print DAT "$html_page";
    close(DAT);
}



syntax highlighted by Code2HTML, v. 0.9.1