File Coverage

blib/lib/Geo/IP2Location.pm
Criterion Covered Total %
statement 479 1071 44.7
branch 95 482 19.7
condition 67 186 36.0
subroutine 86 119 72.2
pod 30 51 58.8
total 757 1909 39.6


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