File Coverage

blib/lib/Geo/IP2Location.pm
Criterion Covered Total %
statement 494 1146 43.1
branch 101 530 19.0
condition 73 204 35.7
subroutine 89 125 71.2
pod 33 54 61.1
total 790 2059 38.3


line stmt bran cond sub pod time code
1             #MIT License
2             #
3             #Copyright (c) 2025 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::IP2Location;
24              
25 3     3   34157 use strict;
  3         10  
  3         136  
26 3     3   32 use vars qw(@ISA $VERSION @EXPORT);
  3         5  
  3         233  
27 3     3   7804 use Math::BigInt;
  3         162050  
  3         18  
28 3     3   108962 use bigint;
  3         10450  
  3         15  
29              
30             $VERSION = '8.80';
31             require Exporter;
32             @ISA = qw(Exporter);
33              
34 3     3   1215 use constant UNKNOWN => "UNKNOWN IP ADDRESS";
  3         10  
  3         226  
35 3     3   21 use constant IPV6_ADDRESS_IN_IPV4_BIN => "IPV6 ADDRESS MISSING IN IPV4 BIN";
  3         4  
  3         167  
36 3     3   16 use constant NO_IP => "MISSING IP ADDRESS";
  3         4  
  3         138  
37 3     3   14 use constant INVALID_IPV6_ADDRESS => "INVALID IPV6 ADDRESS";
  3         9  
  3         118  
38 3     3   14 use constant INVALID_IPV4_ADDRESS => "INVALID IPV4 ADDRESS";
  3         6  
  3         220  
39 3     3   17 use constant INVALID_IP_ADDRESS => "INVALID IP ADDRESS";
  3         5  
  3         132  
40 3     3   33 use constant INVALID_BIN_DATABASE => "Incorrect IP2Location BIN file format. Please make sure that you are using the latest IP2Location BIN file.";
  3         26  
  3         159  
41 3     3   14 use constant NOT_SUPPORTED => "This parameter is unavailable in selected .BIN data file. Please upgrade data file.";
  3         5  
  3         140  
42 3     3   765 use constant MAX_IPV4_RANGE => 4294967295;
  3         5  
  3         129  
43 3     3   1361 use constant MAX_IPV6_RANGE => 340282366920938463463374607431768211455;
  3         5  
  3         128  
44 3     3   423 use constant IP_COUNTRY => 1;
  3         6  
  3         121  
45 3     3   409 use constant IP_COUNTRY_ISP => 2;
  3         7  
  3         115  
46 3     3   393 use constant IP_COUNTRY_REGION_CITY => 3;
  3         6  
  3         181  
47 3     3   379 use constant IP_COUNTRY_REGION_CITY_ISP => 4;
  3         17  
  3         131  
48 3     3   404 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE => 5;
  3         31  
  3         127  
49 3     3   337 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ISP => 6;
  3         7  
  3         167  
50 3     3   661 use constant IP_COUNTRY_REGION_CITY_ISP_DOMAIN => 7;
  3         7  
  3         136  
51 3     3   448 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ISP_DOMAIN => 8;
  3         6  
  3         149  
52 3     3   320 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE => 9;
  3         6  
  3         175  
53 3     3   338 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_ISP_DOMAIN => 10;
  3         6  
  3         116  
54 3     3   441 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE => 11;
  3         7  
  3         147  
55 3     3   345 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN => 12;
  3         6  
  3         138  
56 3     3   361 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_TIMEZONE_NETSPEED => 13;
  3         6  
  3         181  
57 3     3   344 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED => 14;
  3         6  
  3         179  
58 3     3   349 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_AREACODE => 15;
  3         12  
  3         157  
59 3     3   386 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED_AREACODE => 16;
  3         6  
  3         138  
60 3     3   335 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_TIMEZONE_NETSPEED_WEATHER => 17;
  3         141  
  3         135  
61 3     3   369 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED_AREACODE_WEATHER => 18;
  3         5  
  3         118  
62 3     3   376 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ISP_DOMAIN_MOBILE => 19;
  3         6  
  3         152  
63 3     3   351 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED_AREACODE_WEATHER_MOBILE => 20;
  3         6  
  3         179  
64 3     3   377 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_AREACODE_ELEVATION => 21;
  3         5  
  3         141  
65 3     3   339 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED_AREACODE_WEATHER_MOBILE_ELEVATION => 22;
  3         6  
  3         136  
66 3     3   354 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ISP_DOMAIN_MOBILE_USAGETYPE => 23;
  3         21  
  3         192  
67 3     3   338 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED_AREACODE_WEATHER_MOBILE_ELEVATION_USAGETYPE => 24;
  3         5  
  3         162  
68 3     3   369 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED_AREACODE_WEATHER_MOBILE_ELEVATION_USAGETYPE_ADDRESSTYPE_CATEGORY => 25;
  3         5  
  3         135  
69 3     3   348 use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED_AREACODE_WEATHER_MOBILE_ELEVATION_USAGETYPE_ADDRESSTYPE_CATEGORY_DISTRICT_ASN => 26;
  3         28  
  3         128  
70              
71 3     3   349 use constant COUNTRYSHORT => 1;
  3         5  
  3         119  
72 3     3   407 use constant COUNTRYLONG => 2;
  3         5  
  3         112  
73 3     3   366 use constant REGION => 3;
  3         10  
  3         133  
74 3     3   361 use constant CITY => 4;
  3         6  
  3         133  
75 3     3   336 use constant ISP => 5;
  3         6  
  3         122  
76 3     3   336 use constant LATITUDE => 6;
  3         5  
  3         104  
77 3     3   367 use constant LONGITUDE => 7;
  3         7  
  3         183  
78 3     3   316 use constant DOMAIN => 8;
  3         5  
  3         118  
79 3     3   333 use constant ZIPCODE => 9;
  3         19  
  3         128  
80 3     3   350 use constant TIMEZONE => 10;
  3         4  
  3         127  
81 3     3   312 use constant NETSPEED => 11;
  3         6  
  3         111  
82 3     3   334 use constant IDDCODE => 12;
  3         6  
  3         121  
83 3     3   329 use constant AREACODE => 13;
  3         6  
  3         162  
84 3     3   324 use constant WEATHERSTATIONCODE => 14;
  3         31  
  3         133  
85 3     3   362 use constant WEATHERSTATIONNAME => 15;
  3         4  
  3         102  
86 3     3   376 use constant MCC => 16;
  3         4  
  3         103  
87 3     3   321 use constant MNC => 17;
  3         23  
  3         167  
88 3     3   380 use constant MOBILEBRAND => 18;
  3         5  
  3         207  
89 3     3   404 use constant ELEVATION => 19;
  3         6  
  3         130  
90 3     3   594 use constant USAGETYPE => 20;
  3         6  
  3         132  
91 3     3   399 use constant ADDRESSTYPE => 21;
  3         33  
  3         124  
92 3     3   344 use constant CATEGORY => 22;
  3         4  
  3         110  
93 3     3   368 use constant DISTRICT => 23;
  3         5  
  3         134  
94 3     3   323 use constant ASN => 24;
  3         10  
  3         197  
95 3     3   359 use constant AS => 25;
  3         7  
  3         120  
96 3     3   341 use constant ASDOMAIN => 26;
  3         5  
  3         105  
97 3     3   418 use constant ASUSAGETYPE => 27;
  3         13  
  3         125  
98 3     3   348 use constant ASCIDR => 28;
  3         6  
  3         104  
99              
100 3     3   407 use constant ALL => 100;
  3         5  
  3         130  
101 3     3   374 use constant IPV4 => 0;
  3         4  
  3         193  
102 3     3   346 use constant IPV6 => 1;
  3         8  
  3         120  
