#! /usr/bin/perl -w

# quick and dirty geoip by andrew wales <geoip@meow.org.uk>
# http://www.meow.org.uk/stan/pet_projects/geoip.html

#my $query_ip = "132.185.128.144";
my $query_ip = $ARGV[0]||"193.178.223.23";


#my $query_ip = $ENV{"REMOTE_ADDR"};
#if ($query_ip =~ /![0123456789.]/) {
#   print "BAFF!.\n";
#   exit;
#}

$query_int= unpack("N", pack("C4", split(/\./, $query_ip)));

my $found = 0;

($start_time, undef, undef, undef) = times;

for $list (glob "delegated-*-latest") {

    open(LIST, $list) || die ("$!");

    while (defined ($line = <LIST>)) {
        chomp($line);
        next if ($line =~ m/^#/);
        next if ($line !~ m/./);
        if ($line =~ m/\|ipv4\|/) {
            ($registry, $cc, $type, $start, $value, $date, $status) =
                split(/\|/, $line);
            $start_int= ($start eq "*") ? 0 : unpack("N", pack("C4", split(/\./, $start)));
            $value = 0 if ($value =~ m/\D/);
            if ($start_int =~ /\D/) { print "$start_int\n"; }
            if (($query_int >= $start_int) && ($query_int < $start_int+$value)) {
                $registry = uc $registry;
                $cidr = 32-(log($value)/log(2));
                $status.="";
                $type.="";
                print "${registry} says you are in ${cc} (";
                print iso3166($cc);
                print "), ${start}/${cidr}, registered ${date}.\n";
                $found++;
            }
        }
    }
    close(LIST);
}

($end_time, undef, undef, undef) = times;

if ($found == 0) {
    print "no registry knows of you, ${query_ip}.  aren't you an enigma, eh?\n";
}

print "Oh, and that took ", $end_time-$start_time, " seconds.\n";


sub iso3166 {
    my $cc = uc shift;

    # these need hard-coding due to absence from iso 3166
    return "ARIPO" if ($cc =~ m/^AP$/i);
    return "EUROPEAN UNION" if ($cc =~ m/^EU$/i);
    return "UNITED KINGDOM" if ($cc =~ m/^UK$/i);

    open(ISOLIST, "list-en1-semic.txt") || return "baff";
    while (defined ($iso = <ISOLIST>)) {
        chop($iso); chop($iso);
        if ($iso =~ m/;${cc}$/ ) {
            ($country) = split(/;/, $iso, 2);
            return $country;
        }
    }
    close(ISOLIST);
    return "unknown";
}