|
<?php |
|
/** |
|
* +----------------------------------------------------------------------+ |
|
* | PHP version 5 | |
|
* +----------------------------------------------------------------------+ |
|
* | Copyright (C) 2004 MaxMind LLC | |
|
* +----------------------------------------------------------------------+ |
|
* | This library is free software; you can redistribute it and/or | |
|
* | modify it under the terms of the GNU Lesser General Public | |
|
* | License as published by the Free Software Foundation; either | |
|
* | version 2.1 of the License, or (at your option) any later version. | |
|
* | | |
|
* | This library is distributed in the hope that it will be useful, | |
|
* | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
* | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
|
* | Lesser General Public License for more details. | |
|
* | | |
|
* | You should have received a copy of the GNU Lesser General Public | |
|
* | License along with this library; if not, write to the Free Software | |
|
* | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | |
|
* | USA, or view it online at http://www.gnu.org/licenses/lgpl.txt. | |
|
* +----------------------------------------------------------------------+ |
|
* | Authors: Jim Winstead <jimw@apache.org> (original Maxmind version) | |
|
* | Hans Lellelid <hans@xmpl.org> | |
|
* +----------------------------------------------------------------------+ |
|
* |
|
* @category Net |
|
* @package Net_GeoIP |
|
* @author Jim Winstead <jimw@apache.org> (original Maxmind PHP API) |
|
* @author Hans Lellelid <hans@xmpl.org> |
|
* @license LGPL http://www.gnu.org/licenses/lgpl.txt |
|
* @link http://pear.php.net/package/Net_GeoIp |
|
* $Id: GeoIP.php 296763 2010-03-25 00:53:44Z clockwerx $ |
|
*/ |
|
|
|
require_once 'PEAR/Exception.php'; |
|
|
|
/** |
|
* GeoIP class provides an API for performing geo-location lookups based on IP |
|
* address. |
|
* |
|
* To use this class you must have a [binary version] GeoIP database. There is |
|
* a free GeoIP country database which can be obtained from Maxmind: |
|
* {@link http://www.maxmind.com/app/geoip_country} |
|
* |
|
* |
|
* <b>SIMPLE USE</b> |
|
* |
|
* |
|
* Create an instance: |
|
* |
|
* <code> |
|
* $geoip = Net_GeoIP::getInstance('/path/to/geoipdb.dat', Net_GeoIP::SHARED_MEMORY); |
|
* </code> |
|
* |
|
* Depending on which database you are using (free, or one of paid versions) |
|
* you must use appropriate lookup method: |
|
* |
|
* <code> |
|
* // for free country db: |
|
* $country_name = $geoip->lookupCountryName($_SERVER['REMOTE_ADDR']); |
|
* $country_code = $geoip->lookupCountryCode($_SERVER['REMOTE_ADDR']); |
|
* |
|
* // for [non-free] region db: |
|
* list($ctry_code, $region) = $geoip->lookupRegion($_SERVER['REMOTE_ADDR']); |
|
* |
|
* // for [non-free] city db: |
|
* $location = $geoip->lookupLocation($_SERVER['REMOTE_ADDR']); |
|
* print "city: " . $location->city . ", " . $location->region; |
|
* print "lat: " . $location->latitude . ", long: " . $location->longitude; |
|
* |
|
* // for organization or ISP db: |
|
* $org_or_isp_name = $geoip->lookupOrg($_SERVER['REMOTE_ADDR']); |
|
* </code> |
|
* |
|
* |
|
* <b>MULTIPLE INSTANCES</b> |
|
* |
|
* |
|
* You can have several instances of this class, one for each database file |
|
* you are using. You should use the static getInstance() singleton method |
|
* to save on overhead of setting up database segments. Note that only one |
|
* instance is stored per filename, and any flags will be ignored if an |
|
* instance already exists for the specifiedfilename. |
|
* |
|
* <b>Special note on using SHARED_MEMORY flag</b> |
|
* |
|
* If you are using SHARED_MEMORY (shmop) you can only use SHARED_MEMORY for |
|
* one (1) instance (i.e. for one database). Any subsequent attempts to |
|
* instantiate using SHARED_MEMORY will read the same shared memory block |
|
* already initialized, and therefore will cause problems since the expected |
|
* database format won't match the database in the shared memory block. |
|
* |
|
* Note that there is no easy way to flag "nice errors" to prevent attempts |
|
* to create new instances using SHARED_MEMORY flag and it is also not posible |
|
* (in a safe way) to allow new instances to overwrite the shared memory block. |
|
* |
|
* In short, is you are using multiple databses, use the SHARED_MEMORY flag |
|
* with care. |
|
* |
|
* |
|
* <b>LOOKUPS ON HOSTNAMES</b> |
|
* |
|
* |
|
* Note that this PHP API does NOT support lookups on hostnames. This is so |
|
* that the public API can be kept simple and so that the lookup functions |
|
* don't need to try name lookups if IP lookup fails (which would be the only |
|
* way to keep the API simple and support name-based lookups). |
|
* |
|
* If you do not know the IP address, you can convert an name to IP very |
|
* simply using PHP native functions or other libraries: |
|
* |
|
* <code> |
|
* $geoip->lookupCountryName(gethostbyname('www.sunset.se')); |
|
* </code> |
|
* |
|
* Or, if you don't know whether an address is a name or ip address, use |
|
* application-level logic: |
|
* |
|
* <code> |
|
* if (ip2long($ip_or_name) === false) { |
|
* $ip = gethostbyname($ip_or_name); |
|
* } else { |
|
* $ip = $ip_or_name; |
|
* } |
|
* $ctry = $geoip->lookupCountryName($ip); |
|
* </code> |
|
* |
|
* @category Net |
|
* @package Net_GeoIP |
|
* @author Jim Winstead <jimw@apache.org> (original Maxmind PHP API) |
|
* @author Hans Lellelid <hans@xmpl.org> |
|
* @license LGPL http://www.gnu.org/licenses/lgpl.txt |
|
* @link http://pear.php.net/package/Net_GeoIp |
|
*/ |
|
class Net_GeoIP |
|
{ |
|
/** |
|
* Exception error code used for invalid IP address. |
|
*/ |
|
const ERR_INVALID_IP = 218624992; // crc32('Net_GeoIP::ERR_INVALID_IP') |
|
|
|
/** |
|
* Exception error code when there is a DB-format-related error. |
|
*/ |
|
const ERR_DB_FORMAT = 866184008; // crc32('Net_GeoIP::ERR_DB_FORMAT') |
|
|
|
public static $COUNTRY_CODES = array( |
|
"", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", |
|
"AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", |
|
"BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", |
|
"CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", |
|
"CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", |
|
"EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "FX", "GA", "GB", |
|
"GD", "GE", "GF", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", |
|
"GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN", |
|
"IO", "IQ", "IR", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", |
|
"KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", |
|
"LT", "LU", "LV", "LY", "MA", "MC", "MD", "MG", "MH", "MK", "ML", "MM", "MN", |
|
"MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", |
|
"NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", |
|
"PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", |
|
"QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", |
|
"SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TC", "TD", |
|
"TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TL", "TR", "TT", "TV", "TW", |
|
"TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", |
|
"VU", "WF", "WS", "YE", "YT", "RS", "ZA", "ZM", "ME", "ZW", "A1", "A2", "O1", |
|
"AX", "GG", "IM", "JE", "BL", "MF" |
|
); |
|
|
|
public static $COUNTRY_CODES3 = array( |
|
"","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","ANT","AGO","AQ","ARG", |
|
"ASM","AUT","AUS","ABW","AZE","BIH","BRB","BGD","BEL","BFA","BGR","BHR","BDI", |
|
"BEN","BMU","BRN","BOL","BRA","BHS","BTN","BV","BWA","BLR","BLZ","CAN","CC", |
|
"COD","CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI","CUB","CPV", |
|
"CX","CYP","CZE","DEU","DJI","DNK","DMA","DOM","DZA","ECU","EST","EGY","ESH", |
|
"ERI","ESP","ETH","FIN","FJI","FLK","FSM","FRO","FRA","FX","GAB","GBR","GRD", |
|
"GEO","GUF","GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","GS","GTM","GUM", |
|
"GNB","GUY","HKG","HM","HND","HRV","HTI","HUN","IDN","IRL","ISR","IND","IO", |
|
"IRQ","IRN","ISL","ITA","JAM","JOR","JPN","KEN","KGZ","KHM","KIR","COM","KNA", |
|
"PRK","KOR","KWT","CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU", |
|
"LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI","MMR","MNG","MAC", |
|
"MNP","MTQ","MRT","MSR","MLT","MUS","MDV","MWI","MEX","MYS","MOZ","NAM","NCL", |
|
"NER","NFK","NGA","NIC","NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER", |
|
"PYF","PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW","PRY","QAT", |
|
"REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN","SWE","SGP","SHN","SVN","SJM", |
|
"SVK","SLE","SMR","SEN","SOM","SUR","STP","SLV","SYR","SWZ","TCA","TCD","TF", |
|
"TGO","THA","TJK","TKL","TLS","TKM","TUN","TON","TUR","TTO","TUV","TWN","TZA", |
|
"UKR","UGA","UM","USA","URY","UZB","VAT","VCT","VEN","VGB","VIR","VNM","VUT", |
|
"WLF","WSM","YEM","YT","SRB","ZAF","ZMB","MNE","ZWE","A1","A2","O1", |
|
"ALA","GGY","IMN","JEY","BLM","MAF" |
|
); |
|
|
|
public static $COUNTRY_NAMES = array( |
|
"", "Asia/Pacific Region", "Europe", "Andorra", "United Arab Emirates", |
|
"Afghanistan", "Antigua and Barbuda", "Anguilla", "Albania", "Armenia", |
|
"Netherlands Antilles", "Angola", "Antarctica", "Argentina", "American Samoa", |
|
"Austria", "Australia", "Aruba", "Azerbaijan", "Bosnia and Herzegovina", |
|
"Barbados", "Bangladesh", "Belgium", "Burkina Faso", "Bulgaria", "Bahrain", |
|
"Burundi", "Benin", "Bermuda", "Brunei Darussalam", "Bolivia", "Brazil", |
|
"Bahamas", "Bhutan", "Bouvet Island", "Botswana", "Belarus", "Belize", |
|
"Canada", "Cocos (Keeling) Islands", "Congo, The Democratic Republic of the", |
|
"Central African Republic", "Congo", "Switzerland", "Cote D'Ivoire", "Cook Islands", |
|
"Chile", "Cameroon", "China", "Colombia", "Costa Rica", "Cuba", "Cape Verde", |
|
"Christmas Island", "Cyprus", "Czech Republic", "Germany", "Djibouti", |
|
"Denmark", "Dominica", "Dominican Republic", "Algeria", "Ecuador", "Estonia", |
|
"Egypt", "Western Sahara", "Eritrea", "Spain", "Ethiopia", "Finland", "Fiji", |
|
"Falkland Islands (Malvinas)", "Micronesia, Federated States of", "Faroe Islands", |
|
"France", "France, Metropolitan", "Gabon", "United Kingdom", |
|
"Grenada", "Georgia", "French Guiana", "Ghana", "Gibraltar", "Greenland", |
|
"Gambia", "Guinea", "Guadeloupe", "Equatorial Guinea", "Greece", "South Georgia and the South Sandwich Islands", |
|
"Guatemala", "Guam", "Guinea-Bissau", |
|
"Guyana", "Hong Kong", "Heard Island and McDonald Islands", "Honduras", |
|
"Croatia", "Haiti", "Hungary", "Indonesia", "Ireland", "Israel", "India", |
|
"British Indian Ocean Territory", "Iraq", "Iran, Islamic Republic of", |
|
"Iceland", "Italy", "Jamaica", "Jordan", "Japan", "Kenya", "Kyrgyzstan", |
|
"Cambodia", "Kiribati", "Comoros", "Saint Kitts and Nevis", "Korea, Democratic People's Republic of", |
|
"Korea, Republic of", "Kuwait", "Cayman Islands", |
|
"Kazakstan", "Lao People's Democratic Republic", "Lebanon", "Saint Lucia", |
|
"Liechtenstein", "Sri Lanka", "Liberia", "Lesotho", "Lithuania", "Luxembourg", |
|
"Latvia", "Libyan Arab Jamahiriya", "Morocco", "Monaco", "Moldova, Republic of", |
|
"Madagascar", "Marshall Islands", "Macedonia", |
|
"Mali", "Myanmar", "Mongolia", "Macau", "Northern Mariana Islands", |
|
"Martinique", "Mauritania", "Montserrat", "Malta", "Mauritius", "Maldives", |
|
"Malawi", "Mexico", "Malaysia", "Mozambique", "Namibia", "New Caledonia", |
|
"Niger", "Norfolk Island", "Nigeria", "Nicaragua", "Netherlands", "Norway", |
|
"Nepal", "Nauru", "Niue", "New Zealand", "Oman", "Panama", "Peru", "French Polynesia", |
|
"Papua New Guinea", "Philippines", "Pakistan", "Poland", "Saint Pierre and Miquelon", |
|
"Pitcairn Islands", "Puerto Rico", "Palestinian Territory", |
|
"Portugal", "Palau", "Paraguay", "Qatar", "Reunion", "Romania", |
|
"Russian Federation", "Rwanda", "Saudi Arabia", "Solomon Islands", |
|
"Seychelles", "Sudan", "Sweden", "Singapore", "Saint Helena", "Slovenia", |
|
"Svalbard and Jan Mayen", "Slovakia", "Sierra Leone", "San Marino", "Senegal", |
|
"Somalia", "Suriname", "Sao Tome and Principe", "El Salvador", "Syrian Arab Republic", |
|
"Swaziland", "Turks and Caicos Islands", "Chad", "French Southern Territories", |
|
"Togo", "Thailand", "Tajikistan", "Tokelau", "Turkmenistan", |
|
"Tunisia", "Tonga", "Timor-Leste", "Turkey", "Trinidad and Tobago", "Tuvalu", |
|
"Taiwan", "Tanzania, United Republic of", "Ukraine", |
|
"Uganda", "United States Minor Outlying Islands", "United States", "Uruguay", |
|
"Uzbekistan", "Holy See (Vatican City State)", "Saint Vincent and the Grenadines", |
|
"Venezuela", "Virgin Islands, British", "Virgin Islands, U.S.", |
|
"Vietnam", "Vanuatu", "Wallis and Futuna", "Samoa", "Yemen", "Mayotte", |
|
"Serbia", "South Africa", "Zambia", "Montenegro", "Zimbabwe", |
|
"Anonymous Proxy","Satellite Provider","Other", |
|
"Aland Islands","Guernsey","Isle of Man","Jersey","Saint Barthelemy","Saint Martin" |
|
); |
|
|
|
// storage / caching flags |
|
const STANDARD = 0; |
|
const MEMORY_CACHE = 1; |
|
const SHARED_MEMORY = 2; |
|
|
|
// Database structure constants |
|
const COUNTRY_BEGIN = 16776960; |
|
const STATE_BEGIN_REV0 = 16700000; |
|
const STATE_BEGIN_REV1 = 16000000; |
|
|
|
const STRUCTURE_INFO_MAX_SIZE = 20; |
|
const DATABASE_INFO_MAX_SIZE = 100; |
|
const COUNTRY_EDITION = 106; |
|
const REGION_EDITION_REV0 = 112; |
|
const REGION_EDITION_REV1 = 3; |
|
const CITY_EDITION_REV0 = 111; |
|
const CITY_EDITION_REV1 = 2; |
|
const ORG_EDITION = 110; |
|
const SEGMENT_RECORD_LENGTH = 3; |
|
const STANDARD_RECORD_LENGTH = 3; |
|
const ORG_RECORD_LENGTH = 4; |
|
const MAX_RECORD_LENGTH = 4; |
|
const MAX_ORG_RECORD_LENGTH = 300; |
|
const FULL_RECORD_LENGTH = 50; |
|
|
|
const US_OFFSET = 1; |
|
const CANADA_OFFSET = 677; |
|
const WORLD_OFFSET = 1353; |
|
const FIPS_RANGE = 360; |
|
|
|
// SHMOP memory address |
|
const SHM_KEY = 0x4f415401; |
|
|
|
/** |
|
* @var int |
|
*/ |
|
private $flags = 0; |
|
|
|
/** |
|
* @var resource |
|
*/ |
|
private $filehandle; |
|
|
|
/** |
|
* @var string |
|
*/ |
|
private $memoryBuffer; |
|
|
|