File Coverage

blib/lib/Geo/IP2Proxy.pm
Criterion Covered Total %
statement 345 763 45.2
branch 71 338 21.0
condition 46 150 30.6
subroutine 49 73 67.1
pod 21 42 50.0
total 532 1366 38.9


line stmt bran cond sub pod time code
1             #MIT License
2             #
3             #Copyright (c) 2024 IP2Location.com
4             #
5             #Permission is hereby granted, free of charge, to any person obtaining a copy
6             #of this software and associated documentation files (the "Software"), to deal
7             #in the Software without restriction, including without limitation the rights
8             #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9             #copies of the Software, and to permit persons to whom the Software is
10             #furnished to do so, subject to the following conditions:
11             #
12             #The above copyright notice and this permission notice shall be included in all
13             #copies or substantial portions of the Software.
14             #
15             #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16             #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17             #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18             #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19             #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20             #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21             #SOFTWARE.
22              
23             package Geo::IP2Proxy;
24              
25 3     3   36563 use strict;
  3         7  
  3         146  
26 3     3   19 use vars qw(@ISA $VERSION @EXPORT);
  3         4  
  3         201  
27 3     3   5738 use Math::BigInt;
  3         172346  
  3         16  
28              
29             $VERSION = '3.50';
30              
31             require Exporter;
32             @ISA = qw(Exporter);
33              
34 3     3   109890 use constant UNKNOWN => "UNKNOWN IP ADDRESS";
  3         6  
  3         233  
35 3     3   16 use constant IPV6_ADDRESS_IN_IPV4_BIN => "IPV6 ADDRESS MISSING IN IPV4 BIN";
  3         6  
  3         120  
36 3     3   11 use constant NO_IP => "MISSING IP ADDRESS";
  3         6  
  3         107  
37 3     3   11 use constant INVALID_IPV6_ADDRESS => "INVALID IPV6 ADDRESS";
  3         5  
  3         137  
38 3     3   16 use constant INVALID_IPV4_ADDRESS => "INVALID IPV4 ADDRESS";
  3         7  
  3         103  
39 3     3   10 use constant INVALID_IP_ADDRESS => "INVALID IP ADDRESS";
  3         5  
  3         118  
40 3     3   11 use constant INVALID_BIN_DATABASE => "Incorrect IP2Proxy BIN file format. Please make sure that you are using the latest IP2Proxy BIN file.";
  3         4  
  3         92  
41 3     3   11 use constant NOT_SUPPORTED => "NOT SUPPORTED";
  3         31  
  3         143  
42 3     3   14 use constant MAX_IPV4_RANGE => 4294967295;
  3         5  
  3         157  
43 3     3   12 use constant MAX_IPV6_RANGE => 340282366920938463463374607431768211455;
  3         5  
  3         125  
44              
45 3     3   13 use constant COUNTRYSHORT => 1;
  3         3  
  3         113  
46 3     3   28 use constant COUNTRYLONG => 2;
  3         11  
  3         127  
47 3     3   13 use constant REGION => 3;
  3         4  
  3         133  
48 3     3   12 use constant CITY => 4;
  3         4  
  3         127  
49 3     3   24 use constant ISP => 5;
  3         5  
  3         102  
50 3     3   12 use constant PROXYTYPE => 6;
  3         5  
  3         126  
51 3     3   13 use constant ISPROXY => 7;
  3         3  
  3         129  
52 3     3   11 use constant DOMAIN => 8;
  3         6  
  3         119  
53 3     3   32 use constant USAGETYPE => 9;
  3         5  
  3         118  
54 3     3   14 use constant ASN => 10;
  3         3  
  3         91  
55 3     3   12 use constant AS => 11;
  3         5  
  3         124  
56 3     3   11 use constant LASTSEEN => 12;
  3         5  
  3         106  
57 3     3   25 use constant THREAT => 13;
  3         6  
  3         107  
58 3     3   27 use constant PROVIDER => 14;
  3         14  
  3         115  
59 3     3   12 use constant FRAUDSCORE => 15;
  3         5  
  3         108  
60              
61 3     3   12 use constant ALL => 100;
  3         8  
  3         209  
62 3     3   15 use constant IPV4 => 0;
  3         4  
  3         116  
63 3     3   12 use constant IPV6 => 1;
  3         3  
  3         28102  
