Pluf Framework

Pluf Framework Git Source Tree

Root/src/GeoIP.php

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

Archive Download this file

Branches

Tags