103              
104             my @COUNTRY_POSITION = (0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
105             my @REGION_POSITION = (0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3);
106             my @CITY_POSITION = (0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4);
107             my @LATITUDE_POSITION = (0, 0, 0, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5);
108             my @LONGITUDE_POSITION = (0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6);
109             my @ZIPCODE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 7, 7, 7, 0, 7, 0, 7, 7, 7, 0, 7, 7, 7);
110             my @TIMEZONE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 7, 8, 8, 8, 7, 8, 0, 8, 8, 8, 0, 8, 8, 8);
111             my @ISP_POSITION = (0, 0, 3, 0, 5, 0, 7, 5, 7, 0, 8, 0, 9, 0, 9, 0, 9, 0, 9, 7, 9, 0, 9, 7, 9, 9, 9);
112             my @DOMAIN_POSITION = (0, 0, 0, 0, 0, 0, 0, 6, 8, 0, 9, 0, 10, 0, 10, 0, 10, 0, 10, 8, 10, 0, 10, 8, 10, 10, 10);
113             my @NETSPEED_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 11, 0, 11, 8, 11, 0, 11, 0, 11, 0, 11, 11, 11);
114             my @IDDCODE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 12, 0, 12, 0, 12, 9, 12, 0, 12, 12, 12);
115             my @AREACODE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 13, 0, 13, 0, 13, 10, 13, 0, 13, 13, 13);
116             my @WEATHERSTATIONCODE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 14, 0, 14, 0, 14, 0, 14, 14, 14);
117             my @WEATHERSTATIONNAME_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 15, 0, 15, 0, 15, 0, 15, 15, 15);
118             my @MCC_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 16, 0, 16, 9, 16, 16, 16);
119             my @MNC_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 17, 0, 17, 10, 17, 17, 17);
120             my @MOBILEBRAND_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 18, 0, 18, 11, 18, 18, 18);
121             my @ELEVATION_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 19, 0, 19, 19, 19);
122             my @USAGETYPE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 20, 20, 20);
123             my @ADDRESSTYPE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21);
124             my @CATEGORY_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 22);
125             my @DISTRICT_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23);
126             my @ASN_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24);
127             my @AS_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25);
128             my @AS_DOMAIN_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26);
129             my @AS_USAGETYPE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27);
130             my @AS_CIDR_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28);
131             my @COLUMN_SIZE = (0, 2, 3, 4, 5, 6, 7, 6, 8, 7, 9, 8, 10, 8, 11, 10, 13, 10, 15, 11, 18, 11, 19, 12, 20, 22, 28);
132              
133             my @IPV6_COUNTRY_POSITION = (0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
134             my @IPV6_REGION_POSITION = (0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3);
135             my @IPV6_CITY_POSITION = (0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4);
136             my @IPV6_LATITUDE_POSITION = (0, 0, 0, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5);
137             my @IPV6_LONGITUDE_POSITION = (0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6);
138             my @IPV6_ZIPCODE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 7, 7, 7, 0, 7, 0, 7, 7, 7, 0, 7, 7, 7);
139             my @IPV6_TIMEZONE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 7, 8, 8, 8, 7, 8, 0, 8, 8, 8, 0, 8, 8, 8);
140             my @IPV6_ISP_POSITION = (0, 0, 3, 0, 5, 0, 7, 5, 7, 0, 8, 0, 9, 0, 9, 0, 9, 0, 9, 7, 9, 0, 9, 7, 9, 9, 9);
141             my @IPV6_DOMAIN_POSITION = (0, 0, 0, 0, 0, 0, 0, 6, 8, 0, 9, 0, 10, 0, 10, 0, 10, 0, 10, 8, 10, 0, 10, 8, 10, 10, 10);
142             my @IPV6_NETSPEED_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 11, 0, 11, 8, 11, 0, 11, 0, 11, 0, 11, 11, 11);
143             my @IPV6_IDDCODE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 12, 0, 12, 0, 12, 9, 12, 0, 12, 12, 12);
144             my @IPV6_AREACODE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 13, 0, 13, 0, 13, 10, 13, 0, 13, 13, 13);
145             my @IPV6_WEATHERSTATIONCODE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 14, 0, 14, 0, 14, 0, 14, 14, 14);
146             my @IPV6_WEATHERSTATIONNAME_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 15, 0, 15, 0, 15, 0, 15, 15, 15);
147             my @IPV6_MCC_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 16, 0, 16, 9, 16, 16, 16);
148             my @IPV6_MNC_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 17, 0, 17, 10, 17, 17, 17);
149             my @IPV6_MOBILEBRAND_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 18, 0, 18, 11, 18, 18, 18);
150             my @IPV6_ELEVATION_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 19, 0, 19, 19, 19);
151             my @IPV6_USAGETYPE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 20, 20, 20);
152             my @IPV6_ADDRESSTYPE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21);
153             my @IPV6_CATEGORY_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 22);
154             my @IPV6_DISTRICT_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23);
155             my @IPV6_ASN_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24);
156             my @IPV6_AS_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25);
157             my @IPV6_AS_DOMAIN_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26);
158             my @IPV6_AS_USAGETYPE_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27);
159             my @IPV6_AS_CIDR_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28);
160             my @IPV6_COLUMN_SIZE = (0, 2, 3, 4, 5, 6, 7, 6, 8, 7, 9, 8, 10, 8, 11, 10, 13, 10, 15, 11, 18, 11, 19, 12, 20, 22, 28);
161              
162             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})|:))/;
163             my $IPv4_re = qr/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/;
164              
165             my $getLastErrorMessage = "";
166              
167             sub open {
168 2 50 33 2 1 526097 unless( (@_ > 1) && ($_[1]) ) {
169 0         0 $getLastErrorMessage = "Geo::IP2Location::open() requires a database path name.";
170 0         0 die "Geo::IP2Location::open() requires a database path name";
171             }
172 2         639 my ($class, $db_file) = @_;
173 2         6 my $handle;
174             my $obj;
175 2 50       228 unless (CORE::open $handle, "$db_file") {
176 0         0 $getLastErrorMessage = "Geo::IP2Location::open() error in opening $db_file" . ".";
177 0         0 die "Geo::IP2Location::open() error in opening $db_file";
178             }
179 2         14 binmode($handle);
180 2         16 $obj = bless {filehandle => $handle}, $class;
181 2         15 $obj->initialize();
182 2 50       11 if ($obj->{"productcode"} == 1) {
183             } else {
184 2 50 33     567 if (($obj->{"databaseyear"} <= 20) && ($obj->{"productcode"} == 0)) {
185             } else {
186 0         0 $obj->close();
187 0         0 undef $obj;
188 0         0 $getLastErrorMessage = INVALID_BIN_DATABASE;
189 0         0 die INVALID_BIN_DATABASE;
190             }
191             }
192 2         1847 return $obj;
193             }
194              
195             sub close {
196 0     0 0 0 my ($class) = @_;
197 0 0       0 if (CORE::close($class->{filehandle})) {
198 0         0 return 0;
199             } else {
200 0         0 return 1;
201             }
202             }
203              
204             sub initialize {
205 2     2 0 7 my ($obj) = @_;
206 2         30 my @header = $obj->read512($obj->{filehandle}, 1);
207 2         15 $obj->{"databasetype"} = unpack("C", $header[0]);
208 2         8 $obj->{"databasecolumn"} = unpack("C", $header[1]);
209 2         61 $obj->{"databaseyear"} = unpack("C", $header[2]);
210 2         8 $obj->{"databasemonth"} = unpack("C", $header[3]);
211 2         8 $obj->{"databaseday"} = unpack("C", $header[4]);
212 2         15 $obj->{"ipv4databasecount"} = unpack("V", join('', @header[5..8]));
213 2         11 $obj->{"ipv4databaseaddr"} = unpack("V", join('', @header[9..12]));
214 2         69 $obj->{"ipv6databasecount"} = unpack("V", join('', @header[13..16]));
215 2         11 $obj->{"ipv6databaseaddr"} = unpack("V", join('', @header[17..20]));
216 2         11 $obj->{"ipv4indexbaseaddr"} = unpack("V", join('', @header[21..24]));
217 2         9 $obj->{"ipv6indexbaseaddr"} = unpack("V", join('', @header[25..28]));
218 2         6 $obj->{"productcode"} = unpack("C", $header[29]);
219 2         5 $obj->{"licensecode"} = unpack("C", $header[30]);
220 2         9 $obj->{"databasesize"} = unpack("V", join('', @header[31..34]));
221 2         14 return $obj;
222             }
223              
224             sub get_last_error_message {
225 0     0 1 0 my $class = shift(@_);
226 0         0 return ($getLastErrorMessage);
227             }
228              
229             sub get_module_version {
230 0     0 1 0 my $obj = shift(@_);
231 0         0 return $VERSION;
232             }
233              
234             sub get_database_version {
235 0     0 1 0 my $obj = shift(@_);
236 0         0 return $obj->{"databaseyear"} . "." . $obj->{"databasemonth"} . "." . $obj->{"databaseday"};
237             }
238              
239             sub get_country_short {
240 20     20 1 3098 my $obj = shift(@_);
241 20         49 my $ipaddr = shift(@_);
242 20         92 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
243 20 100       82 if ($ipv == 4) {
244 10         564 return $obj->get_ipv4_record($ipnum, COUNTRYSHORT);
245             } else {
246 10 50       416 if ($ipv == 6) {
247 10         396 return $obj->get_ipv6_record($ipnum, COUNTRYSHORT);
248             } else {
249 0         0 return INVALID_IP_ADDRESS;
250             }
251             }
252             }
253              
254             sub get_country_long {
255 0     0 1 0 my $obj = shift(@_);
256 0         0 my $ipaddr = shift(@_);
257 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
258 0 0       0 if ($ipv == 4) {
259 0         0 return $obj->get_ipv4_record($ipnum, COUNTRYLONG);
260             } else {
261 0 0       0 if ($ipv == 6) {
262 0         0 return $obj->get_ipv6_record($ipnum, COUNTRYLONG);
263             } else {
264 0         0 return INVALID_IP_ADDRESS;
265             }
266             }
267             }
268              
269             sub get_region {
270 0     0 1 0 my $obj = shift(@_);
271 0         0 my $ipaddr = shift(@_);
272 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
273 0 0       0 if ($ipv == 4) {
274 0         0 return $obj->get_ipv4_record($ipnum, REGION);
275             } else {
276 0 0       0 if ($ipv == 6) {
277 0         0 return $obj->get_ipv6_record($ipnum, REGION);
278             } else {
279 0         0 return INVALID_IP_ADDRESS;
280             }
281             }
282             }
283              
284             sub get_city {
285 0     0 1 0 my $obj = shift(@_);
286 0         0 my $ipaddr = shift(@_);
287 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
288 0 0       0 if ($ipv == 4) {
289 0         0 return $obj->get_ipv4_record($ipnum, CITY);
290             } else {
291 0 0       0 if ($ipv == 6) {
292 0         0 return $obj->get_ipv6_record($ipnum, CITY);
293             } else {
294 0         0 return INVALID_IP_ADDRESS;
295             }
296             }
297             }
298              
299             sub get_isp {
300 0     0 1 0 my $obj = shift(@_);
301 0         0 my $ipaddr = shift(@_);
302 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
303 0 0       0 if ($ipv == 4) {
304 0         0 return $obj->get_ipv4_record($ipnum, ISP);
305             } else {
306 0 0       0 if ($ipv == 6) {
307 0         0 return $obj->get_ipv6_record($ipnum, ISP);
308             } else {
309 0         0 return INVALID_IP_ADDRESS;
310             }
311             }
312             }
313              
314             sub get_latitude {
315 0     0 1 0 my $obj = shift(@_);
316 0         0 my $ipaddr = shift(@_);
317 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
318 0 0       0 if ($ipv == 4) {
319 0         0 return $obj->get_ipv4_record($ipnum, LATITUDE);
320             } else {
321 0 0       0 if ($ipv == 6) {
322 0         0 return $obj->get_ipv6_record($ipnum, LATITUDE);
323             } else {
324 0         0 return INVALID_IP_ADDRESS;
325             }
326             }
327             }
328              
329             sub get_zipcode {
330 0     0 1 0 my $obj = shift(@_);
331 0         0 my $ipaddr = shift(@_);
332 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
333 0 0       0 if ($ipv == 4) {
334 0         0 return $obj->get_ipv4_record($ipnum, ZIPCODE);
335             } else {
336 0 0       0 if ($ipv == 6) {
337 0         0 return $obj->get_ipv6_record($ipnum, ZIPCODE);
338             } else {
339 0         0 return INVALID_IP_ADDRESS;
340             }
341             }
342             }
343              
344             sub get_longitude {
345 0     0 1 0 my $obj = shift(@_);
346 0         0 my $ipaddr = shift(@_);
347 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
348 0 0       0 if ($ipv == 4) {
349 0         0 return $obj->get_ipv4_record($ipnum, LONGITUDE);
350             } else {
351 0 0       0 if ($ipv == 6) {
352 0         0 return $obj->get_ipv6_record($ipnum, LONGITUDE);
353             } else {
354 0         0 return INVALID_IP_ADDRESS;
355             }
356             }
357             }
358              
359             sub get_domain {
360 0     0 1 0 my $obj = shift(@_);
361 0         0 my $ipaddr = shift(@_);
362 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
363 0 0       0 if ($ipv == 4) {
364 0         0 return $obj->get_ipv4_record($ipnum, DOMAIN);
365             } else {
366 0 0       0 if ($ipv == 6) {
367 0         0 return $obj->get_ipv6_record($ipnum, DOMAIN);
368             } else {
369 0         0 return INVALID_IP_ADDRESS;
370             }
371             }
372             }
373              
374             sub get_timezone {
375 0     0 1 0 my $obj = shift(@_);
376 0         0 my $ipaddr = shift(@_);
377 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
378 0 0       0 if ($ipv == 4) {
379 0         0 return $obj->get_ipv4_record($ipnum, TIMEZONE);
380             } else {
381 0 0       0 if ($ipv == 6) {
382 0         0 return $obj->get_ipv6_record($ipnum, TIMEZONE);
383             } else {
384 0         0 return INVALID_IP_ADDRESS;
385             }
386             }
387             }
388              
389             sub get_netspeed {
390 0     0 1 0 my $obj = shift(@_);
391 0         0 my $ipaddr = shift(@_);
392 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
393 0 0       0 if ($ipv == 4) {
394 0         0 return $obj->get_ipv4_record($ipnum, NETSPEED);
395             } else {
396 0 0       0 if ($ipv == 6) {
397 0         0 return $obj->get_ipv6_record($ipnum, NETSPEED);
398             } else {
399 0         0 return INVALID_IP_ADDRESS;
400             }
401             }
402             }
403              
404             sub get_iddcode {
405 0     0 1 0 my $obj = shift(@_);
406 0         0 my $ipaddr = shift(@_);
407 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
408 0 0       0 if ($ipv == 4) {
409 0         0 return $obj->get_ipv4_record($ipnum, IDDCODE);
410             } else {
411 0 0       0 if ($ipv == 6) {
412 0         0 return $obj->get_ipv6_record($ipnum, IDDCODE);
413             } else {
414 0         0 return INVALID_IP_ADDRESS;
415             }
416             }
417             }
418              
419             sub get_areacode {
420 0     0 1 0 my $obj = shift(@_);
421 0         0 my $ipaddr = shift(@_);
422 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
423 0 0       0 if ($ipv == 4) {
424 0         0 return $obj->get_ipv4_record($ipnum, AREACODE);
425             } else {
426 0 0       0 if ($ipv == 6) {
427 0         0 return $obj->get_ipv6_record($ipnum, AREACODE);
428             } else {
429 0         0 return INVALID_IP_ADDRESS;
430             }
431             }
432             }
433              
434             sub get_weatherstationcode {
435 0     0 1 0 my $obj = shift(@_);
436 0         0 my $ipaddr = shift(@_);
437 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
438 0 0       0 if ($ipv == 4) {
439 0         0 return $obj->get_ipv4_record($ipnum, WEATHERSTATIONCODE);
440             } else {
441 0 0       0 if ($ipv == 6) {
442 0         0 return $obj->get_ipv6_record($ipnum, WEATHERSTATIONCODE);
443             } else {
444 0         0 return INVALID_IP_ADDRESS;
445             }
446             }
447             }
448              
449             sub get_weatherstationname {
450 0     0 1 0 my $obj = shift(@_);
451 0         0 my $ipaddr = shift(@_);
452 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
453 0 0       0 if ($ipv == 4) {
454 0         0 return $obj->get_ipv4_record($ipnum, WEATHERSTATIONNAME);
455             } else {
456 0 0       0 if ($ipv == 6) {
457 0         0 return $obj->get_ipv6_record($ipnum, WEATHERSTATIONNAME);
458             } else {
459 0         0 return INVALID_IP_ADDRESS;
460             }
461             }
462             }
463              
464             sub get_mcc {
465 0     0 1 0 my $obj = shift(@_);
466 0         0 my $ipaddr = shift(@_);
467 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
468 0 0       0 if ($ipv == 4) {
469 0         0 return $obj->get_ipv4_record($ipnum, MCC);
470             } else {
471 0 0       0 if ($ipv == 6) {
472 0         0 return $obj->get_ipv6_record($ipnum, MCC);
473             } else {
474 0         0 return INVALID_IP_ADDRESS;
475             }
476             }
477             }
478              
479             sub get_mnc {
480 0     0 1 0 my $obj = shift(@_);
481 0         0 my $ipaddr = shift(@_);
482 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
483 0 0       0 if ($ipv == 4) {
484 0         0 return $obj->get_ipv4_record($ipnum, MNC);
485             } else {
486 0 0       0 if ($ipv == 6) {
487 0         0 return $obj->get_ipv6_record($ipnum, MNC);
488             } else {
489 0         0 return INVALID_IP_ADDRESS;
490             }
491             }
492             }
493              
494             sub get_mobilebrand {
495 0     0 1 0 my $obj = shift(@_);
496 0         0 my $ipaddr = shift(@_);
497 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
498 0 0       0 if ($ipv == 4) {
499 0         0 return $obj->get_ipv4_record($ipnum, MOBILEBRAND);
500             } else {
501 0 0       0 if ($ipv == 6) {
502 0         0 return $obj->get_ipv6_record($ipnum, MOBILEBRAND);
503             } else {
504 0         0 return INVALID_IP_ADDRESS;
505             }
506             }
507             }
508              
509             sub get_elevation {
510 0     0 1 0 my $obj = shift(@_);
511 0         0 my $ipaddr = shift(@_);
512 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
513 0 0       0 if ($ipv == 4) {
514 0         0 return $obj->get_ipv4_record($ipnum, ELEVATION);
515             } else {
516 0 0       0 if ($ipv == 6) {
517 0         0 return $obj->get_ipv6_record($ipnum, ELEVATION);
518             } else {
519 0         0 return INVALID_IP_ADDRESS;
520             }
521             }
522             }
523              
524             sub get_usagetype {
525 0     0 1 0 my $obj = shift(@_);
526 0         0 my $ipaddr = shift(@_);
527 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
528 0 0       0 if ($ipv == 4) {
529 0         0 return $obj->get_ipv4_record($ipnum, USAGETYPE);
530             } else {
531 0 0       0 if ($ipv == 6) {
532 0         0 return $obj->get_ipv6_record($ipnum, USAGETYPE);
533             } else {
534 0         0 return INVALID_IP_ADDRESS;
535             }
536             }
537             }
538              
539             sub get_addresstype {
540 0     0 1 0 my $obj = shift(@_);
541 0         0 my $ipaddr = shift(@_);
542 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
543 0 0       0 if ($ipv == 4) {
544 0         0 return $obj->get_ipv4_record($ipnum, ADDRESSTYPE);
545             } else {
546 0 0       0 if ($ipv == 6) {
547 0         0 return $obj->get_ipv6_record($ipnum, ADDRESSTYPE);
548             } else {
549 0         0 return INVALID_IP_ADDRESS;
550             }
551             }
552             }
553              
554             sub get_category {
555 0     0 1 0 my $obj = shift(@_);
556 0         0 my $ipaddr = shift(@_);
557 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
558 0 0       0 if ($ipv == 4) {
559 0         0 return $obj->get_ipv4_record($ipnum, CATEGORY);
560             } else {
561 0 0       0 if ($ipv == 6) {
562 0         0 return $obj->get_ipv6_record($ipnum, CATEGORY);
563             } else {
564 0         0 return INVALID_IP_ADDRESS;
565             }
566             }
567             }
568              
569             sub get_district {
570 0     0 1 0 my $obj = shift(@_);
571 0         0 my $ipaddr = shift(@_);
572 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
573 0 0       0 if ($ipv == 4) {
574 0         0 return $obj->get_ipv4_record($ipnum, DISTRICT);
575             } else {
576 0 0       0 if ($ipv == 6) {
577 0         0 return $obj->get_ipv6_record($ipnum, DISTRICT);
578             } else {
579 0         0 return INVALID_IP_ADDRESS;
580             }
581             }
582             }
583              
584             sub get_asn {
585 0     0 1 0 my $obj = shift(@_);
586 0         0 my $ipaddr = shift(@_);
587 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
588 0 0       0 if ($ipv == 4) {
589 0         0 return $obj->get_ipv4_record($ipnum, ASN);
590             } else {
591 0 0       0 if ($ipv == 6) {
592 0         0 return $obj->get_ipv6_record($ipnum, ASN);
593             } else {
594 0         0 return INVALID_IP_ADDRESS;
595             }
596             }
597             }
598              
599             sub get_as {
600 0     0 1 0 my $obj = shift(@_);
601 0         0 my $ipaddr = shift(@_);
602 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
603 0 0       0 if ($ipv == 4) {
604 0         0 return $obj->get_ipv4_record($ipnum, AS);
605             } else {
606 0 0       0 if ($ipv == 6) {
607 0         0 return $obj->get_ipv6_record($ipnum, AS);
608             } else {
609 0         0 return INVALID_IP_ADDRESS;
610             }
611             }
612             }
613              
614             sub get_as_domain {
615 0     0 1 0 my $obj = shift(@_);
616 0         0 my $ipaddr = shift(@_);
617 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
618 0 0       0 if ($ipv == 4) {
619 0         0 return $obj->get_ipv4_record($ipnum, ASDOMAIN);
620             } else {
621 0 0       0 if ($ipv == 6) {
622 0         0 return $obj->get_ipv6_record($ipnum, ASDOMAIN);
623             } else {
624 0         0 return INVALID_IP_ADDRESS;
625             }
626             }
627             }
628              
629             sub get_as_usagetype {
630 0     0 1 0 my $obj = shift(@_);
631 0         0 my $ipaddr = shift(@_);
632 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
633 0 0       0 if ($ipv == 4) {
634 0         0 return $obj->get_ipv4_record($ipnum, ASUSAGETYPE);
635             } else {
636 0 0       0 if ($ipv == 6) {
637 0         0 return $obj->get_ipv6_record($ipnum, ASUSAGETYPE);
638             } else {
639 0         0 return INVALID_IP_ADDRESS;
640             }
641             }
642             }
643              
644             sub get_as_cidr {
645 0     0 1 0 my $obj = shift(@_);
646 0         0 my $ipaddr = shift(@_);
647 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
648 0 0       0 if ($ipv == 4) {
649 0         0 return $obj->get_ipv4_record($ipnum, ASCIDR);
650             } else {
651 0 0       0 if ($ipv == 6) {
652 0         0 return $obj->get_ipv6_record($ipnum, ASCIDR);
653             } else {
654 0         0 return INVALID_IP_ADDRESS;
655             }
656             }
657             }
658              
659             sub get_all {
660 0     0 1 0 my $obj = shift(@_);
661 0         0 my $ipaddr = shift(@_);
662 0         0 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr);
663 0 0       0 if ($ipv == 4) {
664 0         0 return $obj->get_ipv4_record($ipnum, ALL);
665             } else {
666 0 0       0 if ($ipv == 6) {
667 0         0 return $obj->get_ipv6_record($ipnum, ALL);
668             } else {
669 0         0 return (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, 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);
670             }
671             }
672             }
673              
674             sub get_ipv6_record {
675 10     10 0 29 my $obj = shift(@_);
676 10         22 my $ipnum = shift(@_);
677 10         21 my $mode = shift(@_);
678 10         30 my $dbtype = $obj->{"databasetype"};
679              
680 10 50       39 if ($ipnum eq "") {
681 0 0       0 if ($mode == ALL) {
682 0         0 return (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, 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 return NO_IP;
685             }
686             }
687              
688 10 50 33     521 if (($mode == COUNTRYSHORT) && ($IPV6_COUNTRY_POSITION[$dbtype] == 0)) {
689 0         0 return NOT_SUPPORTED;
690             }
691 10 50 33     806 if (($mode == COUNTRYLONG) && ($IPV6_COUNTRY_POSITION[$dbtype] == 0)) {
692 0         0 return NOT_SUPPORTED;
693             }
694 10 50 33     411 if (($mode == REGION) && ($IPV6_REGION_POSITION[$dbtype] == 0)) {
695 0         0 return NOT_SUPPORTED;
696             }
697 10 50 33     391 if (($mode == CITY) && ($IPV6_CITY_POSITION[$dbtype] == 0)) {
698 0         0 return NOT_SUPPORTED;
699             }
700 10 50 33     334 if (($mode == ISP) && ($IPV6_ISP_POSITION[$dbtype] == 0)) {
701 0         0 return NOT_SUPPORTED;
702             }
703 10 50 33     354 if (($mode == LATITUDE) && ($IPV6_LATITUDE_POSITION[$dbtype] == 0)) {
704 0         0 return NOT_SUPPORTED;
705             }
706 10 50 33     351 if (($mode == LONGITUDE) && ($IPV6_LONGITUDE_POSITION[$dbtype] == 0)) {
707 0         0 return NOT_SUPPORTED;
708             }
709 10 50 33     340 if (($mode == DOMAIN) && ($IPV6_DOMAIN_POSITION[$dbtype] == 0)) {
710 0         0 return NOT_SUPPORTED;
711             }
712 10 50 33     337 if (($mode == ZIPCODE) && ($IPV6_ZIPCODE_POSITION[$dbtype] == 0)) {
713 0         0 return NOT_SUPPORTED;
714             }
715 10 50 33     379 if (($mode == TIMEZONE) && ($IPV6_TIMEZONE_POSITION[$dbtype] == 0)) {
716 0         0 return NOT_SUPPORTED;
717             }
718 10 50 33     404 if (($mode == NETSPEED) && ($IPV6_NETSPEED_POSITION[$dbtype] == 0)) {
719 0         0 return NOT_SUPPORTED;
720             }
721 10 50 33     377 if (($mode == IDDCODE) && ($IPV6_IDDCODE_POSITION[$dbtype] == 0)) {
722 0         0 return NOT_SUPPORTED;
723             }
724 10 50 33     356 if (($mode == AREACODE) && ($IPV6_AREACODE_POSITION[$dbtype] == 0)) {
725 0         0 return NOT_SUPPORTED;
726             }
727 10 50 33     421 if (($mode == WEATHERSTATIONCODE) && ($IPV6_WEATHERSTATIONCODE_POSITION[$dbtype] == 0)) {
728 0         0 return NOT_SUPPORTED;
729             }
730 10 50 33     355 if (($mode == WEATHERSTATIONNAME) && ($IPV6_WEATHERSTATIONNAME_POSITION[$dbtype] == 0)) {
731 0         0 return NOT_SUPPORTED;
732             }
733 10 50 33     452 if (($mode == MCC) && ($IPV6_MCC_POSITION[$dbtype] == 0)) {
734 0         0 return NOT_SUPPORTED;
735             }
736 10 50 33     349 if (($mode == MNC) && ($IPV6_MNC_POSITION[$dbtype] == 0)) {
737 0         0 return NOT_SUPPORTED;
738             }
739 10 50 33     342 if (($mode == MOBILEBRAND) && ($IPV6_MOBILEBRAND_POSITION[$dbtype] == 0)) {
740 0         0 return NOT_SUPPORTED;
741             }
742 10 50 33     340 if (($mode == ELEVATION) && ($IPV6_ELEVATION_POSITION[$dbtype] == 0)) {
743 0         0 return NOT_SUPPORTED;
744             }
745 10 50 33     334 if (($mode == USAGETYPE) && ($IPV6_USAGETYPE_POSITION[$dbtype] == 0)) {
746 0         0 return NOT_SUPPORTED;
747             }
748 10 50 33     343 if (($mode == ADDRESSTYPE) && ($IPV6_ADDRESSTYPE_POSITION[$dbtype] == 0)) {
749 0         0 return NOT_SUPPORTED;
750             }
751 10 50 33     349 if (($mode == CATEGORY) && ($IPV6_CATEGORY_POSITION[$dbtype] == 0)) {
752 0         0 return NOT_SUPPORTED;
753             }
754 10 50 33     326 if (($mode == DISTRICT) && ($IPV6_DISTRICT_POSITION[$dbtype] == 0)) {
755 0         0 return NOT_SUPPORTED;
756             }
757 10 50 33     357 if (($mode == ASN) && ($IPV6_ASN_POSITION[$dbtype] == 0)) {
758 0         0 return NOT_SUPPORTED;
759             }
760 10 50 33     359 if (($mode == AS) && ($IPV6_AS_POSITION[$dbtype] == 0)) {
761 0         0 return NOT_SUPPORTED;
762             }
763 10 50 33     346 if (($mode == ASDOMAIN) && ($IPV6_AS_DOMAIN_POSITION[$dbtype] == 0)) {
764 0         0 return NOT_SUPPORTED;
765             }
766 10 50 33     357 if (($mode == ASUSAGETYPE) && ($IPV6_AS_USAGETYPE_POSITION[$dbtype] == 0)) {
767 0         0 return NOT_SUPPORTED;
768             }
769 10 50 33     330 if (($mode == ASCIDR) && ($IPV6_AS_CIDR_POSITION[$dbtype] == 0)) {
770 0         0 return NOT_SUPPORTED;
771             }
772              
773 10         359 my $realipno = $ipnum;
774 10         33 my $handle = $obj->{"filehandle"};
775 10         24 my $baseaddr = $obj->{"ipv6databaseaddr"};
776 10         28 my $dbcount = $obj->{"ipv6databasecount"};
777 10         22 my $dbcolumn = $obj->{"databasecolumn"};
778 10         25 my $indexbaseaddr = $obj->{"ipv6indexbaseaddr"};
779              
780 10 50       31 if ($dbcount == 0) {
781 0 0       0 if ($mode == ALL) {
782 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, 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);
783             } else {
784 0         0 return IPV6_ADDRESS_IN_IPV4_BIN;
785             }
786             }
787              
788 10         2333 my $ipnum1_2 = new Math::BigInt($ipnum);
789 10         776 my $remainder = 0;
790 10         51 ($ipnum1_2, $remainder) = $ipnum1_2->bdiv(2**112);
791 10         4576 my $indexaddr = $indexbaseaddr + ($ipnum1_2 << 3);
792              
793 10         6416 my $low = 0;
794 10         29 my $high = $dbcount;
795 10 50       38 if ($indexbaseaddr > 0) {
796 10         1440 ($low, $high) = $obj->read32x2($handle, $indexaddr);
797             }
798              
799 10         49 my $mid = 0;
800 10         22 my $ipfrom = 0;
801 10         20 my $ipto = 0;
802 10         19 my $ipno = 0;
803              
804 10         19 $ipno = $realipno;
805 10 50       32 if ($realipno == "340282366920938463463374607431768211455") {
806 0         0 $ipno = $ipno->bsub(1);
807             }
808              
809 10         2377 my $raw_positions_row;
810            
811 10         32 while ($low <= $high) {
812 104         24196 $mid = int(($low + $high)/2);
813 104         50872 ($ipfrom, $ipto, $raw_positions_row) = $obj->readRow128($handle, $baseaddr + $mid * (($dbcolumn * 4) + 12), $dbcolumn);
814            
815 104 100 100     5637 if (($ipno >= $ipfrom) && ($ipno < $ipto)) {
816 10         4160 my $row_pointer = $baseaddr + $mid * (($dbcolumn * 4) + 12);
817            
818 10 50       7286 if ($mode == ALL) {
819 0         0 my $country_short = NOT_SUPPORTED;
820 0         0 my $country_long = NOT_SUPPORTED;
821 0         0 my $region = NOT_SUPPORTED;
822 0         0 my $city = NOT_SUPPORTED;
823 0         0 my $isp = NOT_SUPPORTED;
824 0         0 my $latitude = NOT_SUPPORTED;
825 0         0 my $longitude = NOT_SUPPORTED;
826 0         0 my $domain = NOT_SUPPORTED;
827 0         0 my $zipcode = NOT_SUPPORTED;
828 0         0 my $timezone = NOT_SUPPORTED;
829 0         0 my $netspeed = NOT_SUPPORTED;
830 0         0 my $iddcode = NOT_SUPPORTED;
831 0         0 my $areacode = NOT_SUPPORTED;
832 0         0 my $weatherstationcode = NOT_SUPPORTED;
833 0         0 my $weatherstationname = NOT_SUPPORTED;
834 0         0 my $mcc = NOT_SUPPORTED;
835 0         0 my $mnc = NOT_SUPPORTED;
836 0         0 my $mobilebrand = NOT_SUPPORTED;
837 0         0 my $elevation = NOT_SUPPORTED;
838 0         0 my $usagetype = NOT_SUPPORTED;
839 0         0 my $addresstype = NOT_SUPPORTED;
840 0         0 my $category = NOT_SUPPORTED;
841 0         0 my $district = NOT_SUPPORTED;
842 0         0 my $asn = NOT_SUPPORTED;
843 0         0 my $as = NOT_SUPPORTED;
844 0         0 my $as_domain = NOT_SUPPORTED;
845 0         0 my $as_usagetype = NOT_SUPPORTED;
846 0         0 my $as_cidr = NOT_SUPPORTED;
847            
848 0 0       0 if ($IPV6_COUNTRY_POSITION[$dbtype] != 0) {
849 0         0 $country_short = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_COUNTRY_POSITION[$dbtype]+2), 4)));
850 0         0 $country_long = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_COUNTRY_POSITION[$dbtype]+2), 4)) + 3);
851             }
852 0 0       0 if ($IPV6_REGION_POSITION[$dbtype] != 0) {
853 0         0 $region = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_REGION_POSITION[$dbtype]+2), 4)));
854             }
855 0 0       0 if ($IPV6_CITY_POSITION[$dbtype] != 0) {
856 0         0 $city = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_CITY_POSITION[$dbtype]+2), 4)));
857             }
858 0 0       0 if ($IPV6_ISP_POSITION[$dbtype] != 0) {
859 0         0 $isp = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_ISP_POSITION[$dbtype]+2), 4)));
860             }
861 0 0       0 if ($IPV6_LATITUDE_POSITION[$dbtype] != 0) {
862 0         0 $latitude = $obj->readFloat(substr($raw_positions_row, 4 * ($IPV6_LATITUDE_POSITION[$dbtype]+2)));
863 0         0 $latitude = sprintf("%.6f", $latitude);
864             }
865 0 0       0 if ($IPV6_LONGITUDE_POSITION[$dbtype] != 0) {
866 0         0 $longitude = $obj->readFloat(substr($raw_positions_row, 4 * ($IPV6_LONGITUDE_POSITION[$dbtype]+2)));
867 0         0 $longitude = sprintf("%.6f", $longitude);
868             }
869 0 0       0 if ($IPV6_DOMAIN_POSITION[$dbtype] != 0) {
870 0         0 $domain = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_DOMAIN_POSITION[$dbtype]+2), 4)));
871             }
872 0 0       0 if ($IPV6_ZIPCODE_POSITION[$dbtype] != 0) {
873 0         0 $zipcode = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_ZIPCODE_POSITION[$dbtype]+2), 4)));
874             }
875 0 0       0 if ($IPV6_TIMEZONE_POSITION[$dbtype] != 0) {
876 0         0 $timezone = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_TIMEZONE_POSITION[$dbtype]+2), 4)));
877             }
878 0 0       0 if ($IPV6_NETSPEED_POSITION[$dbtype] != 0) {
879 0         0 $netspeed = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_NETSPEED_POSITION[$dbtype]+2), 4)));
880             }
881 0 0       0 if ($IPV6_IDDCODE_POSITION[$dbtype] != 0) {
882 0         0 $iddcode = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_IDDCODE_POSITION[$dbtype]+2), 4)));
883             }
884 0 0       0 if ($IPV6_AREACODE_POSITION[$dbtype] != 0) {
885 0         0 $areacode = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_AREACODE_POSITION[$dbtype]+2), 4)));
886             }
887 0 0       0 if ($IPV6_WEATHERSTATIONCODE_POSITION[$dbtype] != 0) {
888 0         0 $weatherstationcode = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_WEATHERSTATIONCODE_POSITION[$dbtype]+2), 4)));
889             }
890 0 0       0 if ($IPV6_WEATHERSTATIONNAME_POSITION[$dbtype] != 0) {
891 0         0 $weatherstationname = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_WEATHERSTATIONNAME_POSITION[$dbtype]+2), 4)));
892             }
893 0 0       0 if ($IPV6_MCC_POSITION[$dbtype] != 0) {
894 0         0 $mcc = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_MCC_POSITION[$dbtype]+2), 4)));
895             }
896 0 0       0 if ($IPV6_MNC_POSITION[$dbtype] != 0) {
897 0         0 $mnc = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_MNC_POSITION[$dbtype]+2), 4)));
898             }
899 0 0       0 if ($IPV6_MOBILEBRAND_POSITION[$dbtype] != 0) {
900 0         0 $mobilebrand = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_MOBILEBRAND_POSITION[$dbtype]+2), 4)));
901             }
902 0 0       0 if ($IPV6_ELEVATION_POSITION[$dbtype] != 0) {
903 0         0 $elevation = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_ELEVATION_POSITION[$dbtype]+2), 4)));
904             }
905 0 0       0 if ($IPV6_USAGETYPE_POSITION[$dbtype] != 0) {
906 0         0 $usagetype = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_USAGETYPE_POSITION[$dbtype]+2), 4)));
907             }
908 0 0       0 if ($IPV6_ADDRESSTYPE_POSITION[$dbtype] != 0) {
909 0         0 $addresstype = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_ADDRESSTYPE_POSITION[$dbtype]+2), 4)));
910             }
911 0 0       0 if ($IPV6_CATEGORY_POSITION[$dbtype] != 0) {
912 0         0 $category = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_CATEGORY_POSITION[$dbtype]+2), 4)));
913             }
914 0 0       0 if ($IPV6_DISTRICT_POSITION[$dbtype] != 0) {
915 0         0 $district = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_DISTRICT_POSITION[$dbtype]+2), 4)));
916             }
917 0 0       0 if ($IPV6_ASN_POSITION[$dbtype] != 0) {
918 0         0 $asn = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_ASN_POSITION[$dbtype]+2), 4)));
919             }
920 0 0       0 if ($IPV6_AS_POSITION[$dbtype] != 0) {
921 0         0 $as = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_AS_POSITION[$dbtype]+2), 4)));
922             }
923 0 0       0 if ($IPV6_AS_DOMAIN_POSITION[$dbtype] != 0) {
924 0         0 $as_domain = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_AS_DOMAIN_POSITION[$dbtype]+2), 4)));
925             }
926 0 0       0 if ($IPV6_AS_USAGETYPE_POSITION[$dbtype] != 0) {
927 0         0 $as_usagetype = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_AS_USAGETYPE_POSITION[$dbtype]+2), 4)));
928             }
929 0 0       0 if ($IPV6_AS_CIDR_POSITION[$dbtype] != 0) {
930 0         0 $as_cidr = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_AS_CIDR_POSITION[$dbtype]+2), 4)));
931             }
932 0         0 return ($country_short, $country_long, $region, $city, $latitude, $longitude, $zipcode, $timezone, $isp, $domain, $netspeed, $iddcode, $areacode, $weatherstationcode, $weatherstationname, $mcc, $mnc, $mobilebrand, $elevation, $usagetype, $addresstype, $category, $district, $asn, $as, $as_domain, $as_usagetype, $as_cidr);
933             }
934 10 50       481 if ($mode == COUNTRYSHORT) {
935 10         388 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_COUNTRY_POSITION[$dbtype]+2), 4)));
936             }
937 0 0       0 if ($mode == COUNTRYLONG) {
938 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_COUNTRY_POSITION[$dbtype]+2), 4)) + 3);
939             }
940 0 0       0 if ($mode == REGION) {
941 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_REGION_POSITION[$dbtype]+2), 4)));
942             }
943 0 0       0 if ($mode == CITY) {
944 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_CITY_POSITION[$dbtype]+2), 4)));
945             }
946 0 0       0 if ($mode == ISP) {
947 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_ISP_POSITION[$dbtype]+2), 4)));
948             }
949 0 0       0 if ($mode == LATITUDE) {
950 0         0 my $lat = $obj->readFloat(substr($raw_positions_row, 4 * ($IPV6_LATITUDE_POSITION[$dbtype]+2)));
951 0         0 $lat = sprintf("%.6f", $lat);
952 0         0 return $lat;
953             }
954 0 0       0 if ($mode == LONGITUDE) {
955 0         0 my $lon = $obj->readFloat(substr($raw_positions_row, 4 * ($IPV6_LONGITUDE_POSITION[$dbtype]+2)));
956 0         0 $lon = sprintf("%.6f", $lon);
957 0         0 return $lon;
958             }
959 0 0       0 if ($mode == DOMAIN) {
960 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_DOMAIN_POSITION[$dbtype]+2), 4)));
961             }
962 0 0       0 if ($mode == ZIPCODE) {
963 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_ZIPCODE_POSITION[$dbtype]+2), 4)));
964             }
965 0 0       0 if ($mode == TIMEZONE) {
966 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_TIMEZONE_POSITION[$dbtype]+2), 4)));
967             }
968 0 0       0 if ($mode == NETSPEED) {
969 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_NETSPEED_POSITION[$dbtype]+2), 4)));
970             }
971 0 0       0 if ($mode == IDDCODE) {
972 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_IDDCODE_POSITION[$dbtype]+2), 4)));
973             }
974 0 0       0 if ($mode == AREACODE) {
975 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_AREACODE_POSITION[$dbtype]+2), 4)));
976             }
977 0 0       0 if ($mode == WEATHERSTATIONCODE) {
978 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_WEATHERSTATIONCODE_POSITION[$dbtype]+2), 4)));
979             }
980 0 0       0 if ($mode == WEATHERSTATIONNAME) {
981 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_WEATHERSTATIONNAME_POSITION[$dbtype]+2), 4)));
982             }
983 0 0       0 if ($mode == MCC) {
984 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_MCC_POSITION[$dbtype]+2), 4)));
985             }
986 0 0       0 if ($mode == MNC) {
987 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_MNC_POSITION[$dbtype]+2), 4)));
988             }
989 0 0       0 if ($mode == MOBILEBRAND) {
990 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_MOBILEBRAND_POSITION[$dbtype]+2), 4)));
991             }
992 0 0       0 if ($mode == ELEVATION) {
993 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_ELEVATION_POSITION[$dbtype]+2), 4)));
994             }
995 0 0       0 if ($mode == USAGETYPE) {
996 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_USAGETYPE_POSITION[$dbtype]+2), 4)));
997             }
998 0 0       0 if ($mode == ADDRESSTYPE) {
999 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_ADDRESSTYPE_POSITION[$dbtype]+2), 4)));
1000             }
1001 0 0       0 if ($mode == CATEGORY) {
1002 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_CATEGORY_POSITION[$dbtype]+2), 4)));
1003             }
1004 0 0       0 if ($mode == DISTRICT) {
1005 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_DISTRICT_POSITION[$dbtype]+2), 4)));
1006             }
1007 0 0       0 if ($mode == ASN) {
1008 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_ASN_POSITION[$dbtype]+2), 4)));
1009             }
1010 0 0       0 if ($mode == AS) {
1011 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_AS_POSITION[$dbtype]+2), 4)));
1012             }
1013 0 0       0 if ($mode == ASDOMAIN) {
1014 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_AS_DOMAIN_POSITION[$dbtype]+2), 4)));
1015             }
1016 0 0       0 if ($mode == ASUSAGETYPE) {
1017 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_AS_USAGETYPE_POSITION[$dbtype]+2), 4)));
1018             }
1019 0 0       0 if ($mode == ASCIDR) {
1020 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IPV6_AS_CIDR_POSITION[$dbtype]+2), 4)));
1021             }
1022             } else {
1023 94 100       22825 if ($ipno < $ipfrom) {
1024 82         16180 $high = $mid - 1;
1025             } else {
1026 12         2399 $low = $mid + 1;
1027             }
1028             }
1029             }
1030 0 0       0 if ($mode == ALL) {
1031 0         0 return (UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN);
1032             } else {
1033 0         0 return UNKNOWN;
1034             }
1035             }
1036              
1037             sub get_ipv4_record {
1038 10     10 0 28 my $obj = shift(@_);
1039 10         29 my $ipnum = shift(@_);
1040 10         22 my $mode = shift(@_);
1041 10         27 my $dbtype= $obj->{"databasetype"};
1042            
1043 10 50       45 if ($ipnum eq "") {
1044 0 0       0 if ($mode == ALL) {
1045 0         0 return (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, 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);
1046             } else {
1047 0         0 return NO_IP;
1048             }
1049             }
1050            
1051 10 50 33     684 if (($mode == COUNTRYSHORT) && ($COUNTRY_POSITION[$dbtype] == 0)) {
1052 0         0 return NOT_SUPPORTED;
1053             }
1054 10 50 33     993 if (($mode == COUNTRYLONG) && ($COUNTRY_POSITION[$dbtype] == 0)) {
1055 0         0 return NOT_SUPPORTED;
1056             }
1057 10 50 33     429 if (($mode == REGION) && ($REGION_POSITION[$dbtype] == 0)) {
1058 0         0 return NOT_SUPPORTED;
1059             }
1060 10 50 33     558 if (($mode == CITY) && ($CITY_POSITION[$dbtype] == 0)) {
1061 0         0 return NOT_SUPPORTED;
1062             }
1063 10 50 33     480 if (($mode == ISP) && ($ISP_POSITION[$dbtype] == 0)) {
1064 0         0 return NOT_SUPPORTED;
1065             }
1066 10 50 33     417 if (($mode == LATITUDE) && ($LATITUDE_POSITION[$dbtype] == 0)) {
1067 0         0 return NOT_SUPPORTED;
1068             }
1069 10 50 33     419 if (($mode == LONGITUDE) && ($LONGITUDE_POSITION[$dbtype] == 0)) {
1070 0         0 return NOT_SUPPORTED;
1071             }
1072 10 50 33     533 if (($mode == DOMAIN) && ($DOMAIN_POSITION[$dbtype] == 0)) {
1073 0         0 return NOT_SUPPORTED;
1074             }
1075 10 50 33     424 if (($mode == ZIPCODE) && ($ZIPCODE_POSITION[$dbtype] == 0)) {
1076 0         0 return NOT_SUPPORTED;
1077             }
1078 10 50 33     454 if (($mode == TIMEZONE) && ($TIMEZONE_POSITION[$dbtype] == 0)) {
1079 0         0 return NOT_SUPPORTED;
1080             }
1081 10 50 33     416 if (($mode == NETSPEED) && ($NETSPEED_POSITION[$dbtype] == 0)) {
1082 0         0 return NOT_SUPPORTED;
1083             }
1084 10 50 33     421 if (($mode == IDDCODE) && ($IDDCODE_POSITION[$dbtype] == 0)) {
1085 0         0 return NOT_SUPPORTED;
1086             }
1087 10 50 33     524 if (($mode == AREACODE) && ($AREACODE_POSITION[$dbtype] == 0)) {
1088 0         0 return NOT_SUPPORTED;
1089             }
1090 10 50 33     464 if (($mode == WEATHERSTATIONCODE) && ($WEATHERSTATIONCODE_POSITION[$dbtype] == 0)) {
1091 0         0 return NOT_SUPPORTED;
1092             }
1093 10 50 33     424 if (($mode == WEATHERSTATIONNAME) && ($WEATHERSTATIONNAME_POSITION[$dbtype] == 0)) {
1094 0         0 return NOT_SUPPORTED;
1095             }
1096 10 50 33     410 if (($mode == MCC) && ($MCC_POSITION[$dbtype] == 0)) {
1097 0         0 return NOT_SUPPORTED;
1098             }
1099 10 50 33     498 if (($mode == MNC) && ($MNC_POSITION[$dbtype] == 0)) {
1100 0         0 return NOT_SUPPORTED;
1101             }
1102 10 50 33     425 if (($mode == MOBILEBRAND) && ($MOBILEBRAND_POSITION[$dbtype] == 0)) {
1103 0         0 return NOT_SUPPORTED;
1104             }
1105 10 50 33     408 if (($mode == ELEVATION) && ($ELEVATION_POSITION[$dbtype] == 0)) {
1106 0         0 return NOT_SUPPORTED;
1107             }
1108 10 50 33     403 if (($mode == USAGETYPE) && ($USAGETYPE_POSITION[$dbtype] == 0)) {
1109 0         0 return NOT_SUPPORTED;
1110             }
1111 10 50 33     427 if (($mode == ADDRESSTYPE) && ($ADDRESSTYPE_POSITION[$dbtype] == 0)) {
1112 0         0 return NOT_SUPPORTED;
1113             }
1114 10 50 33     500 if (($mode == CATEGORY) && ($CATEGORY_POSITION[$dbtype] == 0)) {
1115 0         0 return NOT_SUPPORTED;
1116             }
1117 10 50 33     470 if (($mode == DISTRICT) && ($DISTRICT_POSITION[$dbtype] == 0)) {
1118 0         0 return NOT_SUPPORTED;
1119             }
1120 10 50 33     417 if (($mode == ASN) && ($ASN_POSITION[$dbtype] == 0)) {
1121 0         0 return NOT_SUPPORTED;
1122             }
1123 10 50 33     413 if (($mode == AS) && ($AS_POSITION[$dbtype] == 0)) {
1124 0         0 return NOT_SUPPORTED;
1125             }
1126 10 50 33     571 if (($mode == ASDOMAIN) && ($AS_DOMAIN_POSITION[$dbtype] == 0)) {
1127 0         0 return NOT_SUPPORTED;
1128             }
1129 10 50 33     434 if (($mode == ASUSAGETYPE) && ($AS_USAGETYPE_POSITION[$dbtype] == 0)) {
1130 0         0 return NOT_SUPPORTED;
1131             }
1132 10 50 33     464 if (($mode == ASCIDR) && ($AS_CIDR_POSITION[$dbtype] == 0)) {
1133 0         0 return NOT_SUPPORTED;
1134             }
1135            
1136 10         410 my $realipno = $ipnum;
1137 10         36 my $handle = $obj->{"filehandle"};
1138 10         24 my $baseaddr = $obj->{"ipv4databaseaddr"};
1139 10         24 my $dbcount = $obj->{"ipv4databasecount"};
1140 10         28 my $dbcolumn = $obj->{"databasecolumn"};
1141 10         34 my $indexbaseaddr = $obj->{"ipv4indexbaseaddr"};
1142              
1143 10         37 my $ipnum1_2 = int($ipnum >> 16);
1144 10         5646 my $indexaddr = $indexbaseaddr + ($ipnum1_2 << 3);
1145              
1146 10         7524 my $low = 0;
1147 10         24 my $high = $dbcount;
1148 10 50       44 if ($indexbaseaddr > 0) {
1149 10         1621 ($low, $high) = $obj->read32x2($handle, $indexaddr);
1150             }
1151 10         48 my $mid = 0;
1152 10         20 my $ipfrom = 0;
1153 10         18 my $ipto = 0;
1154 10         22 my $ipno = 0;
1155              
1156 10 50       34 if ($realipno == MAX_IPV4_RANGE) {
1157 0         0 $ipno = $realipno - 1;
1158             } else {
1159 10         628 $ipno = $realipno;
1160             }
1161              
1162 10         24 my $raw_positions_row;
1163              
1164 10         36 while ($low <= $high) {
1165 15         1803 $mid = int(($low + $high) >> 1);
1166              
1167 15         8892 ($ipfrom, $ipto, $raw_positions_row) = $obj->readRow32($handle, $baseaddr + $mid * $dbcolumn * 4, $dbcolumn);
1168              
1169 15 100 100     100 if (($ipno >= $ipfrom) && ($ipno < $ipto)) {
1170 10 50       5379 if ($mode == ALL) {
1171 0         0 my $country_short = NOT_SUPPORTED;
1172 0         0 my $country_long = NOT_SUPPORTED;
1173 0         0 my $region = NOT_SUPPORTED;
1174 0         0 my $city = NOT_SUPPORTED;
1175 0         0 my $isp = NOT_SUPPORTED;
1176 0         0 my $latitude = NOT_SUPPORTED;
1177 0         0 my $longitude = NOT_SUPPORTED;
1178 0         0 my $domain = NOT_SUPPORTED;
1179 0         0 my $zipcode = NOT_SUPPORTED;
1180 0         0 my $timezone = NOT_SUPPORTED;
1181 0         0 my $netspeed = NOT_SUPPORTED;
1182 0         0 my $iddcode = NOT_SUPPORTED;
1183 0         0 my $areacode = NOT_SUPPORTED;
1184 0         0 my $weatherstationcode = NOT_SUPPORTED;
1185 0         0 my $weatherstationname = NOT_SUPPORTED;
1186 0         0 my $mcc = NOT_SUPPORTED;
1187 0         0 my $mnc = NOT_SUPPORTED;
1188 0         0 my $mobilebrand = NOT_SUPPORTED;
1189 0         0 my $elevation = NOT_SUPPORTED;
1190 0         0 my $usagetype = NOT_SUPPORTED;
1191 0         0 my $addresstype = NOT_SUPPORTED;
1192 0         0 my $category = NOT_SUPPORTED;
1193 0         0 my $district = NOT_SUPPORTED;
1194 0         0 my $asn = NOT_SUPPORTED;
1195 0         0 my $as = NOT_SUPPORTED;
1196 0         0 my $as_domain = NOT_SUPPORTED;
1197 0         0 my $as_usagetype = NOT_SUPPORTED;
1198 0         0 my $as_cidr = NOT_SUPPORTED;
1199            
1200 0 0       0 if ($COUNTRY_POSITION[$dbtype] != 0) {
1201 0         0 $country_short = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($COUNTRY_POSITION[$dbtype]-1), 4)));
1202 0         0 $country_long = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($COUNTRY_POSITION[$dbtype]-1), 4)) + 3);
1203             }
1204              
1205 0 0       0 if ($REGION_POSITION[$dbtype] != 0) {
1206 0         0 $region = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($REGION_POSITION[$dbtype]-1), 4)));
1207             }
1208 0 0       0 if ($CITY_POSITION[$dbtype] != 0) {
1209 0         0 $city = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($CITY_POSITION[$dbtype]-1), 4)));
1210             }
1211 0 0       0 if ($ISP_POSITION[$dbtype] != 0) {
1212 0         0 $isp = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($ISP_POSITION[$dbtype]-1), 4)));
1213             }
1214 0 0       0 if ($LATITUDE_POSITION[$dbtype] != 0) {
1215 0         0 $latitude = $obj->readFloat(substr($raw_positions_row, 4 * ($LATITUDE_POSITION[$dbtype]-1), 4));
1216 0         0 $latitude = sprintf("%.6f", $latitude);
1217             }
1218 0 0       0 if ($LONGITUDE_POSITION[$dbtype] != 0) {
1219 0         0 $longitude = $obj->readFloat(substr($raw_positions_row, 4 * ($LONGITUDE_POSITION[$dbtype]-1), 4));
1220 0         0 $longitude = sprintf("%.6f", $longitude);
1221             }
1222 0 0       0 if ($DOMAIN_POSITION[$dbtype] != 0) {
1223 0         0 $domain = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($DOMAIN_POSITION[$dbtype]-1), 4)));
1224             }
1225 0 0       0 if ($ZIPCODE_POSITION[$dbtype] != 0) {
1226 0         0 $zipcode = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($ZIPCODE_POSITION[$dbtype]-1), 4)));
1227             }
1228 0 0       0 if ($TIMEZONE_POSITION[$dbtype] != 0) {
1229 0         0 $timezone = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($TIMEZONE_POSITION[$dbtype]-1), 4)));
1230             }
1231 0 0       0 if ($NETSPEED_POSITION[$dbtype] != 0) {
1232 0         0 $netspeed = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($NETSPEED_POSITION[$dbtype]-1), 4)));
1233             }
1234 0 0       0 if ($IDDCODE_POSITION[$dbtype] != 0) {
1235 0         0 $iddcode = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IDDCODE_POSITION[$dbtype]-1), 4)));
1236             }
1237 0 0       0 if ($AREACODE_POSITION[$dbtype] != 0) {
1238 0         0 $areacode = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($AREACODE_POSITION[$dbtype]-1), 4)));
1239             }
1240 0 0       0 if ($WEATHERSTATIONCODE_POSITION[$dbtype] != 0) {
1241 0         0 $weatherstationcode = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($WEATHERSTATIONCODE_POSITION[$dbtype]-1), 4)));
1242             }
1243 0 0       0 if ($WEATHERSTATIONNAME_POSITION[$dbtype] != 0) {
1244 0         0 $weatherstationname = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($WEATHERSTATIONNAME_POSITION[$dbtype]-1), 4)));
1245             }
1246 0 0       0 if ($MCC_POSITION[$dbtype] != 0) {
1247 0         0 $mcc = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($MCC_POSITION[$dbtype]-1), 4)));
1248             }
1249 0 0       0 if ($MNC_POSITION[$dbtype] != 0) {
1250 0         0 $mnc = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($MNC_POSITION[$dbtype]-1), 4)));
1251             }
1252 0 0       0 if ($MOBILEBRAND_POSITION[$dbtype] != 0) {
1253 0         0 $mobilebrand = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($MOBILEBRAND_POSITION[$dbtype]-1), 4)));
1254             }
1255 0 0       0 if ($ELEVATION_POSITION[$dbtype] != 0) {
1256 0         0 $elevation = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($ELEVATION_POSITION[$dbtype]-1), 4)));
1257             }
1258 0 0       0 if ($USAGETYPE_POSITION[$dbtype] != 0) {
1259 0         0 $usagetype = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($USAGETYPE_POSITION[$dbtype]-1), 4)));
1260             }
1261 0 0       0 if ($ADDRESSTYPE_POSITION[$dbtype] != 0) {
1262 0         0 $addresstype = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($ADDRESSTYPE_POSITION[$dbtype]-1), 4)));
1263             }
1264 0 0       0 if ($CATEGORY_POSITION[$dbtype] != 0) {
1265 0         0 $category = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($CATEGORY_POSITION[$dbtype]-1), 4)));
1266             }
1267 0 0       0 if ($DISTRICT_POSITION[$dbtype] != 0) {
1268 0         0 $district = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($DISTRICT_POSITION[$dbtype]-1), 4)));
1269             }
1270 0 0       0 if ($ASN_POSITION[$dbtype] != 0) {
1271 0         0 $asn = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($ASN_POSITION[$dbtype]-1), 4)));
1272             }
1273 0 0       0 if ($AS_POSITION[$dbtype] != 0) {
1274 0         0 $as = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($AS_POSITION[$dbtype]-1), 4)));
1275             }
1276 0 0       0 if ($AS_DOMAIN_POSITION[$dbtype] != 0) {
1277 0         0 $as_domain = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($AS_DOMAIN_POSITION[$dbtype]-1), 4)));
1278             }
1279 0 0       0 if ($AS_USAGETYPE_POSITION[$dbtype] != 0) {
1280 0         0 $as_usagetype = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($AS_USAGETYPE_POSITION[$dbtype]-1), 4)));
1281             }
1282 0 0       0 if ($AS_CIDR_POSITION[$dbtype] != 0) {
1283 0         0 $as_cidr = $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($AS_CIDR_POSITION[$dbtype]-1), 4)));
1284             }
1285              
1286 0         0 return ($country_short, $country_long, $region, $city, $latitude, $longitude, $zipcode, $timezone, $isp, $domain, $netspeed, $iddcode, $areacode, $weatherstationcode, $weatherstationname, $mcc, $mnc, $mobilebrand, $elevation, $usagetype, $addresstype, $category, $district, $asn, $as, $as_domain, $as_usagetype, $as_cidr);
1287             }
1288 10 50       509 if ($mode == COUNTRYSHORT) {
1289 10         469 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($COUNTRY_POSITION[$dbtype]-1), 4)));
1290             }
1291 0 0       0 if ($mode == COUNTRYLONG) {
1292 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($COUNTRY_POSITION[$dbtype]-1), 4)) + 3);
1293             }
1294 0 0       0 if ($mode == REGION) {
1295 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($REGION_POSITION[$dbtype]-1), 4)));
1296             }
1297 0 0       0 if ($mode == CITY) {
1298 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($CITY_POSITION[$dbtype]-1), 4)));
1299             }
1300 0 0       0 if ($mode == ISP) {
1301 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($ISP_POSITION[$dbtype]-1), 4)));
1302             }
1303 0 0       0 if ($mode == LATITUDE) {
1304 0         0 my $lat = $obj->readFloat(substr($raw_positions_row, 4 * ($LATITUDE_POSITION[$dbtype]-1), 4));
1305 0         0 $lat = sprintf("%.6f", $lat);
1306 0         0 return $lat;
1307             }
1308 0 0       0 if ($mode == LONGITUDE) {
1309 0         0 my $lon = $obj->readFloat(substr($raw_positions_row, 4 * ($LONGITUDE_POSITION[$dbtype]-1), 4));
1310 0         0 $lon = sprintf("%.6f", $lon);
1311 0         0 return $lon;
1312             }
1313 0 0       0 if ($mode == DOMAIN) {
1314 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($DOMAIN_POSITION[$dbtype]-1), 4)));
1315             }
1316 0 0       0 if ($mode == ZIPCODE) {
1317 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($ZIPCODE_POSITION[$dbtype]-1), 4)));
1318             }
1319 0 0       0 if ($mode == TIMEZONE) {
1320 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($TIMEZONE_POSITION[$dbtype]-1), 4)));
1321             }
1322 0 0       0 if ($mode == NETSPEED) {
1323 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($NETSPEED_POSITION[$dbtype]-1), 4)));
1324             }
1325 0 0       0 if ($mode == IDDCODE) {
1326 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($IDDCODE_POSITION[$dbtype]-1), 4)));
1327             }
1328 0 0       0 if ($mode == AREACODE) {
1329 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($AREACODE_POSITION[$dbtype]-1), 4)));
1330             }
1331 0 0       0 if ($mode == WEATHERSTATIONCODE) {
1332 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($WEATHERSTATIONCODE_POSITION[$dbtype]-1), 4)));
1333             }
1334 0 0       0 if ($mode == WEATHERSTATIONNAME) {
1335 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($WEATHERSTATIONNAME_POSITION[$dbtype]-1), 4)));
1336             }
1337 0 0       0 if ($mode == MCC) {
1338 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($MCC_POSITION[$dbtype]-1), 4)));
1339             }
1340 0 0       0 if ($mode == MNC) {
1341 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($MNC_POSITION[$dbtype]-1), 4)));
1342             }
1343 0 0       0 if ($mode == MOBILEBRAND) {
1344 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($MOBILEBRAND_POSITION[$dbtype]-1), 4)));
1345             }
1346 0 0       0 if ($mode == ELEVATION) {
1347 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($ELEVATION_POSITION[$dbtype]-1), 4)));
1348             }
1349 0 0       0 if ($mode == USAGETYPE) {
1350 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($USAGETYPE_POSITION[$dbtype]-1), 4)));
1351             }
1352 0 0       0 if ($mode == ADDRESSTYPE) {
1353 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($ADDRESSTYPE_POSITION[$dbtype]-1), 4)));
1354             }
1355 0 0       0 if ($mode == CATEGORY) {
1356 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($CATEGORY_POSITION[$dbtype]-1), 4)));
1357             }
1358 0 0       0 if ($mode == DISTRICT) {
1359 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($DISTRICT_POSITION[$dbtype]-1), 4)));
1360             }
1361 0 0       0 if ($mode == ASN) {
1362 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($ASN_POSITION[$dbtype]-1), 4)));
1363             }
1364 0 0       0 if ($mode == AS) {
1365 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($AS_POSITION[$dbtype]-1), 4)));
1366             }
1367 0 0       0 if ($mode == ASDOMAIN) {
1368 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($AS_DOMAIN_POSITION[$dbtype]-1), 4)));
1369             }
1370 0 0       0 if ($mode == ASUSAGETYPE) {
1371 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($AS_USAGETYPE_POSITION[$dbtype]-1), 4)));
1372             }
1373 0 0       0 if ($mode == ASCIDR) {
1374 0         0 return $obj->readStr($handle, unpack("V", substr($raw_positions_row, 4 * ($AS_CIDR_POSITION[$dbtype]-1), 4)));
1375             }
1376             } else {
1377 5 100       1546 if ($ipno < $ipfrom) {
1378 4         1115 $high = $mid - 1;
1379             } else {
1380 1         275 $low = $mid + 1;
1381             }
1382             }
1383             }
1384 0 0       0 if ($mode == ALL) {
1385 0         0 return (UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN);
1386             } else {
1387 0         0 return UNKNOWN;
1388             }
1389             }
1390              
1391             sub readRow32 {
1392 15     15 0 13103 my ($obj, $handle, $position, $column) = @_;
1393 15         58 my $data = "";
1394 15         59 my $data_length = $column * 4 + 4;
1395 15         7792 seek($handle, $position-1, 0);
1396 15         4568 read($handle, $data, $data_length);
1397 15         964 my $ipfrom = substr($data, 0, 4);
1398 15         1278 my $ipfrom_next = substr($data, $data_length - 4, 4);
1399 15         4630 my $result_row = substr($data, 0, $data_length - 4);
1400 15         4368 return (unpack("V", $ipfrom), unpack("V", $ipfrom_next), $result_row);
1401             }
1402              
1403             sub readRow128 {
1404 104     104 0 73983 my ($obj, $handle, $position, $column) = @_;
1405 104         223 my $data = "";
1406 104         273 my $data_length = $column * 4 + 12 + 16;
1407 104         48149 seek($handle, $position-1, 0);
1408 104         23234 read($handle, $data, $data_length);
1409 104         4569 my $ipfrom = substr($data, 0, 16);
1410 104         6159 my $ipfrom_next = substr($data, $data_length - 16, 16);
1411 104         21177 my $result_row = substr($data, 0, $data_length - 16);
1412 104         19965 return (&bytesInt($ipfrom), &bytesInt($ipfrom_next), $result_row);
1413             }
1414              
1415             sub read512 {
1416 2     2 0 8 my ($obj, $handle, $position) = @_;
1417 2         6 my $data = "";
1418 2         15 seek($handle, $position-1, 0);
1419 2         658 read($handle, $data, 64);
1420 2         291 my @data_array = split('', $data);
1421 2         17 while ($#data_array < 63) {
1422 0         0 $data_array[$#data_array+1] = 0x00;
1423             }
1424 2         401 return @data_array;
1425             }
1426              
1427             sub read32x2 {
1428 20     20 0 64 my ($obj, $handle, $position) = @_;
1429 20         51 my $data = "";
1430 20         87 seek($handle, $position-1, 0);
1431 20         5981 read($handle, $data, 8);
1432 20         1275 my $data_1 = substr($data, 0, 4);
1433 20         1539 my $data_2 = substr($data, 4, 4);
1434 20         1593 return (unpack("V", $data_1), unpack("V", $data_2));
1435             }
1436              
1437             sub read128 {
1438 0     0 0 0 my ($obj, $handle, $position) = @_;
1439 0         0 my $data = "";
1440 0         0 seek($handle, $position-1, 0);
1441 0         0 read($handle, $data, 16);
1442 0         0 return &bytesInt($data);
1443             }
1444              
1445             sub read32 {
1446 0     0 0 0 my ($obj, $handle, $position) = @_;
1447 0         0 my $data = "";
1448 0         0 seek($handle, $position-1, 0);
1449 0         0 read($handle, $data, 4);
1450 0         0 return unpack("V", $data);
1451             }
1452              
1453             sub read8 {
1454 0     0 0 0 my ($obj, $handle, $position) = @_;
1455 0         0 my $data = "";
1456 0         0 seek($handle, $position-1, 0);
1457 0         0 read($handle, $data, 1);
1458 0         0 return unpack("C", $data);
1459             }
1460              
1461             sub readStr {
1462 20     20 0 7384 my ($obj, $handle, $position) = @_;
1463 20         49 my $data = "";
1464 20         81 seek($handle, $position, 0);
1465 20         1059 read($handle, $data, 257);
1466 20         1098 my $char_count = unpack("C", substr($data, 0, 1));
1467 20         1450 my $string = substr($data, 1, $char_count);
1468 20         1109 return $string;
1469             }
1470              
1471             sub readFloat {
1472 0     0 0 0 my ($obj, $data) = @_;
1473 0         0 my $is_little_endian = unpack("h*", pack("s", 1));
1474 0 0       0 if ($is_little_endian =~ m/^1/) {
1475             # "LITTLE ENDIAN - x86\n";
1476 0         0 return unpack("f", $data);
1477             } else {
1478             # "BIG ENDIAN - MAC\n";
1479 0         0 return unpack("f", reverse($data));
1480             }
1481             }
1482              
1483             sub bytesInt {
1484 208     208 0 5242 my $binip = shift(@_);
1485 208         865 my @array = split(//, $binip);
1486 208 50       608 return 0 if ($#array != 15);
1487 208         38342 my $ip96_127 = unpack("V", $array[0] . $array[1] . $array[2] . $array[3]);
1488 208         466 my $ip64_95 = unpack("V", $array[4] . $array[5] . $array[6] . $array[7]);
1489 208         399 my $ip32_63 = unpack("V", $array[8] . $array[9] . $array[10] . $array[11]);
1490 208         386 my $ip1_31 = unpack("V", $array[12] . $array[13] . $array[14] . $array[15]);
1491              
1492 208         678 my $big1 = Math::BigInt->new("$ip96_127");
1493 208         16046 my $big2 = Math::BigInt->new("$ip64_95")->blsft(32);
1494 208         68314 my $big3 = Math::BigInt->new("$ip32_63")->blsft(64);
1495 208         72559 my $big4 = Math::BigInt->new("$ip1_31")->blsft(96);
1496 208         194304 $big1 = $big1->badd($big2)->badd($big3)->badd($big4);
1497            
1498 208         53643 return $big1->bstr();
1499             }
1500              
1501             sub validate_ip {
1502 20     20 0 51 my $obj = shift(@_);
1503 20         40 my $ip = shift(@_);
1504 20         49 my $ipv = -1;
1505 20         36 my $ipnum = -1;
1506             #name server lookup if domain name
1507 20         95 $ip = $obj->name2ip($ip);
1508            
1509 20 100       108 if ($obj->ip_is_ipv4($ip)) {
1510             #ipv4 address
1511 10         400 $ipv = 4;
1512 10         42 $ipnum = $obj->ip2no($ip);
1513             } else {
1514             #expand ipv6 address
1515 10         309 $ip = $obj->expand_ipv6_address($ip);
1516 10 50       41 if ($obj->ip_is_ipv6($ip)) {
1517             #ipv6 address
1518 10         281 $ipv = 6;
1519 10         38 $ipnum = $obj->hex2int($ip);
1520            
1521             #reformat ipv4 address in ipv6
1522 10 50 33     39 if (($ipnum >= 281470681743360) && ($ipnum <= 281474976710655)) {
1523 0         0 $ipv = 4;
1524 0         0 $ipnum = $ipnum - 281470681743360;
1525             }
1526              
1527             #reformat 6to4 address to ipv4 address 2002:: to 2002:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
1528 10 50 33     1155 if (($ipnum >= 42545680458834377588178886921629466624) && ($ipnum <= 42550872755692912415807417417958686719)) {
1529 0         0 $ipv = 4;
1530             #bitshift right 80 bits
1531 0         0 $ipnum->brsft(80);
1532             #bitwise modulus to get the last 32 bit
1533 0         0 $ipnum->bmod(4294967296);
1534             }
1535              
1536             #reformat Teredo address to ipv4 address 2001:0000:: to 2001:0000:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:
1537 10 50 33     1120 if (($ipnum >= 42540488161975842760550356425300246528) && ($ipnum <= 42540488241204005274814694018844196863)) {
1538 0         0 $ipv = 4;
1539 0         0 $ipnum = Math::BigInt->new($ipnum);
1540             #bitwise not to invert binary
1541 0         0 $ipnum->bnot();
1542             #bitwise modulus to get the last 32 bit
1543 0         0 $ipnum->bmod(4294967296);
1544             }
1545              
1546             } else {
1547             #not IPv4 and IPv6
1548             }
1549             }
1550 20         1075 return ($ipv, $ipnum);
1551             }
1552              
1553             sub expand_ipv6_address {
1554 10     10 0 22 my $obj = shift(@_);
1555 10         17 my $ip = shift(@_);
1556 10         30 $ip =~ s/\:\:/\:Z\:/;
1557 10         85 my @ip = split(/\:/, $ip);
1558 10         24 my $num = scalar(@ip);
1559              
1560 10         17 my $l = 8;
1561 10 50       37 if ($ip[$#ip] =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
1562 0         0 my $a = sprintf("%x", ($1*256 + $2));
1563 0         0 my $b = sprintf("%x", ($3*256 + $4));
1564 0         0 $ip[$#ip] = $a;
1565 0         0 $ip[$#ip+1] = $b;
1566 0         0 $l--;
1567             }
1568              
1569 10 50       32 if ($#ip == 8) {
1570 0         0 shift(@ip);
1571 0         0 $l++;
1572             }
1573              
1574 10         2032 foreach (0..(scalar(@ip)-1)) {
1575 80 50       13219 next if (length($ip[$_]) > 3);
1576 0         0 $ip[$_] = ('0'x(4-length($ip[$_]))).$ip[$_];
1577             }
1578            
1579 10         1181 foreach (0..(scalar(@ip)-1)) {
1580 80 50       5050 next unless ($ip[$_] eq '000Z');
1581 0         0 my @empty = map { $_ = '0'x4 } (0..7);
  0         0  
1582 0         0 $ip[$_] = join(':', @empty[0..$l-$num]);
1583 0         0 last;
1584             }
1585              
1586 10         87 return (uc(join ':', @ip));
1587             }
1588              
1589             sub hex2int {
1590 10     10 0 18 my $obj = shift(@_);
1591 10         21 my $hexip = shift(@_);
1592              
1593 10         58 $hexip =~ s/\://g;
1594              
1595 10 50       35 unless (length($hexip) == 32) {
1596 0         0 return 0;
1597             };
1598              
1599 10         1952 my $binip = unpack('B128', pack('H32', $hexip));
1600 10         32 my ($n, $dec) = (Math::BigInt->new(1), Math::BigInt->new(0));
1601              
1602 10         1487 foreach (reverse (split('', $binip))) {
1603 1280 100       118815 $_ && ($dec += $n);
1604 1280         9177 $n *= 2;
1605             }
1606              
1607 10         1237 $dec =~ s/^\+//;
1608 10         685 return $dec;
1609             }
1610              
1611             sub ip2no {
1612 10     10 0 24 my $obj = shift(@_);
1613 10         24 my $ip = shift(@_);
1614 10         47 my @block = split(/\./, $ip);
1615 10         24 my $no = 0;
1616 10         21 $no = $block[3];
1617 10         38 $no = $no + $block[2] * 256;
1618 10         9182 $no = $no + $block[1] * 256 * 256;
1619 10         6539 $no = $no + $block[0] * 256 * 256 * 256;
1620 10         8134 return $no;
1621             }
1622              
1623             sub name2ip {
1624 20     20 0 45 my $obj = shift(@_);
1625 20         40 my $host = shift(@_);
1626 20         43 my $ip_address = "";
1627 20 50 66     2124 if (($host =~ m/^$IPv4_re$/) || ($host =~ m/^$IPv6_re$/) || ($host =~ m/^\:\:$/)) {
      33        
1628 20         62 $ip_address = $host;
1629             } else {
1630             # TO_DO: Can we return IPv6 address too?
1631 0         0 my @hostname = gethostbyname($host);
1632 0 0       0 if ($#hostname < 4) {
1633 0         0 $ip_address = $host;
1634             } else {
1635 0         0 $ip_address = join('.', unpack('C4', $hostname[4]));
1636             }
1637             }
1638 20         109 return $ip_address;
1639             }
1640              
1641             sub ip_is_ipv4 {
1642 20     20 0 47 my $obj = shift(@_);
1643 20         47 my $ip = shift(@_);
1644 20 100       229 if ($ip =~ m/^$IPv4_re$/) {
1645 10         48 my @octet = split(/\./, $ip);
1646 10         55 foreach my $i (0 .. $#octet) {
1647 40 50 33     11416 return 0 if (($octet[$i] > 255) || ($octet[$i] < 0));
1648             }
1649 10         3182 return 1;
1650             } else {
1651 10         53 return 0;
1652             }
1653             }
1654              
1655             sub ip_is_ipv6 {
1656 10     10 0 77 my $obj = shift(@_);
1657 10         25 my $ip = shift(@_);
1658 10 50 33     1571 if (($ip =~ m/^$IPv6_re$/) || ($ip =~ m/^$IPv4_re$/) || ($ip =~ m/^\:\:$/)) {
      33        
1659 10         72 return 1;
1660             } else {
1661 0           return 0;
1662             }
1663             }
1664              
1665             1;
1666             __END__