3 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
6 * Copyright (C) 2007 MaxMind LLC
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 define("GEOIP_COUNTRY_BEGIN", 16776960);
24 define("GEOIP_STATE_BEGIN_REV0", 16700000);
25 define("GEOIP_STATE_BEGIN_REV1", 16000000);
26 define("GEOIP_STANDARD", 0);
27 define("GEOIP_MEMORY_CACHE", 1);
28 define("GEOIP_SHARED_MEMORY", 2);
29 define("STRUCTURE_INFO_MAX_SIZE", 20);
30 define("DATABASE_INFO_MAX_SIZE", 100);
31 define("GEOIP_COUNTRY_EDITION", 106);
32 define("GEOIP_PROXY_EDITION", 8);
33 define("GEOIP_ASNUM_EDITION", 9);
34 define("GEOIP_NETSPEED_EDITION", 10);
35 define("GEOIP_REGION_EDITION_REV0", 112);
36 define("GEOIP_REGION_EDITION_REV1", 3);
37 define("GEOIP_CITY_EDITION_REV0", 111);
38 define("GEOIP_CITY_EDITION_REV1", 2);
39 define("GEOIP_ORG_EDITION", 110);
40 define("GEOIP_ISP_EDITION", 4);
41 define("SEGMENT_RECORD_LENGTH", 3);
42 define("STANDARD_RECORD_LENGTH", 3);
43 define("ORG_RECORD_LENGTH", 4);
44 define("MAX_RECORD_LENGTH", 4);
45 define("MAX_ORG_RECORD_LENGTH", 300);
46 define("GEOIP_SHM_KEY", 0x4f415401);
47 define("US_OFFSET", 1);
48 define("CANADA_OFFSET", 677);
49 define("WORLD_OFFSET", 1353);
50 define("FIPS_RANGE", 360);
51 define("GEOIP_UNKNOWN_SPEED", 0);
52 define("GEOIP_DIALUP_SPEED", 1);
53 define("GEOIP_CABLEDSL_SPEED", 2);
54 define("GEOIP_CORPORATE_SPEED", 3);
56 if( !class_exists('GeoIP', false) ) {
62 var $databaseSegments;
65 var $GEOIP_COUNTRY_CODE_TO_NUMBER = array(
66 "" => 0, "AP" => 1, "EU" => 2, "AD" => 3, "AE" => 4, "AF" => 5,
67 "AG" => 6, "AI" => 7, "AL" => 8, "AM" => 9, "AN" => 10, "AO" => 11,
68 "AQ" => 12, "AR" => 13, "AS" => 14, "AT" => 15, "AU" => 16, "AW" => 17,
69 "AZ" => 18, "BA" => 19, "BB" => 20, "BD" => 21, "BE" => 22, "BF" => 23,
70 "BG" => 24, "BH" => 25, "BI" => 26, "BJ" => 27, "BM" => 28, "BN" => 29,
71 "BO" => 30, "BR" => 31, "BS" => 32, "BT" => 33, "BV" => 34, "BW" => 35,
72 "BY" => 36, "BZ" => 37, "CA" => 38, "CC" => 39, "CD" => 40, "CF" => 41,
73 "CG" => 42, "CH" => 43, "CI" => 44, "CK" => 45, "CL" => 46, "CM" => 47,
74 "CN" => 48, "CO" => 49, "CR" => 50, "CU" => 51, "CV" => 52, "CX" => 53,
75 "CY" => 54, "CZ" => 55, "DE" => 56, "DJ" => 57, "DK" => 58, "DM" => 59,
76 "DO" => 60, "DZ" => 61, "EC" => 62, "EE" => 63, "EG" => 64, "EH" => 65,
77 "ER" => 66, "ES" => 67, "ET" => 68, "FI" => 69, "FJ" => 70, "FK" => 71,
78 "FM" => 72, "FO" => 73, "FR" => 74, "FX" => 75, "GA" => 76, "GB" => 77,
79 "GD" => 78, "GE" => 79, "GF" => 80, "GH" => 81, "GI" => 82, "GL" => 83,
80 "GM" => 84, "GN" => 85, "GP" => 86, "GQ" => 87, "GR" => 88, "GS" => 89,
81 "GT" => 90, "GU" => 91, "GW" => 92, "GY" => 93, "HK" => 94, "HM" => 95,
82 "HN" => 96, "HR" => 97, "HT" => 98, "HU" => 99, "ID" => 100, "IE" => 101,
83 "IL" => 102, "IN" => 103, "IO" => 104, "IQ" => 105, "IR" => 106, "IS" => 107,
84 "IT" => 108, "JM" => 109, "JO" => 110, "JP" => 111, "KE" => 112, "KG" => 113,
85 "KH" => 114, "KI" => 115, "KM" => 116, "KN" => 117, "KP" => 118, "KR" => 119,
86 "KW" => 120, "KY" => 121, "KZ" => 122, "LA" => 123, "LB" => 124, "LC" => 125,
87 "LI" => 126, "LK" => 127, "LR" => 128, "LS" => 129, "LT" => 130, "LU" => 131,
88 "LV" => 132, "LY" => 133, "MA" => 134, "MC" => 135, "MD" => 136, "MG" => 137,
89 "MH" => 138, "MK" => 139, "ML" => 140, "MM" => 141, "MN" => 142, "MO" => 143,
90 "MP" => 144, "MQ" => 145, "MR" => 146, "MS" => 147, "MT" => 148, "MU" => 149,
91 "MV" => 150, "MW" => 151, "MX" => 152, "MY" => 153, "MZ" => 154, "NA" => 155,
92 "NC" => 156, "NE" => 157, "NF" => 158, "NG" => 159, "NI" => 160, "NL" => 161,
93 "NO" => 162, "NP" => 163, "NR" => 164, "NU" => 165, "NZ" => 166, "OM" => 167,
94 "PA" => 168, "PE" => 169, "PF" => 170, "PG" => 171, "PH" => 172, "PK" => 173,
95 "PL" => 174, "PM" => 175, "PN" => 176, "PR" => 177, "PS" => 178, "PT" => 179,
96 "PW" => 180, "PY" => 181, "QA" => 182, "RE" => 183, "RO" => 184, "RU" => 185,
97 "RW" => 186, "SA" => 187, "SB" => 188, "SC" => 189, "SD" => 190, "SE" => 191,
98 "SG" => 192, "SH" => 193, "SI" => 194, "SJ" => 195, "SK" => 196, "SL" => 197,
99 "SM" => 198, "SN" => 199, "SO" => 200, "SR" => 201, "ST" => 202, "SV" => 203,
100 "SY" => 204, "SZ" => 205, "TC" => 206, "TD" => 207, "TF" => 208, "TG" => 209,
101 "TH" => 210, "TJ" => 211, "TK" => 212, "TM" => 213, "TN" => 214, "TO" => 215,
102 "TL" => 216, "TR" => 217, "TT" => 218, "TV" => 219, "TW" => 220, "TZ" => 221,
103 "UA" => 222, "UG" => 223, "UM" => 224, "US" => 225, "UY" => 226, "UZ" => 227,
104 "VA" => 228, "VC" => 229, "VE" => 230, "VG" => 231, "VI" => 232, "VN" => 233,
105 "VU" => 234, "WF" => 235, "WS" => 236, "YE" => 237, "YT" => 238, "RS" => 239,
106 "ZA" => 240, "ZM" => 241, "ME" => 242, "ZW" => 243, "A1" => 244, "A2" => 245,
107 "O1" => 246, "AX" => 247, "GG" => 248, "IM" => 249, "JE" => 250, "BL" => 251,
110 var $GEOIP_COUNTRY_CODES = array(
111 "", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ",
112 "AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH",
113 "BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA",
114 "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU",
115 "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG",
116 "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "FX", "GA", "GB",
117 "GD", "GE", "GF", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT",
118 "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN",
119 "IO", "IQ", "IR", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM",
120 "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS",
121 "LT", "LU", "LV", "LY", "MA", "MC", "MD", "MG", "MH", "MK", "ML", "MM", "MN",
122 "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA",
123 "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA",
124 "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY",
125 "QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI",
126 "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TC", "TD",
127 "TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TL", "TR", "TT", "TV", "TW",
128 "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN",
129 "VU", "WF", "WS", "YE", "YT", "RS", "ZA", "ZM", "ME", "ZW", "A1", "A2", "O1",
130 "AX", "GG", "IM", "JE", "BL", "MF"
132 var $GEOIP_COUNTRY_CODES3 = array(
133 "","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","ANT","AGO","AQ","ARG",
134 "ASM","AUT","AUS","ABW","AZE","BIH","BRB","BGD","BEL","BFA","BGR","BHR","BDI",
135 "BEN","BMU","BRN","BOL","BRA","BHS","BTN","BV","BWA","BLR","BLZ","CAN","CC",
136 "COD","CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI","CUB","CPV",
137 "CX","CYP","CZE","DEU","DJI","DNK","DMA","DOM","DZA","ECU","EST","EGY","ESH",
138 "ERI","ESP","ETH","FIN","FJI","FLK","FSM","FRO","FRA","FX","GAB","GBR","GRD",
139 "GEO","GUF","GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","GS","GTM","GUM",
140 "GNB","GUY","HKG","HM","HND","HRV","HTI","HUN","IDN","IRL","ISR","IND","IO",
141 "IRQ","IRN","ISL","ITA","JAM","JOR","JPN","KEN","KGZ","KHM","KIR","COM","KNA",
142 "PRK","KOR","KWT","CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU",
143 "LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI","MMR","MNG","MAC",
144 "MNP","MTQ","MRT","MSR","MLT","MUS","MDV","MWI","MEX","MYS","MOZ","NAM","NCL",
145 "NER","NFK","NGA","NIC","NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER",
146 "PYF","PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW","PRY","QAT",
147 "REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN","SWE","SGP","SHN","SVN","SJM",
148 "SVK","SLE","SMR","SEN","SOM","SUR","STP","SLV","SYR","SWZ","TCA","TCD","TF",
149 "TGO","THA","TJK","TKL","TLS","TKM","TUN","TON","TUR","TTO","TUV","TWN","TZA",
150 "UKR","UGA","UM","USA","URY","UZB","VAT","VCT","VEN","VGB","VIR","VNM","VUT",
151 "WLF","WSM","YEM","YT","SRB","ZAF","ZMB","MNE","ZWE","A1","A2","O1",
152 "ALA","GGY","IMN","JEY","BLM","MAF"
154 var $GEOIP_COUNTRY_NAMES = array(
155 "", "Asia/Pacific Region", "Europe", "Andorra", "United Arab Emirates",
156 "Afghanistan", "Antigua and Barbuda", "Anguilla", "Albania", "Armenia",
157 "Netherlands Antilles", "Angola", "Antarctica", "Argentina", "American Samoa",
158 "Austria", "Australia", "Aruba", "Azerbaijan", "Bosnia and Herzegovina",
159 "Barbados", "Bangladesh", "Belgium", "Burkina Faso", "Bulgaria", "Bahrain",
160 "Burundi", "Benin", "Bermuda", "Brunei Darussalam", "Bolivia", "Brazil",
161 "Bahamas", "Bhutan", "Bouvet Island", "Botswana", "Belarus", "Belize",
162 "Canada", "Cocos (Keeling) Islands", "Congo, The Democratic Republic of the",
163 "Central African Republic", "Congo", "Switzerland", "Cote D'Ivoire", "Cook Islands",
164 "Chile", "Cameroon", "China", "Colombia", "Costa Rica", "Cuba", "Cape Verde",
165 "Christmas Island", "Cyprus", "Czech Republic", "Germany", "Djibouti",
166 "Denmark", "Dominica", "Dominican Republic", "Algeria", "Ecuador", "Estonia",
167 "Egypt", "Western Sahara", "Eritrea", "Spain", "Ethiopia", "Finland", "Fiji",
168 "Falkland Islands (Malvinas)", "Micronesia, Federated States of", "Faroe Islands",
169 "France", "France, Metropolitan", "Gabon", "United Kingdom",
170 "Grenada", "Georgia", "French Guiana", "Ghana", "Gibraltar", "Greenland",
171 "Gambia", "Guinea", "Guadeloupe", "Equatorial Guinea", "Greece", "South Georgia and the South Sandwich Islands",
172 "Guatemala", "Guam", "Guinea-Bissau",
173 "Guyana", "Hong Kong", "Heard Island and McDonald Islands", "Honduras",
174 "Croatia", "Haiti", "Hungary", "Indonesia", "Ireland", "Israel", "India",
175 "British Indian Ocean Territory", "Iraq", "Iran, Islamic Republic of",
176 "Iceland", "Italy", "Jamaica", "Jordan", "Japan", "Kenya", "Kyrgyzstan",
177 "Cambodia", "Kiribati", "Comoros", "Saint Kitts and Nevis", "Korea, Democratic People's Republic of",
178 "Korea, Republic of", "Kuwait", "Cayman Islands",
179 "Kazakhstan", "Lao People's Democratic Republic", "Lebanon", "Saint Lucia",
180 "Liechtenstein", "Sri Lanka", "Liberia", "Lesotho", "Lithuania", "Luxembourg",
181 "Latvia", "Libyan Arab Jamahiriya", "Morocco", "Monaco", "Moldova, Republic of",
182 "Madagascar", "Marshall Islands", "Macedonia",
183 "Mali", "Myanmar", "Mongolia", "Macau", "Northern Mariana Islands",
184 "Martinique", "Mauritania", "Montserrat", "Malta", "Mauritius", "Maldives",
185 "Malawi", "Mexico", "Malaysia", "Mozambique", "Namibia", "New Caledonia",
186 "Niger", "Norfolk Island", "Nigeria", "Nicaragua", "Netherlands", "Norway",
187 "Nepal", "Nauru", "Niue", "New Zealand", "Oman", "Panama", "Peru", "French Polynesia",
188 "Papua New Guinea", "Philippines", "Pakistan", "Poland", "Saint Pierre and Miquelon",
189 "Pitcairn Islands", "Puerto Rico", "Palestinian Territory",
190 "Portugal", "Palau", "Paraguay", "Qatar", "Reunion", "Romania",
191 "Russian Federation", "Rwanda", "Saudi Arabia", "Solomon Islands",
192 "Seychelles", "Sudan", "Sweden", "Singapore", "Saint Helena", "Slovenia",
193 "Svalbard and Jan Mayen", "Slovakia", "Sierra Leone", "San Marino", "Senegal",
194 "Somalia", "Suriname", "Sao Tome and Principe", "El Salvador", "Syrian Arab Republic",
195 "Swaziland", "Turks and Caicos Islands", "Chad", "French Southern Territories",
196 "Togo", "Thailand", "Tajikistan", "Tokelau", "Turkmenistan",
197 "Tunisia", "Tonga", "Timor-Leste", "Turkey", "Trinidad and Tobago", "Tuvalu",
198 "Taiwan", "Tanzania, United Republic of", "Ukraine",
199 "Uganda", "United States Minor Outlying Islands", "United States", "Uruguay",
200 "Uzbekistan", "Holy See (Vatican City State)", "Saint Vincent and the Grenadines",
201 "Venezuela", "Virgin Islands, British", "Virgin Islands, U.S.",
202 "Vietnam", "Vanuatu", "Wallis and Futuna", "Samoa", "Yemen", "Mayotte",
203 "Serbia", "South Africa", "Zambia", "Montenegro", "Zimbabwe",
204 "Anonymous Proxy","Satellite Provider","Other",
205 "Aland Islands","Guernsey","Isle of Man","Jersey","Saint Barthelemy","Saint Martin"
210 if( !function_exists('geoip_load_shared_mem') ) {
211 function geoip_load_shared_mem ($file) {
213 $fp = fopen($file, "rb");
215 print "error opening $file: $php_errormsg\n";
218 $s_array = fstat($fp);
219 $size = $s_array['size'];
220 if ($shmid = @shmop_open (GEOIP_SHM_KEY, "w", 0, 0)) {
221 shmop_delete ($shmid);
222 shmop_close ($shmid);
224 $shmid = shmop_open (GEOIP_SHM_KEY, "c", 0644, $size);
225 shmop_write ($shmid, fread($fp, $size), 0);
226 shmop_close ($shmid);
230 if( !function_exists('_setup_segments') ) {
231 function _setup_segments($gi){
232 $gi->databaseType = GEOIP_COUNTRY_EDITION;
233 $gi->record_length = STANDARD_RECORD_LENGTH;
234 if ($gi->flags & GEOIP_SHARED_MEMORY) {
235 $offset = @shmop_size ($gi->shmid) - 3;
236 for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) {
237 $delim = @shmop_read ($gi->shmid, $offset, 3);
239 if ($delim == (chr(255).chr(255).chr(255))) {
240 $gi->databaseType = ord(@shmop_read ($gi->shmid, $offset, 1));
243 if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
244 $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0;
245 } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){
246 $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1;
247 } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)||
248 ($gi->databaseType == GEOIP_CITY_EDITION_REV1)
249 || ($gi->databaseType == GEOIP_ORG_EDITION)
250 || ($gi->databaseType == GEOIP_ISP_EDITION)
251 || ($gi->databaseType == GEOIP_ASNUM_EDITION)){
252 $gi->databaseSegments = 0;
253 $buf = @shmop_read ($gi->shmid, $offset, SEGMENT_RECORD_LENGTH);
254 for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){
255 $gi->databaseSegments += (ord($buf[$j]) << ($j * 8));
257 if (($gi->databaseType == GEOIP_ORG_EDITION)||
258 ($gi->databaseType == GEOIP_ISP_EDITION)) {
259 $gi->record_length = ORG_RECORD_LENGTH;
267 if (($gi->databaseType == GEOIP_COUNTRY_EDITION)||
268 ($gi->databaseType == GEOIP_PROXY_EDITION)||
269 ($gi->databaseType == GEOIP_NETSPEED_EDITION)){
270 $gi->databaseSegments = GEOIP_COUNTRY_BEGIN;
273 $filepos = ftell($gi->filehandle);
274 fseek($gi->filehandle, -3, SEEK_END);
275 for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) {
276 $delim = fread($gi->filehandle,3);
277 if ($delim == (chr(255).chr(255).chr(255))){
278 $gi->databaseType = ord(fread($gi->filehandle,1));
279 if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
280 $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0;
282 else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){
283 $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1;
284 } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0) ||
285 ($gi->databaseType == GEOIP_CITY_EDITION_REV1) ||
286 ($gi->databaseType == GEOIP_ORG_EDITION) ||
287 ($gi->databaseType == GEOIP_ISP_EDITION) ||
288 ($gi->databaseType == GEOIP_ASNUM_EDITION)){
289 $gi->databaseSegments = 0;
290 $buf = fread($gi->filehandle,SEGMENT_RECORD_LENGTH);
291 for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){
292 $gi->databaseSegments += (ord($buf[$j]) << ($j * 8));
294 if ($gi->databaseType == GEOIP_ORG_EDITION ||
295 $gi->databaseType == GEOIP_ISP_EDITION) {
296 $gi->record_length = ORG_RECORD_LENGTH;
301 fseek($gi->filehandle, -4, SEEK_CUR);
304 if (($gi->databaseType == GEOIP_COUNTRY_EDITION)||
305 ($gi->databaseType == GEOIP_PROXY_EDITION)||
306 ($gi->databaseType == GEOIP_NETSPEED_EDITION)){
307 $gi->databaseSegments = GEOIP_COUNTRY_BEGIN;
309 fseek($gi->filehandle,$filepos,SEEK_SET);
315 if( !function_exists( 'geoip_open' ) ) {
316 function geoip_open($filename, $flags) {
319 if ($gi->flags & GEOIP_SHARED_MEMORY) {
320 $gi->shmid = @shmop_open (GEOIP_SHM_KEY, "a", 0, 0);
322 $gi->filehandle = fopen($filename,"rb") or die( "Can not open $filename\n" );
323 if ($gi->flags & GEOIP_MEMORY_CACHE) {
324 $s_array = fstat($gi->filehandle);
325 $gi->memory_buffer = fread($gi->filehandle, $s_array['size']);
329 $gi = _setup_segments($gi);
334 if( !function_exists( 'geoip_close' ) ) {
335 function geoip_close($gi) {
336 if ($gi->flags & GEOIP_SHARED_MEMORY) {
340 return fclose($gi->filehandle);
344 if( !function_exists( 'geoip_country_id_by_name' ) ) {
345 function geoip_country_id_by_name($gi, $name) {
346 $addr = gethostbyname($name);
347 if (!$addr || $addr == $name) {
350 return geoip_country_id_by_addr($gi, $addr);
354 if( !function_exists( 'geoip_country_code_by_name' ) ) {
355 function geoip_country_code_by_name($gi, $name) {
356 $country_id = geoip_country_id_by_name($gi,$name);
357 if ($country_id !== false) {
358 return $gi->GEOIP_COUNTRY_CODES[$country_id];
364 if( !function_exists( 'geoip_country_name_by_name' ) ) {
365 function geoip_country_name_by_name($gi, $name) {
366 $country_id = geoip_country_id_by_name($gi,$name);
367 if ($country_id !== false) {
368 return $gi->GEOIP_COUNTRY_NAMES[$country_id];
374 if( !function_exists( 'geoip_country_id_by_addr' ) ) {
375 function geoip_country_id_by_addr($gi, $addr) {
376 $ipnum = ip2long($addr);
377 return _geoip_seek_country($gi, $ipnum) - GEOIP_COUNTRY_BEGIN;
381 if( !function_exists( 'geoip_country_code_by_addr' ) ) {
382 function geoip_country_code_by_addr($gi, $addr) {
383 if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) {
384 $record = geoip_record_by_addr($gi,$addr);
385 if ( $record !== false ) {
386 return $record->country_code;
389 $country_id = geoip_country_id_by_addr($gi,$addr);
390 if ($country_id !== false) {
391 return $gi->GEOIP_COUNTRY_CODES[$country_id];
398 if( !function_exists( 'geoip_country_name_by_addr' ) ) {
399 function geoip_country_name_by_addr($gi, $addr) {
400 if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) {
401 $record = geoip_record_by_addr($gi,$addr);
402 return $record->country_name;
404 $country_id = geoip_country_id_by_addr($gi,$addr);
405 if ($country_id !== false) {
406 return $gi->GEOIP_COUNTRY_NAMES[$country_id];
413 if( !function_exists( '_geoip_seek_country' ) ) {
414 function _geoip_seek_country($gi, $ipnum) {
416 for ($depth = 31; $depth >= 0; --$depth) {
417 if ($gi->flags & GEOIP_MEMORY_CACHE) {
418 $buf = substr($gi->memory_buffer,
419 2 * $gi->record_length * $offset,
420 2 * $gi->record_length);
421 } elseif ($gi->flags & GEOIP_SHARED_MEMORY) {
422 $buf = @shmop_read ($gi->shmid,
423 2 * $gi->record_length * $offset,
424 2 * $gi->record_length );
426 fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0
427 or die("fseek failed");
428 $buf = fread($gi->filehandle, 2 * $gi->record_length);
431 for ($i = 0; $i < 2; ++$i) {
432 for ($j = 0; $j < $gi->record_length; ++$j) {
433 $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8);
436 if ($ipnum & (1 << $depth)) {
437 if ($x[1] >= $gi->databaseSegments) {
442 if ($x[0] >= $gi->databaseSegments) {
448 trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR);
453 if( !function_exists( '_get_org' ) ) {
454 function _get_org($gi,$ipnum){
455 $seek_org = _geoip_seek_country($gi,$ipnum);
456 if ($seek_org == $gi->databaseSegments) {
459 $record_pointer = $seek_org + (2 * $gi->record_length - 1) * $gi->databaseSegments;
460 if ($gi->flags & GEOIP_SHARED_MEMORY) {
461 $org_buf = @shmop_read ($gi->shmid, $record_pointer, MAX_ORG_RECORD_LENGTH);
463 fseek($gi->filehandle, $record_pointer, SEEK_SET);
464 $org_buf = fread($gi->filehandle,MAX_ORG_RECORD_LENGTH);
466 $org_buf = substr($org_buf, 0, strpos($org_buf, 0));
471 if( !function_exists( 'geoip_org_by_addr' ) ) {
472 function geoip_org_by_addr ($gi,$addr) {
476 $ipnum = ip2long($addr);
477 return _get_org($gi, $ipnum);
481 if( !function_exists( '_get_region' ) ) {
482 function _get_region($gi,$ipnum){
483 if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
484 $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV0;
485 if ($seek_region >= 1000){
486 $country_code = "US";
487 $region = chr(($seek_region - 1000)/26 + 65) . chr(($seek_region - 1000)%26 + 65);
489 $country_code = $gi->GEOIP_COUNTRY_CODES[$seek_region];
492 return array ($country_code,$region);
493 } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1) {
494 $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV1;
495 //print $seek_region;
496 if ($seek_region < US_OFFSET){
499 } else if ($seek_region < CANADA_OFFSET) {
500 $country_code = "US";
501 $region = chr(($seek_region - US_OFFSET)/26 + 65) . chr(($seek_region - US_OFFSET)%26 + 65);
502 } else if ($seek_region < WORLD_OFFSET) {
503 $country_code = "CA";
504 $region = chr(($seek_region - CANADA_OFFSET)/26 + 65) . chr(($seek_region - CANADA_OFFSET)%26 + 65);
506 $country_code = $gi->GEOIP_COUNTRY_CODES[($seek_region - WORLD_OFFSET) / FIPS_RANGE];
509 return array ($country_code,$region);
514 if( !function_exists( 'geoip_region_by_addr' ) ) {
515 function geoip_region_by_addr ($gi,$addr) {
519 $ipnum = ip2long($addr);
520 return _get_region($gi, $ipnum);
524 if( !function_exists( 'getdnsattributes' ) ) {
525 function getdnsattributes ($l,$ip){
526 $r = new Net_DNS_Resolver();
527 $r->nameservers = array("ws1.maxmind.com");
528 $p = $r->search($l."." . $ip .".s.maxmind.com","TXT","IN");
529 $str = is_object($p->answer[0])?$p->answer[0]->string():'';
530 ereg("\"(.*)\"",$str,$regs);