diff options
Diffstat (limited to 'whoseip/Whoseip/DB.pm')
-rw-r--r-- | whoseip/Whoseip/DB.pm | 37 |
1 files changed, 23 insertions, 14 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 @@ -19,6 +19,7 @@ package Whoseip::DB; use strict; use Fcntl qw(SEEK_SET SEEK_CUR); use Socket qw(inet_ntoa); +use Storable qw(freeze thaw); require Exporter; our @ISA = qw(Exporter); @@ -124,7 +125,8 @@ B<Offset> B<Size> B<Description> 16 4 Entry 0: network mask 20 4 Entry 0: timestamp 24 2 Entry 0: ISO 3166-1 country code - + 26 4 Entry 0: length of additional data + 30 ? Entry 0: additional data . . . . . . . . . @@ -133,6 +135,8 @@ B<Offset> B<Size> B<Description> 16+N*14 4 Entry N: network mask 20+N*14 4 Entry N: timestamp 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 When a leaf page is encountered, the IP address in question is compared with each entry in turn using the usual procedure (B<AND>ing with the network @@ -239,10 +243,11 @@ sub ipdb_save_page($$) { } elsif ($page->{type} == IPDB_PAGE_LEAF) { my @a; 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, $page->{next}, @a)); @@ -349,10 +354,11 @@ sub ipdb_get_page($$) { my ($x, @a) = unpack('LL257', $s); $ret{tab} = \@a; } 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] ]; } # print "$nent\n"; # print join(', ', @{$ret{tab}})."\n"; @@ -459,10 +465,10 @@ sub ipdb_lookup($$) { foreach my $r (@{$page->{tab}}) { if (($ipn & $r->[1]) == $r->[0]) { # 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]}); } } return undef if (!$page->{next}); @@ -479,8 +485,11 @@ Inserts into the database I<$cidr> and the corresponding country code I<$country 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; my $ipn; my $masklen; @@ -541,7 +550,7 @@ sub ipdb_insert($$$) { } } - push @{$page->{tab}}, [ $ipn, $netmask, time(), $country ]; + push @{$page->{tab}}, [ $ipn, $netmask, time(), $country, \%_ ]; $page->{dirty} = 1; return 1; |