File Coverage

blib/lib/Geo/IP2Proxy.pm
Criterion Covered Total %
statement 345 763 45.2
branch 71 338 21.0
condition 46 138 33.3
subroutine 49 73 67.1
pod 21 42 50.0
total 532 1354 39.2


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   43661 use strict;
  3         5  
  3         146  
26 3     3   17 use vars qw(@ISA $VERSION @EXPORT);
  3         5  
  3         197  
27 3     3   4778 use Math::BigInt;
  3         197394  
  3         11  
28              
29             $VERSION = '3.50';
30              
31             require Exporter;
32             @ISA = qw(Exporter);
33              
34 3     3   82040 use constant UNKNOWN => "UNKNOWN IP ADDRESS";
  3         8  
  3         198  
35 3     3   14 use constant IPV6_ADDRESS_IN_IPV4_BIN => "IPV6 ADDRESS MISSING IN IPV4 BIN";
  3         5  
  3         1161  
36 3     3   24 use constant NO_IP => "MISSING IP ADDRESS";
  3         5  
  3         141  
37 3     3   12 use constant INVALID_IPV6_ADDRESS => "INVALID IPV6 ADDRESS";
  3         5  
  3         103  
38 3     3   11 use constant INVALID_IPV4_ADDRESS => "INVALID IPV4 ADDRESS";
  3         8  
  3         146  
39 3     3   12 use constant INVALID_IP_ADDRESS => "INVALID IP ADDRESS";
  3         4  
  3         131  
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         5  
  3         100  
41 3     3   12 use constant NOT_SUPPORTED => "NOT SUPPORTED";
  3         7  
  3         133  
42 3     3   22 use constant MAX_IPV4_RANGE => 4294967295;
  3         6  
  3         130  
43 3     3   12 use constant MAX_IPV6_RANGE => 340282366920938463463374607431768211455;
  3         5  
  3         106  
44              
45 3     3   10 use constant COUNTRYSHORT => 1;
  3         4  
  3         130  
46 3     3   25 use constant COUNTRYLONG => 2;
  3         5  
  3         106  
47 3     3   11 use constant REGION => 3;
  3         3  
  3         89  
48 3     3   11 use constant CITY => 4;
  3         5  
  3         136  
49 3     3   10 use constant ISP => 5;
  3         4  
  3         99  
50 3     3   10 use constant PROXYTYPE => 6;
  3         5  
  3         103  
51 3     3   15 use constant ISPROXY => 7;
  3         3  
  3         150  
52 3     3   24 use constant DOMAIN => 8;
  3         4  
  3         102  
53 3     3   11 use constant USAGETYPE => 9;
  3         3  
  3         94  
54 3     3   10 use constant ASN => 10;
  3         5  
  3         96  
55 3     3   11 use constant AS => 11;
  3         5  
  3         96  
56 3     3   11 use constant LASTSEEN => 12;
  3         4  
  3         120  
57 3     3   12 use constant THREAT => 13;
  3         14  
  3         109  
58 3     3   11 use constant PROVIDER => 14;
  3         8  
  3         115  
59 3     3   10 use constant FRAUDSCORE => 15;
  3         4  
  3         98  
60              
61 3     3   25 use constant ALL => 100;
  3         12  
  3         134  
62 3     3   10 use constant IPV4 => 0;
  3         5  
  3         106  