64              
65             my @IPV4_COUNTRY_POSITION = (0, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3);
66             my @IPV4_REGION_POSITION = (0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4);
67             my @IPV4_CITY_POSITION = (0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5);
68             my @IPV4_ISP_POSITION = (0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6);
69             my @IPV4_PROXYTYPE_POSITION = (0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
70             my @IPV4_DOMAIN_POSITION = (0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7);
71             my @IPV4_USAGETYPE_POSITION = (0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8);
72             my @IPV4_ASN_POSITION = (0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9);
73             my @IPV4_AS_POSITION = (0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10);
74             my @IPV4_LASTSEEN_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11);
75             my @IPV4_THREAT_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, 12);
76             my @IPV4_PROVIDER_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13);
77             my @IPV4_FRAUDSCORE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14);
78              
79             my @IPV6_COUNTRY_POSITION = (0, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3);
80             my @IPV6_REGION_POSITION = (0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4);
81             my @IPV6_CITY_POSITION = (0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5);
82             my @IPV6_ISP_POSITION = (0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6);
83             my @IPV6_PROXYTYPE_POSITION = (0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
84             my @IPV6_DOMAIN_POSITION = (0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7);
85             my @IPV6_USAGETYPE_POSITION = (0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8);
86             my @IPV6_ASN_POSITION = (0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9);
87             my @IPV6_AS_POSITION = (0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10);
88             my @IPV6_LASTSEEN_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11);
89             my @IPV6_THREAT_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, 12);
90             my @IPV6_PROVIDER_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13);
91             my @IPV6_FRAUDSCORE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14);
92              
93             my $IPv6_re = qr/:(?::[0-9a-fA-F]{1,4}){0,5}(?:(?::[0-9a-fA-F]{1,4}){1,2}|:(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})))|[0-9a-fA-F]{1,4}:(?:[0-9a-fA-F]{1,4}:(?:[0-9a-fA-F]{1,4}:(?:[0-9a-fA-F]{1,4}:(?:[0-9a-fA-F]{1,4}:(?:[0-9a-fA-F]{1,4}:(?:[0-9a-fA-F]{1,4}:(?:[0-9a-fA-F]{1,4}|:)|(?::(?:[0-9a-fA-F]{1,4})?|(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))))|:(?:(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))|[0-9a-fA-F]{1,4}(?::[0-9a-fA-F]{1,4})?|))|(?::(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))|:[0-9a-fA-F]{1,4}(?::(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))|(?::[0-9a-fA-F]{1,4}){0,2})|:))|(?:(?::[0-9a-fA-F]{1,4}){0,2}(?::(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))|(?::[0-9a-fA-F]{1,4}){1,2})|:))|(?:(?::[0-9a-fA-F]{1,4}){0,3}(?::(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))|(?::[0-9a-fA-F]{1,4}){1,2})|:))|(?:(?::[0-9a-fA-F]{1,4}){0,4}(?::(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))|(?::[0-9a-fA-F]{1,4}){1,2})|:))/;
94             my $IPv4_re = qr/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/;
95              
96             my $getLastErrorMessage = "";
97              
98             sub open {
99 2 50 33 2 1 368010 unless( (@_ > 1) && ($_[1]) ) {
100 0         0 $getLastErrorMessage = "Geo::IP2Proxy::open() requires a database path name.";
101 0         0 die "Geo::IP2Proxy::open() requires a database path name";
102             }
103 2         8 my ($class, $db_file) = @_;
104 2         4 my $handle;
105             my $obj;
106 2 50       200 unless (CORE::open $handle, "$db_file") {
107 0         0 $getLastErrorMessage = "Geo::IP2Proxy::open() error in opening $db_file" . ".";
108 0         0 die "Geo::IP2Proxy::open() error in opening $db_file";
109             }
110 2         10 binmode($handle);
111 2         12 $obj = bless {filehandle => $handle}, $class;
112 2         11 $obj->initialize();
113 2 50       9 if ($obj->{"productcode"} == 2) {
114             } else {
115 2 50 33     43 if (($obj->{"databaseyear"} <= 20) && ($obj->{"productcode"} == 0)) {
116             } else {
117 0         0 $obj->close();
118 0         0 undef $obj;
119 0         0 $getLastErrorMessage = INVALID_BIN_DATABASE;
120 0         0 die INVALID_BIN_DATABASE;
121             }
122             }
123 2         29 return $obj;
124             }
125              
126             sub close {
127 0     0 0 0 my ($class) = @_;
128 0 0       0 if (CORE::close($class->{filehandle})) {
129 0         0 return 0;
130             } else {
131 0         0 return 1;
132             }
133             }
134              
135             sub initialize {
136 2     2 0 7 my ($obj) = @_;
137 2         25 my @header = $obj->read512($obj->{filehandle}, 1);
138 2         17 $obj->{"databasetype"} = unpack("C", $header[0]);
139 2         8 $obj->{"databasecolumn"} = unpack("C", $header[1]);
140 2         5 $obj->{"databaseyear"} = unpack("C", $header[2]);
141 2         6 $obj->{"databasemonth"} = unpack("C", $header[3]);
142 2         8 $obj->{"databaseday"} = unpack("C", $header[4]);
143 2         17 $obj->{"ipv4databasecount"} = unpack("V", join('', @header[5..8]));
144 2         10 $obj->{"ipv4databaseaddr"} = unpack("V", join('', @header[9..12]));
145 2         8 $obj->{"ipv6databasecount"} = unpack("V", join('', @header[13..16]));
146 2         6 $obj->{"ipv6databaseaddr"} = unpack("V", join('', @header[17..20]));
147 2         9 $obj->{"ipv4indexbaseaddr"} = unpack("V", join('', @header[21..24]));
148 2         7 $obj->{"ipv6indexbaseaddr"} = unpack("V", join('', @header[25..28]));
149 2         5 $obj->{"productcode"} = unpack("C", $header[29]);
150 2         5 $obj->{"licensecode"} = unpack("C", $header[30]);
151 2         6 $obj->{"databasesize"} = unpack("V", join('', @header[31..34]));
152 2         10 return $obj;
153             }
154              
155             sub get_last_error_message {
156 0     0 1 0 my $class = shift(@_);
157 0         0 return ($getLastErrorMessage);
158             }
159              
160             sub getModuleVersion {
161 0     0 1 0 my $obj = shift(@_);
162 0         0 return $VERSION;
163             }
164              
165             sub getPackageVersion {
166 0     0 1 0 my $obj = shift(@_);
167 0         0 return $obj->{"databasetype"};
168             }
169              
170             sub getDatabaseVersion {
171 0     0 1 0 my $obj = shift(@_);
172 0         0 my $databaseyear = 2000 + $obj->{"databaseyear"};
173 0         0 return $databaseyear . "." . $obj->{"databasemonth"} . "." . $obj->{"databaseday"};
174             }
175              
176             sub getCountryShort {
177 6     6 1 462 my $obj = shift(@_);
178 6         13 my $ipaddr = shift(@_);
179 6         24 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
180 6 100       21 if ($ipv == 4) {
181 3         11 return $obj->getIPv4Record($ipnum, COUNTRYSHORT);
182             } else {
183 3 50       9 if ($ipv == 6) {
184 3         19 return $obj->getIPv6Record($ipnum, COUNTRYSHORT);
185             } else {
186 0         0 return INVALID_IP_ADDRESS;
187             }
188             }
189             }
190              
191             sub getCountryLong {
192 0     0 1 0 my $obj = shift(@_);
193 0         0 my $ipaddr = shift(@_);
194 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
195 0 0       0 if ($ipv == 4) {
196 0         0 return $obj->getIPv4Record($ipnum, COUNTRYLONG);
197             } else {
198 0 0       0 if ($ipv == 6) {
199 0         0 return $obj->getIPv6Record($ipnum, COUNTRYLONG);
200             } else {
201 0         0 return INVALID_IP_ADDRESS;
202             }
203             }
204             }
205              
206             sub getRegion {
207 0     0 1 0 my $obj = shift(@_);
208 0         0 my $ipaddr = shift(@_);
209 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
210 0 0       0 if ($ipv == 4) {
211 0         0 return $obj->getIPv4Record($ipnum, REGION);
212             } else {
213 0 0       0 if ($ipv == 6) {
214 0         0 return $obj->getIPv6Record($ipnum, REGION);
215             } else {
216 0         0 return INVALID_IP_ADDRESS;
217             }
218             }
219             }
220              
221             sub getCity {
222 0     0 1 0 my $obj = shift(@_);
223 0         0 my $ipaddr = shift(@_);
224 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
225 0 0       0 if ($ipv == 4) {
226 0         0 return $obj->getIPv4Record($ipnum, CITY);
227             } else {
228 0 0       0 if ($ipv == 6) {
229 0         0 return $obj->getIPv6Record($ipnum, CITY);
230             } else {
231 0         0 return INVALID_IP_ADDRESS;
232             }
233             }
234             }
235              
236             sub getISP {
237 0     0 1 0 my $obj = shift(@_);
238 0         0 my $ipaddr = shift(@_);
239 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
240 0 0       0 if ($ipv == 4) {
241 0         0 return $obj->getIPv4Record($ipnum, ISP);
242             } else {
243 0 0       0 if ($ipv == 6) {
244 0         0 return $obj->getIPv6Record($ipnum, ISP);
245             } else {
246 0         0 return INVALID_IP_ADDRESS;
247             }
248             }
249             }
250              
251             sub getProxyType {
252 0     0 1 0 my $obj = shift(@_);
253 0         0 my $ipaddr = shift(@_);
254 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
255 0 0       0 if ($ipv == 4) {
256 0         0 return $obj->getIPv4Record($ipnum, PROXYTYPE);
257             } else {
258 0 0       0 if ($ipv == 6) {
259 0         0 return $obj->getIPv6Record($ipnum, PROXYTYPE);
260             } else {
261 0         0 return INVALID_IP_ADDRESS;
262             }
263             }
264             }
265              
266             sub isProxy {
267 0     0 1 0 my $obj = shift(@_);
268 0         0 my $ipaddr = shift(@_);
269 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
270 0 0       0 if ($ipv == 4) {
271 0         0 return $obj->getIPv4Record($ipnum, ISPROXY);
272             } else {
273 0 0       0 if ($ipv == 6) {
274 0         0 return $obj->getIPv6Record($ipnum, ISPROXY);
275             } else {
276 0         0 return -1;
277             }
278             }
279             }
280              
281             sub getDomain {
282 0     0 1 0 my $obj = shift(@_);
283 0         0 my $ipaddr = shift(@_);
284 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
285 0 0       0 if ($ipv == 4) {
286 0         0 return $obj->getIPv4Record($ipnum, DOMAIN);
287             } else {
288 0 0       0 if ($ipv == 6) {
289 0         0 return $obj->getIPv6Record($ipnum, DOMAIN);
290             } else {
291 0         0 return INVALID_IP_ADDRESS;
292             }
293             }
294             }
295              
296             sub getUsageType {
297 0     0 1 0 my $obj = shift(@_);
298 0         0 my $ipaddr = shift(@_);
299 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
300 0 0       0 if ($ipv == 4) {
301 0         0 return $obj->getIPv4Record($ipnum, USAGETYPE);
302             } else {
303 0 0       0 if ($ipv == 6) {
304 0         0 return $obj->getIPv6Record($ipnum, USAGETYPE);
305             } else {
306 0         0 return INVALID_IP_ADDRESS;
307             }
308             }
309             }
310              
311             sub getASN {
312 0     0 1 0 my $obj = shift(@_);
313 0         0 my $ipaddr = shift(@_);
314 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
315 0 0       0 if ($ipv == 4) {
316 0         0 return $obj->getIPv4Record($ipnum, ASN);
317             } else {
318 0 0       0 if ($ipv == 6) {
319 0         0 return $obj->getIPv6Record($ipnum, ASN);
320             } else {
321 0         0 return INVALID_IP_ADDRESS;
322             }
323             }
324             }
325              
326             sub getAS {
327 0     0 1 0 my $obj = shift(@_);
328 0         0 my $ipaddr = shift(@_);
329 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
330 0 0       0 if ($ipv == 4) {
331 0         0 return $obj->getIPv4Record($ipnum, AS);
332             } else {
333 0 0       0 if ($ipv == 6) {
334 0         0 return $obj->getIPv6Record($ipnum, AS);
335             } else {
336 0         0 return INVALID_IP_ADDRESS;
337             }
338             }
339             }
340              
341             sub getLastSeen {
342 0     0 1 0 my $obj = shift(@_);
343 0         0 my $ipaddr = shift(@_);
344 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
345 0 0       0 if ($ipv == 4) {
346 0         0 return $obj->getIPv4Record($ipnum, LASTSEEN);
347             } else {
348 0 0       0 if ($ipv == 6) {
349 0         0 return $obj->getIPv6Record($ipnum, LASTSEEN);
350             } else {
351 0         0 return INVALID_IP_ADDRESS;
352             }
353             }
354             }
355              
356             sub getThreat {
357 0     0 1 0 my $obj = shift(@_);
358 0         0 my $ipaddr = shift(@_);
359 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
360 0 0       0 if ($ipv == 4) {
361 0         0 return $obj->getIPv4Record($ipnum, THREAT);
362             } else {
363 0 0       0 if ($ipv == 6) {
364 0         0 return $obj->getIPv6Record($ipnum, THREAT);
365             } else {
366 0         0 return INVALID_IP_ADDRESS;
367             }
368             }
369             }
370              
371             sub getProvider {
372 0     0 1 0 my $obj = shift(@_);
373 0         0 my $ipaddr = shift(@_);
374 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
375 0 0       0 if ($ipv == 4) {
376 0         0 return $obj->getIPv4Record($ipnum, PROVIDER);
377             } else {
378 0 0       0 if ($ipv == 6) {
379 0         0 return $obj->getIPv6Record($ipnum, PROVIDER);
380             } else {
381 0         0 return INVALID_IP_ADDRESS;
382             }
383             }
384             }
385              
386             sub getFraudScore {
387 0     0 1 0 my $obj = shift(@_);
388 0         0 my $ipaddr = shift(@_);
389 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
390 0 0       0 if ($ipv == 4) {
391 0         0 return $obj->getIPv4Record($ipnum, FRAUDSCORE);
392             } else {
393 0 0       0 if ($ipv == 6) {
394 0         0 return $obj->getIPv6Record($ipnum, FRAUDSCORE);
395             } else {
396 0         0 return INVALID_IP_ADDRESS;
397             }
398             }
399             }
400              
401             sub getAll {
402 0     0 1 0 my $obj = shift(@_);
403 0         0 my $ipaddr = shift(@_);
404 0         0 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
405 0 0       0 if ($ipv == 4) {
406 0         0 return $obj->getIPv4Record($ipnum, ALL);
407             } else {
408 0 0       0 if ($ipv == 6) {
409 0         0 return $obj->getIPv6Record($ipnum, ALL);
410             } else {
411 0         0 return (-1, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS, INVALID_IP_ADDRESS);
412             }
413             }
414             }
415              
416             sub getIPv6Record {
417 3     3 0 7 my $obj = shift(@_);
418 3         4 my $ipnum = shift(@_);
419 3         5 my $mode = shift(@_);
420 3         7 my $dbtype = $obj->{"databasetype"};
421              
422 3 50       13 if ($ipnum eq "") {
423 0 0       0 if ($mode == ALL) {
424 0         0 return (-1, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP);
425             } else {
426 0 0       0 if ($mode == ISPROXY) {
427 0         0 return -1;
428             } else {
429 0         0 return NO_IP;
430             }
431             }
432             }
433              
434 3 50 33     141 if (($mode == COUNTRYSHORT) && ($IPV6_COUNTRY_POSITION[$dbtype] == 0)) {
435 0         0 return NOT_SUPPORTED;
436             }
437 3 50 33     15 if (($mode == COUNTRYLONG) && ($IPV6_COUNTRY_POSITION[$dbtype] == 0)) {
438 0         0 return NOT_SUPPORTED;
439             }
440 3 50 33     12 if (($mode == REGION) && ($IPV6_REGION_POSITION[$dbtype] == 0)) {
441 0         0 return NOT_SUPPORTED;
442             }
443 3 50 33     9 if (($mode == CITY) && ($IPV6_CITY_POSITION[$dbtype] == 0)) {
444 0         0 return NOT_SUPPORTED;
445             }
446 3 50 33     11 if (($mode == ISP) && ($IPV6_ISP_POSITION[$dbtype] == 0)) {
447 0         0 return NOT_SUPPORTED;
448             }
449 3 50 33     11 if (($mode == PROXYTYPE) && ($IPV6_PROXYTYPE_POSITION[$dbtype] == 0)) {
450 0         0 return NOT_SUPPORTED;
451             }
452 3 50 33     10 if (($mode == DOMAIN) && ($IPV6_DOMAIN_POSITION[$dbtype] == 0)) {
453 0         0 return NOT_SUPPORTED;
454             }
455 3 50 33     11 if (($mode == USAGETYPE) && ($IPV6_USAGETYPE_POSITION[$dbtype] == 0)) {
456 0         0 return NOT_SUPPORTED;
457             }
458 3 50 33     10 if (($mode == ASN) && ($IPV6_ASN_POSITION[$dbtype] == 0)) {
459 0         0 return NOT_SUPPORTED;
460             }
461 3 50 33     11 if (($mode == AS) && ($IPV6_AS_POSITION[$dbtype] == 0)) {
462 0         0 return NOT_SUPPORTED;
463             }
464 3 50 33     30 if (($mode == LASTSEEN) && ($IPV6_LASTSEEN_POSITION[$dbtype] == 0)) {
465 0         0 return NOT_SUPPORTED;
466             }
467 3 50 33     26 if (($mode == THREAT) && ($IPV6_THREAT_POSITION[$dbtype] == 0)) {
468 0         0 return NOT_SUPPORTED;
469             }
470 3 50 33     11 if (($mode == PROVIDER) && ($IPV6_PROVIDER_POSITION[$dbtype] == 0)) {
471 0         0 return NOT_SUPPORTED;
472             }
473 3 50 33     13 if (($mode == FRAUDSCORE) && ($IPV6_FRAUDSCORE_POSITION[$dbtype] == 0)) {
474 0         0 return NOT_SUPPORTED;
475             }
476            
477 3         14 my $realipno = Math::BigInt->new($ipnum);
478 3         295 my $handle = $obj->{"filehandle"};
479 3         7 my $baseaddr = $obj->{"ipv6databaseaddr"};
480 3         9 my $dbcount = $obj->{"ipv6databasecount"};
481 3         35 my $dbcolumn = $obj->{"databasecolumn"};
482 3         8 my $indexbaseaddr = $obj->{"ipv6indexbaseaddr"};
483              
484 3 50       9 if ($dbcount == 0) {
485 0 0       0 if ($mode == ALL) {
486 0         0 return (IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN, IPV6_ADDRESS_IN_IPV4_BIN);
487             } else {
488 0         0 return IPV6_ADDRESS_IN_IPV4_BIN;
489             }
490             }
491              
492 3         9 my $ipnum1_2 = new Math::BigInt($ipnum);
493 3         203 my $remainder = 0;
494 3         15 ($ipnum1_2, $remainder) = $ipnum1_2->bdiv(2**112);
495 3         2661 my $indexaddr = $indexbaseaddr + ($ipnum1_2 << 3);
496              
497 3         2121 my $low = 0;
498 3         7 my $high = $dbcount;
499 3 50       12 if ($indexbaseaddr > 0) {
500 3         17 ($low, $high) = $obj->read32x2($handle, $indexaddr);
501             }
502              
503 3         9 my $mid = 0;
504 3         5 my $ipfrom = 0;
505 3         7 my $ipto = 0;
506 3         6 my $ipno = 0;
507              
508 3         6 $ipno = $realipno;
509 3 50       15 if ($realipno == "340282366920938463463374607431768211455") {
510 0         0 $ipno = $ipno->bsub(1);
511             }
512            
513 3         787 my $raw_positions_row;
514              
515 3         13 while ($low <= $high) {
516 4         16 $mid = int(($low + $high)/2);
517 4         27 ($ipfrom, $ipto, $raw_positions_row) = $obj->readRow128($handle, $baseaddr + $mid * (($dbcolumn * 4) + 12), $dbcolumn);
518              
519 4 100 66     199 if (($ipno >= $ipfrom) && ($ipno < $ipto)) {
520 3         1404 my $row_pointer = $baseaddr + $mid * (($dbcolumn * 4) + 12);
521              
522 3 50       14 if ($mode == ALL) {
523 0         0 my $countryshort = NOT_SUPPORTED;
524 0         0 my $countrylong = NOT_SUPPORTED;
525 0         0 my $region = NOT_SUPPORTED;
526 0         0 my $city = NOT_SUPPORTED;
527 0         0 my $isp = NOT_SUPPORTED;
528 0         0 my $proxytype = NOT_SUPPORTED;
529 0         0 my $domain = NOT_SUPPORTED;
530 0         0 my $usagetype = NOT_SUPPORTED;
531 0         0 my $asn = NOT_SUPPORTED;
532 0         0 my $as = NOT_SUPPORTED;
533 0         0 my $lastseen = NOT_SUPPORTED;
534 0         0 my $threat = NOT_SUPPORTED;
535 0         0 my $provider = NOT_SUPPORTED;
536 0         0 my $fraudscore = NOT_SUPPORTED;
537 0         0 my $isproxy = -1;
538            
539 0 0       0 if ($IPV6_COUNTRY_POSITION[$dbtype] != 0) {
540 0         0 $countryshort = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_COUNTRY_POSITION[$dbtype]), 4)));
541 0         0 $countrylong = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_COUNTRY_POSITION[$dbtype]), 4)) + 3);
542             }
543 0 0       0 if ($IPV6_REGION_POSITION[$dbtype] != 0) {
544 0         0 $region = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_REGION_POSITION[$dbtype]), 4)));
545             }
546 0 0       0 if ($IPV6_CITY_POSITION[$dbtype] != 0) {
547 0         0 $city = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_CITY_POSITION[$dbtype]), 4)));
548             }
549 0 0       0 if ($IPV6_ISP_POSITION[$dbtype] != 0) {
550 0         0 $isp = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_ISP_POSITION[$dbtype]), 4)));
551             }
552 0 0       0 if ($IPV6_PROXYTYPE_POSITION[$dbtype] != 0) {
553 0         0 $proxytype = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_PROXYTYPE_POSITION[$dbtype]), 4)));
554             }
555 0 0       0 if ($IPV6_DOMAIN_POSITION[$dbtype] != 0) {
556 0         0 $domain = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_DOMAIN_POSITION[$dbtype]), 4)));
557             }
558 0 0       0 if ($IPV6_USAGETYPE_POSITION[$dbtype] != 0) {
559 0         0 $usagetype = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_USAGETYPE_POSITION[$dbtype]), 4)));
560             }
561 0 0       0 if ($IPV6_ASN_POSITION[$dbtype] != 0) {
562 0         0 $asn = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_ASN_POSITION[$dbtype]), 4)));
563             }
564 0 0       0 if ($IPV6_AS_POSITION[$dbtype] != 0) {
565 0         0 $as = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_AS_POSITION[$dbtype]), 4)));
566             }
567 0 0       0 if ($IPV6_LASTSEEN_POSITION[$dbtype] != 0) {
568 0         0 $lastseen = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_LASTSEEN_POSITION[$dbtype]), 4)));
569             }
570 0 0       0 if ($IPV6_THREAT_POSITION[$dbtype] != 0) {
571 0         0 $threat = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_THREAT_POSITION[$dbtype]), 4)));
572             }
573 0 0       0 if ($IPV6_PROVIDER_POSITION[$dbtype] != 0) {
574 0         0 $provider = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_PROVIDER_POSITION[$dbtype]), 4)));
575             }
576 0 0       0 if ($IPV6_FRAUDSCORE_POSITION[$dbtype] != 0) {
577 0         0 $fraudscore = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_FRAUDSCORE_POSITION[$dbtype]), 4)));
578             }
579              
580 0 0 0     0 if (($countryshort eq "-") || ($proxytype eq "-")) {
581 0         0 $isproxy = 0;
582             } else {
583 0 0 0     0 if (($proxytype eq "DCH") || ($proxytype eq "SES") || ($proxytype eq "AIC")) {
      0        
584 0         0 $isproxy = 2;
585             } else {
586 0         0 $isproxy = 1;
587             }
588             }
589 0         0 return ($isproxy, $proxytype, $countryshort, $countrylong, $region, $city, $isp, $domain, $usagetype, $asn, $as, $lastseen, $threat, $provider, $fraudscore);
590             }
591 3 50       12 if ($mode == COUNTRYSHORT) {
592 3         29 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_COUNTRY_POSITION[$dbtype]), 4)));
593             }
594 0 0       0 if ($mode == COUNTRYLONG) {
595 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_COUNTRY_POSITION[$dbtype]), 4)) + 3);
596             }
597 0 0       0 if ($mode == REGION) {
598 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_REGION_POSITION[$dbtype]), 4)));
599             }
600 0 0       0 if ($mode == CITY) {
601 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_CITY_POSITION[$dbtype]), 4)));
602             }
603 0 0       0 if ($mode == ISP) {
604 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_ISP_POSITION[$dbtype]), 4)));
605             }
606 0 0       0 if ($mode == PROXYTYPE) {
607 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_PROXYTYPE_POSITION[$dbtype]), 4)));
608             }
609 0 0       0 if ($mode == DOMAIN) {
610 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_DOMAIN_POSITION[$dbtype]), 4)));
611             }
612 0 0       0 if ($mode == USAGETYPE) {
613 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_USAGETYPE_POSITION[$dbtype]), 4)));
614             }
615 0 0       0 if ($mode == ASN) {
616 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_ASN_POSITION[$dbtype]), 4)));
617             }
618 0 0       0 if ($mode == AS) {
619 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_AS_POSITION[$dbtype]), 4)));
620             }
621 0 0       0 if ($mode == LASTSEEN) {
622 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_LASTSEEN_POSITION[$dbtype]), 4)));
623             }
624 0 0       0 if ($mode == THREAT) {
625 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_THREAT_POSITION[$dbtype]), 4)));
626             }
627 0 0       0 if ($mode == PROVIDER) {
628 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_PROVIDER_POSITION[$dbtype]), 4)));
629             }
630 0 0       0 if ($mode == FRAUDSCORE) {
631 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_FRAUDSCORE_POSITION[$dbtype]), 4)));
632             }
633              
634 0 0       0 if ($mode == ISPROXY) {
635 0         0 my $countryshort = NOT_SUPPORTED;
636 0         0 my $proxytype = NOT_SUPPORTED;
637 0         0 my $isproxy = NOT_SUPPORTED;
638 0 0       0 if ($IPV6_PROXYTYPE_POSITION[$dbtype] == 0) {
639             # PX1, use country as detection
640 0         0 $countryshort = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_COUNTRY_POSITION[$dbtype]), 4)));
641             } else {
642 0         0 $proxytype = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 8 + 4 * ($IPV6_PROXYTYPE_POSITION[$dbtype]), 4)));
643             }
644 0 0 0     0 if (($countryshort eq "-") || ($proxytype eq "-")) {
645 0         0 $isproxy = 0;
646             } else {
647 0 0 0     0 if (($proxytype eq "DCH") || ($proxytype eq "SES") || ($proxytype eq "AIC")) {
      0        
648 0         0 $isproxy = 2;
649             } else {
650 0         0 $isproxy = 1;
651             }
652             }
653 0         0 return $isproxy;
654             }
655             } else {
656 1 50       180 if ($ipno < $ipfrom) {
657 1         323 $high = $mid - 1;
658             } else {
659 0         0 $low = $mid + 1;
660             }
661             }
662             }
663 0 0       0 if ($mode == ALL) {
664 0         0 return (-1, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN);
665             } else {
666 0 0       0 if ($mode == ISPROXY) {
667 0         0 return -1;
668             } else {
669 0         0 return UNKNOWN;
670             }
671             }
672             }
673              
674             sub getIPv4Record {
675 3     3 0 4 my $obj = shift(@_);
676 3         5 my $ipnum = shift(@_);
677 3         6 my $mode = shift(@_);
678 3         6 my $dbtype= $obj->{"databasetype"};
679              
680 3 50       8 if ($ipnum eq "") {
681 0 0       0 if ($mode == ALL) {
682 0         0 return (-1, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP, NO_IP);
683             } else {
684 0 0       0 if ($mode == ISPROXY) {
685 0         0 return -1;
686             } else {
687 0         0 return NO_IP;
688             }
689             }
690             }
691            
692 3 50 33     15 if (($mode == COUNTRYSHORT) && ($IPV4_COUNTRY_POSITION[$dbtype] == 0)) {
693 0         0 return NOT_SUPPORTED;
694             }
695 3 50 33     9 if (($mode == COUNTRYLONG) && ($IPV4_COUNTRY_POSITION[$dbtype] == 0)) {
696 0         0 return NOT_SUPPORTED;
697             }
698 3 50 33     49 if (($mode == REGION) && ($IPV4_REGION_POSITION[$dbtype] == 0)) {
699 0         0 return NOT_SUPPORTED;
700             }
701 3 50 33     8 if (($mode == CITY) && ($IPV4_CITY_POSITION[$dbtype] == 0)) {
702 0         0 return NOT_SUPPORTED;
703             }
704 3 50 33     9 if (($mode == ISP) && ($IPV4_ISP_POSITION[$dbtype] == 0)) {
705 0         0 return NOT_SUPPORTED;
706             }
707 3 50 33     15 if (($mode == PROXYTYPE) && ($IPV4_PROXYTYPE_POSITION[$dbtype] == 0)) {
708 0         0 return NOT_SUPPORTED;
709             }
710 3 50 33     16 if (($mode == DOMAIN) && ($IPV4_DOMAIN_POSITION[$dbtype] == 0)) {
711 0         0 return NOT_SUPPORTED;
712             }
713 3 50 33     8 if (($mode == USAGETYPE) && ($IPV4_USAGETYPE_POSITION[$dbtype] == 0)) {
714 0         0 return NOT_SUPPORTED;
715             }
716 3 50 33     7 if (($mode == ASN) && ($IPV4_ASN_POSITION[$dbtype] == 0)) {
717 0         0 return NOT_SUPPORTED;
718             }
719 3 50 33     7 if (($mode == AS) && ($IPV4_AS_POSITION[$dbtype] == 0)) {
720 0         0 return NOT_SUPPORTED;
721             }
722 3 50 33     7 if (($mode == LASTSEEN) && ($IPV4_LASTSEEN_POSITION[$dbtype] == 0)) {
723 0         0 return NOT_SUPPORTED;
724             }
725 3 50 33     8 if (($mode == THREAT) && ($IPV4_THREAT_POSITION[$dbtype] == 0)) {
726 0         0 return NOT_SUPPORTED;
727             }
728 3 50 33     7 if (($mode == PROVIDER) && ($IPV4_PROVIDER_POSITION[$dbtype] == 0)) {
729 0         0 return NOT_SUPPORTED;
730             }
731 3 50 33     5 if (($mode == FRAUDSCORE) && ($IPV4_FRAUDSCORE_POSITION[$dbtype] == 0)) {
732 0         0 return NOT_SUPPORTED;
733             }
734              
735 3         4 my $realipno = $ipnum;
736 3         5 my $handle = $obj->{"filehandle"};
737 3         5 my $baseaddr = $obj->{"ipv4databaseaddr"};
738 3         4 my $dbcount = $obj->{"ipv4databasecount"};
739 3         5 my $dbcolumn = $obj->{"databasecolumn"};
740 3         4 my $indexbaseaddr = $obj->{"ipv4indexbaseaddr"};
741              
742 3         5 my $ipnum1_2 = int($ipnum >> 16);
743 3         5 my $indexaddr = $indexbaseaddr + ($ipnum1_2 << 3);
744              
745 3         3 my $low = 0;
746 3         9 my $high = $dbcount;
747 3 50       6 if ($indexbaseaddr > 0) {
748 3         8 ($low, $high) = $obj->read32x2($handle, $indexaddr);
749             }
750 3         13 my $mid = 0;
751 3         5 my $ipfrom = 0;
752 3         5 my $ipto = 0;
753 3         3 my $ipno = 0;
754              
755 3 50       9 if ($realipno == MAX_IPV4_RANGE) {
756 0         0 $ipno = $realipno - 1;
757             } else {
758 3         6 $ipno = $realipno;
759             }
760            
761 3         3 my $raw_positions_row;
762              
763 3         9 while ($low <= $high) {
764 15         22 $mid = int(($low + $high) >> 1);
765 15         39 ($ipfrom, $ipto, $raw_positions_row) = $obj->readRow32($handle, $baseaddr + $mid * $dbcolumn * 4, $dbcolumn);
766            
767 15 100 100     45 if (($ipno >= $ipfrom) && ($ipno < $ipto)) {
768 3 50       5 if ($mode == ALL) {
769 0         0 my $countryshort = NOT_SUPPORTED;
770 0         0 my $countrylong = NOT_SUPPORTED;
771 0         0 my $region = NOT_SUPPORTED;
772 0         0 my $city = NOT_SUPPORTED;
773 0         0 my $isp = NOT_SUPPORTED;
774 0         0 my $proxytype = NOT_SUPPORTED;
775 0         0 my $domain = NOT_SUPPORTED;
776 0         0 my $usagetype = NOT_SUPPORTED;
777 0         0 my $asn = NOT_SUPPORTED;
778 0         0 my $as = NOT_SUPPORTED;
779 0         0 my $lastseen = NOT_SUPPORTED;
780 0         0 my $threat = NOT_SUPPORTED;
781 0         0 my $provider = NOT_SUPPORTED;
782 0         0 my $fraudscore = NOT_SUPPORTED;
783 0         0 my $isproxy = -1;
784              
785 0 0       0 if ($IPV4_COUNTRY_POSITION[$dbtype] != 0) {
786 0         0 my $pos = unpack("V", substr($raw_positions_row, 4 * ($IPV4_COUNTRY_POSITION[$dbtype]-1), 4));
787 0         0 $countryshort = $obj->readStr($handle, $pos);
788 0         0 $countrylong = $obj->readStr($handle, $pos + 3);
789             }
790 0 0       0 if ($IPV4_REGION_POSITION[$dbtype] != 0) {
791 0         0 $region = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_REGION_POSITION[$dbtype]-1), 4)));
792             }
793 0 0       0 if ($IPV4_CITY_POSITION[$dbtype] != 0) {
794 0         0 $city = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_CITY_POSITION[$dbtype]-1), 4)));
795             }
796 0 0       0 if ($IPV4_ISP_POSITION[$dbtype] != 0) {
797 0         0 $isp = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_ISP_POSITION[$dbtype]-1), 4)));
798             }
799 0 0       0 if ($IPV4_PROXYTYPE_POSITION[$dbtype] != 0) {
800 0         0 $proxytype = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_PROXYTYPE_POSITION[$dbtype]-1), 4)));
801             }
802 0 0       0 if ($IPV4_DOMAIN_POSITION[$dbtype] != 0) {
803 0         0 $domain = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_DOMAIN_POSITION[$dbtype]-1), 4)));
804             }
805 0 0       0 if ($IPV4_USAGETYPE_POSITION[$dbtype] != 0) {
806 0         0 $usagetype = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_USAGETYPE_POSITION[$dbtype]-1), 4)));
807             }
808 0 0       0 if ($IPV4_ASN_POSITION[$dbtype] != 0) {
809 0         0 $asn = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_ASN_POSITION[$dbtype]-1), 4)));
810             }
811 0 0       0 if ($IPV4_AS_POSITION[$dbtype] != 0) {
812 0         0 $as = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_AS_POSITION[$dbtype]-1), 4)));
813             }
814 0 0       0 if ($IPV4_LASTSEEN_POSITION[$dbtype] != 0) {
815 0         0 $lastseen = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_LASTSEEN_POSITION[$dbtype]-1), 4)));
816             }
817 0 0       0 if ($IPV4_THREAT_POSITION[$dbtype] != 0) {
818 0         0 $threat = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_THREAT_POSITION[$dbtype]-1), 4)));
819             }
820 0 0       0 if ($IPV4_PROVIDER_POSITION[$dbtype] != 0) {
821 0         0 $provider = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_PROVIDER_POSITION[$dbtype]-1), 4)));
822             }
823 0 0       0 if ($IPV4_FRAUDSCORE_POSITION[$dbtype] != 0) {
824 0         0 $fraudscore = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_FRAUDSCORE_POSITION[$dbtype]-1), 4)));
825             }
826              
827 0 0       0 if ($countryshort eq "-") {
828 0         0 $isproxy = 0;
829             } else {
830 0 0 0     0 if (($proxytype eq "DCH") || ($proxytype eq "SES") || ($proxytype eq "AIC")) {
      0        
831 0         0 $isproxy = 2;
832             } else {
833 0         0 $isproxy = 1;
834             }
835             }
836 0         0 return ($isproxy, $proxytype, $countryshort, $countrylong, $region, $city, $isp, $domain, $usagetype, $asn, $as, $lastseen, $threat, $provider, $fraudscore);
837             }
838 3 50       20 if ($mode == COUNTRYSHORT) {
839 3         13 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_COUNTRY_POSITION[$dbtype]-1), 4)));
840             }
841 0 0       0 if ($mode == COUNTRYLONG) {
842 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_COUNTRY_POSITION[$dbtype]-1), 4))+3);
843             }
844 0 0       0 if ($mode == REGION) {
845 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_REGION_POSITION[$dbtype]-1), 4)));
846             }
847 0 0       0 if ($mode == CITY) {
848 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_CITY_POSITION[$dbtype]-1), 4)));
849             }
850 0 0       0 if ($mode == ISP) {
851 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_ISP_POSITION[$dbtype]-1), 4)));
852             }
853 0 0       0 if ($mode == PROXYTYPE) {
854 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_PROXYTYPE_POSITION[$dbtype]-1), 4)));
855             }
856 0 0       0 if ($mode == DOMAIN) {
857 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_DOMAIN_POSITION[$dbtype]-1), 4)));
858             }
859 0 0       0 if ($mode == USAGETYPE) {
860 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_USAGETYPE_POSITION[$dbtype]-1), 4)));
861             }
862 0 0       0 if ($mode == ASN) {
863 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_ASN_POSITION[$dbtype]-1), 4)));
864             }
865 0 0       0 if ($mode == AS) {
866 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_AS_POSITION[$dbtype]-1), 4)));
867             }
868 0 0       0 if ($mode == LASTSEEN) {
869 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_LASTSEEN_POSITION[$dbtype]-1), 4)));
870             }
871 0 0       0 if ($mode == THREAT) {
872 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_THREAT_POSITION[$dbtype]-1), 4)));
873             }
874 0 0       0 if ($mode == PROVIDER) {
875 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_PROVIDER_POSITION[$dbtype]-1), 4)));
876             }
877 0 0       0 if ($mode == FRAUDSCORE) {
878 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_FRAUDSCORE_POSITION[$dbtype]-1), 4)));
879             }
880 0 0       0 if ($mode == ISPROXY) {
881 0         0 my $countryshort = NOT_SUPPORTED;
882 0         0 my $proxytype = NOT_SUPPORTED;
883 0         0 my $isproxy = NOT_SUPPORTED;
884 0 0       0 if ($IPV4_PROXYTYPE_POSITION[$dbtype] == 0) {
885             # PX1, use country as detection
886 0         0 $countryshort = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_COUNTRY_POSITION[$dbtype]-1), 4)));
887             } else {
888 0         0 $proxytype = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV4_PROXYTYPE_POSITION[$dbtype]-1), 4)));
889             }
890 0 0 0     0 if (($countryshort eq "-") || ($proxytype eq "-")) {
891 0         0 $isproxy = 0;
892             } else {
893 0 0 0     0 if (($proxytype eq "DCH") || ($proxytype eq "SES") || ($proxytype eq "AIC")) {
      0        
894 0         0 $isproxy = 2;
895             } else {
896 0         0 $isproxy = 1;
897             }
898             }
899 0         0 return $isproxy;
900             }
901             } else {
902 12 100       36 if ($ipno < $ipfrom) {
903 9         25 $high = $mid - 1;
904             } else {
905 3         6 $low = $mid + 1;
906             }
907             }
908             }
909 0 0       0 if ($mode == ALL) {
910 0         0 return (-1, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN);
911             } else {
912 0 0       0 if ($mode == ISPROXY) {
913 0         0 return -1;
914             } else {
915 0         0 return UNKNOWN;
916             }
917             }
918             }
919              
920             sub readRow32 {
921 15     15 0 27 my ($obj, $handle, $position, $column) = @_;
922 15         39 my $data = "";
923 15         20 my $data_length = $column * 4 + 4;
924 15         114 seek($handle, $position-1, 0);
925 15         95 read($handle, $data, $data_length);
926 15         30 my $ipfrom = substr($data, 0, 4);
927 15         26 my $ipfrom_next = substr($data, $data_length - 4, 4);
928 15         21 my $result_row = substr($data, 0, $data_length - 4);
929 15         59 return (unpack("V", $ipfrom), unpack("V", $ipfrom_next), $result_row);
930             }
931              
932             sub readRow128 {
933 4     4 0 13 my ($obj, $handle, $position, $column) = @_;
934 4         9 my $data = "";
935 4         9 my $data_length = $column * 4 + 12 + 16;
936 4         54 seek($handle, $position-1, 0);
937 4         59 read($handle, $data, $data_length);
938 4         13 my $ipfrom = substr($data, 0, 16);
939 4         11 my $ipfrom_next = substr($data, $data_length - 16, 16);
940 4         10 my $result_row = substr($data, 0, $data_length - 16);
941 4         15 return (&bytesInt($ipfrom), &bytesInt($ipfrom_next), $result_row);
942             }
943              
944             sub read512 {
945 2     2 0 6 my ($obj, $handle, $position) = @_;
946 2         4 my $data = "";
947 2         13 seek($handle, $position-1, 0);
948 2         72 read($handle, $data, 64);
949 2         60 my @data_array = split('', $data);
950 2         13 while ($#data_array < 63) {
951 0         0 $data_array[$#data_array+1] = 0x00;
952             }
953 2         77 return @data_array;
954             }
955              
956             sub read32x2 {
957 6     6 0 15 my ($obj, $handle, $position) = @_;
958 6         12 my $data = "";
959 6         52 seek($handle, $position-1, 0);
960 6         1359 read($handle, $data, 8);
961 6         22 my $data_1 = substr($data, 0, 4);
962 6         19 my $data_2 = substr($data, 4, 4);
963 6         35 return (unpack("V", $data_1), unpack("V", $data_2));
964             }
965              
966             sub read128 {
967 0     0 0 0 my ($obj, $handle, $position) = @_;
968 0         0 my $data = "";
969 0         0 seek($handle, $position-1, 0);
970 0         0 read($handle, $data, 16);
971 0         0 return &bytesInt($data);
972             }
973              
974             sub read32 {
975 0     0 0 0 my ($obj, $handle, $position) = @_;
976 0         0 my $data = "";
977 0         0 seek($handle, $position-1, 0);
978 0         0 read($handle, $data, 4);
979 0         0 return unpack("V", $data);
980             }
981              
982             sub read8 {
983 0     0 0 0 my ($obj, $handle, $position) = @_;
984 0         0 my $data = "";
985 0         0 seek($handle, $position-1, 0);
986 0         0 read($handle, $data, 1);
987 0         0 return unpack("C", $data);
988             }
989              
990             sub readStr {
991 6     6 0 15 my ($obj, $handle, $position) = @_;
992 6         12 my $data = "";
993 6         12 my $string = "";
994 6         95 seek($handle, $position, 0);
995 6         84 read($handle, $data, 1);
996 6         21 read($handle, $string, unpack("C", $data));
997 6         72 return $string;
998             }
999              
1000             sub readFloat {
1001 0     0 0 0 my ($obj, $handle, $position) = @_;
1002 0         0 my $data = "";
1003 0         0 seek($handle, $position-1, 0);
1004 0         0 read($handle, $data, 4);
1005              
1006 0         0 my $is_little_endian = unpack("h*", pack("s", 1));
1007 0 0       0 if ($is_little_endian =~ m/^1/) {
1008             # "LITTLE ENDIAN - x86\n";
1009 0         0 return unpack("f", $data);
1010             } else {
1011             # "BIG ENDIAN - MAC\n";
1012 0         0 return unpack("f", reverse($data));
1013             }
1014             }
1015              
1016             sub bytesInt {
1017 8     8 0 194 my $binip = shift(@_);
1018 8         49 my @array = split(//, $binip);
1019 8 50       52 return 0 if ($#array != 15);
1020 8         39 my $ip96_127 = unpack("V", $array[0] . $array[1] . $array[2] . $array[3]);
1021 8         19 my $ip64_95 = unpack("V", $array[4] . $array[5] . $array[6] . $array[7]);
1022 8         22 my $ip32_63 = unpack("V", $array[8] . $array[9] . $array[10] . $array[11]);
1023 8         19 my $ip1_31 = unpack("V", $array[12] . $array[13] . $array[14] . $array[15]);
1024              
1025 8         42 my $big1 = Math::BigInt->new("$ip96_127");
1026 8         837 my $big2 = Math::BigInt->new("$ip64_95")->blsft(32);
1027 8         4884 my $big3 = Math::BigInt->new("$ip32_63")->blsft(64);
1028 8         4736 my $big4 = Math::BigInt->new("$ip1_31")->blsft(96);
1029 8         4747 $big1 = $big1->badd($big2)->badd($big3)->badd($big4);
1030            
1031 8         2431 return $big1->bstr();
1032             }
1033              
1034             sub validateIP {
1035 6     6 0 12 my $obj = shift(@_);
1036 6         13 my $ip = shift(@_);
1037 6         25 my $ipv = -1;
1038 6         11 my $ipnum = -1;
1039            
1040             #name server lookup if domain name
1041 6         22 $ip = $obj->nameIP($ip);
1042            
1043 6 100       20 if ($obj->isIPv4($ip)) {
1044             #ipv4 address
1045 3         4 $ipv = 4;
1046 3         9 $ipnum = $obj->ipNo($ip);
1047             } else {
1048             #expand ipv6 address
1049 3         11 $ip = $obj->expandIPv6Address($ip);
1050 3 50       10 if ($obj->isIPv6($ip)) {
1051             #ipv6 address
1052 3         6 $ipv = 6;
1053 3         12 $ipnum = $obj->hexInt($ip);
1054            
1055             #reformat ipv4 address in ipv6
1056 3 50 66     15 if (($ipnum >= 281470681743360) && ($ipnum <= 281474976710655)) {
1057 0         0 $ipv = 4;
1058 0         0 $ipnum = $ipnum - 281470681743360;
1059             }
1060             #reformat 6to4 address to ipv4 address 2002:: to 2002:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
1061 3 50 66     1131 if (($ipnum >= 42545680458834377588178886921629466624) && ($ipnum <= 42550872755692912415807417417958686719)) {
1062 0         0 $ipv = 4;
1063             #bitshift right 80 bits
1064 0         0 $ipnum->brsft(80);
1065             #bitwise modulus to get the last 32 bit
1066 0         0 $ipnum->bmod(4294967296);
1067             }
1068             #reformat Teredo address to ipv4 address 2001:0000:: to 2001:0000:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:
1069 3 50 66     2941 if (($ipnum >= 42540488161975842760550356425300246528) && ($ipnum <= 42540488241204005274814694018844196863)) {
1070 0         0 $ipv = 4;
1071 0         0 $ipnum = Math::BigInt->new($ipnum);
1072             #bitwise not to invert binary
1073 0         0 $ipnum->bnot();
1074             #bitwise modulus to get the last 32 bit
1075 0         0 $ipnum->bmod(4294967296);
1076             }
1077             } else {
1078             #not IPv4 and IPv6
1079             }
1080             }
1081 6         2013 return ($ipv, $ipnum);
1082             }
1083              
1084             sub expandIPv6Address {
1085 3     3 0 7 my $obj = shift(@_);
1086 3         5 my $ip = shift(@_);
1087 3         9 $ip =~ s/\:\:/\:Z\:/;
1088 3         15 my @ip = split(/\:/, $ip);
1089 3         6 my $num = scalar(@ip);
1090              
1091 3         6 my $l = 8;
1092 3 50       11 if ($ip[$#ip] =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
1093 0         0 my $a = sprintf("%x", ($1*256 + $2));
1094 0         0 my $b = sprintf("%x", ($3*256 + $4));
1095 0         0 $ip[$#ip] = $a;
1096 0         0 $ip[$#ip+1] = $b;
1097 0         0 $l--;
1098             }
1099              
1100 3 50       9 if ($#ip == 8) {
1101 0         0 shift(@ip);
1102 0         0 $l++;
1103             }
1104              
1105 3         10 foreach (0..(scalar(@ip)-1)) {
1106 24         46 $ip[$_] = ('0'x(4-length ($ip[$_]))).$ip[$_];
1107             }
1108              
1109 3         9 foreach (0..(scalar(@ip)-1)) {
1110 24 50       43 next unless ($ip[$_] eq '000Z');
1111 0         0 my @empty = map { $_ = '0'x4 } (0..7);
  0         0  
1112 0         0 $ip[$_] = join(':', @empty[0..$l-$num]);
1113 0         0 last;
1114             }
1115              
1116 3         18 return (uc(join ':', @ip));
1117             }
1118              
1119             sub hexInt {
1120 3     3 0 8 my $obj = shift(@_);
1121 3         7 my $hexip = shift(@_);
1122              
1123 3         19 $hexip =~ s/\://g;
1124              
1125 3 50       24 unless (length($hexip) == 32) {
1126 0         0 return 0;
1127             };
1128              
1129 3         26 my $binip = unpack('B128', pack('H32', $hexip));
1130 3         34 my ($n, $dec) = (Math::BigInt->new(1), Math::BigInt->new(0));
1131              
1132 3         693 foreach (reverse (split('', $binip))) {
1133 384 100       87158 $_ && ($dec += $n);
1134 384         2912 $n *= 2;
1135             }
1136              
1137 3         800 $dec =~ s/^\+//;
1138 3         189 return $dec;
1139             }
1140              
1141             sub ipNo {
1142 3     3 0 5 my $obj = shift(@_);
1143 3         6 my $ip = shift(@_);
1144 3         9 my @block = split(/\./, $ip);
1145 3         6 my $no = 0;
1146 3         5 $no = $block[3];
1147 3         7 $no = $no + $block[2] * 256;
1148 3         6 $no = $no + $block[1] * 256 * 256;
1149 3         5 $no = $no + $block[0] * 256 * 256 * 256;
1150 3         22 return $no;
1151             }
1152              
1153             sub nameIP {
1154 6     6 0 12 my $obj = shift(@_);
1155 6         13 my $host = shift(@_);
1156 6         8 my $ip_address = "";
1157 6 50 66     1562 if (($host =~ m/^$IPv4_re$/) || ($host =~ m/^$IPv6_re$/) || ($host =~ m/^\:\:$/)) {
      33        
1158 6         21 $ip_address = $host;
1159             } else {
1160             # TO_DO: Can we return IPv6 address too?
1161 0         0 $ip_address = join('.', unpack('C4',(gethostbyname($host))[4]));
1162             }
1163 6         40 return $ip_address;
1164             }
1165              
1166             sub isIPv4 {
1167 6     6 0 11 my $obj = shift(@_);
1168 6         14 my $ip = shift(@_);
1169 6 100       126 if ($ip =~ m/^$IPv4_re$/) {
1170 3         16 my @octet = split(/\./, $ip);
1171 3         13 foreach my $i (0 .. $#octet) {
1172 12 50 33     43 return 0 if (($octet[$i] > 255) || ($octet[$i] < 0));
1173             }
1174 3         13 return 1;
1175             } else {
1176 3         10 return 0;
1177             }
1178             }
1179              
1180             sub isIPv6 {
1181 3     3 0 6 my $obj = shift(@_);
1182 3         6 my $ip = shift(@_);
1183 3 50 33     1343 if (($ip =~ m/^$IPv6_re$/) || ($ip =~ m/^$IPv4_re$/)) {
1184 3         16 return 1;
1185             } else {
1186 0           return 0;
1187             }
1188             }
1189              
1190             1;
1191             __END__