Skip to content

Instantly share code, notes, and snippets.

@kingwrcy
Created January 8, 2013 05:50
Show Gist options
  • Save kingwrcy/4481566 to your computer and use it in GitHub Desktop.
Save kingwrcy/4481566 to your computer and use it in GitHub Desktop.
Get IP location from IP address via qqwry.dat.
##############################################################################
#\tThe format of the QQWry datafile can be referred at
#\thttp://lumaqq.linuxsir.org/article/qqwry_format_detail.html.
#\tBy JerryWang 2013年1月8日13:44:43
#\tThe latest version of QQWry datafile can be found at http://www.cz88.net/fox/
##############################################################################
use strict;
use warnings;
use v5.10;
sub usage(){
say "-----------------------------------------------------------------";
say "[+]useage:\n[+]\tindex.pl 1.2.3.4";
}
sub search_index{
my ($start,$end,$searched_index) = @_;
my $mid = $start + int(($end-$start)/7/2)*7;
my $middle_index;
seek MYFILE,$mid,0;
read MYFILE,$middle_index,4;
$middle_index = unpack("L",$middle_index);
return $mid if $searched_index == $middle_index ;
if($end - $start == 7){
my $end_ip = unpack("L",$end);
my $search_index_ip = unpack("L",$searched_index);
if($end_ip < $search_index_ip){
return $end;
}
return $start;
}
if ($searched_index > $middle_index){search_index($mid,$end,$searched_index);}
else {search_index($start,$mid,$searched_index);};
}
sub read_flag{
my $flag;
read MYFILE,$flag,1;
return $flag;
}
sub move_cursor{
my $offset = shift;
seek MYFILE,$offset,0;
}
sub read_bytes{
my $len = shift;
my $content;
read MYFILE,$content,$len;
return unpack("L",$content."\0");
}
sub ip2long{
return unpack(N,(pack(C4,(split( /\./,shift)))));
}
sub long2ip{
my @a = unpack(C4,(pack(N,shift)));
return join ".",@a;
}
usage and exit if(@ARGV != 1);
my $ip = ip2long $ARGV[0];
my ($index_start,$index_end,$offset_startip,$offset_endip);
my ($redirct_flag,$offset_country,$offset_country2,$offset_area);
my ($start_ip,$end_ip,$country,$area);
$/ = "\0";
open(MYFILE,"qqwry.dat") or die "can not open qqwry.dat:$!";
binmode MYFILE;
$index_start = read_bytes 4;
$index_end = read_bytes 4;
$offset_startip = search_index($index_start,$index_end,$ip);
move_cursor $offset_startip;
$start_ip = read_bytes 4;
$offset_endip = read_bytes 3;
move_cursor $offset_endip;
$end_ip = read_bytes 4;
$redirct_flag = read_flag;
if ($redirct_flag eq "\1"){
$offset_country = read_bytes 3;
move_cursor $offset_country;
$redirct_flag = read_flag;
if($redirct_flag eq "\2"){
$offset_country2 = read_bytes 3;
move_cursor $offset_country2;
$country = <MYFILE>;
move_cursor $offset_country+4;
$redirct_flag = read_flag;
if($redirct_flag eq "\1" or $redirct_flag eq "\2"){
$offset_area = read_bytes 3;
move_cursor $offset_area;
$area = $offset_area == 0 ? "Unknow" :<MYFILE>;
}else{
move_cursor $offset_country+4;
$area = <MYFILE>;
}
}else{
move_cursor $offset_country;
$country = <MYFILE>;
$area = <MYFILE>;
}
}elsif ($redirct_flag eq "\2"){
$offset_country = read_bytes 3;
move_cursor $offset_country;
$country = <MYFILE>;
move_cursor $offset_endip+8;
$redirct_flag = read_flag;
if($redirct_flag eq "\2"){
$offset_area2 = read_bytes 3;
move_cursor $offset_area2;
$area = $offset_area2 == 0 ? "Unknow" :<MYFILE>;
}else{
seek MYFILE,-1,1;
$area = <MYFILE>;
}
}else{
move_cursor $offset_endip+4;
$country = <MYFILE>;
$redirct_flag = read_flag;
if($redirct_flag eq "\2"){
$offset_area = read_bytes 3;
move_cursor $offset_area;
$area = $offset_area == 0 ? "Unknow" :<MYFILE>;
}else{
seek MYFILE,-1,1;
$area = <MYFILE>
}
}
move_cursor $index_end+4;
my $offset_info = read_bytes 3;
move_cursor $offset_info+4;
my $info = <MYFILE>;
$info .= <MYFILE>;
close MYFILE;
say "##################################################################";
say "Total Count:".(int(($index_end - $index_start)/7)+1);
say "Start IP Address:".long2ip $start_ip;
say "End Ip Address:".long2ip $end_ip;
say "Country:$country";
say "Area:$area";
say "Info:$info";
say "##################################################################";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment