| 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 | */␊ |
| 35 | define('GEOIP_COUNTRY_BEGIN', 16776960);␊ |
| 36 | define('GEOIP_STATE_BEGIN_REV0', 16700000);␊ |
| 37 | define('GEOIP_STATE_BEGIN_REV1', 16000000);␊ |
| 38 | define('GEOIP_STANDARD', 0);␊ |
| 39 | define('GEOIP_MEMORY_CACHE', 1);␊ |
| 40 | define('GEOIP_SHARED_MEMORY', 2);␊ |
| 41 | define('STRUCTURE_INFO_MAX_SIZE', 20);␊ |
| 42 | define('DATABASE_INFO_MAX_SIZE', 100);␊ |
| 43 | ␊ |
| 44 | define('GEOIP_COUNTRY_EDITION', 106);␊ |
| 45 | define('GEOIP_PROXY_EDITION', 8);␊ |
| 46 | define('GEOIP_ASNUM_EDITION', 9);␊ |
| 47 | define('GEOIP_NETSPEED_EDITION', 10);␊ |
| 48 | define('GEOIP_REGION_EDITION_REV0', 112);␊ |
| 49 | define('GEOIP_REGION_EDITION_REV1', 3);␊ |
| 50 | define('GEOIP_CITY_EDITION_REV0', 111);␊ |
| 51 | define('GEOIP_CITY_EDITION_REV1', 2);␊ |
| 52 | define('GEOIP_ORG_EDITION', 110);␊ |
| 53 | define('GEOIP_ISP_EDITION', 4);␊ |
| 54 | define('SEGMENT_RECORD_LENGTH', 3);␊ |
| 55 | define('STANDARD_RECORD_LENGTH', 3);␊ |
| 56 | define('ORG_RECORD_LENGTH', 4);␊ |
| 57 | define('MAX_RECORD_LENGTH', 4);␊ |
| 58 | define('MAX_ORG_RECORD_LENGTH', 300);␊ |
| 59 | define('GEOIP_SHM_KEY', 0x4f415401);␊ |
| 60 | define('US_OFFSET', 1);␊ |
| 61 | define('CANADA_OFFSET', 677);␊ |
| 62 | define('WORLD_OFFSET', 1353);␊ |
| 63 | define('FIPS_RANGE', 360);␊ |
| 64 | define('GEOIP_UNKNOWN_SPEED', 0);␊ |
| 65 | define('GEOIP_DIALUP_SPEED', 1);␊ |
| 66 | define('GEOIP_CABLEDSL_SPEED', 2);␊ |
| 67 | define('GEOIP_CORPORATE_SPEED', 3);␊ |
| 68 | ␊ |
| 69 | class 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 | ␊ |
| 239 | function 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 | ␊ |
| 257 | function _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 | ␊ |
| 340 | function 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 | ␊ |
| 357 | function GeoIP_close($gi) {␊ |
| 358 | if ($gi->flags & GEOIP_SHARED_MEMORY) {␊ |
| 359 | return true;␊ |
| 360 | }␊ |
| 361 | ␊ |
| 362 | return fclose($gi->filehandle);␊ |
| 363 | }␊ |
| 364 | ␊ |
| 365 | function 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 | ␊ |
| 373 | function 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 | ␊ |
| 381 | function 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 | ␊ |
| 389 | function GeoIP_country_id_by_addr($gi, $addr) {␊ |
| 390 | $ipnum = ip2long($addr);␊ |
| 391 | return _GeoIP_seek_country($gi, $ipnum) - GEOIP_COUNTRY_BEGIN;␊ |
| 392 | }␊ |
| 393 | ␊ |
| 394 | function 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 | ␊ |
| 407 | function 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 | ␊ |
| 420 | function _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 | ␊ |
| 458 | function _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 | ␊ |
| 474 | function 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 | ␊ |
| 482 | function _get_region($gi,$ipnum){␊ |
| 483 | if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){␊ |
| 484 | $seek_region = _GeoIP_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV0;␊ |
| 485 | if ($seek_region >= 1000){␊ |
| 486 | $country_code = "US";␊ |
| 487 | $region = chr(($seek_region - 1000)/26 + 65) . chr(($seek_region - 1000)%26 + 65);␊ |
| 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 | ␊ |
| 513 | function 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 | ␊ |
| 521 | function 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 | */␊ |
| 538 | function 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 | } |