#!/usr/bin/perl

# tell the web browser we're going to send it HTML text it needs to process
# instead of plain text which it can display without processing
print "Content-Type: text/html\n\n";

# variables
$debug = 0;
$linenumber = 0;
$error = 0;
$whois_server = 0;
$current_max_server = 6;
# whois server definitions
#  0 = arin.net
#  1 = dnsstuff.com
#  2 = zoneedit.com
#  3 = ripe.net
#  4 = apnic.net
#  5 = lacnic.net
#  6 = afrinic.net

# http://remote.12dt.com/rns/
# http://www.dnsstuff.com/
# http://www.dnsstuff.com/tools/ptr.ch?ip=+209.16.217.15+
# http://www.zoneedit.com/lookup.html?ipaddress=209.16.217.15&server=&reverse=Look+it+up
# http://www.ripe.net/fcgi-bin/whois?form_type=simple&full_query_string=&searchtext=194.140.65.241&submit.x=9&submit.y=9&submit=Search
# http://apnic.net/apnic-bin/whois.pl?searchtext=211.0.0.0&whois=Go
# http://lacnic.net/cgi-bin/lacnic/whois?lg=EN&query=24.99.119.99
# http://www.afrinic.net/cgi-bin/whois?form_type=simple&full_query_string=&searchtext=82.201.209.19

@servers = ("arin.net", "dnsstuff.com", "zoneedit.com", "ripe.net", "apnic.net", "lacnic.net", "afrinic.net");
$my_server = "http://robertdell.dyndns.org/";
$my_cgi_name = "cgi-bin/getaccesslog.cgi";

if ($ENV{'REQUEST_METHOD'} eq 'GET') {
  # Split the name-value pairs
  @pairs = split(/&/, $ENV{'QUERY_STRING'});
  }
elsif ($ENV{'REQUEST_METHOD'} eq 'POST') {
  # Get the input
  read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

  # Split the name-value pairs
  @pairs = split(/&/, $buffer);
  }
else {
  };

foreach $pair (@pairs) {

  # Split the pair up into individual variables.                       #
  local($name, $value) = split(/=/, $pair);

  # Decode the form encoding on the name and value variables.          #
  # v1.92: remove null bytes                                           #
  $name =~ tr/+/ /;
  $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  $name =~ tr/\0//d;

  $value =~ tr/+/ /;
  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  $value =~ tr/\0//d;

  if ($name eq "method") {
    $whois_server = $value;
    if ($whois_server < 0) {
      $whois_server = 0;
      }
    elsif ($whois_server > $current_max_server) {
      $whois_server = 0;
      };
    };
  };

# refresh how often?
$refresh_hours   = 0;
$refresh_minutes = 6;
$refresh_seconds = 0;

$refreshtime = ((($refresh_hours*60)+$refresh_minutes)*60)+$refresh_seconds;

# Version history
# 1.0.0  Original program written
# 1.1.0  Changed the output to HTML 4.01 compliant
# 2.0.0  Changed the IP addresses to 4 sets of 3 numbers for ease of readability
# 2.1.0  Added the ability of checking whois to the IP addresses with a single click
# 2.1.1  Added comments and version number for addition to the CPAN archives
# 2.1.2  Added better error handling
# 2.2.0  changed the local net address selection and added both local net selections.
# 3.0.0  Added a new feature to the get log program to allow it to work with logcleaner (strips out the overloads, updated the counter files)
#        skips 0.0.0.0 IP address.
#        Also fixed a minor bug in the local IP address filters.
# 3.1.0  added a refresh to ensure acurateness of an access log if it's kept on.
# 3.2.0  added multiple reverse dns query addresses but it's still secure and hard coded.
# 3.3.0  added javascript engine and code to switch between multiple whois servers
# 3.4.0  added <hr /> when it gets to the line where we last counted
# 3.4.1  added coloring to certain aspects of the log
# 3.5.0  added new reverse dns servers
# 3.5.1  changed download location
# 3.6.0  added one more reverse dns server
# 3.6.1  fixed bug in displaying afrinic.net name
#
$version = "GetLog version 3.6.1";

# The location of an apache log file in the following format
#
# 10.0.1.1 - - [15/Jan/2005:01:09:18 -0500] "GET /cgi-bin/getagentlog.cgi HTTP/1.1" 200 59734
#
$mylogfilename = "/private/var/log/httpd/access_log";
# $mylogfilename = "/access.log";

$mytitle = "Access log";

# Create an error message
if ($debug == 1) {
  $errormessage = join( "", "<h3>Cannot open the access logs.<br />\n", $mylogfilename, "</h3>\n\n");
  }
else {
  $errormessage = "</small>\n\n<h3>Cannot open the log file.</h3>\n\n<small>\n";
  }

# print a HTML header for the display
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n";
print "<html>\n";
print "<head>\n";
print "  <title> ",$mytitle," </title>\n";
print "  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\n";
print "  <meta http-equiv=\"refresh\" content=\"",$refreshtime,"\">\n";
print "  <link type=\"text/css\" rel=\"stylesheet\" href=\"/css/chapterstyle.css\">\n";
print "  <script language=\"JavaScript\" type=\"text/javascript\">\n";
print "    function refreshme(how) {\n";
print "    if (how=='0') {\n";
print "      window.location=\"$my_server$my_cgi_name\";\n";
print "      };\n";
print "    if (how=='1') {\n";
print "      window.location=\"$my_server$my_cgi_name?method=1\";\n";
print "      };\n";
print "    if (how=='2') {\n";
print "      window.location=\"$my_server$my_cgi_name?method=2\";\n";
print "      };\n";
print "    if (how=='3') {\n";
print "      window.location=\"$my_server$my_cgi_name?method=3\";\n";
print "      };\n";
print "    if (how=='4') {\n";
print "      window.location=\"$my_server$my_cgi_name?method=4\";\n";
print "      };\n";
print "    if (how=='5') {\n";
print "      window.location=\"$my_server$my_cgi_name?method=5\";\n";
print "      };\n";
print "    if (how=='6') {\n";
print "      window.location=\"$my_server$my_cgi_name?method=6\";\n";
print "      };\n";
print "    }\n";
print "  </script>\n";
print "</head>\n";
print "<body>\n";
print "<table class=\"noframes\">\n<tr>\n<td>\n";
print "<h1>",$mytitle,"</h1>\n";
print "<h4>",$version,"</h4>\n";
print "<hr />\n";
print "<p class=\"noindent\">get <a href=\"http://cpan.org/authors/id/X/XY/XYZZY/\" target=\"_blank\">$version</a> script.</p>\n";
print "<p class=\"noindent\">line number - IP address - date/time - method - file - protocol - result code - bytes served</p>\n";
print "<ul> Result codes\n";
print "  <li>200 - file found and served</li>\n";
print "  <li>302 - file moved</li>\n";
print "  <li>304 - file has not changed</li>\n";
print "  <li><b class=\"red\">401<\/b> - user not authorized</li>\n";
print "  <li><b class=\"red\">404<\/b> - file not found</li>\n";
print "  <li><b class=\"red\">414<\/b> - request too long</li>\n";
print "  <li>500 - file access error, somebody tried to access a file outside the web server folder.</li>\n";
print "  <li><b class=\"red\">501<\/b> - request method unknown, somebody tried to hack the site.</li>\n";
print "</ul>\n";
print "<p>You are now using server ",@servers[$whois_server],"</p>\n\n";
print "<ul>whois server\n";
if ($whois_server == 0) {
  print "  <li>arin.net</li>\n";
  }
else {
  print "  <li onclick=\"refreshme('0');\">arin.net</li>\n";
  };
if ($whois_server == 1) {
  print "  <li>dnsstuff.com</li>\n";
  }
else {
  print "  <li onclick=\"refreshme('1');\">dnsstuff.com</li>\n";
  };
if ($whois_server == 2) {
  print "  <li>zoneedit.com</li>\n";
  }
