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