1# Copyright (C) 2005-2016 IP2Location.com 2# All Rights Reserved 3# 4# This library is free software: you can redistribute it and/or 5# modify it under the terms of the GNU Lesser General Public 6# License as published by the Free Software Foundation, either 7# version 3 of the License, or (at your option) any later version. 8# 9# This library is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12# Lesser General Public License for more details. 13# 14# You should have received a copy of the GNU Lesser General Public 15# License along with this library; If not, see <http://www.gnu.org/licenses/>. 16 17package Geo::IP2Location; 18 19use strict; 20use vars qw(@ISA $VERSION @EXPORT); 21use Math::BigInt; 22 23$VERSION = '8.03'; 24 25require Exporter; 26@ISA = qw(Exporter); 27 28use constant UNKNOWN => "UNKNOWN IP ADDRESS"; 29use constant IPV6_ADDRESS_IN_IPV4_BIN => "IPV6 ADDRESS MISSING IN IPV4 BIN"; 30use constant NO_IP => "MISSING IP ADDRESS"; 31use constant INVALID_IPV6_ADDRESS => "INVALID IPV6 ADDRESS"; 32use constant INVALID_IPV4_ADDRESS => "INVALID IPV4 ADDRESS"; 33use constant INVALID_IP_ADDRESS => "INVALID IP ADDRESS"; 34use constant NOT_SUPPORTED => "This parameter is unavailable in selected .BIN data file. Please upgrade data file."; 35use constant MAX_IPV4_RANGE => 4294967295; 36use constant MAX_IPV6_RANGE => 340282366920938463463374607431768211455; 37use constant IP_COUNTRY => 1; 38use constant IP_COUNTRY_ISP => 2; 39use constant IP_COUNTRY_REGION_CITY => 3; 40use constant IP_COUNTRY_REGION_CITY_ISP => 4; 41use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE => 5; 42use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ISP => 6; 43use constant IP_COUNTRY_REGION_CITY_ISP_DOMAIN => 7; 44use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ISP_DOMAIN => 8; 45use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE => 9; 46use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_ISP_DOMAIN => 10; 47use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE => 11; 48use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN => 12; 49use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_TIMEZONE_NETSPEED => 13; 50use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED => 14; 51use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_AREACODE => 15; 52use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED_AREACODE => 16; 53use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_TIMEZONE_NETSPEED_WEATHER => 17; 54use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED_AREACODE_WEATHER => 18; 55use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ISP_DOMAIN_MOBILE => 19; 56use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED_AREACODE_WEATHER_MOBILE => 20; 57use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_AREACODE_ELEVATION => 21; 58use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED_AREACODE_WEATHER_MOBILE_ELEVATION => 22; 59use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ISP_DOMAIN_MOBILE_USAGETYPE => 23; 60use constant IP_COUNTRY_REGION_CITY_LATITUDE_LONGITUDE_ZIPCODE_TIMEZONE_ISP_DOMAIN_NETSPEED_AREACODE_WEATHER_MOBILE_ELEVATION_USAGETYPE => 24; 61 62use constant COUNTRYSHORT => 1; 63use constant COUNTRYLONG => 2; 64use constant REGION => 3; 65use constant CITY => 4; 66use constant ISP => 5; 67use constant LATITUDE => 6; 68use constant LONGITUDE => 7; 69use constant DOMAIN => 8; 70use constant ZIPCODE => 9; 71use constant TIMEZONE => 10; 72use constant NETSPEED => 11; 73use constant IDDCODE => 12; 74use constant AREACODE => 13; 75use constant WEATHERSTATIONCODE => 14; 76use constant WEATHERSTATIONNAME => 15; 77use constant MCC => 16; 78use constant MNC => 17; 79use constant MOBILEBRAND => 18; 80use constant ELEVATION => 19; 81use constant USAGETYPE => 20; 82 83use constant ALL => 100; 84use constant IPV4 => 0; 85use constant IPV6 => 1; 86 87my @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); 88my @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); 89my @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); 90my @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); 91my @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); 92my @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); 93my @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); 94my @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); 95my @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); 96my @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); 97my @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); 98my @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); 99my @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); 100my @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); 101my @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); 102my @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); 103my @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); 104my @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); 105my @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); 106 107my @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); 108my @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); 109my @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); 110my @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); 111my @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); 112my @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); 113my @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); 114my @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); 115my @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); 116my @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); 117my @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); 118my @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); 119my @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); 120my @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); 121my @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); 122my @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); 123my @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); 124my @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); 125my @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); 126 127my $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})|:))/; 128my $IPv4_re = qr/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/; 129 130sub open { 131 die "Geo::IP2Location::open() requires a database path name" unless( (@_ > 1) && ($_[1]) ); 132 my ($class, $db_file) = @_; 133 my $handle; 134 my $obj; 135 CORE::open $handle, "$db_file" or die "Geo::IP2Location::open() error opening $db_file"; 136 binmode($handle); 137 $obj = bless {filehandle => $handle}, $class; 138 $obj->initialize(); 139 return $obj; 140} 141 142sub initialize { 143 my ($obj) = @_; 144 $obj->{"databasetype"} = $obj->read8($obj->{filehandle}, 1); 145 $obj->{"databasecolumn"} = $obj->read8($obj->{filehandle}, 2); 146 $obj->{"databaseyear"} = $obj->read8($obj->{filehandle}, 3); 147 $obj->{"databasemonth"} = $obj->read8($obj->{filehandle}, 4); 148 $obj->{"databaseday"} = $obj->read8($obj->{filehandle}, 5); 149 $obj->{"ipv4databasecount"} = $obj->read32($obj->{filehandle}, 6); 150 $obj->{"ipv4databaseaddr"} = $obj->read32($obj->{filehandle}, 10); 151 $obj->{"ipv6databasecount"} = $obj->read32($obj->{filehandle}, 14); 152 $obj->{"ipv6databaseaddr"} = $obj->read32($obj->{filehandle}, 18); 153 $obj->{"ipv4indexbaseaddr"} = $obj->read32($obj->{filehandle}, 22); 154 $obj->{"ipv6indexbaseaddr"} = $obj->read32($obj->{filehandle}, 26); 155 return $obj; 156} 157 158sub get_module_version { 159 my $obj = shift(@_); 160 return $VERSION; 161} 162 163sub get_database_version { 164 my $obj = shift(@_); 165 return $obj->{"databaseyear"} . "." . $obj->{"databasemonth"} . "." . $obj->{"databaseday"}; 166} 167 168sub get_country_short { 169 my $obj = shift(@_); 170 my $ipaddr = shift(@_); 171 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 172 if ($ipv == 4) { 173 return $obj->get_record($ipnum, COUNTRYSHORT); 174 } else { 175 if ($ipv == 6) { 176 return $obj->get_ipv6_record($ipnum, COUNTRYSHORT); 177 } else { 178 return INVALID_IP_ADDRESS; 179 } 180 } 181} 182 183sub get_country_long { 184 my $obj = shift(@_); 185 my $ipaddr = shift(@_); 186 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 187 if ($ipv == 4) { 188 return $obj->get_record($ipnum, COUNTRYLONG); 189 } else { 190 if ($ipv == 6) { 191 return $obj->get_ipv6_record($ipnum, COUNTRYLONG); 192 } else { 193 return INVALID_IP_ADDRESS; 194 } 195 } 196} 197 198sub get_region { 199 my $obj = shift(@_); 200 my $ipaddr = shift(@_); 201 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 202 if ($ipv == 4) { 203 return $obj->get_record($ipnum, REGION); 204 } else { 205 if ($ipv == 6) { 206 return $obj->get_ipv6_record($ipnum, REGION); 207 } else { 208 return INVALID_IP_ADDRESS; 209 } 210 } 211} 212 213sub get_city { 214 my $obj = shift(@_); 215 my $ipaddr = shift(@_); 216 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 217 if ($ipv == 4) { 218 return $obj->get_record($ipnum, CITY); 219 } else { 220 if ($ipv == 6) { 221 return $obj->get_ipv6_record($ipnum, CITY); 222 } else { 223 return INVALID_IP_ADDRESS; 224 } 225 } 226} 227 228sub get_isp { 229 my $obj = shift(@_); 230 my $ipaddr = shift(@_); 231 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 232 if ($ipv == 4) { 233 return $obj->get_record($ipnum, ISP); 234 } else { 235 if ($ipv == 6) { 236 return $obj->get_ipv6_record($ipnum, ISP); 237 } else { 238 return INVALID_IP_ADDRESS; 239 } 240 } 241} 242 243sub get_latitude { 244 my $obj = shift(@_); 245 my $ipaddr = shift(@_); 246 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 247 if ($ipv == 4) { 248 return $obj->get_record($ipnum, LATITUDE); 249 } else { 250 if ($ipv == 6) { 251 return $obj->get_ipv6_record($ipnum, LATITUDE); 252 } else { 253 return INVALID_IP_ADDRESS; 254 } 255 } 256} 257 258sub get_zipcode { 259 my $obj = shift(@_); 260 my $ipaddr = shift(@_); 261 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 262 if ($ipv == 4) { 263 return $obj->get_record($ipnum, ZIPCODE); 264 } else { 265 if ($ipv == 6) { 266 return $obj->get_ipv6_record($ipnum, ZIPCODE); 267 } else { 268 return INVALID_IP_ADDRESS; 269 } 270 } 271} 272 273sub get_longitude { 274 my $obj = shift(@_); 275 my $ipaddr = shift(@_); 276 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 277 if ($ipv == 4) { 278 return $obj->get_record($ipnum, LONGITUDE); 279 } else { 280 if ($ipv == 6) { 281 return $obj->get_ipv6_record($ipnum, LONGITUDE); 282 } else { 283 return INVALID_IP_ADDRESS; 284 } 285 } 286} 287 288sub get_domain { 289 my $obj = shift(@_); 290 my $ipaddr = shift(@_); 291 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 292 if ($ipv == 4) { 293 return $obj->get_record($ipnum, DOMAIN); 294 } else { 295 if ($ipv == 6) { 296 return $obj->get_ipv6_record($ipnum, DOMAIN); 297 } else { 298 return INVALID_IP_ADDRESS; 299 } 300 } 301} 302 303sub get_timezone { 304 my $obj = shift(@_); 305 my $ipaddr = shift(@_); 306 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 307 if ($ipv == 4) { 308 return $obj->get_record($ipnum, TIMEZONE); 309 } else { 310 if ($ipv == 6) { 311 return $obj->get_ipv6_record($ipnum, TIMEZONE); 312 } else { 313 return INVALID_IP_ADDRESS; 314 } 315 } 316} 317 318sub get_netspeed { 319 my $obj = shift(@_); 320 my $ipaddr = shift(@_); 321 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 322 if ($ipv == 4) { 323 return $obj->get_record($ipnum, NETSPEED); 324 } else { 325 if ($ipv == 6) { 326 return $obj->get_ipv6_record($ipnum, NETSPEED); 327 } else { 328 return INVALID_IP_ADDRESS; 329 } 330 } 331} 332 333sub get_iddcode { 334 my $obj = shift(@_); 335 my $ipaddr = shift(@_); 336 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 337 if ($ipv == 4) { 338 return $obj->get_record($ipnum, IDDCODE); 339 } else { 340 if ($ipv == 6) { 341 return $obj->get_ipv6_record($ipnum, IDDCODE); 342 } else { 343 return INVALID_IP_ADDRESS; 344 } 345 } 346} 347 348sub get_areacode { 349 my $obj = shift(@_); 350 my $ipaddr = shift(@_); 351 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 352 if ($ipv == 4) { 353 return $obj->get_record($ipnum, AREACODE); 354 } else { 355 if ($ipv == 6) { 356 return $obj->get_ipv6_record($ipnum, AREACODE); 357 } else { 358 return INVALID_IP_ADDRESS; 359 } 360 } 361} 362 363sub get_weatherstationcode { 364 my $obj = shift(@_); 365 my $ipaddr = shift(@_); 366 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 367 if ($ipv == 4) { 368 return $obj->get_record($ipnum, WEATHERSTATIONCODE); 369 } else { 370 if ($ipv == 6) { 371 return $obj->get_ipv6_record($ipnum, WEATHERSTATIONCODE); 372 } else { 373 return INVALID_IP_ADDRESS; 374 } 375 } 376} 377 378sub get_weatherstationname { 379 my $obj = shift(@_); 380 my $ipaddr = shift(@_); 381 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 382 if ($ipv == 4) { 383 return $obj->get_record($ipnum, WEATHERSTATIONNAME); 384 } else { 385 if ($ipv == 6) { 386 return $obj->get_ipv6_record($ipnum, WEATHERSTATIONNAME); 387 } else { 388 return INVALID_IP_ADDRESS; 389 } 390 } 391} 392 393sub get_mcc { 394 my $obj = shift(@_); 395 my $ipaddr = shift(@_); 396 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 397 if ($ipv == 4) { 398 return $obj->get_record($ipnum, MCC); 399 } else { 400 if ($ipv == 6) { 401 return $obj->get_ipv6_record($ipnum, MCC); 402 } else { 403 return INVALID_IP_ADDRESS; 404 } 405 } 406} 407 408sub get_mnc { 409 my $obj = shift(@_); 410 my $ipaddr = shift(@_); 411 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 412 if ($ipv == 4) { 413 return $obj->get_record($ipnum, MNC); 414 } else { 415 if ($ipv == 6) { 416 return $obj->get_ipv6_record($ipnum, MNC); 417 } else { 418 return INVALID_IP_ADDRESS; 419 } 420 } 421} 422 423sub get_mobilebrand { 424 my $obj = shift(@_); 425 my $ipaddr = shift(@_); 426 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 427 if ($ipv == 4) { 428 return $obj->get_record($ipnum, MOBILEBRAND); 429 } else { 430 if ($ipv == 6) { 431 return $obj->get_ipv6_record($ipnum, MOBILEBRAND); 432 } else { 433 return INVALID_IP_ADDRESS; 434 } 435 } 436} 437 438sub get_elevation { 439 my $obj = shift(@_); 440 my $ipaddr = shift(@_); 441 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 442 if ($ipv == 4) { 443 return $obj->get_record($ipnum, ELEVATION); 444 } else { 445 if ($ipv == 6) { 446 return $obj->get_ipv6_record($ipnum, ELEVATION); 447 } else { 448 return INVALID_IP_ADDRESS; 449 } 450 } 451} 452 453sub get_usagetype { 454 my $obj = shift(@_); 455 my $ipaddr = shift(@_); 456 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 457 if ($ipv == 4) { 458 return $obj->get_record($ipnum, USAGETYPE); 459 } else { 460 if ($ipv == 6) { 461 return $obj->get_ipv6_record($ipnum, USAGETYPE); 462 } else { 463 return INVALID_IP_ADDRESS; 464 } 465 } 466} 467 468sub get_all { 469 my $obj = shift(@_); 470 my $ipaddr = shift(@_); 471 my ($ipv, $ipnum) = $obj->validate_ip($ipaddr); 472 if ($ipv == 4) { 473 return $obj->get_record($ipnum, ALL); 474 } else { 475 if ($ipv == 6) { 476 return $obj->get_ipv6_record($ipnum, ALL); 477 } else { 478 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); 479 } 480 } 481} 482 483sub get_ipv6_record { 484 my $obj = shift(@_); 485 my $ipnum = shift(@_); 486 my $mode = shift(@_); 487 my $dbtype = $obj->{"databasetype"}; 488 489 if ($ipnum eq "") { 490 if ($mode == ALL) { 491 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); 492 } else { 493 return NO_IP; 494 } 495 } 496 497 if (($mode == COUNTRYSHORT) && ($IPV6_COUNTRY_POSITION[$dbtype] == 0)) { 498 return NOT_SUPPORTED; 499 } 500 if (($mode == COUNTRYLONG) && ($IPV6_COUNTRY_POSITION[$dbtype] == 0)) { 501 return NOT_SUPPORTED; 502 } 503 if (($mode == REGION) && ($IPV6_REGION_POSITION[$dbtype] == 0)) { 504 return NOT_SUPPORTED; 505 } 506 if (($mode == CITY) && ($IPV6_CITY_POSITION[$dbtype] == 0)) { 507 return NOT_SUPPORTED; 508 } 509 if (($mode == ISP) && ($IPV6_ISP_POSITION[$dbtype] == 0)) { 510 return NOT_SUPPORTED; 511 } 512 if (($mode == LATITUDE) && ($IPV6_LATITUDE_POSITION[$dbtype] == 0)) { 513 return NOT_SUPPORTED; 514 } 515 if (($mode == LONGITUDE) && ($IPV6_LONGITUDE_POSITION[$dbtype] == 0)) { 516 return NOT_SUPPORTED; 517 } 518 if (($mode == DOMAIN) && ($IPV6_DOMAIN_POSITION[$dbtype] == 0)) { 519 return NOT_SUPPORTED; 520 } 521 if (($mode == ZIPCODE) && ($IPV6_ZIPCODE_POSITION[$dbtype] == 0)) { 522 return NOT_SUPPORTED; 523 } 524 if (($mode == TIMEZONE) && ($IPV6_TIMEZONE_POSITION[$dbtype] == 0)) { 525 return NOT_SUPPORTED; 526 } 527 if (($mode == NETSPEED) && ($IPV6_NETSPEED_POSITION[$dbtype] == 0)) { 528 return NOT_SUPPORTED; 529 } 530 if (($mode == IDDCODE) && ($IPV6_IDDCODE_POSITION[$dbtype] == 0)) { 531 return NOT_SUPPORTED; 532 } 533 if (($mode == AREACODE) && ($IPV6_AREACODE_POSITION[$dbtype] == 0)) { 534 return NOT_SUPPORTED; 535 } 536 if (($mode == WEATHERSTATIONCODE) && ($IPV6_WEATHERSTATIONCODE_POSITION[$dbtype] == 0)) { 537 return NOT_SUPPORTED; 538 } 539 if (($mode == WEATHERSTATIONNAME) && ($IPV6_WEATHERSTATIONNAME_POSITION[$dbtype] == 0)) { 540 return NOT_SUPPORTED; 541 } 542 if (($mode == MCC) && ($IPV6_MCC_POSITION[$dbtype] == 0)) { 543 return NOT_SUPPORTED; 544 } 545 if (($mode == MNC) && ($IPV6_MNC_POSITION[$dbtype] == 0)) { 546 return NOT_SUPPORTED; 547 } 548 if (($mode == MOBILEBRAND) && ($IPV6_MOBILEBRAND_POSITION[$dbtype] == 0)) { 549 return NOT_SUPPORTED; 550 } 551 if (($mode == ELEVATION) && ($IPV6_ELEVATION_POSITION[$dbtype] == 0)) { 552 return NOT_SUPPORTED; 553 } 554 if (($mode == USAGETYPE) && ($IPV6_USAGETYPE_POSITION[$dbtype] == 0)) { 555 return NOT_SUPPORTED; 556 } 557 558 my $realipno = $ipnum; 559 my $handle = $obj->{"filehandle"}; 560 my $baseaddr = $obj->{"ipv6databaseaddr"}; 561 my $dbcount = $obj->{"ipv6databasecount"}; 562 my $dbcolumn = $obj->{"databasecolumn"}; 563 my $indexbaseaddr = $obj->{"ipv6indexbaseaddr"}; 564 565 if ($dbcount == 0) { 566 if ($mode == ALL) { 567 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); 568 } else { 569 return IPV6_ADDRESS_IN_IPV4_BIN; 570 } 571 } 572 573 my $ipnum1_2 = new Math::BigInt($ipnum); 574 my $remainder = 0; 575 ($ipnum1_2, $remainder) = $ipnum1_2->bdiv(2**112); 576 my $indexaddr = $indexbaseaddr + ($ipnum1_2 << 3); 577 578 my $low = 0; 579 my $high = $dbcount; 580 if ($indexbaseaddr > 0) { 581 $low = $obj->read32($handle, $indexaddr); 582 $high = $obj->read32($handle, $indexaddr + 4); 583 } 584 585 my $mid = 0; 586 my $ipfrom = 0; 587 my $ipto = 0; 588 my $ipno = 0; 589 590 if ($realipno == MAX_IPV6_RANGE) { 591 $ipno = $realipno - 1; 592 } else { 593 $ipno = $realipno; 594 } 595 596 while ($low <= $high) { 597 $mid = int(($low + $high)/2); 598 $ipfrom = $obj->read128($handle, $baseaddr + $mid * (($dbcolumn * 4) + 12)); 599 $ipto = $obj->read128($handle, $baseaddr + ($mid + 1) * (($dbcolumn * 4) + 12)); 600 if (($ipno >= $ipfrom) && ($ipno < $ipto)) { 601 my $row_pointer = $baseaddr + $mid * (($dbcolumn * 4) + 12); 602 if ($mode == ALL) { 603 my $country_short = NOT_SUPPORTED; 604 my $country_long = NOT_SUPPORTED; 605 my $region = NOT_SUPPORTED; 606 my $city = NOT_SUPPORTED; 607 my $isp = NOT_SUPPORTED; 608 my $latitude = NOT_SUPPORTED; 609 my $longitude = NOT_SUPPORTED; 610 my $domain = NOT_SUPPORTED; 611 my $zipcode = NOT_SUPPORTED; 612 my $timezone = NOT_SUPPORTED; 613 my $netspeed = NOT_SUPPORTED; 614 my $iddcode = NOT_SUPPORTED; 615 my $areacode = NOT_SUPPORTED; 616 my $weatherstationcode = NOT_SUPPORTED; 617 my $weatherstationname = NOT_SUPPORTED; 618 my $mcc = NOT_SUPPORTED; 619 my $mnc = NOT_SUPPORTED; 620 my $mobilebrand = NOT_SUPPORTED; 621 my $elevation = NOT_SUPPORTED; 622 my $usagetype = NOT_SUPPORTED; 623 624 if ($IPV6_COUNTRY_POSITION[$dbtype] != 0) { 625 $country_short = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_COUNTRY_POSITION[$dbtype]))); 626 $country_long = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_COUNTRY_POSITION[$dbtype])) + 3); 627 } 628 if ($IPV6_REGION_POSITION[$dbtype] != 0) { 629 $region = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_REGION_POSITION[$dbtype]))); 630 } 631 if ($IPV6_CITY_POSITION[$dbtype] != 0) { 632 $city = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_CITY_POSITION[$dbtype]))); 633 } 634 if ($IPV6_ISP_POSITION[$dbtype] != 0) { 635 $isp = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_ISP_POSITION[$dbtype]))); 636 } 637 if ($IPV6_LATITUDE_POSITION[$dbtype] != 0) { 638 $latitude = $obj->readFloat($handle, $row_pointer + 8 + 4 * ($IPV6_LATITUDE_POSITION[$dbtype])); 639 $latitude = sprintf("%.6f", $latitude); 640 } 641 if ($IPV6_LONGITUDE_POSITION[$dbtype] != 0) { 642 $longitude = $obj->readFloat($handle, $row_pointer + 8 + 4 * ($IPV6_LONGITUDE_POSITION[$dbtype])); 643 $longitude = sprintf("%.6f", $longitude); 644 } 645 if ($IPV6_DOMAIN_POSITION[$dbtype] != 0) { 646 $domain = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_DOMAIN_POSITION[$dbtype]))); 647 } 648 if ($IPV6_ZIPCODE_POSITION[$dbtype] != 0) { 649 $zipcode = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_ZIPCODE_POSITION[$dbtype]))); 650 } 651 if ($IPV6_TIMEZONE_POSITION[$dbtype] != 0) { 652 $timezone = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_TIMEZONE_POSITION[$dbtype]))); 653 } 654 if ($IPV6_NETSPEED_POSITION[$dbtype] != 0) { 655 $netspeed = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_NETSPEED_POSITION[$dbtype]))); 656 } 657 if ($IPV6_IDDCODE_POSITION[$dbtype] != 0) { 658 $iddcode = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_IDDCODE_POSITION[$dbtype]))); 659 } 660 if ($IPV6_AREACODE_POSITION[$dbtype] != 0) { 661 $areacode = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_AREACODE_POSITION[$dbtype]))); 662 } 663 if ($IPV6_WEATHERSTATIONCODE_POSITION[$dbtype] != 0) { 664 $weatherstationcode = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_WEATHERSTATIONCODE_POSITION[$dbtype]))); 665 } 666 if ($IPV6_WEATHERSTATIONNAME_POSITION[$dbtype] != 0) { 667 $weatherstationname = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_WEATHERSTATIONNAME_POSITION[$dbtype]))); 668 } 669 if ($IPV6_MCC_POSITION[$dbtype] != 0) { 670 $mcc = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_MCC_POSITION[$dbtype]))); 671 } 672 if ($IPV6_MNC_POSITION[$dbtype] != 0) { 673 $mnc = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_MNC_POSITION[$dbtype]))); 674 } 675 if ($IPV6_MOBILEBRAND_POSITION[$dbtype] != 0) { 676 $mobilebrand = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_MOBILEBRAND_POSITION[$dbtype]))); 677 } 678 if ($IPV6_ELEVATION_POSITION[$dbtype] != 0) { 679 $elevation = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_ELEVATION_POSITION[$dbtype]))); 680 } 681 if ($IPV6_USAGETYPE_POSITION[$dbtype] != 0) { 682 $usagetype = $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_USAGETYPE_POSITION[$dbtype]))); 683 } 684 return ($country_short, $country_long, $region, $city, $latitude, $longitude, $zipcode, $timezone, $isp, $domain, $netspeed, $iddcode, $areacode, $weatherstationcode, $weatherstationname, $mcc, $mnc, $mobilebrand, $elevation, $usagetype); 685 } 686 if ($mode == COUNTRYSHORT) { 687 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_COUNTRY_POSITION[$dbtype]))); 688 } 689 if ($mode == COUNTRYLONG) { 690 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_COUNTRY_POSITION[$dbtype])) + 3); 691 } 692 if ($mode == REGION) { 693 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_REGION_POSITION[$dbtype]))); 694 } 695 if ($mode == CITY) { 696 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_CITY_POSITION[$dbtype]))); 697 } 698 if ($mode == ISP) { 699 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_ISP_POSITION[$dbtype]))); 700 } 701 if ($mode == LATITUDE) { 702 my $lat = $obj->readFloat($handle, $row_pointer + 8 + 4 * ($IPV6_LATITUDE_POSITION[$dbtype])); 703 $lat = sprintf("%.6f", $lat); 704 return $lat; 705 } 706 if ($mode == LONGITUDE) { 707 my $lon = $obj->readFloat($handle, $row_pointer + 8 + 4 * ($IPV6_LONGITUDE_POSITION[$dbtype])); 708 $lon = sprintf("%.6f", $lon); 709 return $lon; 710 } 711 if ($mode == DOMAIN) { 712 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_DOMAIN_POSITION[$dbtype]))); 713 } 714 if ($mode == ZIPCODE) { 715 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_ZIPCODE_POSITION[$dbtype]))); 716 } 717 if ($mode == TIMEZONE) { 718 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_TIMEZONE_POSITION[$dbtype]))); 719 } 720 if ($mode == NETSPEED) { 721 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_NETSPEED_POSITION[$dbtype]))); 722 } 723 if ($mode == IDDCODE) { 724 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_IDDCODE_POSITION[$dbtype]))); 725 } 726 if ($mode == AREACODE) { 727 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_AREACODE_POSITION[$dbtype]))); 728 } 729 if ($mode == WEATHERSTATIONCODE) { 730 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_WEATHERSTATIONCODE_POSITION[$dbtype]))); 731 } 732 if ($mode == WEATHERSTATIONNAME) { 733 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_WEATHERSTATIONNAME_POSITION[$dbtype]))); 734 } 735 if ($mode == MCC) { 736 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_MCC_POSITION[$dbtype]))); 737 } 738 if ($mode == MNC) { 739 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_MNC_POSITION[$dbtype]))); 740 } 741 if ($mode == MOBILEBRAND) { 742 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_MOBILEBRAND_POSITION[$dbtype]))); 743 } 744 if ($mode == ELEVATION) { 745 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_ELEVATION_POSITION[$dbtype]))); 746 } 747 if ($mode == USAGETYPE) { 748 return $obj->readStr($handle, $obj->read32($handle, $row_pointer + 8 + 4 * ($IPV6_USAGETYPE_POSITION[$dbtype]))); 749 } 750 } else { 751 if ($ipno < $ipfrom) { 752 $high = $mid - 1; 753 } else { 754 $low = $mid + 1; 755 } 756 } 757 } 758 if ($mode == ALL) { 759 return (UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN); 760 } else { 761 return UNKNOWN; 762 } 763} 764 765sub get_record { 766 my $obj = shift(@_); 767 my $ipnum = shift(@_); 768 my $mode = shift(@_); 769 my $dbtype= $obj->{"databasetype"}; 770 771 if ($ipnum eq "") { 772 if ($mode == ALL) { 773 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); 774 } else { 775 return NO_IP; 776 } 777 } 778 779 if (($mode == COUNTRYSHORT) && ($COUNTRY_POSITION[$dbtype] == 0)) { 780 return NOT_SUPPORTED; 781 } 782 if (($mode == COUNTRYLONG) && ($COUNTRY_POSITION[$dbtype] == 0)) { 783 return NOT_SUPPORTED; 784 } 785 if (($mode == REGION) && ($REGION_POSITION[$dbtype] == 0)) { 786 return NOT_SUPPORTED; 787 } 788 if (($mode == CITY) && ($CITY_POSITION[$dbtype] == 0)) { 789 return NOT_SUPPORTED; 790 } 791 if (($mode == ISP) && ($ISP_POSITION[$dbtype] == 0)) { 792 return NOT_SUPPORTED; 793 } 794 if (($mode == LATITUDE) && ($LATITUDE_POSITION[$dbtype] == 0)) { 795 return NOT_SUPPORTED; 796 } 797 if (($mode == LONGITUDE) && ($LONGITUDE_POSITION[$dbtype] == 0)) { 798 return NOT_SUPPORTED; 799 } 800 if (($mode == DOMAIN) && ($DOMAIN_POSITION[$dbtype] == 0)) { 801 return NOT_SUPPORTED; 802 } 803 if (($mode == ZIPCODE) && ($ZIPCODE_POSITION[$dbtype] == 0)) { 804 return NOT_SUPPORTED; 805 } 806 if (($mode == TIMEZONE) && ($TIMEZONE_POSITION[$dbtype] == 0)) { 807 return NOT_SUPPORTED; 808 } 809 if (($mode == NETSPEED) && ($NETSPEED_POSITION[$dbtype] == 0)) { 810 return NOT_SUPPORTED; 811 } 812 if (($mode == IDDCODE) && ($IDDCODE_POSITION[$dbtype] == 0)) { 813 return NOT_SUPPORTED; 814 } 815 if (($mode == AREACODE) && ($AREACODE_POSITION[$dbtype] == 0)) { 816 return NOT_SUPPORTED; 817 } 818 if (($mode == WEATHERSTATIONCODE) && ($WEATHERSTATIONCODE_POSITION[$dbtype] == 0)) { 819 return NOT_SUPPORTED; 820 } 821 if (($mode == WEATHERSTATIONNAME) && ($WEATHERSTATIONNAME_POSITION[$dbtype] == 0)) { 822 return NOT_SUPPORTED; 823 } 824 if (($mode == MCC) && ($MCC_POSITION[$dbtype] == 0)) { 825 return NOT_SUPPORTED; 826 } 827 if (($mode == MNC) && ($MNC_POSITION[$dbtype] == 0)) { 828 return NOT_SUPPORTED; 829 } 830 if (($mode == MOBILEBRAND) && ($MOBILEBRAND_POSITION[$dbtype] == 0)) { 831 return NOT_SUPPORTED; 832 } 833 if (($mode == ELEVATION) && ($ELEVATION_POSITION[$dbtype] == 0)) { 834 return NOT_SUPPORTED; 835 } 836 if (($mode == USAGETYPE) && ($USAGETYPE_POSITION[$dbtype] == 0)) { 837 return NOT_SUPPORTED; 838 } 839 840 my $realipno = $ipnum; 841 my $handle = $obj->{"filehandle"}; 842 my $baseaddr = $obj->{"ipv4databaseaddr"}; 843 my $dbcount = $obj->{"ipv4databasecount"}; 844 my $dbcolumn = $obj->{"databasecolumn"}; 845 my $indexbaseaddr = $obj->{"ipv4indexbaseaddr"}; 846 847 my $ipnum1_2 = int($ipnum >> 16); 848 my $indexaddr = $indexbaseaddr + ($ipnum1_2 << 3); 849 850 my $low = 0; 851 my $high = $dbcount; 852 if ($indexbaseaddr > 0) { 853 $low = $obj->read32($handle, $indexaddr); 854 $high = $obj->read32($handle, $indexaddr + 4); 855 } 856 my $mid = 0; 857 my $ipfrom = 0; 858 my $ipto = 0; 859 my $ipno = 0; 860 861 if ($realipno == MAX_IPV4_RANGE) { 862 $ipno = $realipno - 1; 863 } else { 864 $ipno = $realipno; 865 } 866 867 while ($low <= $high) { 868 $mid = int(($low + $high) >> 1); 869 $ipfrom = $obj->read32($handle, $baseaddr + $mid * $dbcolumn * 4); 870 $ipto = $obj->read32($handle, $baseaddr + ($mid + 1) * $dbcolumn * 4); 871 if (($ipno >= $ipfrom) && ($ipno < $ipto)) { 872 if ($mode == ALL) { 873 my $country_short = NOT_SUPPORTED; 874 my $country_long = NOT_SUPPORTED; 875 my $region = NOT_SUPPORTED; 876 my $city = NOT_SUPPORTED; 877 my $isp = NOT_SUPPORTED; 878 my $latitude = NOT_SUPPORTED; 879 my $longitude = NOT_SUPPORTED; 880 my $domain = NOT_SUPPORTED; 881 my $zipcode = NOT_SUPPORTED; 882 my $timezone = NOT_SUPPORTED; 883 my $netspeed = NOT_SUPPORTED; 884 my $iddcode = NOT_SUPPORTED; 885 my $areacode = NOT_SUPPORTED; 886 my $weatherstationcode = NOT_SUPPORTED; 887 my $weatherstationname = NOT_SUPPORTED; 888 my $mcc = NOT_SUPPORTED; 889 my $mnc = NOT_SUPPORTED; 890 my $mobilebrand = NOT_SUPPORTED; 891 my $elevation = NOT_SUPPORTED; 892 my $usagetype = NOT_SUPPORTED; 893 894 if ($COUNTRY_POSITION[$dbtype] != 0) { 895 $country_short = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($COUNTRY_POSITION[$dbtype]-1))); 896 $country_long = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($COUNTRY_POSITION[$dbtype]-1))+3); 897 } 898 899 if ($REGION_POSITION[$dbtype] != 0) { 900 $region = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($REGION_POSITION[$dbtype]-1))); 901 } 902 if ($CITY_POSITION[$dbtype] != 0) { 903 $city = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($CITY_POSITION[$dbtype]-1))); 904 } 905 if ($ISP_POSITION[$dbtype] != 0) { 906 $isp = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($ISP_POSITION[$dbtype]-1))); 907 } 908 if ($LATITUDE_POSITION[$dbtype] != 0) { 909 $latitude = $obj->readFloat($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($LATITUDE_POSITION[$dbtype]-1)); 910 $latitude = sprintf("%.6f", $latitude); 911 } 912 if ($LONGITUDE_POSITION[$dbtype] != 0) { 913 $longitude = $obj->readFloat($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($LONGITUDE_POSITION[$dbtype]-1)); 914 $longitude = sprintf("%.6f", $longitude); 915 } 916 if ($DOMAIN_POSITION[$dbtype] != 0) { 917 $domain = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($DOMAIN_POSITION[$dbtype]-1))); 918 } 919 if ($ZIPCODE_POSITION[$dbtype] != 0) { 920 $zipcode = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($ZIPCODE_POSITION[$dbtype]-1))); 921 } 922 if ($TIMEZONE_POSITION[$dbtype] != 0) { 923 $timezone = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($TIMEZONE_POSITION[$dbtype]-1))); 924 } 925 if ($NETSPEED_POSITION[$dbtype] != 0) { 926 $netspeed = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($NETSPEED_POSITION[$dbtype]-1))); 927 } 928 if ($IDDCODE_POSITION[$dbtype] != 0) { 929 $iddcode = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($IDDCODE_POSITION[$dbtype]-1))); 930 } 931 if ($AREACODE_POSITION[$dbtype] != 0) { 932 $areacode = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($AREACODE_POSITION[$dbtype]-1))); 933 } 934 if ($WEATHERSTATIONCODE_POSITION[$dbtype] != 0) { 935 $weatherstationcode = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($WEATHERSTATIONCODE_POSITION[$dbtype]-1))); 936 } 937 if ($WEATHERSTATIONNAME_POSITION[$dbtype] != 0) { 938 $weatherstationname = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($WEATHERSTATIONNAME_POSITION[$dbtype]-1))); 939 } 940 if ($MCC_POSITION[$dbtype] != 0) { 941 $mcc = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($MCC_POSITION[$dbtype]-1))); 942 } 943 if ($MNC_POSITION[$dbtype] != 0) { 944 $mnc = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($MNC_POSITION[$dbtype]-1))); 945 } 946 if ($MOBILEBRAND_POSITION[$dbtype] != 0) { 947 $mobilebrand = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($MOBILEBRAND_POSITION[$dbtype]-1))); 948 } 949 if ($ELEVATION_POSITION[$dbtype] != 0) { 950 $elevation = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($ELEVATION_POSITION[$dbtype]-1))); 951 } 952 if ($USAGETYPE_POSITION[$dbtype] != 0) { 953 $usagetype = $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($USAGETYPE_POSITION[$dbtype]-1))); 954 } 955 return ($country_short, $country_long, $region, $city, $latitude, $longitude, $zipcode, $timezone, $isp, $domain, $netspeed, $iddcode, $areacode, $weatherstationcode, $weatherstationname, $mcc, $mnc, $mobilebrand, $elevation, $usagetype); 956 } 957 if ($mode == COUNTRYSHORT) { 958 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($COUNTRY_POSITION[$dbtype]-1))); 959 } 960 if ($mode == COUNTRYLONG) { 961 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($COUNTRY_POSITION[$dbtype]-1))+3); 962 } 963 if ($mode == REGION) { 964 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($REGION_POSITION[$dbtype]-1))); 965 } 966 if ($mode == CITY) { 967 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($CITY_POSITION[$dbtype]-1))); 968 } 969 if ($mode == ISP) { 970 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($ISP_POSITION[$dbtype]-1))); 971 } 972 if ($mode == LATITUDE) { 973 my $lat = $obj->readFloat($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($LATITUDE_POSITION[$dbtype]-1)); 974 $lat = sprintf("%.6f", $lat); 975 return $lat; 976 } 977 if ($mode == LONGITUDE) { 978 my $lon = $obj->readFloat($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($LONGITUDE_POSITION[$dbtype]-1)); 979 $lon = sprintf("%.6f", $lon); 980 return $lon; 981 } 982 if ($mode == DOMAIN) { 983 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($DOMAIN_POSITION[$dbtype]-1))); 984 } 985 if ($mode == ZIPCODE) { 986 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($ZIPCODE_POSITION[$dbtype]-1))); 987 } 988 if ($mode == TIMEZONE) { 989 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($TIMEZONE_POSITION[$dbtype]-1))); 990 } 991 if ($mode == NETSPEED) { 992 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($NETSPEED_POSITION[$dbtype]-1))); 993 } 994 if ($mode == IDDCODE) { 995 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($IDDCODE_POSITION[$dbtype]-1))); 996 } 997 if ($mode == AREACODE) { 998 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($AREACODE_POSITION[$dbtype]-1))); 999 } 1000 if ($mode == WEATHERSTATIONCODE) { 1001 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($WEATHERSTATIONCODE_POSITION[$dbtype]-1))); 1002 } 1003 if ($mode == WEATHERSTATIONNAME) { 1004 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($WEATHERSTATIONNAME_POSITION[$dbtype]-1))); 1005 } 1006 if ($mode == MCC) { 1007 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($MCC_POSITION[$dbtype]-1))); 1008 } 1009 if ($mode == MNC) { 1010 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($MNC_POSITION[$dbtype]-1))); 1011 } 1012 if ($mode == MOBILEBRAND) { 1013 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($MOBILEBRAND_POSITION[$dbtype]-1))); 1014 } 1015 if ($mode == ELEVATION) { 1016 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($ELEVATION_POSITION[$dbtype]-1))); 1017 } 1018 if ($mode == USAGETYPE) { 1019 return $obj->readStr($handle, $obj->read32($handle, $baseaddr + ($mid * $dbcolumn * 4) + 4 * ($USAGETYPE_POSITION[$dbtype]-1))); 1020 } 1021 } else { 1022 if ($ipno < $ipfrom) { 1023 $high = $mid - 1; 1024 } else { 1025 $low = $mid + 1; 1026 } 1027 } 1028 } 1029 if ($mode == ALL) { 1030 return (UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN); 1031 } else { 1032 return UNKNOWN; 1033 } 1034} 1035 1036sub read128 { 1037 my ($obj, $handle, $position) = @_; 1038 my $data = ""; 1039 seek($handle, $position-1, 0); 1040 read($handle, $data, 16); 1041 return &bytes2int($data); 1042} 1043 1044sub read32 { 1045 my ($obj, $handle, $position) = @_; 1046 my $data = ""; 1047 seek($handle, $position-1, 0); 1048 read($handle, $data, 4); 1049 return unpack("V", $data); 1050} 1051 1052sub read8 { 1053 my ($obj, $handle, $position) = @_; 1054 my $data = ""; 1055 seek($handle, $position-1, 0); 1056 read($handle, $data, 1); 1057 return unpack("C", $data); 1058} 1059 1060sub readStr { 1061 my ($obj, $handle, $position) = @_; 1062 my $data = ""; 1063 my $string = ""; 1064 seek($handle, $position, 0); 1065 read($handle, $data, 1); 1066 read($handle, $string, unpack("C", $data)); 1067 return $string; 1068} 1069 1070sub readFloat { 1071 my ($obj, $handle, $position) = @_; 1072 my $data = ""; 1073 seek($handle, $position-1, 0); 1074 read($handle, $data, 4); 1075 1076 my $is_little_endian = unpack("h*", pack("s", 1)); 1077 if ($is_little_endian =~ m/^1/) { 1078 # "LITTLE ENDIAN - x86\n"; 1079 return unpack("f", $data); 1080 } else { 1081 # "BIG ENDIAN - MAC\n"; 1082 return unpack("f", reverse($data)); 1083 } 1084} 1085 1086sub bytes2int { 1087 my $binip = shift(@_); 1088 my @array = split(//, $binip); 1089 return 0 if ($#array != 15); 1090 my $ip96_127 = unpack("V", $array[0] . $array[1] . $array[2] . $array[3]); 1091 my $ip64_95 = unpack("V", $array[4] . $array[5] . $array[6] . $array[7]); 1092 my $ip32_63 = unpack("V", $array[8] . $array[9] . $array[10] . $array[11]); 1093 my $ip1_31 = unpack("V", $array[12] . $array[13] . $array[14] . $array[15]); 1094 1095 my $big1 = Math::BigInt->new("$ip96_127"); 1096 my $big2 = Math::BigInt->new("$ip64_95")->blsft(32); 1097 my $big3 = Math::BigInt->new("$ip32_63")->blsft(64); 1098 my $big4 = Math::BigInt->new("$ip1_31")->blsft(96); 1099 $big1 = $big1->badd($big2)->badd($big3)->badd($big4); 1100 1101 return $big1->bstr(); 1102} 1103 1104sub validate_ip { 1105 my $obj = shift(@_); 1106 my $ip = shift(@_); 1107 my $ipv = -1; 1108 my $ipnum = -1; 1109 #name server lookup if domain name 1110 $ip = $obj->name2ip($ip); 1111 1112 if ($obj->ip_is_ipv4($ip)) { 1113 #ipv4 address 1114 $ipv = 4; 1115 $ipnum = $obj->ip2no($ip); 1116 } else { 1117 #expand ipv6 address 1118 $ip = $obj->expand_ipv6_address($ip); 1119 if ($obj->ip_is_ipv6($ip)) { 1120 #ipv6 address 1121 $ipv = 6; 1122 $ipnum = $obj->hex2int($ip); 1123 1124 #reformat ipv4 address in ipv6 1125 if (($ipnum >= 281470681743360) && ($ipnum <= 281474976710655)) { 1126 $ipv = 4; 1127 $ipnum = $ipnum - 281470681743360; 1128 } 1129 } else { 1130 #not IPv4 and IPv6 1131 } 1132 } 1133 return ($ipv, $ipnum); 1134} 1135 1136sub expand_ipv6_address { 1137 my $obj = shift(@_); 1138 my $ip = shift(@_); 1139 $ip =~ s/\:\:/\:Z\:/; 1140 my @ip = split(/\:/, $ip); 1141 my $num = scalar(@ip); 1142 1143 my $l = 8; 1144 if ($ip[$#ip] =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) { 1145 my $a = sprintf("%x", ($1*256 + $2)); 1146 my $b = sprintf("%x", ($3*256 + $4)); 1147 $ip[$#ip] = $a; 1148 $ip[$#ip+1] = $b; 1149 $l--; 1150 } 1151 1152 if ($#ip == 8) { 1153 shift(@ip); 1154 $l++; 1155 } 1156 1157 foreach (0..(scalar(@ip)-1)) { 1158 $ip[$_] = ('0'x(4-length ($ip[$_]))).$ip[$_]; 1159 } 1160 1161 foreach (0..(scalar(@ip)-1)) { 1162 next unless ($ip[$_] eq '000Z'); 1163 my @empty = map { $_ = '0'x4 } (0..7); 1164 $ip[$_] = join(':', @empty[0..$l-$num]); 1165 last; 1166 } 1167 1168 return (uc(join ':', @ip)); 1169} 1170 1171sub hex2int { 1172 my $obj = shift(@_); 1173 my $hexip = shift(@_); 1174 1175 $hexip =~ s/\://g; 1176 1177 unless (length($hexip) == 32) { 1178 return 0; 1179 }; 1180 1181 my $binip = unpack('B128', pack('H32', $hexip)); 1182 my ($n, $dec) = (Math::BigInt->new(1), Math::BigInt->new(0)); 1183 1184 foreach (reverse (split('', $binip))) { 1185 $_ && ($dec += $n); 1186 $n *= 2; 1187 } 1188 1189 $dec =~ s/^\+//; 1190 return $dec; 1191} 1192 1193sub ip2no { 1194 my $obj = shift(@_); 1195 my $ip = shift(@_); 1196 my @block = split(/\./, $ip); 1197 my $no = 0; 1198 $no = $block[3]; 1199 $no = $no + $block[2] * 256; 1200 $no = $no + $block[1] * 256 * 256; 1201 $no = $no + $block[0] * 256 * 256 * 256; 1202 return $no; 1203} 1204 1205sub name2ip { 1206 my $obj = shift(@_); 1207 my $host = shift(@_); 1208 my $ip_address = ""; 1209 if (($host =~ m/^$IPv4_re$/) || ($host =~ m/^$IPv6_re$/) || ($host =~ m/^\:\:$/)) { 1210 $ip_address = $host; 1211 } else { 1212 # TO_DO: Can we return IPv6 address too? 1213 $ip_address = join('.', unpack('C4',(gethostbyname($host))[4])); 1214 } 1215 return $ip_address; 1216} 1217 1218sub ip_is_ipv4 { 1219 my $obj = shift(@_); 1220 my $ip = shift(@_); 1221 if ($ip =~ m/^$IPv4_re$/) { 1222 return 1; 1223 } else { 1224 return 0; 1225 } 1226} 1227 1228sub ip_is_ipv6 { 1229 my $obj = shift(@_); 1230 my $ip = shift(@_); 1231 if (($ip =~ m/^$IPv6_re$/) || ($ip =~ m/^$IPv4_re$/)) { 1232 return 1; 1233 } else { 1234 return 0; 1235 } 1236} 1237 12381; 1239__END__ 1240 1241=head1 NAME 1242 1243Geo::IP2Location - Fast lookup of country, region, city, latitude, longitude, ZIP code, time zone, ISP, domain name, connection type, IDD code, area code, weather station code and station, MCC, MNC, mobile carrier brand name, elevation and usage type from IP address by using IP2Location database. It supports both IPv4 and IPv6 addressing. Please visit http://www.ip2location.com for more information. 1244 1245=head1 SYNOPSIS 1246 1247 use Geo::IP2Location; 1248 my $obj = Geo::IP2Location->open("IP-COUNTRY-REGION-CITY-LATITUDE-LONGITUDE-ZIPCODE-TIMEZONE-ISP-DOMAIN-NETSPEED-AREACODE-WEATHER-MOBILE-ELEVATION-USAGETYPE.BIN"); 1249 1250 my $dbversion = $obj->get_database_version(); 1251 my $moduleversion = $obj->get_module_version(); 1252 my $countryshort = $obj->get_country_short("20.11.187.239"); 1253 my $countrylong = $obj->get_country_long("20.11.187.239"); 1254 my $region = $obj->get_region("20.11.187.239"); 1255 my $city = $obj->get_city("20.11.187.239"); 1256 my $latitude = $obj->get_latitude("20.11.187.239"); 1257 my $longitude = $obj->get_longitude("20.11.187.239"); 1258 my $isp = $obj->get_isp("20.11.187.239"); 1259 my $domain = $obj->get_domain("20.11.187.239"); 1260 my $zipcode = $obj->get_zipcode("20.11.187.239"); 1261 my $timezone = $obj->get_timezone("20.11.187.239"); 1262 my $netspeed = $obj->get_netspeed("20.11.187.239"); 1263 my $iddcode = $obj->get_iddcode("20.11.187.239"); 1264 my $areacode = $obj->get_areacode("20.11.187.239"); 1265 my $weatherstationcode = $obj->get_weatherstationcode("20.11.187.239"); 1266 my $weatherstationname = $obj->get_weatherstationname("20.11.187.239"); 1267 my $mcc = $obj->get_mcc("20.11.187.239"); 1268 my $mnc = $obj->get_mnc("20.11.187.239"); 1269 my $brand = $obj->get_mobilebrand("20.11.187.239"); 1270 my $elevation = $obj->get_elevation("20.11.187.239"); 1271 my $usagetype = $obj->get_usagetype("20.11.187.239"); 1272 1273 ($cos, $col, $reg, $cit, $lat, $lon, $zip, $tmz, $isp, $dom, $ns, $idd, $area, $wcode, $wname, $mcc, $mnc, $brand, $elevation, $usagetype) = $obj->get_all("20.11.187.239"); 1274 ($cos, $col, $reg, $cit, $lat, $lon, $zip, $tmz, $isp, $dom, $ns, $idd, $area, $wcode, $wname, $mcc, $mnc, $brand, $elevation, $usagetype) = $obj->get_all("2001:1000:0000:0000:0000:0000:0000:0000"); 1275 1276 1277=head1 DESCRIPTION 1278 1279This Perl module provides fast lookup of country, region, city, latitude, longitude, ZIP code, time zone, ISP, domain name, connection type, IDD code, area code, weather station code and station, MCC, MNC, mobile carrier brand, elevation and usage type from IP address using IP2Location database. This module uses a file based .BIN database available at http://www.ip2location.com upon subscription. This database contains IP blocks as keys and other information as values. It supports IP address in IPv4 or IPv6. 1280 1281This module can be used in many types of project such as: 1282 1283 1) select the geographically closest mirror 1284 2) analyze web server logs to determine the countries of visitors 1285 3) credit card fraud detection 1286 4) software export controls 1287 5) display native language and currency 1288 6) prevent password sharing and abuse of service 1289 7) geotargeting in advertisement 1290 1291=head1 IP2LOCATION DATABASES 1292 1293The complete IPv4 and IPv6 database are available at: 1294 1295http://www.ip2location.com 1296 1297The database will be updated in monthly basis for greater accuracy. Free sample database is available at: 1298 1299http://www.ip2location.com/developers 1300 1301=head1 CLASS METHODS 1302 1303=over 4 1304 1305=item $obj = Geo::IP2Location->open($database_file); 1306 1307Constructs a new Geo::IP2Location object with the database located at $database_file. 1308 1309=back 1310 1311=head1 OBJECT METHODS 1312 1313=over 4 1314 1315=item $countryshort = $obj->get_country_short( $ip ); 1316 1317Returns the ISO 3166 country code of IP address or domain name. Returns "-" for unassigned or private IP address. 1318 1319=item $countrylong = $obj->get_country_long( $ip ); 1320 1321Returns the full country name of IP address or domain name. Returns "-" for unassigned or private IP address. 1322 1323=item $region = $obj->get_region( $ip ); 1324 1325Returns the region of IP address or domain name. 1326 1327=item $city = $obj->get_city( $ip ); 1328 1329Returns the city of IP address or domain name. 1330 1331=item $latitude = $obj->get_latitude( $ip ); 1332 1333Returns the latitude of IP address or domain name. 1334 1335=item $longitude = $obj->get_longitude( $ip ); 1336 1337Returns the longitude of IP address or domain name. 1338 1339=item $isp = $obj->get_isp( $ip ); 1340 1341Returns the ISP name of IP address or domain name. 1342 1343=item $domain = $obj->get_domain( $ip ); 1344 1345Returns the domain name of IP address or domain name. 1346 1347=item $zip = $obj->get_zipcode( $ip ); 1348 1349Returns the ZIP code of IP address or domain name. 1350 1351=item $tz = $obj->get_timezone( $ip ); 1352 1353Returns the time zone of IP address or domain name. 1354 1355=item $ns = $obj->get_netspeed( $ip ); 1356 1357Returns the connection type (DIAL, DSL or COMP) of IP address or domain name. 1358 1359=item $idd = $obj->get_iddcode( $ip ); 1360 1361Returns the country IDD calling code of IP address or domain name. 1362 1363=item $area = $obj->get_areacode( $ip ); 1364 1365Returns the phone area code code of IP address or domain name. 1366 1367=item $wcode = $obj->get_weatherstationcode( $ip ); 1368 1369Returns the nearest weather station code of IP address or domain name. 1370 1371=item $wname = $obj->get_weatherstationname( $ip ); 1372 1373Returns the nearest weather station name of IP address or domain name. 1374 1375=item $mcc = $obj->get_mcc( $ip ); 1376 1377Returns the mobile carrier code (MCC) of IP address or domain name. 1378 1379=item $mnc = $obj->get_mnc( $ip ); 1380 1381Returns the mobile network code (MNC) of IP address or domain name. 1382 1383=item $brand = $obj->get_mobilebrand( $ip ); 1384 1385Returns the mobile carrier brand of IP address or domain name. 1386 1387=item $elevation = $obj->get_elevation( $ip ); 1388 1389Returns the elevation of IP address or domain name. 1390 1391=item $usagetype = $obj->get_usagetype( $ip ); 1392 1393Returns the usage type of IP address or domain name. 1394 1395=item ($cos, $col, $reg, $cit, $lat, $lon, $zip, $tmz, $isp, $dom, $ns, $idd, $area, $wcode, $wname, $mcc, $mnc, $brand, $elevation, $usagetype) = $obj->get_all( $ip ); 1396 1397Returns an array of country, region, city, latitude, longitude, ZIP code, time zone, ISP, domain name, connection type, IDD code, area code, weather station code and station, MCC, MNC, mobile carrier brand, elevation and usage type of IP address. 1398 1399=item $dbversion = $obj->get_database_version(); 1400 1401Returns the version number of database. 1402 1403=item $moduleversion = $obj->get_module_version(); 1404 1405Returns the version number of Perl module. 1406 1407=head1 SEE ALSO 1408 1409http://www.ip2location.com 1410 1411=head1 VERSION 1412 14138.01 1414 1415=head1 AUTHOR 1416 1417Copyright (c) 2016 IP2Location.com 1418 1419All rights reserved. This package is free software; It is licensed under the GPL. 1420 1421=cut 1422