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