<?php
define(
'GEOIP_COUNTRY_BEGIN'
, 16776960);
define(
'GEOIP_STATE_BEGIN_REV0'
, 16700000);
define(
'GEOIP_STATE_BEGIN_REV1'
, 16000000);
define(
'GEOIP_STANDARD'
, 0);
define(
'GEOIP_MEMORY_CACHE'
, 1);
define(
'GEOIP_SHARED_MEMORY'
, 2);
define(
'STRUCTURE_INFO_MAX_SIZE'
, 20);
define(
'DATABASE_INFO_MAX_SIZE'
, 100);
define(
'GEOIP_COUNTRY_EDITION'
, 106);
define(
'GEOIP_PROXY_EDITION'
, 8);
define(
'GEOIP_ASNUM_EDITION'
, 9);
define(
'GEOIP_NETSPEED_EDITION'
, 10);
define(
'GEOIP_REGION_EDITION_REV0'
, 112);
define(
'GEOIP_REGION_EDITION_REV1'
, 3);
define(
'GEOIP_CITY_EDITION_REV0'
, 111);
define(
'GEOIP_CITY_EDITION_REV1'
, 2);
define(
'GEOIP_ORG_EDITION'
, 110);
define(
'GEOIP_ISP_EDITION'
, 4);
define(
'SEGMENT_RECORD_LENGTH'
, 3);
define(
'STANDARD_RECORD_LENGTH'
, 3);
define(
'ORG_RECORD_LENGTH'
, 4);
define(
'MAX_RECORD_LENGTH'
, 4);
define(
'MAX_ORG_RECORD_LENGTH'
, 300);
define(
'GEOIP_SHM_KEY'
, 0x4f415401);
define(
'US_OFFSET'
, 1);
define(
'CANADA_OFFSET'
, 677);
define(
'WORLD_OFFSET'
, 1353);
define(
'FIPS_RANGE'
, 360);
define(
'GEOIP_UNKNOWN_SPEED'
, 0);
define(
'GEOIP_DIALUP_SPEED'
, 1);
define(
'GEOIP_CABLEDSL_SPEED'
, 2);
define(
'GEOIP_CORPORATE_SPEED'
, 3);
class
GeoIP {
var
$flags
;
var
$filehandle
;
var
$memory_buffer
;
var
$databaseType
;
var
$databaseSegments
;
var
$record_length
;
var
$shmid
;
var
$GEOIP_COUNTRY_CODE_TO_NUMBER
=
array
(
''
=> 0,
'AP'
=> 1,
'EU'
=> 2,
'AD'
=> 3,
'AE'
=> 4,
'AF'
=> 5,
'AG'
=> 6,
'AI'
=> 7,
'AL'
=> 8,
'AM'
=> 9,
'AN'
=> 10,
'AO'
=> 11,
'AQ'
=> 12,
'AR'
=> 13,
'AS'
=> 14,
'AT'
=> 15,
'AU'
=> 16,
'AW'
=> 17,
'AZ'
=> 18,
'BA'
=> 19,
'BB'
=> 20,
'BD'
=> 21,
'BE'
=> 22,
'BF'
=> 23,
'BG'
=> 24,
'BH'
=> 25,
'BI'
=> 26,
'BJ'
=> 27,
'BM'
=> 28,
'BN'
=> 29,
'BO'
=> 30,
'BR'
=> 31,
'BS'
=> 32,
'BT'
=> 33,
'BV'
=> 34,
'BW'
=> 35,
'BY'
=> 36,
'BZ'
=> 37,
'CA'
=> 38,
'CC'
=> 39,
'CD'
=> 40,
'CF'
=> 41,
'CG'
=> 42,
'CH'
=> 43,
'CI'
=> 44,
'CK'
=> 45,
'CL'
=> 46,
'CM'
=> 47,
'CN'
=> 48,
'CO'
=> 49,
'CR'
=> 50,
'CU'
=> 51,
'CV'
=> 52,
'CX'
=> 53,
'CY'
=> 54,
'CZ'
=> 55,
'DE'
=> 56,
'DJ'
=> 57,
'DK'
=> 58,
'DM'
=> 59,
'DO'
=> 60,
'DZ'
=> 61,
'EC'
=> 62,
'EE'
=> 63,
'EG'
=> 64,
'EH'
=> 65,
'ER'
=> 66,
'ES'
=> 67,
'ET'
=> 68,
'FI'
=> 69,
'FJ'
=> 70,
'FK'
=> 71,
'FM'
=> 72,
'FO'
=> 73,
'FR'
=> 74,
'FX'
=> 75,
'GA'
=> 76,
'GB'
=> 77,
'GD'
=> 78,
'GE'
=> 79,
'GF'
=> 80,
'GH'
=> 81,
'GI'
=> 82,
'GL'
=> 83,
'GM'
=> 84,
'GN'
=> 85,
'GP'
=> 86,
'GQ'
=> 87,
'GR'
=> 88,
'GS'
=> 89,
'GT'
=> 90,
'GU'
=> 91,
'GW'
=> 92,
'GY'
=> 93,
'HK'
=> 94,
'HM'
=> 95,
'HN'
=> 96,
'HR'
=> 97,
'HT'
=> 98,
'HU'
=> 99,
'ID'
=> 100,
'IE'
=> 101,
'IL'
=> 102,
'IN'
=> 103,
'IO'
=> 104,
'IQ'
=> 105,
'IR'
=> 106,
'IS'
=> 107,
'IT'
=> 108,
'JM'
=> 109,
'JO'
=> 110,
'JP'
=> 111,
'KE'
=> 112,
'KG'
=> 113,
'KH'
=> 114,
'KI'
=> 115,
'KM'
=> 116,
'KN'
=> 117,
'KP'
=> 118,
'KR'
=> 119,
'KW'
=> 120,
'KY'
=> 121,
'KZ'
=> 122,
'LA'
=> 123,
'LB'
=> 124,
'LC'
=> 125,
'LI'
=> 126,
'LK'
=> 127,
'LR'
=> 128,
'LS'
=> 129,
'LT'
=> 130,
'LU'
=> 131,
'LV'
=> 132,
'LY'
=> 133,
'MA'
=> 134,
'MC'
=> 135,
'MD'
=> 136,
'MG'
=> 137,
'MH'
=> 138,
'MK'
=> 139,
'ML'
=> 140,
'MM'
=> 141,
'MN'
=> 142,
'MO'
=> 143,
'MP'
=> 144,
'MQ'
=> 145,
'MR'
=> 146,
'MS'
=> 147,
'MT'
=> 148,
'MU'
=> 149,
'MV'
=> 150,
'MW'
=> 151,
'MX'
=> 152,
'MY'
=> 153,
'MZ'
=> 154,
'NA'
=> 155,
'NC'
=> 156,
'NE'
=> 157,
'NF'
=> 158,
'NG'
=> 159,
'NI'
=> 160,
'NL'
=> 161,
'NO'
=> 162,
'NP'
=> 163,
'NR'
=> 164,
'NU'
=> 165,
'NZ'
=> 166,
'OM'
=> 167,
'PA'
=> 168,
'PE'
=> 169,
'PF'
=> 170,
'PG'
=> 171,
'PH'
=> 172,
'PK'
=> 173,
'PL'
=> 174,
'PM'
=> 175,
'PN'
=> 176,
'PR'
=> 177,
'PS'
=> 178,
'PT'
=> 179,
'PW'
=> 180,
'PY'
=> 181,
'QA'
=> 182,
'RE'
=> 183,
'RO'
=> 184,
'RU'
=> 185,
'RW'
=> 186,
'SA'
=> 187,
'SB'
=> 188,
'SC'
=> 189,
'SD'
=> 190,
'SE'
=> 191,
'SG'
=> 192,
'SH'
=> 193,
'SI'
=> 194,
'SJ'
=> 195,
'SK'
=> 196,
'SL'
=> 197,
'SM'
=> 198,
'SN'
=> 199,
'SO'
=> 200,
'SR'
=> 201,
'ST'
=> 202,
'SV'
=> 203,
'SY'
=> 204,
'SZ'
=> 205,
'TC'
=> 206,
'TD'
=> 207,
'TF'
=> 208,
'TG'
=> 209,
'TH'
=> 210,
'TJ'
=> 211,
'TK'
=> 212,
'TM'
=> 213,
'TN'
=> 214,
'TO'
=> 215,
'TL'
=> 216,
'TR'
=> 217,
'TT'
=> 218,
'TV'
=> 219,
'TW'
=> 220,
'TZ'
=> 221,
'UA'
=> 222,
'UG'
=> 223,
'UM'
=> 224,
'US'
=> 225,
'UY'
=> 226,
'UZ'
=> 227,
'VA'
=> 228,
'VC'
=> 229,
'VE'
=> 230,
'VG'
=> 231,
'VI'
=> 232,
'VN'
=> 233,
'VU'
=> 234,
'WF'
=> 235,
'WS'
=> 236,
'YE'
=> 237,
'YT'
=> 238,
'RS'
=> 239,
'ZA'
=> 240,
'ZM'
=> 241,
'ME'
=> 242,
'ZW'
=> 243,
'A1'
=> 244,
'A2'
=> 245,
'O1'
=> 246,
'AX'
=> 247,
'GG'
=> 248,
'IM'
=> 249,
'JE'
=> 250);
var
$GEOIP_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'
);
var
$GEOIP_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'
);
var
$GEOIP_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'
);
}
function
GeoIP_load_shared_mem (
$file
) {
$fp
=
fopen
(
$file
,
'rb'
);
if
(!
$fp
) {
print
"error opening $file: $php_errormsg\n"
;
exit
;
}
$s_array
=
fstat
(
$fp
);
$size
=
$s_array
[
'size'
];
if
(
$shmid
= @shmop_open (GEOIP_SHM_KEY,
"w"
, 0, 0)) {
shmop_delete (
$shmid
);
shmop_close (
$shmid
);
}
$shmid
= shmop_open (GEOIP_SHM_KEY,
"c"
, 0644,
$size
);
shmop_write (
$shmid
,
fread
(
$fp
,
$size
), 0);
shmop_close (
$shmid
);
}
function
_setup_segments(
$gi
){
$gi
->databaseType = GEOIP_COUNTRY_EDITION;
$gi
->record_length = STANDARD_RECORD_LENGTH;
if
(
$gi
->flags & GEOIP_SHARED_MEMORY) {
$offset
= @shmop_size (
$gi
->shmid) - 3;
for
(
$i
= 0;
$i
< STRUCTURE_INFO_MAX_SIZE;
$i
++) {
$delim
= @shmop_read (
$gi
->shmid,
$offset
, 3);
$offset
+= 3;
if
(
$delim
== (
chr
(255).
chr
(255).
chr
(255))) {
$gi
->databaseType = ord(@shmop_read (
$gi
->shmid,
$offset
, 1));
$offset
++;
if
(
$gi
->databaseType == GEOIP_REGION_EDITION_REV0){
$gi
->databaseSegments = GEOIP_STATE_BEGIN_REV0;
}
else
if
(
$gi
->databaseType == GEOIP_REGION_EDITION_REV1){
$gi
->databaseSegments = GEOIP_STATE_BEGIN_REV1;
}
else
if
((
$gi
->databaseType == GEOIP_CITY_EDITION_REV0)||
(
$gi
->databaseType == GEOIP_CITY_EDITION_REV1)
|| (
$gi
->databaseType == GEOIP_ORG_EDITION)
|| (
$gi
->databaseType == GEOIP_ISP_EDITION)
|| (
$gi
->databaseType == GEOIP_ASNUM_EDITION)){
$gi
->databaseSegments = 0;
$buf
= @shmop_read (
$gi
->shmid,
$offset
, SEGMENT_RECORD_LENGTH);
for
(
$j
= 0;
$j
< SEGMENT_RECORD_LENGTH;
$j
++){
$gi
->databaseSegments += (ord(
$buf
[
$j
]) << (
$j
* 8));
}
if
((
$gi
->databaseType == GEOIP_ORG_EDITION)||
(
$gi
->databaseType == GEOIP_ISP_EDITION)) {
$gi
->record_length = ORG_RECORD_LENGTH;
}
}
break
;
}
else
{
$offset
-= 4;
}
}
if
((
$gi
->databaseType == GEOIP_COUNTRY_EDITION)||
(
$gi
->databaseType == GEOIP_PROXY_EDITION)||
(
$gi
->databaseType == GEOIP_NETSPEED_EDITION)){
$gi
->databaseSegments = GEOIP_COUNTRY_BEGIN;
}
}
else
{
$filepos
=
ftell
(
$gi
->filehandle);
fseek
(
$gi
->filehandle, -3, SEEK_END);
for
(
$i
= 0;
$i
< STRUCTURE_INFO_MAX_SIZE;
$i
++) {
$delim
=
fread
(
$gi
->filehandle,3);
if
(
$delim
== (
chr
(255).
chr
(255).
chr
(255))){
$gi
->databaseType = ord(
fread
(
$gi
->filehandle,1));
if
(
$gi
->databaseType == GEOIP_REGION_EDITION_REV0){
$gi
->databaseSegments = GEOIP_STATE_BEGIN_REV0;
}
else
if
(
$gi
->databaseType == GEOIP_REGION_EDITION_REV1){
$gi
->databaseSegments = GEOIP_STATE_BEGIN_REV1;
}
else
if
((
$gi
->databaseType == GEOIP_CITY_EDITION_REV0) ||
(
$gi
->databaseType == GEOIP_CITY_EDITION_REV1) ||
(
$gi
->databaseType == GEOIP_ORG_EDITION) ||
(
$gi
->databaseType == GEOIP_ISP_EDITION) ||
(
$gi
->databaseType == GEOIP_ASNUM_EDITION)){
$gi
->databaseSegments = 0;
$buf
=
fread
(
$gi
->filehandle,SEGMENT_RECORD_LENGTH);
for
(
$j
= 0;
$j
< SEGMENT_RECORD_LENGTH;
$j
++){
$gi
->databaseSegments += (ord(
$buf
[
$j
]) << (
$j
* 8));
}
if
(
$gi
->databaseType == GEOIP_ORG_EDITION ||
$gi
->databaseType == GEOIP_ISP_EDITION) {
$gi
->record_length = ORG_RECORD_LENGTH;
}
}
break
;
}
else
{
fseek
(
$gi
->filehandle, -4, SEEK_CUR);
}
}
if
((
$gi
->databaseType == GEOIP_COUNTRY_EDITION)||
(
$gi
->databaseType == GEOIP_PROXY_EDITION)||
(
$gi
->databaseType == GEOIP_NETSPEED_EDITION)){
$gi
->databaseSegments = GEOIP_COUNTRY_BEGIN;
}
fseek
(
$gi
->filehandle,
$filepos
,SEEK_SET);
}
return
$gi
;
}
function
GeoIP_open(
$filename
,
$flags
) {
$gi
=
new
GeoIP;
$gi
->flags =
$flags
;
if
(
$gi
->flags & GEOIP_SHARED_MEMORY) {
$gi
->shmid = @shmop_open (GEOIP_SHM_KEY,
"a"
, 0, 0);
}
else
{
$gi
->filehandle =
fopen
(
$filename
,
"rb"
);
if
(
$gi
->flags & GEOIP_MEMORY_CACHE) {
$s_array
=
fstat
(
$gi
->filehandle);
$gi
->memory_buffer =
fread
(
$gi
->filehandle,
$s_array
[
'size'
]);
}
}
$gi
= _setup_segments(
$gi
);
return
$gi
;
}
function
GeoIP_close(
$gi
) {
if
(
$gi
->flags & GEOIP_SHARED_MEMORY) {
return
true;
}
return
fclose(
$gi
->filehandle);
}
function
GeoIP_country_id_by_name(
$gi
,
$name
) {
$addr
=
gethostbyname
(
$name
);
if
(!
$addr
||
$addr
==
$name
) {
return
false;
}
return
GeoIP_country_id_by_addr(
$gi
,
$addr
);
}
function
GeoIP_country_code_by_name(
$gi
,
$name
) {
$country_id
= GeoIP_country_id_by_name(
$gi
,
$name
);
if
(
$country_id
!== false) {
return
$gi
->GEOIP_COUNTRY_CODES[
$country_id
];
}
return
false;
}
function
GeoIP_country_name_by_name(
$gi
,
$name
) {
$country_id
= GeoIP_country_id_by_name(
$gi
,
$name
);
if
(
$country_id
!== false) {
return
$gi
->GEOIP_COUNTRY_NAMES[
$country_id
];
}
return
false;
}
function
GeoIP_country_id_by_addr(
$gi
,
$addr
) {
$ipnum
=
ip2long
(
$addr
);
return
_GeoIP_seek_country(
$gi
,
$ipnum
) - GEOIP_COUNTRY_BEGIN;
}
function
GeoIP_country_code_by_addr(
$gi
,
$addr
) {
if
(
$gi
->databaseType == GEOIP_CITY_EDITION_REV1) {
$record
= GeoIP_record_by_addr(
$gi
,
$addr
);
return
$record
->country_code;
}
else
{
$country_id
= GeoIP_country_id_by_addr(
$gi
,
$addr
);
if
(
$country_id
!== false) {
return
$gi
->GEOIP_COUNTRY_CODES[
$country_id
];
}
}
return
false;
}
function
GeoIP_country_name_by_addr(
$gi
,
$addr
) {
if
(
$gi
->databaseType == GEOIP_CITY_EDITION_REV1) {
$record
= GeoIP_record_by_addr(
$gi
,
$addr
);
return
$record
->country_name;
}
else
{
$country_id
= GeoIP_country_id_by_addr(
$gi
,
$addr
);
if
(
$country_id
!== false) {
return
$gi
->GEOIP_COUNTRY_NAMES[
$country_id
];
}
}
return
false;
}
function
_GeoIP_seek_country(
$gi
,
$ipnum
) {
$offset
= 0;
for
(
$depth
= 31;
$depth
>= 0; --
$depth
) {
if
(
$gi
->flags & GEOIP_MEMORY_CACHE) {
$buf
=
substr
(
$gi
->memory_buffer,
2 *
$gi
->record_length *
$offset
,
2 *
$gi
->record_length);
}
elseif
(
$gi
->flags & GEOIP_SHARED_MEMORY) {
$buf
= @shmop_read (
$gi
->shmid,
2 *
$gi
->record_length *
$offset
,
2 *
$gi
->record_length );
}
else
{
fseek
(
$gi
->filehandle, 2 *
$gi
->record_length *
$offset
, SEEK_SET) == 0
or
die
(
"fseek failed"
);
$buf
=
fread
(
$gi
->filehandle, 2 *
$gi
->record_length);
}
$x
=
array
(0,0);
for
(
$i
= 0;
$i
< 2; ++
$i
) {
for
(
$j
= 0;
$j
<
$gi
->record_length; ++
$j
) {
$x
[
$i
] += ord(
$buf
[
$gi
->record_length *
$i
+
$j
]) << (
$j
* 8);
}
}
if
(
$ipnum
& (1 <<
$depth
)) {
if
(
$x
[1] >=
$gi
->databaseSegments) {
return
$x
[1];
}
$offset
=
$x
[1];
}
else
{
if
(
$x
[0] >=
$gi
->databaseSegments) {
return
$x
[0];
}
$offset
=
$x
[0];
}
}
trigger_error(
"error traversing database - perhaps it is corrupt?"
, E_USER_ERROR);
return
false;
}
function
_get_org(
$gi
,
$ipnum
){
$seek_org
= _GeoIP_seek_country(
$gi
,
$ipnum
);
if
(
$seek_org
==
$gi
->databaseSegments) {
return
NULL;
}
$record_pointer
=
$seek_org
+ (2 *
$gi
->record_length - 1) *
$gi
->databaseSegments;
if
(
$gi
->flags & GEOIP_SHARED_MEMORY) {
$org_buf
= @shmop_read (
$gi
->shmid,
$record_pointer
, MAX_ORG_RECORD_LENGTH);
}
else
{
fseek
(
$gi
->filehandle,
$record_pointer
, SEEK_SET);
$org_buf
=
fread
(
$gi
->filehandle,MAX_ORG_RECORD_LENGTH);
}
$org_buf
=
substr
(
$org_buf
, 0,
strpos
(
$org_buf
, 0));
return
$org_buf
;
}
function
GeoIP_org_by_addr (
$gi
,
$addr
) {
if
(
$addr
== NULL) {
return
0;
}
$ipnum
=
ip2long
(
$addr
);
return
_get_org(
$gi
,
$ipnum
);
}
function
_get_region(
$gi
,
$ipnum
){
if
(
$gi
->databaseType == GEOIP_REGION_EDITION_REV0){
$seek_region
= _GeoIP_seek_country(
$gi
,
$ipnum
) - GEOIP_STATE_BEGIN_REV0;
if
(
$seek_region
>= 1000){
$country_code
=
"US"
;
$region
=
chr
((
$seek_region
- 1000)/26 + 65) .
chr
((
$seek_region
- 1000)%26 + 65);
}
else
{
$country_code
=
$gi
->GEOIP_COUNTRY_CODES[
$seek_region
];
$region
=
""
;
}
return
array
(
$country_code
,
$region
);
}
else
if
(
$gi
->databaseType == GEOIP_REGION_EDITION_REV1) {
$seek_region
= _GeoIP_seek_country(
$gi
,
$ipnum
) - GEOIP_STATE_BEGIN_REV1;
if
(
$seek_region
< US_OFFSET){
$country_code
=
""
;
$region
=
""
;
}
else
if
(
$seek_region
< CANADA_OFFSET) {
$country_code
=
"US"
;
$region
=
chr
((
$seek_region
- US_OFFSET)/26 + 65) .
chr
((
$seek_region
- US_OFFSET)%26 + 65);
}
else
if
(
$seek_region
< WORLD_OFFSET) {
$country_code
=
"CA"
;
$region
=
chr
((
$seek_region
- CANADA_OFFSET)/26 + 65) .
chr
((
$seek_region
- CANADA_OFFSET)%26 + 65);
}
else
{
$country_code
=
$gi
->GEOIP_COUNTRY_CODES[(
$seek_region
- WORLD_OFFSET) / FIPS_RANGE];
$region
=
""
;
}
return
array
(
$country_code
,
$region
);
}
}
function
GeoIP_region_by_addr (
$gi
,
$addr
) {
if
(
$addr
== NULL) {
return
0;
}
$ipnum
=
ip2long
(
$addr
);
return
_get_region(
$gi
,
$ipnum
);
}
function
GeoIP_getdnsattributes (
$l
,
$ip
){
$r
=
new
Net_DNS_Resolver();
$r
->nameservers =
array
(
"ws1.maxmind.com"
);
$p
=
$r
->search(
$l
.
"."
.
$ip
.
".s.maxmind.com"
,
"TXT"
,
"IN"
);
$str
=
is_object
(
$p
->answer[0])?
$p
->answer[0]->string():
''
;
ereg
(
"\"(.*)\""
,
$str
,
$regs
);
$str
=
$regs
[1];
return
$str
;
}
function
GeoIP_countryOfRequest(
$request
,
$geoipdb
)
{
$gi
= GeoIP_open(
$geoipdb
, GEOIP_STANDARD);
$code
= GeoIP_country_code_by_addr(
$gi
,
$request
->remote_addr);
GeoIP_close(
$gi
);
return
(
$code
!= false) ?
$code
:
'ZZ'
;
}