aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2014-10-14 23:02:46 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2014-10-14 23:02:46 +0300
commit22ea7f92356b66406e7507002b826cbf12e14d52 (patch)
tree7a30a51940f2a82f63105a15000f7788e9384a40
parentc60e1f248a5b911e502b46420389aad42bb7fac9 (diff)
downloaddnstools-22ea7f92356b66406e7507002b826cbf12e14d52.tar.gz
dnstools-22ea7f92356b66406e7507002b826cbf12e14d52.tar.bz2
whoseip: keep arbitrary additional data in the cache database
* whoseip/Whoseip/DB.pm (ipdb_save_page): Save additional data (serialized hash). (ipdb_get_page): Decode serialized additional data. (ipdb_insert): Take hash as additional arguments. * whoseip/whoseip.pl (range2count): Handle multiple ranges. (cidr_to_range): New function. Use in all functions instead of Net::CIDR::cidr2range. (serve): Pass cidr as additional argument to ipdb_insert
-rw-r--r--whoseip/Whoseip/DB.pm37
-rw-r--r--whoseip/whoseip.pl46
2 files changed, 59 insertions, 24 deletions
diff --git a/whoseip/Whoseip/DB.pm b/whoseip/Whoseip/DB.pm
index b7cba34..fbd3a61 100644
--- a/whoseip/Whoseip/DB.pm
+++ b/whoseip/Whoseip/DB.pm
@@ -21,2 +21,3 @@ use Fcntl qw(SEEK_SET SEEK_CUR);
use Socket qw(inet_ntoa);
+use Storable qw(freeze thaw);
@@ -126,3 +127,4 @@ B<Offset> B<Size> B<Description>
24 2 Entry 0: ISO 3166-1 country code
-
+ 26 4 Entry 0: length of additional data
+ 30 ? Entry 0: additional data
. . .
@@ -135,2 +137,4 @@ B<Offset> B<Size> B<Description>
24+N*14 2 Entry N: ISO 3166-1 country code
+ 26+N*14 4 Entry N: length of additional data
+ 30+N*14 ? Entry N: additional data
@@ -241,6 +245,7 @@ sub ipdb_save_page($$) {
foreach my $ent (@{$page->{tab}}) {
- push @a, @{$ent};
+ push @a, @{$ent}[0 .. 3],freeze($ent->[4]);
}
$ret = syswrite($dbf->{fd},
- pack('LLL(LLLa2)*@'."$dbf->{pagesize}", $page->{type},
+ pack('LLL(LLLa2L/a)*@'."$dbf->{pagesize}",
+ $page->{type},
$#{$page->{tab}} + 1,
@@ -351,6 +356,7 @@ sub ipdb_get_page($$) {
} elsif ($ret{type} == IPDB_PAGE_LEAF) {
- (my $x, my $nent, $ret{next}, my @a) =
- unpack('LLL(LLLa2)*', $s);
- for (my $i = 0; $i < $nent; $i += 4) {
- push @{$ret{tab}}, [ $a[$i], $a[$i+1], $a[$i+2], $a[$i+3] ];
+ (my $x, my $nent, $ret{next}) =
+ unpack('LLL', $s);
+ my ($x1, $x2, $x3, @a) = unpack("LLL(LLLa2L/a)$nent", $s);
+ for (my $i = 0; $i < $nent; $i += 5) {
+ push @{$ret{tab}}, [ @a[$i .. $i+3], thaw $a[$i+4] ];
}
@@ -461,6 +467,6 @@ sub ipdb_lookup($$) {
# FIXME: check timestamp
-
- return ( country => $r->[3],
- network => inet_ntoa(pack('N', $r->[0])),
- netmask => inet_ntoa(pack('N', $r->[1])) );
+ return ( ( country => $r->[3],
+ network => inet_ntoa(pack('N', $r->[0])),
+ netmask => inet_ntoa(pack('N', $r->[1])) ),
+ %{$r->[4]});
}
@@ -481,4 +487,7 @@ Currently, I<$cidr> must be in the form B<I<Net-address>/I<Netmask-length>>.
=cut
-sub ipdb_insert($$$) {
- my ($dbf, $cidr, $country) = @_;
+sub ipdb_insert {
+ my $dbf = shift;
+ my $cidr = shift;
+ my $country = shift;
+ local %_ = @_;
my @ipo;
@@ -543,3 +552,3 @@ sub ipdb_insert($$$) {
- push @{$page->{tab}}, [ $ipn, $netmask, time(), $country ];
+ push @{$page->{tab}}, [ $ipn, $netmask, time(), $country, \%_ ];
$page->{dirty} = 1;
diff --git a/whoseip/whoseip.pl b/whoseip/whoseip.pl
index dc512df..d5f5f11 100644
--- a/whoseip/whoseip.pl
+++ b/whoseip/whoseip.pl
@@ -21,3 +21,3 @@ use Pod::Usage;
use Pod::Man;
-use Socket qw(:DEFAULT :crlf);
+use Socket qw(:DEFAULT :crlf inet_ntoa);
use Net::CIDR;
@@ -145,5 +145,29 @@ sub str2ipv4 {
sub range2count {
- my @a = split /-/, shift;
- return 0 unless $#a == 1;
- return str2ipv4($a[1]) - str2ipv4($a[0]) + 1;
+ my $count = 0;
+ foreach my $arg (@_) {
+ my @a = split /-/, shift;
+ next unless $#a == 1;
+ $count += str2ipv4($a[1]) - str2ipv4($a[0]) + 1;
+ }
+ return $count;
+}
+
+sub cidr_to_range {
+ my @a;
+
+ @a = sort { $a->[0] <=> $b->[0] }
+ map {
+ map { [ map { str2ipv4($_) } split(/-/, $_, 2) ] }
+ Net::CIDR::cidr2range($_)
+ } split /,/, shift;
+
+ for (my $i = 1; $i <= $#a; $i++) {
+ if ($a[$i]->[0] == $a[$i-1]->[1] + 1) {
+ $a[$i-1]->[1] = $a[$i]->[1];
+ splice @a, $i, 1;
+ }
+ }
+
+ return join ',', map { inet_ntoa(pack('N', $_->[0])) . '-' .
+ inet_ntoa(pack('N', $_->[1])) } @a;
}
@@ -240,3 +264,3 @@ sub lacnic_decode {
$ref->{cidr} = $cidr;
- $ref->{range} = join ',', Net::CIDR::cidr2range($cidr);
+ $ref->{range} = cidr_to_range($cidr);
$ref->{count} = range2count($ref->{range});
@@ -295,3 +319,3 @@ sub nic_ad_jp_decode {
$ref->{cidr} = $1;
- $ref->{range} = join ',', Net::CIDR::cidr2range($ref->{cidr});
+ $ref->{range} = cidr_to_range($ref->{cidr});
$ref->{count} = range2count($ref->{range});
@@ -416,5 +440,7 @@ sub serve {
$res{status} = 'OK';
- $res{cidr} = Net::CIDR::addrandmask2cidr($res{network},
- $res{netmask});
- $res{range} = join ',', Net::CIDR::cidr2range($res{cidr});
+ unless (defined($res{cidr})) {
+ $res{cidr} = Net::CIDR::addrandmask2cidr($res{network},
+ $res{netmask});
+ }
+ $res{range} = cidr_to_range($res{cidr});
$res{count} = range2count($res{range});
@@ -437,3 +463,3 @@ sub serve {
foreach my $cidr (split /,/, $res{cidr}) {
- ipdb_insert($dbf, $cidr, $res{country});
+ ipdb_insert($dbf, $cidr, $res{country}, cidr=>$res{cidr});
}

Return to:

Send suggestions and report system problems to the System administrator.