#!/usr/bin/perl

use CGI;
use Carp;

my $debug = "";
my $handler;
my $db_file = 'ipscountry.dat' ;

my @baseX = qw(0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z . , ; ' " ` < > { } [ ] = + - ~ * @ # % $ & ! ?) ;

my %countrys = qw(
-- N/A L0 localhost I0 IntraNet A1 Anonymous_Proxy A2 Satellite_Provider
AD Andorra AE United_Arab_Emirates AF Afghanistan AG Antigua_and_Barbuda AI Anguilla AL Albania AM Armenia AN Netherlands_Antilles 
AO Angola AP Asia/Pacific_Region AQ Antarctica AR Argentina AS American_Samoa AT Austria AU Australia AW Aruba AZ Azerbaijan BA Bosnia_and_Herzegovina BB Barbados BD Bangladesh 
BE Belgium BF Burkina_Faso BG Bulgaria BH Bahrain BI Burundi BJ Benin BM Bermuda BN Brunei_Darussalam BO Bolivia BR Brazil BS Bahamas BT Bhutan BV Bouvet_Island BW Botswana 
BY Belarus BZ Belize CA Canada CC Cocos_(Keeling)_Islands CD Congo,_The_Democratic_Republic_of_the CF Central_African_Republic CG Congo CH Switzerland CI Cote_D'Ivoire CK Cook_Islands 
CL Chile CM Cameroon CN China CO Colombia CR Costa_Rica CU Cuba CV Cape_Verde CX Christmas_Island CY Cyprus CZ Czech_Republic DE Germany DJ Djibouti DK Denmark DM Dominica 
DO Dominican_Republic DZ Algeria EC Ecuador EE Estonia EG Egypt EH Western_Sahara ER Eritrea ES Spain ET Ethiopia EU Europe FI Finland FJ Fiji FK Falkland_Islands_(Malvinas) 
FM Micronesia,_Federated_States_of FO Faroe_Islands FR France FX France,_Metropolitan GA Gabon GB United_Kingdom GD Grenada GE Georgia GF French_Guiana GH Ghana GI Gibraltar 
GL Greenland GM Gambia GN Guinea GP Guadeloupe GQ Equatorial_Guinea GR Greece GS South_Georgia_and_the_South_Sandwich_Islands GT Guatemala GU Guam GW Guinea-Bissau GY Guyana 
HK Hong_Kong HM Heard_Island_and_McDonald_Islands HN Honduras HR Croatia HT Haiti HU Hungary ID Indonesia IE Ireland IL Israel IN India IO British_Indian_Ocean_Territory 
IQ Iraq IR Iran,_Islamic_Republic_of IS Iceland IT Italy JM Jamaica JO Jordan JP Japan KE Kenya KG Kyrgyzstan KH Cambodia KI Kiribati KM Comoros KN Saint_Kitts_and_Nevis 
KP Korea,_Democratic_People's_Republic_of KR Korea,_Republic_of KW Kuwait KY Cayman_Islands KZ Kazakhstan LA Lao_People's_Democratic_Republic LB Lebanon LC Saint_Lucia LI Liechtenstein 
LK Sri_Lanka LR Liberia LS Lesotho LT Lithuania LU Luxembourg LV Latvia LY Libyan_Arab_Jamahiriya MA Morocco MC Monaco MD Moldova,_Republic_of MG Madagascar MH Marshall_Islands 
MK Macedonia,_the_Former_Yugoslav_Republic_of ML Mali MM Myanmar MN Mongolia MO Macau MP Northern_Mariana_Islands MQ Martinique MR Mauritania MS Montserrat MT Malta MU Mauritius 
MV Maldives MW Malawi MX Mexico MY Malaysia MZ Mozambique NA Namibia NC New_Caledonia NE Niger NF Norfolk_Island NG Nigeria NI Nicaragua NL Netherlands NO Norway NP Nepal 
NR Nauru NU Niue NZ New_Zealand OM Oman PA Panama PE Peru PF French_Polynesia PG Papua_New_Guinea PH Philippines PK Pakistan PL Poland PM Saint_Pierre_and_Miquelon PN Pitcairn 
PR Puerto_Rico PS Palestinian_Territory,_Occupied PT Portugal PW Palau PY Paraguay QA Qatar RE Reunion RO Romania RU Russian_Federation RW Rwanda SA Saudi_Arabia SB Solomon_Islands 
SC Seychelles SD Sudan SE Sweden SG Singapore SH Saint_Helena SI Slovenia SJ Svalbard_and_Jan_Mayen SK Slovakia SL Sierra_Leone SM San_Marino SN Senegal SO Somalia SR Suriname 
ST Sao_Tome_and_Principe SV El_Salvador SY Syrian_Arab_Republic SZ Swaziland TC Turks_and_Caicos_Islands TD Chad TF French_Southern_Territories TG Togo TH Thailand TJ Tajikistan 
TK Tokelau TM Turkmenistan TN Tunisia TO Tonga TP East_Timor TR Turkey TT Trinidad_and_Tobago TV Tuvalu TW Taiwan,_Province_of_China TZ Tanzania,_United_Republic_of UA Ukraine 
UG Uganda UM United_States_Minor_Outlying_Islands US United_States UY Uruguay UZ Uzbekistan VA Holy_See_(Vatican_City_State) VC Saint_Vincent_and_the_Grenadines VE Venezuela 
VG Virgin_Islands,_British VI Virgin_Islands,_U.S. VN Vietnam VU Vanuatu WF Wallis_and_Futuna WS Samoa YE Yemen YT Mayotte YU Yugoslavia ZA South_Africa ZM Zambia ZR Zaire ZW Zimbabwe
) ;

my (%baseX,$base,$THIS,%pos,$start) ;


####################
# DECLARE BASE LIB #
####################

{
  my $c = 0 ;
  %baseX = map { $_ => ($c++) } @baseX ;
  $base = @baseX ;

  foreach my $Key ( keys %countrys )
  {
    $countrys{$Key} =~ s/_/ /gs ;
    #$debug .= "$Key : $countrys{$Key}<br>";
  }
}

##########
# LOADDB #
##########

sub LoadDB {
  my ($buffer) ;
  open($handler,$db_file) || Carp::croak("Failed to open database file $db_file for read!") ;
  binmode($handler) ;
  
  while( read($handler, $buffer , 1 , length($buffer) ) ) {
    if ($buffer =~ /##headers##(\d+)##$/s  ) {
      my $headers ;
      read($handler, $headers , $1 ) ;
      my (%head) = ( $headers =~ /(\d+)=(\d+)/gs );
      foreach my $Key ( keys %head ) { $pos{$Key} = $head{$Key};}
      $buffer = '' ;
    }
    elsif ($buffer =~ /##start##$/s  ) {
      $start = tell($handler) ;
      last ;
    }
  }
  @searchorder = ( sort {$a <=> $b} keys %pos ) ;
}

##########
# LOOKUP #
##########

sub LookUp {
  my ( $ip ) = @_ ;
  
  $ip =~ s/\.+/\./gs ;
  $ip =~ s/^\.// ;
  $ip =~ s/\.$// ;
  
  if ($ip !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { $ip = nslookup($ip) ;}

  ## Since the last class is always from the same country, will try 0 and cache 0:
  my $ip_class = $ip ;
  $ip_class =~ s/\.\d+$/\.0/ ;

  my $ipnb = ip2nb($ip_class) ;

  my $buf_pos = 0 ;

  foreach my $Key ( @searchorder ) {
    if ($ipnb <= $Key) { $buf_pos = $pos{$Key} ; last ;}
  }
    
  my ($buffer,$country,$iprange) ;
  
  ## Will read the DB in the disk:
    seek($handler , 0 , 0) if $] < 5.006001 ; ## Fix bug on Perl 5.6.0
    seek($handler , $buf_pos + $start, 0) ;
    while( read($handler , $buffer , 7) ) {
      $country = substr($buffer , 0 , 2) ;
      $iprange = baseX2dec( substr($buffer , 2) ) ;
      if ($ipnb >= $iprange) { last ;}
    }

  return( $country , $countrys{$country} , $ip_class ) ;
}

############
# NSLOOKUP #
############

sub nslookup {
  my ( $host ) = @_ ;
  require Socket ;
  my $iaddr = Socket::inet_aton($host) ;
  my @ip = unpack('C4',$iaddr) ;
  if (! @ip && ! $_[1]) { return( &nslookup("www.$host",1) ) ;}
  return( join (".",@ip) ) ;
}

#########
# IP2NB #
#########

sub ip2nb {
  my @ip = split(/\./ , $_[0]) ;
  #return( 16777216* $ip[0] + 65536* $ip[1] + 256* $ip[2] + $ip[3] ) ;
  return( ($ip[0]<<24) + ($ip[1]<<16) + ($ip[2]<<8) + $ip[3] ) ;
}

#########
# NB2IP #
#########

sub nb2ip {
  my ( $ipn ) = @_ ;
  
  my @ip ;
  
  my $x = $ipn ;
  
  while($x > 1) {
    my $c = $x / 256 ;
    my $ci = int($x / 256) ;
    #push(@ip , $x - ($ci*256)) ;
    push(@ip , $x - ($ci<<8)) ;
    $x = $ci ;
  }
  
  push(@ip , $x) if $x > 0 ;
  
  while( $#ip < 3 ) { push(@ip , 0) ;}
  
  @ip = reverse (@ip) ;
    
  return( join (".", @ip) ) ;
}
 
#############
# DEC2BASEX #
#############

sub dec2baseX {
  my ( $dec ) = @_ ;
  
  my @base ;
  my $x = $dec ;
  
  while($x > 1) {
    my $c = $x / $base ;
    my $ci = int($x / $base) ;
    push(@base , $x - ($ci*$base) ) ;
    $x = $ci ;
  }
  
  push(@base , $x) if $x > 0 ;
  
  while( $#base < 4 ) { push(@base , 0) ;}
  
  my $baseX ;
  
  foreach my $base_i ( reverse @base ) {
    $baseX .= $baseX[$base_i] ;
  }
  
  return( $baseX ) ;
}

#############
# BASEX2DEC #
#############

sub baseX2dec {
  my ( $baseX ) = @_ ;
  
  my @base = split("" , $baseX) ;
  my $dec ;

  my $i = -1 ;
  foreach my $base_i ( reverse @base ) {
    $i++ ;
    $dec += $baseX{$base_i} * ($base**$i) ;
  }

  return( $dec ) ;
}

#######
# END #
#######

LoadDB;

my($country,$country_name,$sip) = LookUp($ENV{REMOTE_ADDR}) ;

if( $country_name =~ m/.{16,16}/)
{
    $country_name .="                ";
}

($msg = <<EOMA) =~ s/^\s//gm;
<head><script language=javascript>
var offset=-1;

var text="$country_name ".split("");
var len=text.length;
var viewable=18;
if(len < viewable) viewable=len;

function scrollit()
{
    var show="";
    offset++;
    if( offset > len-viewable ) offset = 0;
    for(i=0;i<viewable;i++)
    {
        show += text[offset+i];
    }
    node = document.getElementById("a");
    node.innerText = show;
}    
function init()
{
    setInterval('scrollit()',250);
}
</script></head>
<body bgcolor=black style='margin:0' onload='init();'><center>
<a href="https://all-antiques.com" target="__blank"><div style="font-family:terminal;font-size:7pt;color:#00c000;text-decoration:none;">All-Antiques.com</div></a>
EOMA

$query = CGI::new();
print $query->header();
print $msg;
print("<span style='font-family:terminal;font-size:10pt;color:#00FF00;text-decoration:none;'>$ENV{REMOTE_ADDR}</span>");
print("<br><span style='font-family:terminal;font-size:7pt;color:#00E000;text-decoration:none;'><b id='a'>$country_name</b></span></center></body>");