63 3     3   10 use constant IPV6 => 1;
  3         4  
  3         32503  
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 283056 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         27 my ($class, $db_file) = @_;
104 2         5 my $handle;
105             my $obj;
106 2 50       141 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         8 binmode($handle);
111 2         100 $obj = bless {filehandle => $handle}, $class;
112 2         13 $obj->initialize();
113 2 50       8 if ($obj->{"productcode"} == 2) {
114             } else {
115 2 50 33     15 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         8 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 5 my ($obj) = @_;
137 2         24 my @header = $obj->read512($obj->{filehandle}, 1);
138 2         14 $obj->{"databasetype"} = unpack("C", $header[0]);
139 2         6 $obj->{"databasecolumn"} = unpack("C", $header[1]);
140 2         13 $obj->{"databaseyear"} = unpack("C", $header[2]);
141 2         5 $obj->{"databasemonth"} = unpack("C", $header[3]);
142 2         9 $obj->{"databaseday"} = unpack("C", $header[4]);
143 2         14 $obj->{"ipv4databasecount"} = unpack("V", join('', @header[5..8]));
144 2         9 $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         5 $obj->{"ipv4indexbaseaddr"} = unpack("V", join('', @header[21..24]));
148 2         8 $obj->{"ipv6indexbaseaddr"} = unpack("V", join('', @header[25..28]));
149 2         5 $obj->{"productcode"} = unpack("C", $header[29]);
150 2         6 $obj->{"licensecode"} = unpack("C", $header[30]);
151 2         7 $obj->{"databasesize"} = unpack("V", join('', @header[31..34]));
152 2         11 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 457 my $obj = shift(@_);
178 6         13 my $ipaddr = shift(@_);
179 6         21 my ($ipv, $ipnum) = $obj->validateIP($ipaddr);
180 6 100       21 if ($ipv == 4) {
181 3         12 return $obj->getIPv4Record($ipnum, COUNTRYSHORT);
182             } else {
183 3 50       7 if ($ipv == 6) {
184 3         17 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 6 my $obj = shift(@_);
418 3         6 my $ipnum = shift(@_);
419 3         6 my $mode = shift(@_);
420 3         10 my $dbtype = $obj->{"databasetype"};
421              
422 3 50       12 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     128 if (($mode == COUNTRYSHORT) && ($IPV6_COUNTRY_POSITION[$dbtype] == 0)) {
435 0         0 return NOT_SUPPORTED;
436             }
437 3 50 33     14 if (($mode == COUNTRYLONG) && ($IPV6_COUNTRY_POSITION[$dbtype] == 0)) {
438 0         0 return NOT_SUPPORTED;
439             }
440 3 50 33     15 if (($mode == REGION) && ($IPV6_REGION_POSITION[$dbtype] == 0)) {
441 0         0 return NOT_SUPPORTED;
442             }
443 3 50 33     10 if (($mode == CITY) && ($IPV6_CITY_POSITION[$dbtype] == 0)) {
444 0         0 return NOT_SUPPORTED;
445             }
446 3 50 33     9 if (($mode == ISP) && ($IPV6_ISP_POSITION[$dbtype] == 0)) {
447 0         0 return NOT_SUPPORTED;
448             }
449 3 50 33     10 if (($mode == PROXYTYPE) && ($IPV6_PROXYTYPE_POSITION[$dbtype] == 0)) {
450 0         0 return NOT_SUPPORTED;
451             }
452 3 50 33     7 if (($mode == DOMAIN) && ($IPV6_DOMAIN_POSITION[$dbtype] == 0)) {
453 0         0 return NOT_SUPPORTED;
454             }
455 3 50 33     10 if (($mode == USAGETYPE) && ($IPV6_USAGETYPE_POSITION[$dbtype] == 0)) {
456 0         0 return NOT_SUPPORTED;
457             }
458 3 50 33     8 if (($mode == ASN) && ($IPV6_ASN_POSITION[$dbtype] == 0)) {
459 0         0 return NOT_SUPPORTED;
460             }
461 3 50 33     8 if (($mode == AS) && ($IPV6_AS_POSITION[$dbtype] == 0)) {
462 0         0 return NOT_SUPPORTED;
463             }
464 3 50 33     8 if (($mode == LASTSEEN) && ($IPV6_LASTSEEN_POSITION[$dbtype] == 0)) {
465 0         0 return NOT_SUPPORTED;
466             }
467 3 50 33     44 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     8 if (($mode == FRAUDSCORE) && ($IPV6_FRAUDSCORE_POSITION[$dbtype] == 0)) {
474 0         0 return NOT_SUPPORTED;
475             }
476            
477 3         9 my $realipno = Math::BigInt->new($ipnum);
478 3         228 my $handle = $obj->{"filehandle"};
479 3         7 my $baseaddr = $obj->{"ipv6databaseaddr"};
480 3         5 my $dbcount = $obj->{"ipv6databasecount"};
481 3         5 my $dbcolumn = $obj->{"databasecolumn"};
482 3         7 my $indexbaseaddr = $obj->{"ipv6indexbaseaddr"};
483              
484 3 50       6 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         10 my $ipnum1_2 = new Math::BigInt($ipnum);
493 3         176 my $remainder = 0;
494 3         13 ($ipnum1_2, $remainder) = $ipnum1_2->bdiv(2**112);
495 3         2255 my $indexaddr = $indexbaseaddr + ($ipnum1_2 << 3);
496              
497 3         1466 my $low = 0;
498 3         5 my $high = $dbcount;
499 3 50       9 if ($indexbaseaddr > 0) {
500 3         13 ($low, $high) = $obj->read32x2($handle, $indexaddr);
501             }
502              
503 3         6 my $mid = 0;
504 3         3 my $ipfrom = 0;
505 3         5 my $ipto = 0;
506 3         5 my $ipno = 0;
507              
508 3         5 $ipno = $realipno;
509 3 50       7 if ($realipno == "340282366920938463463374607431768211455") {
510 0         0 $ipno = $ipno->bsub(1);
511             }
512            
513 3         430 my $raw_positions_row;
514              
515 3         7 while ($low <= $high) {
516 4         9 $mid = int(($low + $high)/2);
517 4         14 ($ipfrom, $ipto, $raw_positions_row) = $obj->readRow128($handle, $baseaddr + $mid * (($dbcolumn * 4) + 12), $dbcolumn);
518              
519 4 100 66     176 if (($ipno >= $ipfrom) && ($ipno < $ipto)) {
520 3         1051 my $row_pointer = $baseaddr + $mid * (($dbcolumn * 4) + 12);
521              
522 3 50       12 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")) {
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       6 if ($mode == COUNTRYSHORT) {
592 3         22 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")) {
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       216 if ($ipno < $ipfrom) {
657 1         177 $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 6 my $obj = shift(@_);
676 3         7 my $ipnum = shift(@_);
677 3         5 my $mode = shift(@_);
678 3         9 my $dbtype= $obj->{"databasetype"};
679              
680 3 50       9 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     17 if (($mode == COUNTRYSHORT) && ($IPV4_COUNTRY_POSITION[$dbtype] == 0)) {
693 0         0 return NOT_SUPPORTED;
694             }
695 3 50 33     25 if (($mode == COUNTRYLONG) && ($IPV4_COUNTRY_POSITION[$dbtype] == 0)) {
696 0         0 return NOT_SUPPORTED;
697             }
698 3 50 33     17 if (($mode == REGION) && ($IPV4_REGION_POSITION[$dbtype] == 0)) {
699 0         0 return NOT_SUPPORTED;
700             }
701 3 50 33     10 if (($mode == CITY) && ($IPV4_CITY_POSITION[$dbtype] == 0)) {
702 0         0 return NOT_SUPPORTED;
703             }
704 3 50 33     10 if (($mode == ISP) && ($IPV4_ISP_POSITION[$dbtype] == 0)) {
705 0         0 return NOT_SUPPORTED;
706             }
707 3 50 33     9 if (($mode == PROXYTYPE) && ($IPV4_PROXYTYPE_POSITION[$dbtype] == 0)) {
708 0         0 return NOT_SUPPORTED;
709             }
710 3 50 33     15 if (($mode == DOMAIN) && ($IPV4_DOMAIN_POSITION[$dbtype] == 0)) {
711 0         0 return NOT_SUPPORTED;
712             }
713 3 50 33     12 if (($mode == USAGETYPE) && ($IPV4_USAGETYPE_POSITION[$dbtype] == 0)) {
714 0         0 return NOT_SUPPORTED;
715             }
716 3 50 33     10 if (($mode == ASN) && ($IPV4_ASN_POSITION[$dbtype] == 0)) {
717 0         0 return NOT_SUPPORTED;
718             }
719 3 50 33     8 if (($mode == AS) && ($IPV4_AS_POSITION[$dbtype] == 0)) {
720 0         0 return NOT_SUPPORTED;
721             }
722 3 50 33     13 if (($mode == LASTSEEN) && ($IPV4_LASTSEEN_POSITION[$dbtype] == 0)) {
723 0         0 return NOT_SUPPORTED;
724             }
725 3 50 33     10 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     9 if (($mode == FRAUDSCORE) && ($IPV4_FRAUDSCORE_POSITION[$dbtype] == 0)) {
732 0         0 return NOT_SUPPORTED;
733             }
734              
735 3         8 my $realipno = $ipnum;
736 3         6 my $handle = $obj->{"filehandle"};
737 3         6 my $baseaddr = $obj->{"ipv4databaseaddr"};
738 3         5 my $dbcount = $obj->{"ipv4databasecount"};
739 3         6 my $dbcolumn = $obj->{"databasecolumn"};
740 3         7 my $indexbaseaddr = $obj->{"ipv4indexbaseaddr"};
741              
742 3         6 my $ipnum1_2 = int($ipnum >> 16);
743 3         6 my $indexaddr = $indexbaseaddr + ($ipnum1_2 << 3);
744              
745 3         5 my $low = 0;
746 3         4 my $high = $dbcount;
747 3 50       10 if ($indexbaseaddr > 0) {
748 3         9 ($low, $high) = $obj->read32x2($handle, $indexaddr);
749             }
750 3         6 my $mid = 0;
751 3         12 my $ipfrom = 0;
752 3         7 my $ipto = 0;
753 3         4 my $ipno = 0;
754              
755 3 50       8 if ($realipno == MAX_IPV4_RANGE) {
756 0         0 $ipno = $realipno - 1;
757             } else {
758 3         7 $ipno = $realipno;
759             }
760            
761 3         4 my $raw_positions_row;
762              
763 3         27 while ($low <= $high) {
764 15         25 $mid = int(($low + $high) >> 1);
765 15         42 ($ipfrom, $ipto, $raw_positions_row) = $obj->readRow32($handle, $baseaddr + $mid * $dbcolumn * 4, $dbcolumn);
766            
767 15 100 100     59 if (($ipno >= $ipfrom) && ($ipno < $ipto)) {
768 3 50       25 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")) {
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       26 if ($mode == COUNTRYSHORT) {
839 3         20 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")) {
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       25 if ($ipno < $ipfrom) {
903 9         20 $high = $mid - 1;
904             } else {
905 3         12 $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 32 my ($obj, $handle, $position, $column) = @_;
922 15         24 my $data = "";
923 15         22 my $data_length = $column * 4 + 4;
924 15         145 seek($handle, $position-1, 0);
925 15         98 read($handle, $data, $data_length);
926 15         34 my $ipfrom = substr($data, 0, 4);
927 15         28 my $ipfrom_next = substr($data, $data_length - 4, 4);
928 15         27 my $result_row = substr($data, 0, $data_length - 4);
929 15         53 return (unpack("V", $ipfrom), unpack("V", $ipfrom_next), $result_row);
930             }
931              
932             sub readRow128 {
933 4     4 0 9 my ($obj, $handle, $position, $column) = @_;
934 4         5 my $data = "";
935 4         5 my $data_length = $column * 4 + 12 + 16;
936 4         31 seek($handle, $position-1, 0);
937 4         29 read($handle, $data, $data_length);
938 4         6 my $ipfrom = substr($data, 0, 16);
939 4         9 my $ipfrom_next = substr($data, $data_length - 16, 16);
940 4         15 my $result_row = substr($data, 0, $data_length - 16);
941 4         14 return (&bytesInt($ipfrom), &bytesInt($ipfrom_next), $result_row);
942             }
943              
944             sub read512 {
945 2     2 0 5 my ($obj, $handle, $position) = @_;
946 2         6 my $data = "";
947 2         13 seek($handle, $position-1, 0);
948 2         67 read($handle, $data, 64);
949 2         36 my @data_array = split('', $data);
950 2         11 while ($#data_array < 63) {
951 0         0 $data_array[$#data_array+1] = 0x00;
952             }
953 2         62 return @data_array;
954             }
955              
956             sub read32x2 {
957 6     6 0 14 my ($obj, $handle, $position) = @_;
958 6         10 my $data = "";
959 6         48 seek($handle, $position-1, 0);
960 6         808 read($handle, $data, 8);
961 6         18 my $data_1 = substr($data, 0, 4);
962 6         15 my $data_2 = substr($data, 4, 4);
963 6         25 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         9 my $string = "";
994 6         59 seek($handle, $position, 0);
995 6         50 read($handle, $data, 1);
996 6         17 read($handle, $string, unpack("C", $data));
997 6         56 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 113 my $binip = shift(@_);
1018 8         28 my @array = split(//, $binip);
1019 8 50       17 return 0 if ($#array != 15);
1020 8         19 my $ip96_127 = unpack("V", $array[0] . $array[1] . $array[2] . $array[3]);
1021 8         12 my $ip64_95 = unpack("V", $array[4] . $array[5] . $array[6] . $array[7]);
1022 8         13 my $ip32_63 = unpack("V", $array[8] . $array[9] . $array[10] . $array[11]);
1023 8         12 my $ip1_31 = unpack("V", $array[12] . $array[13] . $array[14] . $array[15]);
1024              
1025 8         21 my $big1 = Math::BigInt->new("$ip96_127");
1026 8         481 my $big2 = Math::BigInt->new("$ip64_95")->blsft(32);
1027 8         2940 my $big3 = Math::BigInt->new("$ip32_63")->blsft(64);
1028 8         2793 my $big4 = Math::BigInt->new("$ip1_31")->blsft(96);
1029 8         3052 $big1 = $big1->badd($big2)->badd($big3)->badd($big4);
1030            
1031 8         1898 return $big1->bstr();
1032             }
1033              
1034             sub validateIP {
1035 6     6 0 16 my $obj = shift(@_);
1036 6         9 my $ip = shift(@_);
1037 6         9 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       18 if ($obj->isIPv4($ip)) {
1044             #ipv4 address
1045 3         4 $ipv = 4;
1046 3         12 $ipnum = $obj->ipNo($ip);
1047             } else {
1048             #expand ipv6 address
1049 3         10 $ip = $obj->expandIPv6Address($ip);
1050 3 50       10 if ($obj->isIPv6($ip)) {
1051             #ipv6 address
1052 3         4 $ipv = 6;
1053 3         9 $ipnum = $obj->hexInt($ip);
1054            
1055             #reformat ipv4 address in ipv6
1056 3 50 66     9 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     728 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     1898 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         1785 return ($ipv, $ipnum);
1082             }
1083              
1084             sub expandIPv6Address {
1085 3     3 0 6 my $obj = shift(@_);
1086 3         6 my $ip = shift(@_);
1087 3         7 $ip =~ s/\:\:/\:Z\:/;
1088 3         13 my @ip = split(/\:/, $ip);
1089 3         4 my $num = scalar(@ip);
1090              
1091 3         7 my $l = 8;
1092 3 50       9 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       8 if ($#ip == 8) {
1101 0         0 shift(@ip);
1102 0         0 $l++;
1103             }
1104              
1105 3         10 foreach (0..(scalar(@ip)-1)) {
1106 24         61 $ip[$_] = ('0'x(4-length ($ip[$_]))).$ip[$_];
1107             }
1108              
1109 3         9 foreach (0..(scalar(@ip)-1)) {
1110 24 50       40 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         17 return (uc(join ':', @ip));
1117             }
1118              
1119             sub hexInt {
1120 3     3 0 5 my $obj = shift(@_);
1121 3         6 my $hexip = shift(@_);
1122              
1123 3         15 $hexip =~ s/\://g;
1124              
1125 3 50       18 unless (length($hexip) == 32) {
1126 0         0 return 0;
1127             };
1128              
1129 3         20 my $binip = unpack('B128', pack('H32', $hexip));
1130 3         19 my ($n, $dec) = (Math::BigInt->new(1), Math::BigInt->new(0));
1131              
1132 3         653 foreach (reverse (split('', $binip))) {
1133 384 100       60553 $_ && ($dec += $n);
1134 384         1957 $n *= 2;
1135             }
1136              
1137 3         567 $dec =~ s/^\+//;
1138 3         125 return $dec;
1139             }
1140              
1141             sub ipNo {
1142 3     3 0 5 my $obj = shift(@_);
1143 3         7 my $ip = shift(@_);
1144 3         8 my @block = split(/\./, $ip);
1145 3         6 my $no = 0;
1146 3         7 $no = $block[3];
1147 3         9 $no = $no + $block[2] * 256;
1148 3         6 $no = $no + $block[1] * 256 * 256;
1149 3         8 $no = $no + $block[0] * 256 * 256 * 256;
1150 3         9 return $no;
1151             }
1152              
1153             sub nameIP {
1154 6     6 0 10 my $obj = shift(@_);
1155 6         10 my $host = shift(@_);
1156 6         29 my $ip_address = "";
1157 6 50 66     1449 if (($host =~ m/^$IPv4_re$/) || ($host =~ m/^$IPv6_re$/) || ($host =~ m/^\:\:$/)) {
      33        
1158 6         39 $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         36 return $ip_address;
1164             }
1165              
1166             sub isIPv4 {
1167 6     6 0 13 my $obj = shift(@_);
1168 6         12 my $ip = shift(@_);
1169 6 100       107 if ($ip =~ m/^$IPv4_re$/) {
1170 3         11 my @octet = split(/\./, $ip);
1171 3         14 foreach my $i (0 .. $#octet) {
1172 12 50 33     77 return 0 if (($octet[$i] > 255) || ($octet[$i] < 0));
1173             }
1174 3         16 return 1;
1175             } else {
1176 3         10 return 0;
1177             }
1178             }
1179              
1180             sub isIPv6 {
1181 3     3 0 5 my $obj = shift(@_);
1182 3         6 my $ip = shift(@_);
1183 3 50 33     1454 if (($ip =~ m/^$IPv6_re$/) || ($ip =~ m/^$IPv4_re$/)) {
1184 3         15 return 1;
1185             } else {
1186 0           return 0;
1187             }
1188             }
1189              
1190             1;
1191             __END__