]> CyberLeo.Net >> Repos - Github/YOURLS.git/blob - includes/geo/geoip.inc
Revert geoip lib update
[Github/YOURLS.git] / includes / geo / geoip.inc
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
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);
55 define("GEOIP_DOMAIN_EDITION", 11);
56 define("GEOIP_COUNTRY_EDITION_V6", 12);
57 define("GEOIP_LOCATIONA_EDITION", 13);
58 define("GEOIP_ACCURACYRADIUS_EDITION", 14);
59 define("GEOIP_CITYCOMBINED_EDITION", 15);
60 define("GEOIP_CITY_EDITION_REV1_V6", 30);
61 define("GEOIP_CITY_EDITION_REV0_V6",31);
62 define("GEOIP_NETSPEED_EDITION_REV1",32);
63 define("GEOIP_NETSPEED_EDITION_REV1_V6",33);
64 define("GEOIP_USERTYPE_EDITION",28);
65 define("GEOIP_USERTYPE_EDITION_V6",29);
66 define("GEOIP_ASNUM_EDITION_V6",21);
67 define("GEOIP_ISP_EDITION_V6",22);
68 define("GEOIP_ORG_EDITION_V6",23);
69 define("GEOIP_DOMAIN_EDITION_V6",24);
70
71 define("CITYCOMBINED_FIXED_RECORD", 7 );
72
73 if( !class_exists('GeoIP', false) ) {
74 class GeoIP {
75     var $flags;
76     var $filehandle;
77     var $memory_buffer;
78     var $databaseType;
79     var $databaseSegments;
80     var $record_length;
81     var $shmid;
82     var $GEOIP_COUNTRY_CODE_TO_NUMBER = array(
83 "" => 0, "AP" => 1, "EU" => 2, "AD" => 3, "AE" => 4, "AF" => 5,
84 "AG" => 6, "AI" => 7, "AL" => 8, "AM" => 9, "CW" => 10, "AO" => 11,
85 "AQ" => 12, "AR" => 13, "AS" => 14, "AT" => 15, "AU" => 16, "AW" => 17,
86 "AZ" => 18, "BA" => 19, "BB" => 20, "BD" => 21, "BE" => 22, "BF" => 23,
87 "BG" => 24, "BH" => 25, "BI" => 26, "BJ" => 27, "BM" => 28, "BN" => 29,
88 "BO" => 30, "BR" => 31, "BS" => 32, "BT" => 33, "BV" => 34, "BW" => 35,
89 "BY" => 36, "BZ" => 37, "CA" => 38, "CC" => 39, "CD" => 40, "CF" => 41,
90 "CG" => 42, "CH" => 43, "CI" => 44, "CK" => 45, "CL" => 46, "CM" => 47,
91 "CN" => 48, "CO" => 49, "CR" => 50, "CU" => 51, "CV" => 52, "CX" => 53,
92 "CY" => 54, "CZ" => 55, "DE" => 56, "DJ" => 57, "DK" => 58, "DM" => 59,
93 "DO" => 60, "DZ" => 61, "EC" => 62, "EE" => 63, "EG" => 64, "EH" => 65,
94 "ER" => 66, "ES" => 67, "ET" => 68, "FI" => 69, "FJ" => 70, "FK" => 71,
95 "FM" => 72, "FO" => 73, "FR" => 74, "SX" => 75, "GA" => 76, "GB" => 77,
96 "GD" => 78, "GE" => 79, "GF" => 80, "GH" => 81, "GI" => 82, "GL" => 83,
97 "GM" => 84, "GN" => 85, "GP" => 86, "GQ" => 87, "GR" => 88, "GS" => 89,
98 "GT" => 90, "GU" => 91, "GW" => 92, "GY" => 93, "HK" => 94, "HM" => 95,
99 "HN" => 96, "HR" => 97, "HT" => 98, "HU" => 99, "ID" => 100, "IE" => 101,
100 "IL" => 102, "IN" => 103, "IO" => 104, "IQ" => 105, "IR" => 106, "IS" => 107,
101 "IT" => 108, "JM" => 109, "JO" => 110, "JP" => 111, "KE" => 112, "KG" => 113,
102 "KH" => 114, "KI" => 115, "KM" => 116, "KN" => 117, "KP" => 118, "KR" => 119,
103 "KW" => 120, "KY" => 121, "KZ" => 122, "LA" => 123, "LB" => 124, "LC" => 125,
104 "LI" => 126, "LK" => 127, "LR" => 128, "LS" => 129, "LT" => 130, "LU" => 131,
105 "LV" => 132, "LY" => 133, "MA" => 134, "MC" => 135, "MD" => 136, "MG" => 137,
106 "MH" => 138, "MK" => 139, "ML" => 140, "MM" => 141, "MN" => 142, "MO" => 143,
107 "MP" => 144, "MQ" => 145, "MR" => 146, "MS" => 147, "MT" => 148, "MU" => 149,
108 "MV" => 150, "MW" => 151, "MX" => 152, "MY" => 153, "MZ" => 154, "NA" => 155,
109 "NC" => 156, "NE" => 157, "NF" => 158, "NG" => 159, "NI" => 160, "NL" => 161,
110 "NO" => 162, "NP" => 163, "NR" => 164, "NU" => 165, "NZ" => 166, "OM" => 167,
111 "PA" => 168, "PE" => 169, "PF" => 170, "PG" => 171, "PH" => 172, "PK" => 173,
112 "PL" => 174, "PM" => 175, "PN" => 176, "PR" => 177, "PS" => 178, "PT" => 179,
113 "PW" => 180, "PY" => 181, "QA" => 182, "RE" => 183, "RO" => 184, "RU" => 185,
114 "RW" => 186, "SA" => 187, "SB" => 188, "SC" => 189, "SD" => 190, "SE" => 191,
115 "SG" => 192, "SH" => 193, "SI" => 194, "SJ" => 195, "SK" => 196, "SL" => 197,
116 "SM" => 198, "SN" => 199, "SO" => 200, "SR" => 201, "ST" => 202, "SV" => 203,
117 "SY" => 204, "SZ" => 205, "TC" => 206, "TD" => 207, "TF" => 208, "TG" => 209,
118 "TH" => 210, "TJ" => 211, "TK" => 212, "TM" => 213, "TN" => 214, "TO" => 215,
119 "TL" => 216, "TR" => 217, "TT" => 218, "TV" => 219, "TW" => 220, "TZ" => 221,
120 "UA" => 222, "UG" => 223, "UM" => 224, "US" => 225, "UY" => 226, "UZ" => 227,
121 "VA" => 228, "VC" => 229, "VE" => 230, "VG" => 231, "VI" => 232, "VN" => 233,
122 "VU" => 234, "WF" => 235, "WS" => 236, "YE" => 237, "YT" => 238, "RS" => 239,
123 "ZA" => 240, "ZM" => 241, "ME" => 242, "ZW" => 243, "A1" => 244, "A2" => 245,
124 "O1" => 246, "AX" => 247, "GG" => 248, "IM" => 249, "JE" => 250, "BL" => 251,
125 "MF" => 252, "BQ" => 253, "SS" => 254
126 );
127     var $GEOIP_COUNTRY_CODES = array(
128      "","AP","EU","AD","AE","AF","AG","AI","AL","AM","CW",
129         "AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB",
130         "BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO",
131         "BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD",
132         "CF","CG","CH","CI","CK","CL","CM","CN","CO","CR",
133         "CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO",
134         "DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ",
135         "FK","FM","FO","FR","SX","GA","GB","GD","GE","GF",
136         "GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT",
137         "GU","GW","GY","HK","HM","HN","HR","HT","HU","ID",
138         "IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO",
139         "JP","KE","KG","KH","KI","KM","KN","KP","KR","KW",
140         "KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT",
141         "LU","LV","LY","MA","MC","MD","MG","MH","MK","ML",
142         "MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV",
143         "MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI",
144         "NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF",
145         "PG","PH","PK","PL","PM","PN","PR","PS","PT","PW",
146         "PY","QA","RE","RO","RU","RW","SA","SB","SC","SD",
147         "SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO",
148         "SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH",
149         "TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW",
150         "TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE",
151         "VG","VI","VN","VU","WF","WS","YE","YT","RS","ZA",
152         "ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE",
153   "BL","MF", "BQ", "SS", "O1" );
154     var $GEOIP_COUNTRY_CODES3 = array(
155       "","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","CUW",
156         "AGO","ATA","ARG","ASM","AUT","AUS","ABW","AZE","BIH","BRB",
157         "BGD","BEL","BFA","BGR","BHR","BDI","BEN","BMU","BRN","BOL",
158         "BRA","BHS","BTN","BVT","BWA","BLR","BLZ","CAN","CCK","COD",
159         "CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI",
160         "CUB","CPV","CXR","CYP","CZE","DEU","DJI","DNK","DMA","DOM",
161         "DZA","ECU","EST","EGY","ESH","ERI","ESP","ETH","FIN","FJI",
162         "FLK","FSM","FRO","FRA","SXM","GAB","GBR","GRD","GEO","GUF",
163         "GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","SGS","GTM",
164         "GUM","GNB","GUY","HKG","HMD","HND","HRV","HTI","HUN","IDN",
165         "IRL","ISR","IND","IOT","IRQ","IRN","ISL","ITA","JAM","JOR",
166         "JPN","KEN","KGZ","KHM","KIR","COM","KNA","PRK","KOR","KWT",
167         "CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU",
168         "LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI",
169         "MMR","MNG","MAC","MNP","MTQ","MRT","MSR","MLT","MUS","MDV",
170         "MWI","MEX","MYS","MOZ","NAM","NCL","NER","NFK","NGA","NIC",
171         "NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER","PYF",
172         "PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW",
173         "PRY","QAT","REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN",
174         "SWE","SGP","SHN","SVN","SJM","SVK","SLE","SMR","SEN","SOM",
175         "SUR","STP","SLV","SYR","SWZ","TCA","TCD","ATF","TGO","THA",
176         "TJK","TKL","TKM","TUN","TON","TLS","TUR","TTO","TUV","TWN",
177         "TZA","UKR","UGA","UMI","USA","URY","UZB","VAT","VCT","VEN",
178         "VGB","VIR","VNM","VUT","WLF","WSM","YEM","MYT","SRB","ZAF",
179         "ZMB","MNE","ZWE","A1","A2","O1","ALA","GGY","IMN","JEY",
180   "BLM","MAF", "BES", "SSD", "O1"
181   );
182     var $GEOIP_COUNTRY_NAMES = array(
183     "","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Curacao",
184         "Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados",
185         "Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia",
186         "Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the",
187         "Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica",
188         "Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic",
189         "Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji",
190         "Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","Sint Maarten (Dutch part)","Gabon","United Kingdom","Grenada","Georgia","French Guiana",
191         "Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala",
192         "Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia",
193         "Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan",
194         "Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait",
195         "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania",
196         "Luxembourg","Latvia","Libya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali",
197         "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives",
198         "Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua",
199         "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia",
200         "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau",
201         "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan",
202         "Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname",
203         "Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand",
204         "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan",
205         "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",
206         "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa",
207         "Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey",
208         "Saint Barthelemy","Saint Martin", "Bonaire, Saint Eustatius and Saba",
209         "South Sudan", "Other"
210 );
211
212     var $GEOIP_CONTINENT_CODES = array(
213   "--", "AS","EU","EU","AS","AS","NA","NA","EU","AS","NA",
214         "AF","AN","SA","OC","EU","OC","NA","AS","EU","NA",
215         "AS","EU","AF","EU","AS","AF","AF","NA","AS","SA",
216         "SA","NA","AS","AN","AF","EU","NA","NA","AS","AF",
217         "AF","AF","EU","AF","OC","SA","AF","AS","SA","NA",
218         "NA","AF","AS","AS","EU","EU","AF","EU","NA","NA",
219         "AF","SA","EU","AF","AF","AF","EU","AF","EU","OC",
220         "SA","OC","EU","EU","NA","AF","EU","NA","AS","SA",
221         "AF","EU","NA","AF","AF","NA","AF","EU","AN","NA",
222         "OC","AF","SA","AS","AN","NA","EU","NA","EU","AS",
223         "EU","AS","AS","AS","AS","AS","EU","EU","NA","AS",
224         "AS","AF","AS","AS","OC","AF","NA","AS","AS","AS",
225         "NA","AS","AS","AS","NA","EU","AS","AF","AF","EU",
226         "EU","EU","AF","AF","EU","EU","AF","OC","EU","AF",
227         "AS","AS","AS","OC","NA","AF","NA","EU","AF","AS",
228         "AF","NA","AS","AF","AF","OC","AF","OC","AF","NA",
229         "EU","EU","AS","OC","OC","OC","AS","NA","SA","OC",
230         "OC","AS","AS","EU","NA","OC","NA","AS","EU","OC",
231         "SA","AS","AF","EU","EU","AF","AS","OC","AF","AF",
232         "EU","AS","AF","EU","EU","EU","AF","EU","AF","AF",
233         "SA","AF","NA","AS","AF","NA","AF","AN","AF","AS",
234         "AS","OC","AS","AF","OC","AS","EU","NA","OC","AS",
235         "AF","EU","AF","OC","NA","SA","AS","EU","NA","SA",
236         "NA","NA","AS","OC","OC","OC","AS","AF","EU","AF",
237         "AF","EU","AF","--","--","--","EU","EU","EU","EU",
238         "NA","NA","NA", "AF", "--"
239 );
240 }
241 } // class_exists
242
243 if( !function_exists('geoip_load_shared_mem') ) {
244 function geoip_load_shared_mem ($file) {
245
246   $fp = fopen($file, "rb");
247   if (!$fp) {
248     print "error opening $file: $php_errormsg\n";
249     exit;
250   }
251   $s_array = fstat($fp);
252   $size = $s_array['size'];
253   if ($shmid = @shmop_open (GEOIP_SHM_KEY, "w", 0, 0)) {
254     shmop_delete ($shmid);
255     shmop_close ($shmid);
256   }
257   $shmid = shmop_open (GEOIP_SHM_KEY, "c", 0644, $size);
258   shmop_write ($shmid, fread($fp, $size), 0);
259   shmop_close ($shmid);
260 }
261 } // function_exists
262
263 if( !function_exists('_setup_segments') ) {
264 function _setup_segments($gi){
265   $gi->databaseType = GEOIP_COUNTRY_EDITION;
266   $gi->record_length = STANDARD_RECORD_LENGTH;
267   if ($gi->flags & GEOIP_SHARED_MEMORY) {
268     $offset = @shmop_size ($gi->shmid) - 3;
269     for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) {
270         $delim = @shmop_read ($gi->shmid, $offset, 3);
271         $offset += 3;
272         if ($delim == (chr(255).chr(255).chr(255))) {
273             $gi->databaseType = ord(@shmop_read ($gi->shmid, $offset, 1));
274             $offset++;
275
276             if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
277                 $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0;
278             } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){
279                 $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1;
280             } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)||
281                      ($gi->databaseType == GEOIP_CITY_EDITION_REV1) 
282                     || ($gi->databaseType == GEOIP_ORG_EDITION)
283                     || ($gi->databaseType == GEOIP_ORG_EDITION_V6)
284                     || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
285                     || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
286                     || ($gi->databaseType == GEOIP_ISP_EDITION)
287                     || ($gi->databaseType == GEOIP_ISP_EDITION_V6)
288                     || ($gi->databaseType == GEOIP_USERTYPE_EDITION)
289                     || ($gi->databaseType == GEOIP_USERTYPE_EDITION_V6)
290                     || ($gi->databaseType == GEOIP_LOCATIONA_EDITION)
291                     || ($gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION)
292                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
293                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
294                     || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1)                    
295                     || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6)                    
296                     || ($gi->databaseType == GEOIP_ASNUM_EDITION)
297                     || ($gi->databaseType == GEOIP_ASNUM_EDITION_V6)){
298                 $gi->databaseSegments = 0;
299                 $buf = @shmop_read ($gi->shmid, $offset, SEGMENT_RECORD_LENGTH);
300                 for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){
301                     $gi->databaseSegments += (ord($buf[$j]) << ($j * 8));
302                 }
303                     if (($gi->databaseType == GEOIP_ORG_EDITION)
304                         || ($gi->databaseType == GEOIP_ORG_EDITION_V6)
305                         || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
306                         || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
307                         || ($gi->databaseType == GEOIP_ISP_EDITION)
308                         || ($gi->databaseType == GEOIP_ISP_EDITION_V6)) {
309                         $gi->record_length = ORG_RECORD_LENGTH;
310                 }
311             }
312             break;
313         } else {
314             $offset -= 4;
315         }
316     }
317     if (($gi->databaseType == GEOIP_COUNTRY_EDITION)||
318         ($gi->databaseType == GEOIP_COUNTRY_EDITION_V6)||
319         ($gi->databaseType == GEOIP_PROXY_EDITION)||
320         ($gi->databaseType == GEOIP_NETSPEED_EDITION)){
321         $gi->databaseSegments = GEOIP_COUNTRY_BEGIN;
322     }
323   } else {
324     $filepos = ftell($gi->filehandle);
325     fseek($gi->filehandle, -3, SEEK_END);
326     for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) {
327         $delim = fread($gi->filehandle,3);
328         if ($delim == (chr(255).chr(255).chr(255))){
329         $gi->databaseType = ord(fread($gi->filehandle,1));
330         if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
331             $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0;
332         }
333         else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){
334             $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1;
335                 }  else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)
336                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV1)
337                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
338                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
339                     || ($gi->databaseType == GEOIP_ORG_EDITION) 
340                     || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
341                     || ($gi->databaseType == GEOIP_ISP_EDITION)
342                     || ($gi->databaseType == GEOIP_ORG_EDITION_V6) 
343                     || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
344                     || ($gi->databaseType == GEOIP_ISP_EDITION_V6)
345                     || ($gi->databaseType == GEOIP_LOCATIONA_EDITION)
346                     || ($gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION)
347                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
348                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
349                     || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1)                    
350                     || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6)                    
351                     || ($gi->databaseType == GEOIP_USERTYPE_EDITION)
352                     || ($gi->databaseType == GEOIP_USERTYPE_EDITION_V6) 
353                     || ($gi->databaseType == GEOIP_ASNUM_EDITION)
354                     || ($gi->databaseType == GEOIP_ASNUM_EDITION_V6)){
355             $gi->databaseSegments = 0;
356             $buf = fread($gi->filehandle,SEGMENT_RECORD_LENGTH);
357             for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){
358             $gi->databaseSegments += (ord($buf[$j]) << ($j * 8));
359             }
360             if (   ( $gi->databaseType == GEOIP_ORG_EDITION )
361                 || ( $gi->databaseType == GEOIP_DOMAIN_EDITION )
362                 || ( $gi->databaseType == GEOIP_ISP_EDITION ) 
363                 || ( $gi->databaseType == GEOIP_ORG_EDITION_V6 )
364                 || ( $gi->databaseType == GEOIP_DOMAIN_EDITION_V6 )
365                 || ( $gi->databaseType == GEOIP_ISP_EDITION_V6 )) {
366             $gi->record_length = ORG_RECORD_LENGTH;
367             }
368         }
369         break;
370         } else {
371         fseek($gi->filehandle, -4, SEEK_CUR);
372         }
373     }
374     if (($gi->databaseType == GEOIP_COUNTRY_EDITION)||
375         ($gi->databaseType == GEOIP_COUNTRY_EDITION_V6)||
376         ($gi->databaseType == GEOIP_PROXY_EDITION)||
377         ($gi->databaseType == GEOIP_NETSPEED_EDITION)){
378          $gi->databaseSegments = GEOIP_COUNTRY_BEGIN;
379     }
380     fseek($gi->filehandle,$filepos,SEEK_SET);
381   }
382   return $gi;
383 }
384 } // function_exists
385
386 if( !function_exists( 'geoip_open' ) ) {
387 function geoip_open($filename, $flags) {
388   $gi = new GeoIP;
389   $gi->flags = $flags;
390   if ($gi->flags & GEOIP_SHARED_MEMORY) {
391     $gi->shmid = @shmop_open (GEOIP_SHM_KEY, "a", 0, 0);
392     } else {
393     $gi->filehandle = fopen($filename,"rb") or die( "Can not open $filename\n" );
394     if ($gi->flags & GEOIP_MEMORY_CACHE) {
395         $s_array = fstat($gi->filehandle);
396         $gi->memory_buffer = fread($gi->filehandle, $s_array['size']);
397     }
398   }
399
400   $gi = _setup_segments($gi);
401   return $gi;
402 }
403 } // function_exists
404
405 if( !function_exists( 'geoip_close' ) ) {
406 function geoip_close($gi) {
407   if ($gi->flags & GEOIP_SHARED_MEMORY) {
408     return true;
409   }
410
411   return fclose($gi->filehandle);
412 }
413 } // function_exists
414
415 if( !function_exists( 'geoip_country_id_by_name_v6' ) ) {
416 function geoip_country_id_by_name_v6($gi, $name) {
417   $rec = dns_get_record($name, DNS_AAAA);
418   if ( !$rec ) {
419     return false;
420   }
421   $addr = $rec[0]["ipv6"];
422   if (!$addr || $addr == $name) {
423     return false;
424   }
425   return geoip_country_id_by_addr_v6($gi, $addr);
426 }
427 } // function_exists
428
429 if( !function_exists( 'geoip_country_id_by_name' ) ) {
430 function geoip_country_id_by_name($gi, $name) {
431   $addr = gethostbyname($name);
432   if (!$addr || $addr == $name) {
433     return false;
434   }
435   return geoip_country_id_by_addr($gi, $addr);
436 }
437 } // function_exists
438
439 if( !function_exists( 'geoip_country_code_by_name_v6' ) ) {
440 function geoip_country_code_by_name_v6($gi, $name) {
441   $country_id = geoip_country_id_by_name_v6($gi,$name);
442   if ($country_id !== false) {
443         return $gi->GEOIP_COUNTRY_CODES[$country_id];
444   }
445   return false;
446 }
447 } // function_exists
448
449 if( !function_exists( 'geoip_country_code_by_name' ) ) {
450 function geoip_country_code_by_name($gi, $name) {
451   $country_id = geoip_country_id_by_name($gi,$name);
452   if ($country_id !== false) {
453         return $gi->GEOIP_COUNTRY_CODES[$country_id];
454   }
455   return false;
456 }
457 } // function_exists
458
459 if( !function_exists( 'geoip_country_name_by_name_v6' ) ) {
460 function geoip_country_name_by_name_v6($gi, $name) {
461   $country_id = geoip_country_id_by_name_v6($gi,$name);
462   if ($country_id !== false) {
463         return $gi->GEOIP_COUNTRY_NAMES[$country_id];
464   }
465   return false;
466 }
467 } // function_exists
468
469 if( !function_exists( 'geoip_country_name_by_name' ) ) {
470 function geoip_country_name_by_name($gi, $name) {
471   $country_id = geoip_country_id_by_name($gi,$name);
472   if ($country_id !== false) {
473         return $gi->GEOIP_COUNTRY_NAMES[$country_id];
474   }
475   return false;
476 }
477 } // function_exists
478
479 if( !function_exists( 'geoip_country_id_by_addr_v6' ) ) {
480 function geoip_country_id_by_addr_v6($gi, $addr) {
481   $ipnum = inet_pton($addr);
482   return _geoip_seek_country_v6($gi, $ipnum) - GEOIP_COUNTRY_BEGIN;
483 }
484 } // function_exists
485
486 if( !function_exists( 'geoip_country_id_by_addr' ) ) {
487 function geoip_country_id_by_addr($gi, $addr) {
488   $ipnum = ip2long($addr);
489   return _geoip_seek_country($gi, $ipnum) - GEOIP_COUNTRY_BEGIN;
490 }
491 } // function_exists
492
493 if( !function_exists( 'geoip_country_code_by_addr_v6' ) ) {
494 function geoip_country_code_by_addr_v6($gi, $addr) {
495     $country_id = geoip_country_id_by_addr_v6($gi,$addr);
496     if ($country_id !== false) {
497       return $gi->GEOIP_COUNTRY_CODES[$country_id];
498     }
499   return false;
500 }
501 } // function_exists
502
503 if( !function_exists( 'geoip_country_code_by_addr' ) ) {
504 function geoip_country_code_by_addr($gi, $addr) {
505   if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) {
506     $record = geoip_record_by_addr($gi,$addr);
507     if ( $record !== false ) {
508       return $record->country_code;
509     }
510   } else {
511     $country_id = geoip_country_id_by_addr($gi,$addr);
512     if ($country_id !== false) {
513       return $gi->GEOIP_COUNTRY_CODES[$country_id];
514     }
515   }
516   return false;
517 }
518 } // function_exists
519
520 if( !function_exists( 'geoip_country_name_by_addr_v6' ) ) {
521 function geoip_country_name_by_addr_v6($gi, $addr) {
522     $country_id = geoip_country_id_by_addr_v6($gi,$addr);
523     if ($country_id !== false) {
524       return $gi->GEOIP_COUNTRY_NAMES[$country_id];
525     }
526   return false;
527 }
528 } // function_exists
529
530 if( !function_exists( 'geoip_country_name_by_addr' ) ) {
531 function geoip_country_name_by_addr($gi, $addr) {
532   if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) {
533     $record = geoip_record_by_addr($gi,$addr);
534     return $record->country_name;
535   } else {
536     $country_id = geoip_country_id_by_addr($gi,$addr);
537     if ($country_id !== false) {
538       return $gi->GEOIP_COUNTRY_NAMES[$country_id];
539     }
540   }
541   return false;
542 }
543 } // function_exists
544
545 if( !function_exists( '_geoip_seek_country_v6' ) ) {
546 function _geoip_seek_country_v6($gi, $ipnum) {
547
548   # arrays from unpack start with offset 1
549   # yet another php mystery. array_merge work around 
550   # this broken behaviour
551   $v6vec = array_merge(unpack( "C16", $ipnum));
552
553   $offset = 0;
554   for ($depth = 127; $depth >= 0; --$depth) {
555     if ($gi->flags & GEOIP_MEMORY_CACHE) {
556       // workaround php's broken substr, strpos, etc handling with
557       // mbstring.func_overload and mbstring.internal_encoding
558       $enc = mb_internal_encoding();
559        mb_internal_encoding('ISO-8859-1'); 
560
561       $buf = substr($gi->memory_buffer,
562                             2 * $gi->record_length * $offset,
563                             2 * $gi->record_length);
564
565       mb_internal_encoding($enc);
566     } elseif ($gi->flags & GEOIP_SHARED_MEMORY) {
567       $buf = @shmop_read ($gi->shmid, 
568                             2 * $gi->record_length * $offset,
569                             2 * $gi->record_length );
570         } else {
571       fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0
572         or die("fseek failed");
573       $buf = fread($gi->filehandle, 2 * $gi->record_length);
574     }
575     $x = array(0,0);
576     for ($i = 0; $i < 2; ++$i) {
577       for ($j = 0; $j < $gi->record_length; ++$j) {
578         $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8);
579       }
580     }
581
582     $bnum = 127 - $depth;
583     $idx = $bnum >> 3;
584     $b_mask = 1 << ( $bnum & 7 ^ 7 );
585     if (($v6vec[$idx] & $b_mask) > 0) {
586       if ($x[1] >= $gi->databaseSegments) {
587         return $x[1];
588       }
589       $offset = $x[1];
590     } else {
591       if ($x[0] >= $gi->databaseSegments) {
592         return $x[0];
593       }
594       $offset = $x[0];
595     }
596   }
597   trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR);
598   return false;
599 }
600 } // function_exists
601
602 if( !function_exists( '_geoip_seek_country' ) ) {
603 function _geoip_seek_country($gi, $ipnum) {
604   $offset = 0;
605   for ($depth = 31; $depth >= 0; --$depth) {
606     if ($gi->flags & GEOIP_MEMORY_CACHE) {
607       // workaround php's broken substr, strpos, etc handling with
608       // mbstring.func_overload and mbstring.internal_encoding
609       $enc = mb_internal_encoding();
610        mb_internal_encoding('ISO-8859-1'); 
611
612       $buf = substr($gi->memory_buffer,
613                             2 * $gi->record_length * $offset,
614                             2 * $gi->record_length);
615
616       mb_internal_encoding($enc);
617     } elseif ($gi->flags & GEOIP_SHARED_MEMORY) {
618       $buf = @shmop_read ($gi->shmid, 
619                             2 * $gi->record_length * $offset,
620                             2 * $gi->record_length );
621         } else {
622       fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0
623         or die("fseek failed");
624       $buf = fread($gi->filehandle, 2 * $gi->record_length);
625     }
626     $x = array(0,0);
627     for ($i = 0; $i < 2; ++$i) {
628       for ($j = 0; $j < $gi->record_length; ++$j) {
629         $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8);
630       }
631     }
632     if ($ipnum & (1 << $depth)) {
633       if ($x[1] >= $gi->databaseSegments) {
634         return $x[1];
635       }
636       $offset = $x[1];
637         } else {
638       if ($x[0] >= $gi->databaseSegments) {
639         return $x[0];
640       }
641       $offset = $x[0];
642     }
643   }
644   trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR);
645   return false;
646 }
647 } // function_exists
648
649 if( !function_exists( '_common_get_org' ) ) {
650 function _common_get_org($gi, $seek_org){
651   $record_pointer = $seek_org + (2 * $gi->record_length - 1) * $gi->databaseSegments;
652   if ($gi->flags & GEOIP_SHARED_MEMORY) {
653     $org_buf = @shmop_read ($gi->shmid, $record_pointer, MAX_ORG_RECORD_LENGTH);
654     } else {
655     fseek($gi->filehandle, $record_pointer, SEEK_SET);
656     $org_buf = fread($gi->filehandle,MAX_ORG_RECORD_LENGTH);
657   }
658   // workaround php's broken substr, strpos, etc handling with
659   // mbstring.func_overload and mbstring.internal_encoding
660   $enc = mb_internal_encoding();
661   mb_internal_encoding('ISO-8859-1'); 
662   $org_buf = substr($org_buf, 0, strpos($org_buf, "\0"));
663   mb_internal_encoding($enc);
664   return $org_buf;
665 }
666 } // function_exists
667
668 if( !function_exists( '_get_org_v6' ) ) {
669 function _get_org_v6($gi,$ipnum){
670   $seek_org = _geoip_seek_country_v6($gi,$ipnum);
671   if ($seek_org == $gi->databaseSegments) {
672     return NULL;
673   }
674   return _common_get_org($gi, $seek_org);
675 }
676 } // function_exists
677
678 if( !function_exists( '_get_org' ) ) {
679 function _get_org($gi,$ipnum){
680   $seek_org = _geoip_seek_country($gi,$ipnum);
681   if ($seek_org == $gi->databaseSegments) {
682     return NULL;
683   }
684   return _common_get_org($gi, $seek_org);
685 }
686 } // function_exists
687
688
689
690 if( !function_exists( 'geoip_name_by_addr_v6' ) ) {
691 function geoip_name_by_addr_v6 ($gi,$addr) {
692   if ($addr == NULL) {
693     return 0;
694   }
695   $ipnum = inet_pton($addr);
696   return _get_org_v6($gi, $ipnum);
697 }
698 } // function_exists
699
700 if( !function_exists( 'geoip_name_by_addr' ) ) {
701 function geoip_name_by_addr ($gi,$addr) {
702   if ($addr == NULL) {
703     return 0;
704   }
705   $ipnum = ip2long($addr);
706   return _get_org($gi, $ipnum);
707 }
708 } // function_exists
709
710 if( !function_exists( 'geoip_org_by_addr' ) ) {
711 function geoip_org_by_addr ($gi,$addr) {
712   return geoip_name_by_addr($gi, $addr);
713 }
714 } // function_exists
715
716 if( !function_exists( '_get_region' ) ) {
717 function _get_region($gi,$ipnum){
718   if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
719     $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV0;
720     if ($seek_region >= 1000){
721       $country_code = "US";
722       $region = chr(($seek_region - 1000)/26 + 65) . chr(($seek_region - 1000)%26 + 65);
723     } else {
724             $country_code = $gi->GEOIP_COUNTRY_CODES[$seek_region];
725       $region = "";
726     }
727   return array ($country_code,$region);
728     }  else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1) {
729     $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV1;
730     //print $seek_region;
731     if ($seek_region < US_OFFSET){
732       $country_code = "";
733       $region = "";  
734         } else if ($seek_region < CANADA_OFFSET) {
735       $country_code = "US";
736       $region = chr(($seek_region - US_OFFSET)/26 + 65) . chr(($seek_region - US_OFFSET)%26 + 65);
737         } else if ($seek_region < WORLD_OFFSET) {
738       $country_code = "CA";
739       $region = chr(($seek_region - CANADA_OFFSET)/26 + 65) . chr(($seek_region - CANADA_OFFSET)%26 + 65);
740     } else {
741             $country_code = $gi->GEOIP_COUNTRY_CODES[($seek_region - WORLD_OFFSET) / FIPS_RANGE];
742       $region = "";
743     }
744   return array ($country_code,$region);
745   }
746 }
747 } // function_exists
748
749 if( !function_exists( 'geoip_region_by_addr' ) ) {
750 function geoip_region_by_addr ($gi,$addr) {
751   if ($addr == NULL) {
752     return 0;
753   }
754   $ipnum = ip2long($addr);
755   return _get_region($gi, $ipnum);
756 }
757 } // function_exists
758
759 if( !function_exists( 'getdnsattributes' ) ) {
760 function getdnsattributes ($l,$ip){
761   $r = new Net_DNS_Resolver();
762   $r->nameservers = array("ws1.maxmind.com");
763   $p = $r->search($l."." . $ip .".s.maxmind.com","TXT","IN");
764   $str = is_object($p->answer[0])?$p->answer[0]->string():'';
765   $str = substr( $str, 1, -1 );
766   return $str;
767 }
768 } // function_exists