else {
  print "  <li onclick=\"refreshme('2');\">zoneedit.com</li>\n";
  };
if ($whois_server == 3) {
  print "  <li>ripe.net</li>\n";
  }
else {
  print "  <li onclick=\"refreshme('3');\">ripe.net</li>\n";
  };
if ($whois_server == 4) {
  print "  <li>apnic.net</li>\n";
  }
else {
  print "  <li onclick=\"refreshme('4');\">apnic.net</li>\n";
  };
if ($whois_server == 5) {
  print "  <li>lacnic.net</li>\n";
  }
else {
  print "  <li onclick=\"refreshme('5');\">lacnic.net</li>\n";
  };
if ($whois_server == 6) {
  print "  <li>afrinic.net</li>\n";
  }
else {
  print "  <li onclick=\"refreshme('6');\">afrinic.net</li>\n";
  };
print "</ul>\n";
print "<hr />\n\n<small>\n";

print "\n";

# Open up the log file
open(LOGFILE, $mylogfilename) or $error = 1;

if ($error == 1) {
  print $errormessage; }
else {

# get the data
  @data = <LOGFILE>;
  foreach $line(@data) {
# get rid of the overload logs that Apache cannot filter out
    if (($line =~ m/^.*\"SEARCH.*\"/) or ($line =~ m/^.*\"CONNECT.*\"/)) {
      
      }
    else {
# filter out the local net addresses (10.0.1.x and 192.168.1.x)
      if (($line =~ m/^10\D0\D1\D.*/) or ($line =~ m/^192\D168\D1\D.*/) or ($line =~ m/^0\D0\D0\D0\D.*/)) {
        if ($line =~ m/0\D0\D0\D0/) {
          print "<hr />\n";
          };
        }
      else {
# convert the numbers into 3 digits each for easier readability
        # match first number in ip address
        if ($line =~ m/^\d\D/) {
          $first = join("","00",substr($line,0,1));
          $line =~ s/^\d\D//;
          }
        elsif ($line =~ m/^\d\d\D/) {
          $first = join("","0",substr($line,0,2));
          $line =~ s/^\d\d\D//;
          }
        else {
          $first = substr ($line,0,3);
          $line =~ s/^\d\d\d\D//;
          };

        # match second number in ip address
        if ($line =~ m/^\d\D/) {
          $second = join("","00",substr($line,0,1));
          $line =~ s/^\d\D//;
          }
        elsif ($line =~ m/^\d\d\D/) {
          $second = join("","0",substr($line,0,2));
          $line =~ s/^\d\d\D//;
          }
        else {
          $second = substr ($line,0,3);
          $line =~ s/^\d\d\d\D//;
          };

        # match third number in ip address
        if ($line =~ m/^\d\D/) {
          $third = join("","00",substr($line,0,1));
          $line =~ s/^\d\D//;
          }
        elsif ($line =~ m/^\d\d\D/) {
          $third = join("","0",substr($line,0,2));
          $line =~ s/^\d\d\D//;
          }
        else {
          $third = substr ($line,0,3);
          $line =~ s/^\d\d\d\D//;
          };

        # match fourth number in ip address
        if ($line =~ m/^\d\D/) {
          $fourth = join("","00",substr($line,0,1));
          $line =~ s/^\d\D//;
          }
        elsif ($line =~ m/^\d\d\D/) {
          $fourth = join("","0",substr($line,0,2));
          $line =~ s/^\d\d\D//;
          }
        else {
          $fourth = substr ($line,0,3);
          $line =~ s/^\d\d\d\D//;
          };

# convert the IP back into 4 sets of 3 digits
        $ip = join(".", $first, $second, $third, $fourth);
        $my_ip = join(".", $first, $second, $third, $fourth);
        &breakip;
# The URL of the whois server query
        if ($whois_server == 0) {
          $whois = join("", "http://ws.arin.net/cgi-bin/whois.pl?queryinput=", $my_ip);
          }
        elsif ($whois_server == 1) {
          $whois = join("", "http://www.dnsstuff.com/tools/ptr.ch?ip=+", $my_ip, "+");
          }
        elsif ($whois_server == 2) {
          $whois = join("", "http://www.zoneedit.com/lookup.html?ipaddress=", $my_ip, "&server=&reverse=Look+it+up");
          }
        elsif ($whois_server == 3) {
          $whois = join("", "http://www.ripe.net/fcgi-bin/whois?form_type=simple&full_query_string=&searchtext=", $my_ip, "&submit.x=9&submit.y=9&submit=Search");
          }
        elsif ($whois_server == 4) {
          $whois = join("", "http://apnic.net/apnic-bin/whois.pl?searchtext=", $my_ip, "&whois=Go");
          }
        elsif ($whois_server == 5) {
          $whois = join("", "http://lacnic.net/cgi-bin/lacnic/whois?lg=EN&query=", $my_ip);
          }
        elsif ($whois_server == 6) {
          $whois = join("", "http://www.afrinic.net/cgi-bin/whois?form_type=simple&full_query_string=&searchtext=", $my_ip);
          }
       else {
         $whois = "unable to determine the whois server";
         };

        $linenumber++;
        # strip off carriage returns
        $line =~ s/\n//;
        
        # ------ coloring start ------
        $line =~ s/games/<b>games<\/b>/g;
        $line =~ s/stories/<b class=\"red\">stories<\/b>/g;
        $line =~ s/\ 401\ /<b class=\"red\">\ 401\ <\/b>/;
        $line =~ s/\ 404\ /<b class=\"red\">\ 404\ <\/b>/;
        $line =~ s/\ 414\ /<b class=\"red\">\ 414\ <\/b>/;
        $line =~ s/\ 501\ /<b class=\"red\">\ 501\ <\/b>/;
        $line =~ s/DR_Scripts/<b class=\"purple\">DR_Scripts<\/b>/g;
        $line =~ s/images/<b class=\"green\">images<\/b>/g;
        $line =~ s/cgi-bin/<b class=\"yellow\">cgi-bin<\/b>/g;
        $line =~ s/css/<b class=\"maroon\">css<\/b>/g;
        # ------ coloring end ------
        
        print "<p class=\"noindent\">",$linenumber,": <a class=\"noindent\" href=\"",$whois,"\" target=\"_blank\">",$ip,"</a> ",$line,"</p>\n";
        };
      };
    };

  close(LOGFILE);
  if ($linenumber == 0) {
    print "<p class=\"noindent\">No log entries at this time.  The log has just been freshly cleaned.</p>\n";
    };
  };

# print the HTML footer
print "</small>\n\n<hr />\n";
print "<h1>The End</h1>\n<hr />\n";
print "</td>\n</tr>\n</table>\n";
print "</body>\n",;
print "</html>\n\n";


exit 0 ;

sub breakip {
  $first =~ s/^0//;
  $first =~ s/^0//;
  $second =~ s/^0//;
  $second =~ s/^0//;
  $third =~ s/^0//;
  $third =~ s/^0//;
  $fourth =~ s/^0//;
  $fourth =~ s/^0//;
  $my_ip = join(".", $first, $second, $third, $fourth);
  };




=head1 getlog

This script allows for ease of getting and reading the access logs of the website
through a web page

=head1 DESCRIPTION

This script scans through the site's access log and ensures all IP addresses are
4 sets of 3 digits, adds a link to the whois page, and then displays that information
to the screen.  It strips out overloads and local accesses.

=head1 README

This script scans through the site's access log and ensures all IP addresses are
4 sets of 3 digits, adds a link to the whois page, and then displays that information
to the screen.  It strips out overloads and local accesses.

=head1 INSTRUCTIONS

You will also need a style sheet on your website according to the requisites you provide.

=head1 PREREQUISITES

The Apache web server and an access log.

=head1 COREQUISITES

CGI

=pod OSNAMES

any

=pod SCRIPT CATEGORIES

Web

=cut