v2
This commit is contained in:
parent
fa3bdf5590
commit
6df0e11148
151
xtr.pl
151
xtr.pl
@ -4,55 +4,82 @@ use strict;
|
||||
use warnings;
|
||||
use Net::Traceroute;
|
||||
use Net::DNS::Resolver;
|
||||
use Net::Whois::IP;
|
||||
use Dancer2;
|
||||
#use JSON::PP;
|
||||
use Socket;
|
||||
use DBI;
|
||||
use File::Fetch;
|
||||
use PerlIO::gzip;
|
||||
use Data::Dumper;
|
||||
|
||||
### README
|
||||
# to install needed modules on debian:
|
||||
# * apt-get install libnet-whois-ip-perl libperlio-gzip-perl libdancer2-perl libnet-dns-perl libnet-traceroute-perl libdbi-perl libdbd-sqlite3-perl
|
||||
|
||||
### vars
|
||||
my $dbfile = "ip2asn.db";
|
||||
my $ip2asn_csv_url = 'http://iptoasn.com/data/ip2asn-v4-u32.tsv.gz';
|
||||
|
||||
### connect to database
|
||||
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile","","");
|
||||
$dbh->do("PRAGMA cache_size = 800000");
|
||||
|
||||
### create database & table if needed and fill with ip information
|
||||
if(create_db_table($dbh)) { get_ipas_data($dbh,$ip2asn_csv_url); }
|
||||
|
||||
### hook for HTTP "security"
|
||||
hook 'before' => sub {
|
||||
header 'Access-Control-Allow-Origin' => '*';
|
||||
};
|
||||
|
||||
### main get route
|
||||
get '/:ip' => sub {
|
||||
my $ip = route_parameters->get('ip') || 8.8.8.8;
|
||||
my $trace = traceit($ip);
|
||||
my $trace = traceit($dbh,$ip);
|
||||
return encode_json $trace;
|
||||
};
|
||||
|
||||
### start the loop
|
||||
start;
|
||||
|
||||
|
||||
### if you reach this, you're done
|
||||
exit;
|
||||
|
||||
|
||||
sub traceit
|
||||
{
|
||||
my ($host) = @_;
|
||||
my ($dbh,$host) = @_;
|
||||
my $tr = Net::Traceroute->new(host => $host, use_icmp => 1, timeout => 1 );
|
||||
|
||||
my @array = ();
|
||||
if($tr->found)
|
||||
{
|
||||
#print Dumper($tr->hops);
|
||||
foreach my $hop (@{$tr->{'hops'}})
|
||||
my @array = ();
|
||||
if($tr->found)
|
||||
{
|
||||
my $sum = sprintf("%.1f",($hop->[0]->[2] + $hop->[1]->[2] + $hop->[2]->[2])/3);
|
||||
my $res = Net::DNS::Resolver->new;
|
||||
my $query = $res->query($hop->[0]->[1], 'PTR');
|
||||
my $answer = "nonono";
|
||||
if($query)
|
||||
foreach my $hop (@{$tr->{'hops'}})
|
||||
{
|
||||
foreach my $rr ($query->answer)
|
||||
my $sum = sprintf("%.1f",($hop->[0]->[2] + $hop->[1]->[2] + $hop->[2]->[2])/3);
|
||||
my $res = Net::DNS::Resolver->new;
|
||||
my $query = $res->query($hop->[0]->[1], 'PTR');
|
||||
my $answer = " ";
|
||||
if($query)
|
||||
{
|
||||
if($rr->type eq "PTR")
|
||||
foreach my $rr ($query->answer)
|
||||
{
|
||||
$answer = $rr->ptrdname;
|
||||
if($rr->type eq "PTR")
|
||||
{
|
||||
$answer = $rr->ptrdname;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### get AS to IP
|
||||
my $as = 0;
|
||||
if($hop->[0]->[1] ne "255.255.255.255")
|
||||
{
|
||||
$as = find_as($dbh, $hop->[0]->[1]);
|
||||
}
|
||||
push(@array, [$hop->[0]->[1],$answer,$sum,$as]);
|
||||
}
|
||||
# print $hop->[0]->[1]."\t(".$answer.") - ".$sum."\n";
|
||||
push(@array, [$hop->[0]->[1],$answer,$sum]);
|
||||
}
|
||||
}
|
||||
|
||||
if($tr->found)
|
||||
{
|
||||
@ -64,3 +91,87 @@ if($tr->found)
|
||||
}
|
||||
}
|
||||
|
||||
sub get_ipas_data
|
||||
{
|
||||
my ($dbh,$ip2asn_csv_url) = @_;
|
||||
|
||||
my $ff = File::Fetch->new(uri => $ip2asn_csv_url);
|
||||
my $temp_file = $ff->fetch( to => '/tmp' );
|
||||
|
||||
open(FILE,"<:gzip",$temp_file) or die "Can't open file: $!";
|
||||
my @data = <FILE>;
|
||||
close(FILE);
|
||||
|
||||
$dbh->do('begin');
|
||||
|
||||
my $max_commit = 10000;
|
||||
my $inserted = 0;
|
||||
my $array_size = @data;
|
||||
my $last_p = -1;
|
||||
print "loading data...\n";
|
||||
foreach my $line (@data)
|
||||
{
|
||||
chomp($line);
|
||||
if($line=~/^(\d+)\s+(\d+)\s+(\d+)/)
|
||||
{
|
||||
if($3 eq "0") { next; }
|
||||
#my %temp_hash = ('from' => $1, 'to' => $2, 'as' => $3);
|
||||
#push(@ipaslist,\%temp_hash);
|
||||
my $insert_cmd .= "INSERT INTO ip2asn VALUES (".$1.",".$2.",".$3.");";
|
||||
my $insert_sth = $dbh->prepare($insert_cmd);
|
||||
$inserted += $insert_sth->execute();
|
||||
|
||||
# print status for console users
|
||||
my $p = int($inserted * 100 / $array_size);
|
||||
if($p != $last_p) { print $p % 10 ? "" : "$p%\n"; }
|
||||
$last_p = $p;
|
||||
|
||||
# only commit every $max_commit statements (it's faster)
|
||||
unless ($inserted % $max_commit)
|
||||
{
|
||||
$dbh->do('commit');
|
||||
$dbh->do('begin');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$dbh->do('commit');
|
||||
unlink($temp_file);
|
||||
print "data prepared for searches!\n";
|
||||
}
|
||||
|
||||
sub find_as
|
||||
{
|
||||
my ($dbh, $ip) = @_;
|
||||
my $ip_id = unpack("N", inet_aton($ip));
|
||||
|
||||
my $get_as_cmd = "SELECT ip_as FROM ip2asn WHERE ip_from < ".$ip_id." AND ip_to > ".$ip_id.";";
|
||||
my $get_as_sth = $dbh->prepare($get_as_cmd);
|
||||
$get_as_sth->execute();
|
||||
my $result = $get_as_sth->fetch;
|
||||
return $result->[0] || 0;
|
||||
}
|
||||
|
||||
sub create_db_table
|
||||
{
|
||||
my ($dbh) = @_;
|
||||
|
||||
my $check_table_cmd = "SELECT name FROM sqlite_master WHERE type='table' AND name='ip2asn';";
|
||||
my $check_table_sth = $dbh->prepare($check_table_cmd);
|
||||
$check_table_sth->execute();
|
||||
if(!$check_table_sth->fetch)
|
||||
{
|
||||
print "creating table...\n";
|
||||
my $create_table_cmd = "CREATE TABLE ip2asn( ip_from INTEGER, ip_to INTEGER, ip_as INTEGER)";
|
||||
my $create_table_sth = $dbh->prepare($create_table_cmd);
|
||||
$create_table_sth->execute();
|
||||
#my $create_index_cmd = "CREATE INDEX ip2asnIndex ON ip2asn(ip_from,ip_to);";
|
||||
#my $create_index_sth = $dbh->prepare($create_index_cmd);
|
||||
#$create_index_sth->execute();
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user