1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ 2/* GeoIP.c 3 * 4 * Copyright (C) 2006 MaxMind LLC 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#include "GeoIP.h" 22 23static geoipv6_t IPV6_NULL; 24 25#if !defined(_WIN32) 26#include <unistd.h> 27#include <netdb.h> 28#include <sys/mman.h> 29#endif /* !defined(_WIN32) */ 30 31#include <errno.h> 32#include <stdio.h> 33#include <stdlib.h> 34#include <string.h> 35#include <assert.h> 36#include <sys/types.h> /* for fstat */ 37#include <sys/stat.h> /* for fstat */ 38 39#ifdef HAVE_GETTIMEOFDAY 40#include <sys/time.h> /* for gettimeofday */ 41#endif 42 43#ifdef HAVE_STDINT_H 44#include <stdint.h> /* For uint32_t */ 45#endif 46 47#ifdef _UNUSED 48#elif defined(__GNUC__) 49#define _UNUSED __attribute__ ((unused)) 50#else 51#define _UNUSED 52#endif 53 54#ifndef INADDR_NONE 55#define INADDR_NONE -1 56#endif 57 58#define COUNTRY_BEGIN 16776960 59#define LARGE_COUNTRY_BEGIN 16515072 60#define STATE_BEGIN_REV0 16700000 61#define STATE_BEGIN_REV1 16000000 62#define STRUCTURE_INFO_MAX_SIZE 20 63#define DATABASE_INFO_MAX_SIZE 100 64#define MAX_ORG_RECORD_LENGTH 300 65#define US_OFFSET 1 66#define CANADA_OFFSET 677 67#define WORLD_OFFSET 1353 68#define FIPS_RANGE 360 69 70#define CHECK_ERR(err, msg) { \ 71 if (err != Z_OK) { \ 72 fprintf(stderr, "%s error: %d\n", msg, err); \ 73 exit(1); \ 74 } \ 75} 76 77#ifndef HAVE_PREAD 78#define pread(fd, buf, count, offset) \ 79 ( \ 80 lseek(fd, offset, SEEK_SET) == offset ? \ 81 read(fd, buf, count) : \ 82 -1 \ 83 ) 84#endif /* HAVE_PREAD */ 85 86 87 88const char GeoIP_country_code[255][3] = { "--","AP","EU","AD","AE","AF","AG","AI","AL","AM","CW", 89 "AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB", 90 "BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO", 91 "BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD", 92 "CF","CG","CH","CI","CK","CL","CM","CN","CO","CR", 93 "CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO", 94 "DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ", 95 "FK","FM","FO","FR","SX","GA","GB","GD","GE","GF", 96 "GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT", 97 "GU","GW","GY","HK","HM","HN","HR","HT","HU","ID", 98 "IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO", 99 "JP","KE","KG","KH","KI","KM","KN","KP","KR","KW", 100 "KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT", 101 "LU","LV","LY","MA","MC","MD","MG","MH","MK","ML", 102 "MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV", 103 "MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI", 104 "NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF", 105 "PG","PH","PK","PL","PM","PN","PR","PS","PT","PW", 106 "PY","QA","RE","RO","RU","RW","SA","SB","SC","SD", 107 "SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO", 108 "SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH", 109 "TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW", 110 "TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE", 111 "VG","VI","VN","VU","WF","WS","YE","YT","RS","ZA", 112 "ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE", 113 "BL","MF", "BQ", "SS" }; 114 115static const unsigned num_GeoIP_countries = (unsigned)(sizeof(GeoIP_country_code)/sizeof(GeoIP_country_code[0])); 116 117const char GeoIP_country_code3[255][4] = { "--","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","CUW", 118 "AGO","ATA","ARG","ASM","AUT","AUS","ABW","AZE","BIH","BRB", 119 "BGD","BEL","BFA","BGR","BHR","BDI","BEN","BMU","BRN","BOL", 120 "BRA","BHS","BTN","BVT","BWA","BLR","BLZ","CAN","CCK","COD", 121 "CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI", 122 "CUB","CPV","CXR","CYP","CZE","DEU","DJI","DNK","DMA","DOM", 123 "DZA","ECU","EST","EGY","ESH","ERI","ESP","ETH","FIN","FJI", 124 "FLK","FSM","FRO","FRA","SXM","GAB","GBR","GRD","GEO","GUF", 125 "GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","SGS","GTM", 126 "GUM","GNB","GUY","HKG","HMD","HND","HRV","HTI","HUN","IDN", 127 "IRL","ISR","IND","IOT","IRQ","IRN","ISL","ITA","JAM","JOR", 128 "JPN","KEN","KGZ","KHM","KIR","COM","KNA","PRK","KOR","KWT", 129 "CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU", 130 "LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI", 131 "MMR","MNG","MAC","MNP","MTQ","MRT","MSR","MLT","MUS","MDV", 132 "MWI","MEX","MYS","MOZ","NAM","NCL","NER","NFK","NGA","NIC", 133 "NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER","PYF", 134 "PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW", 135 "PRY","QAT","REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN", 136 "SWE","SGP","SHN","SVN","SJM","SVK","SLE","SMR","SEN","SOM", 137 "SUR","STP","SLV","SYR","SWZ","TCA","TCD","ATF","TGO","THA", 138 "TJK","TKL","TKM","TUN","TON","TLS","TUR","TTO","TUV","TWN", 139 "TZA","UKR","UGA","UMI","USA","URY","UZB","VAT","VCT","VEN", 140 "VGB","VIR","VNM","VUT","WLF","WSM","YEM","MYT","SRB","ZAF", 141 "ZMB","MNE","ZWE","A1","A2","O1","ALA","GGY","IMN","JEY", 142 "BLM","MAF", "BES", "SSD" }; 143 144const char * GeoIP_utf8_country_name[255] = {"N/A","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Cura" "\xc3\xa7" "ao", 145 "Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados", 146 "Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia", 147 "Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the", 148 "Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica", 149 "Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic", 150 "Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji", 151 "Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","Sint Maarten (Dutch part)","Gabon","United Kingdom","Grenada","Georgia","French Guiana", 152 "Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala", 153 "Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia", 154 "Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan", 155 "Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait", 156 "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania", 157 "Luxembourg","Latvia","Libya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali", 158 "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives", 159 "Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua", 160 "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia", 161 "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau", 162 "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan", 163 "Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname", 164 "Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand", 165 "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan", 166 "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", 167 "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa", 168 "Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey", 169 "Saint Barthelemy","Saint Martin", "Bonaire, Saint Eustatius and Saba", "South Sudan"}; 170 171const char * GeoIP_country_name[255] = {"N/A","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Curacao", 172 "Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados", 173 "Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia", 174 "Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the", 175 "Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica", 176 "Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic", 177 "Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji", 178 "Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","Sint Maarten (Dutch part)","Gabon","United Kingdom","Grenada","Georgia","French Guiana", 179 "Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala", 180 "Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia", 181 "Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan", 182 "Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait", 183 "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania", 184 "Luxembourg","Latvia","Libya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali", 185 "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives", 186 "Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua", 187 "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia", 188 "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau", 189 "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan", 190 "Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname", 191 "Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand", 192 "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan", 193 "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", 194 "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa", 195 "Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey", 196 "Saint Barthelemy","Saint Martin", "Bonaire, Saint Eustatius and Saba", "South Sudan"}; 197 198/* Possible continent codes are AF, AS, EU, NA, OC, SA for Africa, Asia, Europe, North America, Oceania 199and South America. */ 200 201const char GeoIP_country_continent[255][3] = { 202 "--", "AS","EU","EU","AS","AS","NA","NA","EU","AS","NA", 203 "AF","AN","SA","OC","EU","OC","NA","AS","EU","NA", 204 "AS","EU","AF","EU","AS","AF","AF","NA","AS","SA", 205 "SA","NA","AS","AN","AF","EU","NA","NA","AS","AF", 206 "AF","AF","EU","AF","OC","SA","AF","AS","SA","NA", 207 "NA","AF","AS","AS","EU","EU","AF","EU","NA","NA", 208 "AF","SA","EU","AF","AF","AF","EU","AF","EU","OC", 209 "SA","OC","EU","EU","NA","AF","EU","NA","AS","SA", 210 "AF","EU","NA","AF","AF","NA","AF","EU","AN","NA", 211 "OC","AF","SA","AS","AN","NA","EU","NA","EU","AS", 212 "EU","AS","AS","AS","AS","AS","EU","EU","NA","AS", 213 "AS","AF","AS","AS","OC","AF","NA","AS","AS","AS", 214 "NA","AS","AS","AS","NA","EU","AS","AF","AF","EU", 215 "EU","EU","AF","AF","EU","EU","AF","OC","EU","AF", 216 "AS","AS","AS","OC","NA","AF","NA","EU","AF","AS", 217 "AF","NA","AS","AF","AF","OC","AF","OC","AF","NA", 218 "EU","EU","AS","OC","OC","OC","AS","NA","SA","OC", 219 "OC","AS","AS","EU","NA","OC","NA","AS","EU","OC", 220 "SA","AS","AF","EU","EU","AF","AS","OC","AF","AF", 221 "EU","AS","AF","EU","EU","EU","AF","EU","AF","AF", 222 "SA","AF","NA","AS","AF","NA","AF","AN","AF","AS", 223 "AS","OC","AS","AF","OC","AS","EU","NA","OC","AS", 224 "AF","EU","AF","OC","NA","SA","AS","EU","NA","SA", 225 "NA","NA","AS","OC","OC","OC","AS","AF","EU","AF", 226 "AF","EU","AF","--","--","--","EU","EU","EU","EU", 227 "NA","NA","NA", "AF" 228}; 229 230static const char * get_db_description(int dbtype){ 231 const char * ptr; 232 if ( dbtype >= NUM_DB_TYPES || dbtype < 0 ) 233 return "Unknown"; 234 ptr = GeoIPDBDescription[dbtype]; 235 return ptr == NULL ? "Unknown" : ptr; 236} 237 238geoipv6_t _GeoIP_lookupaddress_v6 (const char *host); 239 240#if defined(_WIN32) 241/* http://www.mail-archive.com/users@ipv6.org/msg02107.html */ 242static const char * _GeoIP_inet_ntop(int af, const void *src, char *dst, socklen_t cnt) 243{ 244 if (af == AF_INET) 245 { 246 struct sockaddr_in in; 247 memset(&in, 0, sizeof(in)); 248 in.sin_family = AF_INET; 249 memcpy(&in.sin_addr, src, sizeof(struct in_addr)); 250 getnameinfo((struct sockaddr *)&in, sizeof(struct 251sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST); 252 return dst; 253 } 254 else if (af == AF_INET6) 255 { 256 struct sockaddr_in6 in; 257 memset(&in, 0, sizeof(in)); 258 in.sin6_family = AF_INET6; 259 memcpy(&in.sin6_addr, src, sizeof(struct in_addr6)); 260 getnameinfo((struct sockaddr *)&in, sizeof(struct 261sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST); 262 return dst; 263 } 264 return NULL; 265} 266 267static int _GeoIP_inet_pton(int af, const char *src, void *dst) 268{ 269 struct addrinfo hints, *res, *ressave; 270 271 memset(&hints, 0, sizeof(struct addrinfo)); 272 hints.ai_family = af; 273 274 if (getaddrinfo(src, NULL, &hints, &res) != 0) 275 { 276 fprintf(stderr, "Couldn't resolve host %s\n", src); 277 return -1; 278 } 279 280 ressave = res; 281 282 while (res) 283 { 284 memcpy(dst, res->ai_addr, res->ai_addrlen); 285 res = res->ai_next; 286 } 287 288 freeaddrinfo(ressave); 289 return 0; 290} 291#else 292static int _GeoIP_inet_pton(int af, const char *src, void *dst) { 293 return inet_pton(af, src, dst); 294} 295static const char * _GeoIP_inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { 296 return inet_ntop(af, src, dst, cnt); 297} 298 299#endif /* defined(_WIN32) */ 300 301 302int __GEOIP_V6_IS_NULL(geoipv6_t v6) { 303 int i; 304 for (i=0;i<16;i++) { 305 if (v6.s6_addr[i]) 306 return 0; 307 } 308 return 1; 309} 310 311void __GEOIP_PREPARE_TEREDO(geoipv6_t* v6){ 312 int i; 313 if ((v6->s6_addr[0]) != 0x20) return; 314 if ((v6->s6_addr[1]) != 0x01) return; 315 if ((v6->s6_addr[2]) != 0x00) return; 316 if ((v6->s6_addr[3]) != 0x00) return; 317 318 for ( i = 0; i< 12; i++) 319 v6->s6_addr[i] = 0; 320 for ( ; i < 16; i++) 321 v6->s6_addr[i]^=0xff; 322} 323 324const char * GeoIPDBDescription[NUM_DB_TYPES] = { 325 NULL, 326 "GeoIP Country Edition", 327 "GeoIP City Edition, Rev 1", 328 "GeoIP Region Edition, Rev 1", 329 "GeoIP ISP Edition", 330 "GeoIP Organization Edition", 331 "GeoIP City Edition, Rev 0", 332 "GeoIP Region Edition, Rev 0", 333 "GeoIP Proxy Edition", 334 "GeoIP ASNum Edition", 335 "GeoIP Netspeed Edition", 336 "GeoIP Domain Name Edition", 337 "GeoIP Country V6 Edition", 338 "GeoIP LocationID ASCII Edition", 339 "GeoIP Accuracy Radius Edition", 340 NULL, 341 NULL, 342 "GeoIP Large Country Edition", 343 "GeoIP Large Country V6 Edition", 344 NULL, 345 "GeoIP CCM Edition", 346 "GeoIP ASNum V6 Edition", 347 "GeoIP ISP V6 Edition", 348 "GeoIP Organization V6 Edition", 349 "GeoIP Domain Name V6 Edition", 350 "GeoIP LocationID ASCII V6 Edition", 351 "GeoIP Registrar Edition", 352 "GeoIP Registrar V6 Edition", 353 "GeoIP UserType Edition", 354 "GeoIP UserType V6 Edition", 355 "GeoIP City Edition V6, Rev 1", 356 "GeoIP City Edition V6, Rev 0", 357 "GeoIP Netspeed Edition, Rev 1", 358 "GeoIP Netspeed Edition V6, Rev1", 359 "GeoIP Country Confidence Edition", 360 "GeoIP City Confidence Edition", 361 "GeoIP Region Confidence Edition", 362 "GeoIP Postal Confidence Edition", 363 "GeoIP Accuracy Radius Edition V6" 364}; 365 366char * GeoIP_custom_directory = NULL; 367 368void GeoIP_setup_custom_directory (char * dir) { 369 GeoIP_custom_directory = dir; 370} 371 372char *_GeoIP_full_path_to(const char *file_name) { 373 int len; 374 char *path = malloc(sizeof(char) * 1024); 375 376 if (GeoIP_custom_directory == NULL){ 377#if !defined(_WIN32) 378 memset(path, 0, sizeof(char) * 1024); 379 snprintf(path, sizeof(char) * 1024 - 1, "%s/%s", GEOIPDATADIR, file_name); 380#else 381 char buf[MAX_PATH], *p, *q = NULL; 382 memset(buf, 0, sizeof(buf)); 383 len = GetModuleFileNameA(GetModuleHandle(NULL), buf, sizeof(buf) - 1); 384 for (p = buf + len; p > buf; p--) 385 if (*p == '\\') 386 { 387 if (!q) 388 q = p; 389 else 390 *p = '/'; 391 } 392 *q = 0; 393 memset(path, 0, sizeof(char) * 1024); 394 snprintf(path, sizeof(char) * 1024 - 1, "%s/%s", buf, file_name); 395#endif 396 } else { 397 len = strlen(GeoIP_custom_directory); 398 if (GeoIP_custom_directory[len-1] != '/') { 399 snprintf(path, sizeof(char) * 1024 - 1, "%s/%s", GeoIP_custom_directory, file_name); 400 } else { 401 snprintf(path, sizeof(char) * 1024 - 1, "%s%s", GeoIP_custom_directory, file_name); 402 } 403 } 404 return path; 405} 406 407char ** GeoIPDBFileName = NULL; 408 409void _GeoIP_setup_dbfilename() { 410 if (NULL == GeoIPDBFileName) { 411 GeoIPDBFileName = malloc(sizeof(char *) * NUM_DB_TYPES); 412 memset(GeoIPDBFileName, 0, sizeof(char *) * NUM_DB_TYPES); 413 414 GeoIPDBFileName[GEOIP_COUNTRY_EDITION] = _GeoIP_full_path_to("GeoIP.dat"); 415 GeoIPDBFileName[GEOIP_REGION_EDITION_REV0] = _GeoIP_full_path_to("GeoIPRegion.dat"); 416 GeoIPDBFileName[GEOIP_REGION_EDITION_REV1] = _GeoIP_full_path_to("GeoIPRegion.dat"); 417 GeoIPDBFileName[GEOIP_CITY_EDITION_REV0] = _GeoIP_full_path_to("GeoIPCity.dat"); 418 GeoIPDBFileName[GEOIP_CITY_EDITION_REV1] = _GeoIP_full_path_to("GeoIPCity.dat"); 419 GeoIPDBFileName[GEOIP_ISP_EDITION] = _GeoIP_full_path_to("GeoIPISP.dat"); 420 GeoIPDBFileName[GEOIP_ORG_EDITION] = _GeoIP_full_path_to("GeoIPOrg.dat"); 421 GeoIPDBFileName[GEOIP_PROXY_EDITION] = _GeoIP_full_path_to("GeoIPProxy.dat"); 422 GeoIPDBFileName[GEOIP_ASNUM_EDITION] = _GeoIP_full_path_to("GeoIPASNum.dat"); 423 GeoIPDBFileName[GEOIP_NETSPEED_EDITION] = _GeoIP_full_path_to("GeoIPNetSpeed.dat"); 424 GeoIPDBFileName[GEOIP_DOMAIN_EDITION] = _GeoIP_full_path_to("GeoIPDomain.dat"); 425 GeoIPDBFileName[GEOIP_COUNTRY_EDITION_V6] = _GeoIP_full_path_to("GeoIPv6.dat"); 426 GeoIPDBFileName[GEOIP_LOCATIONA_EDITION] = _GeoIP_full_path_to("GeoIPLocA.dat"); 427 GeoIPDBFileName[GEOIP_ACCURACYRADIUS_EDITION] = _GeoIP_full_path_to("GeoIPDistance.dat"); 428 GeoIPDBFileName[GEOIP_LARGE_COUNTRY_EDITION] = _GeoIP_full_path_to("GeoIP.dat"); 429 GeoIPDBFileName[GEOIP_LARGE_COUNTRY_EDITION_V6] = _GeoIP_full_path_to("GeoIPv6.dat"); 430 GeoIPDBFileName[GEOIP_ASNUM_EDITION_V6] = _GeoIP_full_path_to("GeoIPASNumv6.dat"); 431 GeoIPDBFileName[GEOIP_ISP_EDITION_V6] = _GeoIP_full_path_to("GeoIPISPv6.dat"); 432 GeoIPDBFileName[GEOIP_ORG_EDITION_V6] = _GeoIP_full_path_to("GeoIPOrgv6.dat"); 433 GeoIPDBFileName[GEOIP_DOMAIN_EDITION_V6] = _GeoIP_full_path_to("GeoIPDomainv6.dat"); 434 GeoIPDBFileName[GEOIP_LOCATIONA_EDITION_V6] = _GeoIP_full_path_to("GeoIPLocAv6.dat"); 435 GeoIPDBFileName[GEOIP_REGISTRAR_EDITION] = _GeoIP_full_path_to("GeoIPRegistrar.dat"); 436 GeoIPDBFileName[GEOIP_REGISTRAR_EDITION_V6] = _GeoIP_full_path_to("GeoIPRegistrarv6.dat"); 437 GeoIPDBFileName[GEOIP_USERTYPE_EDITION] = _GeoIP_full_path_to("GeoIPUserType.dat"); 438 GeoIPDBFileName[GEOIP_USERTYPE_EDITION_V6] = _GeoIP_full_path_to("GeoIPUserTypev6.dat"); 439 GeoIPDBFileName[GEOIP_CITY_EDITION_REV0_V6] = _GeoIP_full_path_to("GeoIPCityv6.dat"); 440 GeoIPDBFileName[GEOIP_CITY_EDITION_REV1_V6] = _GeoIP_full_path_to("GeoIPCityv6.dat"); 441 GeoIPDBFileName[GEOIP_NETSPEED_EDITION_REV1] = _GeoIP_full_path_to("GeoIPNetSpeedCell.dat"); 442 GeoIPDBFileName[GEOIP_NETSPEED_EDITION_REV1_V6] = _GeoIP_full_path_to("GeoIPNetSpeedCellv6.dat"); 443 GeoIPDBFileName[GEOIP_COUNTRYCONF_EDITION] = _GeoIP_full_path_to("GeoIPCountryConf.dat"); 444 GeoIPDBFileName[GEOIP_CITYCONF_EDITION] = _GeoIP_full_path_to("GeoIPCityConf.dat"); 445 GeoIPDBFileName[GEOIP_REGIONCONF_EDITION] = _GeoIP_full_path_to("GeoIPRegionConf.dat"); 446 GeoIPDBFileName[GEOIP_POSTALCONF_EDITION] = _GeoIP_full_path_to("GeoIPPostalConf.dat"); 447 GeoIPDBFileName[GEOIP_ACCURACYRADIUS_EDITION_V6] = _GeoIP_full_path_to("GeoIPDistancev6.dat"); 448 } 449} 450 451static 452int _file_exists(const char *file_name) { 453 struct stat file_stat; 454 return( (stat(file_name, &file_stat) == 0) ? 1:0); 455} 456 457char * _GeoIP_iso_8859_1__utf8(const char * iso) { 458 signed char c; 459 char k; 460 char * p; 461 char * t = (char *)iso; 462 int len = 0; 463 while ( ( c = *t++) ){ 464 if ( c < 0 ) 465 len++; 466 } 467 len += t - iso; 468 t = p = malloc( len ); 469 470 if ( p ){ 471 while ( ( c = *iso++ ) ) { 472 if (c < 0 ) { 473 k = 0xc2; 474 if (c >= -64 ) 475 k++; 476 *t++ = k; 477 c &= ~0x40; 478 } 479 *t++ = c; 480 } 481 *t++ = 0x00; 482 } 483 return p; 484} 485 486int GeoIP_is_private_ipnum_v4( unsigned long ipnum ){ 487return ((ipnum >= 167772160U && ipnum <= 184549375U) 488 || (ipnum >= 2851995648U && ipnum <= 2852061183U) 489 || (ipnum >= 2886729728U && ipnum <= 2887778303U) 490 || (ipnum >= 3232235520U && ipnum <= 3232301055U) 491 || (ipnum >= 2130706432U && ipnum <= 2147483647U))? 1 : 0; 492} 493 494int GeoIP_is_private_v4( const char * addr ){ 495 unsigned long ipnum = GeoIP_addr_to_num(addr); 496 return GeoIP_is_private_ipnum_v4(ipnum); 497} 498 499int GeoIP_db_avail(int type) { 500 const char * filePath; 501 if (type < 0 || type >= NUM_DB_TYPES) { 502 return 0; 503 } 504 _GeoIP_setup_dbfilename(); 505 filePath = GeoIPDBFileName[type]; 506 if (NULL == filePath) { 507 return 0; 508 } 509 return _file_exists(filePath); 510} 511 512static int _database_has_content( int database_type ){ 513 return ((database_type != GEOIP_COUNTRY_EDITION 514 && database_type != GEOIP_PROXY_EDITION 515 && database_type != GEOIP_NETSPEED_EDITION 516 && database_type != GEOIP_COUNTRY_EDITION_V6 517 && database_type != GEOIP_LARGE_COUNTRY_EDITION 518 && database_type != GEOIP_LARGE_COUNTRY_EDITION_V6 519 && database_type != GEOIP_REGION_EDITION_REV0 520 && database_type != GEOIP_REGION_EDITION_REV1) ? 1 : 0 ); 521} 522 523static 524void _setup_segments(GeoIP * gi) { 525 int i, j, segment_record_length; 526 unsigned char delim[3]; 527 unsigned char buf[LARGE_SEGMENT_RECORD_LENGTH]; 528 ssize_t silence _UNUSED; 529 int fno = fileno(gi->GeoIPDatabase); 530 531 gi->databaseSegments = NULL; 532 533 /* default to GeoIP Country Edition */ 534 gi->databaseType = GEOIP_COUNTRY_EDITION; 535 gi->record_length = STANDARD_RECORD_LENGTH; 536 lseek(fno, -3l, SEEK_END); 537 for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) { 538 silence = read(fno, delim, 3); 539 if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) { 540 silence = read(fno, &gi->databaseType, 1 ); 541 if (gi->databaseType >= 106) { 542 /* backwards compatibility with databases from April 2003 and earlier */ 543 gi->databaseType -= 105; 544 } 545 546 if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { 547 /* Region Edition, pre June 2003 */ 548 gi->databaseSegments = malloc(sizeof(int)); 549 gi->databaseSegments[0] = STATE_BEGIN_REV0; 550 } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { 551 /* Region Edition, post June 2003 */ 552 gi->databaseSegments = malloc(sizeof(int)); 553 gi->databaseSegments[0] = STATE_BEGIN_REV1; 554 } else if (gi->databaseType == GEOIP_CITY_EDITION_REV0 || 555 gi->databaseType == GEOIP_CITY_EDITION_REV1 || 556 gi->databaseType == GEOIP_ORG_EDITION || 557 gi->databaseType == GEOIP_ORG_EDITION_V6 || 558 gi->databaseType == GEOIP_DOMAIN_EDITION || 559 gi->databaseType == GEOIP_DOMAIN_EDITION_V6 || 560 gi->databaseType == GEOIP_ISP_EDITION || 561 gi->databaseType == GEOIP_ISP_EDITION_V6 || 562 gi->databaseType == GEOIP_REGISTRAR_EDITION || 563 gi->databaseType == GEOIP_REGISTRAR_EDITION_V6 || 564 gi->databaseType == GEOIP_USERTYPE_EDITION || 565 gi->databaseType == GEOIP_USERTYPE_EDITION_V6 || 566 gi->databaseType == GEOIP_ASNUM_EDITION || 567 gi->databaseType == GEOIP_ASNUM_EDITION_V6 || 568 gi->databaseType == GEOIP_NETSPEED_EDITION_REV1 || 569 gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6 || 570 gi->databaseType == GEOIP_LOCATIONA_EDITION || 571 gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION || 572 gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION_V6 || 573 gi->databaseType == GEOIP_CITY_EDITION_REV0_V6 || 574 gi->databaseType == GEOIP_CITY_EDITION_REV1_V6 || 575 gi->databaseType == GEOIP_CITYCONF_EDITION || 576 gi->databaseType == GEOIP_COUNTRYCONF_EDITION || 577 gi->databaseType == GEOIP_REGIONCONF_EDITION || 578 gi->databaseType == GEOIP_POSTALCONF_EDITION 579 ) { 580 /* City/Org Editions have two segments, read offset of second segment */ 581 gi->databaseSegments = malloc(sizeof(int)); 582 gi->databaseSegments[0] = 0; 583 584 segment_record_length = SEGMENT_RECORD_LENGTH; 585 586 silence = read(fno, buf, segment_record_length ); 587 for (j = 0; j < segment_record_length; j++) { 588 gi->databaseSegments[0] += (buf[j] << (j * 8)); 589 } 590 591 /* the record_length must be correct from here on */ 592 if (gi->databaseType == GEOIP_ORG_EDITION || 593 gi->databaseType == GEOIP_ORG_EDITION_V6 || 594 gi->databaseType == GEOIP_DOMAIN_EDITION || 595 gi->databaseType == GEOIP_DOMAIN_EDITION_V6 || 596 gi->databaseType == GEOIP_ISP_EDITION || 597 gi->databaseType == GEOIP_ISP_EDITION_V6 ) 598 gi->record_length = ORG_RECORD_LENGTH; 599 } 600 break; 601 } else { 602 lseek(fno, -4l, SEEK_CUR); 603 } 604 } 605 if (gi->databaseType == GEOIP_COUNTRY_EDITION || 606 gi->databaseType == GEOIP_PROXY_EDITION || 607 gi->databaseType == GEOIP_NETSPEED_EDITION || 608 gi->databaseType == GEOIP_COUNTRY_EDITION_V6 ) { 609 gi->databaseSegments = malloc(sizeof(int)); 610 gi->databaseSegments[0] = COUNTRY_BEGIN; 611 } 612 else if ( gi->databaseType == GEOIP_LARGE_COUNTRY_EDITION || 613 gi->databaseType == GEOIP_LARGE_COUNTRY_EDITION_V6 ) { 614 gi->databaseSegments = malloc(sizeof(int)); 615 gi->databaseSegments[0] = LARGE_COUNTRY_BEGIN; 616 } 617 618} 619 620static 621int _check_mtime(GeoIP *gi) { 622 struct stat buf; 623 unsigned int idx_size; 624 625#if !defined(_WIN32) 626 struct timeval t; 627#else /* !defined(_WIN32) */ 628 FILETIME ft; 629 ULONGLONG t; 630#endif /* !defined(_WIN32) */ 631 632 if (gi->flags & GEOIP_CHECK_CACHE) { 633 634#if !defined(_WIN32) 635 /* stat only has second granularity, so don't 636 * call it more than once a second */ 637 gettimeofday(&t, NULL); 638 if (t.tv_sec == gi->last_mtime_check){ 639 return 0; 640 } 641 gi->last_mtime_check = t.tv_sec; 642 643#else /* !defined(_WIN32) */ 644 645 /* stat only has second granularity, so don't 646 call it more than once a second */ 647 GetSystemTimeAsFileTime(&ft); 648 t = FILETIME_TO_USEC(ft) / 1000 / 1000; 649 if (t == gi->last_mtime_check){ 650 return 0; 651 } 652 gi->last_mtime_check = t; 653 654#endif /* !defined(_WIN32) */ 655 656 if (stat(gi->file_path, &buf) != -1) { 657 /* make sure that the database file is at least 60 658 * seconds untouched. Otherwise we might load the 659 * database only partly and crash 660 */ 661 if (buf.st_mtime != gi->mtime && ( buf.st_mtime + 60 < gi->last_mtime_check ) ) { 662 /* GeoIP Database file updated */ 663 if (gi->flags & (GEOIP_MEMORY_CACHE | GEOIP_MMAP_CACHE)) { 664 if ( gi->flags & GEOIP_MMAP_CACHE) { 665#if !defined(_WIN32) 666 /* MMAP is only avail on UNIX */ 667 munmap(gi->cache, gi->size); 668 gi->cache = NULL; 669#endif 670 } else { 671 /* reload database into memory cache */ 672 if ((gi->cache = (unsigned char*) realloc(gi->cache, buf.st_size)) == NULL) { 673 fprintf(stderr,"Out of memory when reloading %s\n",gi->file_path); 674 return -1; 675 } 676 } 677 } 678 /* refresh filehandle */ 679 fclose(gi->GeoIPDatabase); 680 gi->GeoIPDatabase = fopen(gi->file_path,"rb"); 681 if (gi->GeoIPDatabase == NULL) { 682 fprintf(stderr,"Error Opening file %s when reloading\n",gi->file_path); 683 return -1; 684 } 685 gi->mtime = buf.st_mtime; 686 gi->size = buf.st_size; 687 688 if ( gi->flags & GEOIP_MMAP_CACHE) { 689#if defined(_WIN32) 690 fprintf(stderr, "GEOIP_MMAP_CACHE is not supported on WIN32\n"); 691 gi->cache = 0; 692 return -1; 693#else 694 gi->cache = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fileno(gi->GeoIPDatabase), 0); 695 if ( gi->cache == MAP_FAILED ) { 696 697 fprintf(stderr,"Error remapping file %s when reloading\n",gi->file_path); 698 699 gi->cache = NULL; 700 return -1; 701 } 702#endif 703 } else if ( gi->flags & GEOIP_MEMORY_CACHE ) { 704 if (pread(fileno(gi->GeoIPDatabase), gi->cache, buf.st_size, 0) != (ssize_t) buf.st_size) { 705 fprintf(stderr,"Error reading file %s when reloading\n",gi->file_path); 706 return -1; 707 } 708 } 709 710 if (gi->databaseSegments != NULL) { 711 free(gi->databaseSegments); 712 gi->databaseSegments = NULL; 713 } 714 _setup_segments(gi); 715 if (gi->databaseSegments == NULL) { 716 fprintf(stderr, "Error reading file %s -- corrupt\n", gi->file_path); 717 return -1; 718 } 719 720 /* make sure the index is <= file size 721 * This test makes sense for all modes - not 722 * only index 723 */ 724 idx_size = _database_has_content(gi->databaseType) ? gi->databaseSegments[0] * (long)gi->record_length * 2 : buf.st_size; 725 if ( idx_size > buf.st_size ){ 726 fprintf(stderr, "Error file %s -- corrupt\n", gi->file_path); 727 return -1; 728 } 729 730 if (gi->flags & GEOIP_INDEX_CACHE) { 731 gi->index_cache = (unsigned char *) realloc(gi->index_cache, sizeof(unsigned char) * idx_size ); 732 if (gi->index_cache != NULL) { 733 if (pread(fileno(gi->GeoIPDatabase), gi->index_cache, 734 idx_size, 0 ) != (ssize_t) idx_size) { 735 fprintf(stderr,"Error reading file %s where reloading\n",gi->file_path); 736 return -1; 737 } 738 } 739 } 740 } 741 } 742 } 743 return 0; 744} 745 746#define ADDR_STR_LEN (8 * 4 + 7 + 1) 747unsigned int _GeoIP_seek_record_v6_gl (GeoIP *gi, geoipv6_t ipnum, GeoIPLookup * gl) { 748 int depth; 749 char paddr[ADDR_STR_LEN]; 750 unsigned int x; 751 unsigned char stack_buffer[2 * MAX_RECORD_LENGTH]; 752 const unsigned char *buf = (gi->cache == NULL) ? stack_buffer : NULL; 753 unsigned int offset = 0; 754 755 const unsigned char * p; 756 int j; 757 ssize_t silence _UNUSED; 758 int fno = fileno(gi->GeoIPDatabase); 759 _check_mtime(gi); 760 if ( GeoIP_teredo(gi) ) 761 __GEOIP_PREPARE_TEREDO(&ipnum); 762 for (depth = 127; depth >= 0; depth--) { 763 if (gi->cache == NULL && gi->index_cache == NULL) { 764 /* read from disk */ 765 silence = pread(fno, stack_buffer,gi->record_length * 2, (long)gi->record_length * 2 * offset ); 766 } else if (gi->index_cache == NULL) { 767 /* simply point to record in memory */ 768 buf = gi->cache + (long)gi->record_length * 2 *offset; 769 } else { 770 buf = gi->index_cache + (long)gi->record_length * 2 * offset; 771 } 772 773 if (GEOIP_CHKBIT_V6(depth, ipnum.s6_addr )) { 774 /* Take the right-hand branch */ 775 if ( gi->record_length == 3 ) { 776 /* Most common case is completely unrolled and uses constants. */ 777 x = (buf[3*1 + 0] << (0*8)) 778 + (buf[3*1 + 1] << (1*8)) 779 + (buf[3*1 + 2] << (2*8)); 780 781 } else { 782 /* General case */ 783 j = gi->record_length; 784 p = &buf[2*j]; 785 x = 0; 786 do { 787 x <<= 8; 788 x += *(--p); 789 } while ( --j ); 790 } 791 792 } else { 793 /* Take the left-hand branch */ 794 if ( gi->record_length == 3 ) { 795 /* Most common case is completely unrolled and uses constants. */ 796 x = (buf[3*0 + 0] << (0*8)) 797 + (buf[3*0 + 1] << (1*8)) 798 + (buf[3*0 + 2] << (2*8)); 799 } else { 800 /* General case */ 801 j = gi->record_length; 802 p = &buf[1*j]; 803 x = 0; 804 do { 805 x <<= 8; 806 x += *(--p); 807 } while ( --j ); 808 } 809 } 810 811 if (x >= gi->databaseSegments[0]) { 812 gi->netmask = gl->netmask = 128 - depth; 813 return x; 814 } 815 offset = x; 816 } 817 818 /* shouldn't reach here */ 819 _GeoIP_inet_ntop(AF_INET6, &ipnum.s6_addr[0], paddr, ADDR_STR_LEN); 820 fprintf(stderr,"Error Traversing Database for ipnum = %s - Perhaps database is corrupt?\n", paddr); 821 return 0; 822} 823 824geoipv6_t 825_GeoIP_addr_to_num_v6(const char *addr) 826{ 827 geoipv6_t ipnum; 828 if ( 1 == _GeoIP_inet_pton(AF_INET6, addr, &ipnum.s6_addr[0] ) ) 829 return ipnum; 830 return IPV6_NULL; 831} 832 833 834unsigned int _GeoIP_seek_record_gl (GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { 835 int depth; 836 unsigned int x; 837 unsigned char stack_buffer[2 * MAX_RECORD_LENGTH]; 838 const unsigned char *buf = (gi->cache == NULL) ? stack_buffer : NULL; 839 unsigned int offset = 0; 840 ssize_t silence _UNUSED; 841 842 const unsigned char * p; 843 int j; 844 int fno = fileno(gi->GeoIPDatabase); 845 _check_mtime(gi); 846 for (depth = 31; depth >= 0; depth--) { 847 if (gi->cache == NULL && gi->index_cache == NULL) { 848 /* read from disk */ 849 silence = pread(fno, stack_buffer, gi->record_length * 2, gi->record_length * 2 * offset); 850 } else if (gi->index_cache == NULL) { 851 /* simply point to record in memory */ 852 buf = gi->cache + (long)gi->record_length * 2 *offset; 853 } else { 854 buf = gi->index_cache + (long)gi->record_length * 2 * offset; 855 } 856 857 if (ipnum & (1 << depth)) { 858 /* Take the right-hand branch */ 859 if ( gi->record_length == 3 ) { 860 /* Most common case is completely unrolled and uses constants. */ 861 x = (buf[3*1 + 0] << (0*8)) 862 + (buf[3*1 + 1] << (1*8)) 863 + (buf[3*1 + 2] << (2*8)); 864 865 } else { 866 /* General case */ 867 j = gi->record_length; 868 p = &buf[2*j]; 869 x = 0; 870 do { 871 x <<= 8; 872 x += *(--p); 873 } while ( --j ); 874 } 875 876 } else { 877 /* Take the left-hand branch */ 878 if ( gi->record_length == 3 ) { 879 /* Most common case is completely unrolled and uses constants. */ 880 x = (buf[3*0 + 0] << (0*8)) 881 + (buf[3*0 + 1] << (1*8)) 882 + (buf[3*0 + 2] << (2*8)); 883 } else { 884 /* General case */ 885 j = gi->record_length; 886 p = &buf[1*j]; 887 x = 0; 888 do { 889 x <<= 8; 890 x += *(--p); 891 } while ( --j ); 892 } 893 } 894 895 if (x >= gi->databaseSegments[0]) { 896 gi->netmask = gl->netmask = 32 - depth; 897 return x; 898 } 899 offset = x; 900 } 901 /* shouldn't reach here */ 902 fprintf(stderr,"Error Traversing Database for ipnum = %lu - Perhaps database is corrupt?\n",ipnum); 903 return 0; 904} 905 906unsigned long 907GeoIP_addr_to_num(const char *addr) 908{ 909 unsigned int c, octet, t; 910 unsigned long ipnum; 911 int i = 3; 912 913 octet = ipnum = 0; 914 while ((c = *addr++)) { 915 if (c == '.') { 916 if (octet > 255) 917 return 0; 918 ipnum <<= 8; 919 ipnum += octet; 920 i--; 921 octet = 0; 922 } else { 923 t = octet; 924 octet <<= 3; 925 octet += t; 926 octet += t; 927 c -= '0'; 928 if (c > 9) 929 return 0; 930 octet += c; 931 } 932 } 933 if ((octet > 255) || (i != 0)) 934 return 0; 935 ipnum <<= 8; 936 return ipnum + octet; 937} 938 939GeoIP* GeoIP_open_type (int type, int flags) { 940 GeoIP * gi; 941 const char * filePath; 942 if (type < 0 || type >= NUM_DB_TYPES) { 943 printf("Invalid database type %d\n", type); 944 return NULL; 945 } 946 _GeoIP_setup_dbfilename(); 947 filePath = GeoIPDBFileName[type]; 948 if (filePath == NULL) { 949 printf("Invalid database type %d\n", type); 950 return NULL; 951 } 952 gi = GeoIP_open (filePath, flags); 953 954 if ( gi ){ 955 /* make sure this is the requested database type */ 956 int database_type = gi->databaseType ; 957 if ( database_type > 105 ) 958 database_type -= 105; 959 /* type must match, but we accept org and asnum, 960 * since domain and *conf database have always the wrong type 961 * for historical reason. Maybe we fix it at some point. 962 */ 963 if ( database_type == type 964 || database_type == GEOIP_ASNUM_EDITION 965 || database_type == GEOIP_ORG_EDITION ) 966 return gi; 967 GeoIP_delete(gi); 968 } 969 970 return NULL; 971} 972 973GeoIP* GeoIP_new (int flags) { 974 GeoIP * gi; 975 _GeoIP_setup_dbfilename(); 976 gi = GeoIP_open (GeoIPDBFileName[GEOIP_COUNTRY_EDITION], flags); 977 return gi; 978} 979 980GeoIP* GeoIP_open (const char * filename, int flags) { 981 struct stat buf; 982 unsigned int idx_size; 983 GeoIP * gi; 984 size_t len; 985 986 gi = (GeoIP *)malloc(sizeof(GeoIP)); 987 if (gi == NULL) 988 return NULL; 989 len = sizeof(char) * (strlen(filename)+1); 990 gi->file_path = malloc(len); 991 if (gi->file_path == NULL) { 992 free(gi); 993 return NULL; 994 } 995 strncpy(gi->file_path, filename, len); 996 gi->GeoIPDatabase = fopen(filename,"rb"); 997 if (gi->GeoIPDatabase == NULL) { 998 fprintf(stderr,"Error Opening file %s\n",filename); 999 free(gi->file_path); 1000 free(gi); 1001 return NULL; 1002 } else { 1003 if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) { 1004 fprintf(stderr,"Error stating file %s\n",filename); 1005 free(gi->file_path); 1006 free(gi); 1007 return NULL; 1008 } 1009 if (flags & (GEOIP_MEMORY_CACHE | GEOIP_MMAP_CACHE) ) { 1010 gi->mtime = buf.st_mtime; 1011 gi->size = buf.st_size; 1012 1013 /* MMAP added my Peter Shipley */ 1014 if ( flags & GEOIP_MMAP_CACHE ) { 1015#if !defined(_WIN32) 1016 gi->cache = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fileno(gi->GeoIPDatabase), 0); 1017 if ( gi->cache == MAP_FAILED ) { 1018 fprintf(stderr,"Error mmaping file %s\n",filename); 1019 free(gi->file_path); 1020 free(gi); 1021 return NULL; 1022 } 1023#endif 1024 } else { 1025 gi->cache = (unsigned char *) malloc(sizeof(unsigned char) * buf.st_size); 1026 1027 if (gi->cache != NULL) { 1028 if (pread(fileno(gi->GeoIPDatabase),gi->cache, buf.st_size, 0) != (ssize_t) buf.st_size) { 1029 fprintf(stderr,"Error reading file %s\n",filename); 1030 free(gi->cache); 1031 free(gi->file_path); 1032 free(gi); 1033 return NULL; 1034 } 1035 } 1036 } 1037 } else { 1038 if (flags & GEOIP_CHECK_CACHE) { 1039 if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) { 1040 fprintf(stderr,"Error stating file %s\n",filename); 1041 free(gi->file_path); 1042 free(gi); 1043 return NULL; 1044 } 1045 gi->mtime = buf.st_mtime; 1046 } 1047 gi->cache = NULL; 1048 } 1049 gi->flags = flags; 1050 gi->charset = GEOIP_CHARSET_ISO_8859_1; 1051 gi->ext_flags = 1U << GEOIP_TEREDO_BIT; 1052 _setup_segments(gi); 1053 1054 idx_size = _database_has_content(gi->databaseType) ? gi->databaseSegments[0] * (long)gi->record_length * 2 : buf.st_size; 1055 1056 /* make sure the index is <= file size */ 1057 if ( idx_size > buf.st_size ){ 1058 fprintf(stderr, "Error file %s -- corrupt\n", gi->file_path); 1059 if (flags & GEOIP_MEMORY_CACHE) { 1060 free(gi->cache); 1061 } 1062#if !defined(_WIN32) 1063 else if ( flags & GEOIP_MMAP_CACHE) { 1064 /* MMAP is only avail on UNIX */ 1065 munmap(gi->cache, gi->size); 1066 gi->cache = NULL; 1067 } 1068#endif 1069 free(gi->file_path); 1070 free(gi); 1071 return NULL; 1072 } 1073 1074 if (flags & GEOIP_INDEX_CACHE) { 1075 gi->index_cache = (unsigned char *) malloc(sizeof(unsigned char) * idx_size); 1076 if (gi->index_cache != NULL) { 1077 if (pread(fileno(gi->GeoIPDatabase),gi->index_cache, idx_size, 0) != idx_size ) { 1078 fprintf(stderr,"Error reading file %s\n",filename); 1079 free(gi->databaseSegments); 1080 free(gi->index_cache); 1081 free(gi); 1082 return NULL; 1083 } 1084 } 1085 } else { 1086 gi->index_cache = NULL; 1087 } 1088 return gi; 1089 } 1090} 1091 1092void GeoIP_delete (GeoIP *gi) { 1093 if (gi == NULL ) 1094 return; 1095 if (gi->GeoIPDatabase != NULL) 1096 fclose(gi->GeoIPDatabase); 1097 if (gi->cache != NULL) { 1098 if ( gi->flags & GEOIP_MMAP_CACHE ) { 1099#if !defined(_WIN32) 1100 munmap(gi->cache, gi->size); 1101#endif 1102 } else { 1103 free(gi->cache); 1104 } 1105 gi->cache = NULL; 1106 } 1107 if (gi->index_cache != NULL) 1108 free(gi->index_cache); 1109 if (gi->file_path != NULL) 1110 free(gi->file_path); 1111 if (gi->databaseSegments != NULL) 1112 free(gi->databaseSegments); 1113 free(gi); 1114} 1115 1116const char *GeoIP_country_code_by_name_v6_gl (GeoIP* gi, const char *name, GeoIPLookup * gl) { 1117 int country_id; 1118 country_id = GeoIP_id_by_name_v6_gl(gi, name, gl); 1119 return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; 1120} 1121 1122const char *GeoIP_country_code_by_name_gl (GeoIP* gi, const char *name, GeoIPLookup * gl) { 1123 int country_id; 1124 country_id = GeoIP_id_by_name_gl(gi, name, gl); 1125 return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; 1126} 1127 1128const char *GeoIP_country_code3_by_name_v6_gl (GeoIP* gi, const char *name, GeoIPLookup * gl) { 1129 int country_id; 1130 country_id = GeoIP_id_by_name_v6_gl(gi, name, gl); 1131 return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; 1132} 1133 1134const char *GeoIP_country_code3_by_name_gl (GeoIP* gi, const char *name, GeoIPLookup * gl) { 1135 int country_id; 1136 country_id = GeoIP_id_by_name_gl(gi, name, gl); 1137 return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; 1138} 1139 1140const char *GeoIP_country_name_by_name_v6_gl (GeoIP* gi, const char *name, GeoIPLookup * gl) { 1141 int country_id; 1142 country_id = GeoIP_id_by_name_v6_gl(gi, name, gl); 1143 return GeoIP_country_name_by_id(gi, country_id ); 1144} 1145 1146const char *GeoIP_country_name_by_name_gl (GeoIP* gi, const char *name, GeoIPLookup * gl) { 1147 int country_id; 1148 country_id = GeoIP_id_by_name_gl(gi, name, gl); 1149 return GeoIP_country_name_by_id(gi, country_id ); 1150} 1151 1152unsigned long _GeoIP_lookupaddress (const char *host) { 1153 unsigned long addr = inet_addr(host); 1154 struct hostent phe2; 1155 struct hostent * phe = &phe2; 1156 char *buf = NULL; 1157#ifdef HAVE_GETHOSTBYNAME_R 1158 int buflength = 16384; 1159 int herr = 0; 1160#endif 1161 int result = 0; 1162#ifdef HAVE_GETHOSTBYNAME_R 1163 buf = malloc(buflength); 1164#endif 1165 if (addr == INADDR_NONE) { 1166#ifdef HAVE_GETHOSTBYNAME_R 1167 while (1) { 1168 /* we use gethostbyname_r here because it is thread-safe and gethostbyname is not */ 1169#ifdef GETHOSTBYNAME_R_RETURNS_INT 1170 result = gethostbyname_r(host,&phe2,buf,buflength,&phe,&herr); 1171#else 1172 phe = gethostbyname_r(host,&phe2,buf,buflength,&herr); 1173#endif 1174 if (herr != ERANGE) 1175 break; 1176 if (result == 0) 1177 break; 1178 /* double the buffer if the buffer is too small */ 1179 buflength = buflength * 2; 1180 buf = realloc(buf,buflength); 1181 } 1182#else 1183 /* Some systems do not support gethostbyname_r, such as Mac OS X */ 1184 phe = gethostbyname(host); 1185#endif 1186 if (!phe || result != 0) { 1187 free(buf); 1188 return 0; 1189 } 1190#if !defined(_WIN32) 1191 addr = *((in_addr_t *) phe->h_addr_list[0]); 1192#else 1193 addr = ((IN_ADDR *) phe->h_addr_list[0])->S_un.S_addr; 1194#endif 1195 } 1196#ifdef HAVE_GETHOSTBYNAME_R 1197 free(buf); 1198#endif 1199 return ntohl(addr); 1200} 1201 1202geoipv6_t 1203_GeoIP_lookupaddress_v6(const char *host) 1204{ 1205 geoipv6_t ipnum; 1206 int gaierr; 1207 struct addrinfo hints, *aifirst; 1208 1209 memset(&hints, 0, sizeof(hints)); 1210 hints.ai_family = AF_INET6; 1211 /* hints.ai_flags = AI_V4MAPPED; */ 1212 hints.ai_socktype = SOCK_STREAM; 1213 1214 if ((gaierr = getaddrinfo(host, NULL, &hints, &aifirst)) != 0) { 1215 /* fprintf(stderr, "Err: %s (%d %s)\n", host, gaierr, gai_strerror(gaierr)); */ 1216 return IPV6_NULL; 1217 } 1218 memcpy(ipnum.s6_addr, ((struct sockaddr_in6 *) aifirst->ai_addr)->sin6_addr.s6_addr, sizeof(geoipv6_t)); 1219 freeaddrinfo(aifirst); 1220 /* inet_pton(AF_INET6, host, ipnum.s6_addr); */ 1221 1222 return ipnum; 1223} 1224 1225int GeoIP_id_by_name_gl (GeoIP* gi, const char *name, GeoIPLookup *gl ) { 1226 unsigned long ipnum; 1227 int ret; 1228 if (name == NULL) { 1229 return 0; 1230 } 1231 if (gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION && gi->databaseType != GEOIP_COUNTRY_EDITION && gi->databaseType != GEOIP_PROXY_EDITION && gi->databaseType != GEOIP_NETSPEED_EDITION) { 1232 printf("Invalid database type %s, expected %s\n", get_db_description(gi->databaseType), get_db_description(GEOIP_COUNTRY_EDITION)); 1233 return 0; 1234 } 1235 if (!(ipnum = _GeoIP_lookupaddress(name))) 1236 return 0; 1237 ret = _GeoIP_seek_record_gl(gi, ipnum, gl) - gi->databaseSegments[0]; 1238 return ret; 1239} 1240 1241int GeoIP_id_by_name_v6_gl (GeoIP* gi, const char *name, GeoIPLookup * gl) { 1242 geoipv6_t ipnum; 1243 int ret; 1244 if (name == NULL) { 1245 return 0; 1246 } 1247 if (gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION_V6 && gi->databaseType != GEOIP_COUNTRY_EDITION_V6) { 1248 printf("Invalid database type %s, expected %s\n", get_db_description(gi->databaseType), get_db_description(GEOIP_COUNTRY_EDITION_V6)); 1249 return 0; 1250 } 1251 ipnum = _GeoIP_lookupaddress_v6(name); 1252 if (__GEOIP_V6_IS_NULL(ipnum)) 1253 return 0; 1254 1255 ret = _GeoIP_seek_record_v6_gl(gi, ipnum, gl) - gi->databaseSegments[0]; 1256 return ret; 1257} 1258 1259const char *GeoIP_country_code_by_addr_v6_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1260 int country_id; 1261 country_id = GeoIP_id_by_addr_v6_gl(gi, addr, gl); 1262 return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; 1263} 1264 1265 1266const char *GeoIP_country_code_by_addr_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1267 int country_id; 1268 country_id = GeoIP_id_by_addr_gl(gi, addr, gl); 1269 return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; 1270} 1271const char *GeoIP_country_code3_by_addr_v6_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1272 int country_id; 1273 country_id = GeoIP_id_by_addr_v6_gl(gi, addr, gl); 1274 return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; 1275} 1276 1277const char *GeoIP_country_code3_by_addr_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1278 int country_id; 1279 country_id = GeoIP_id_by_addr_gl(gi, addr, gl); 1280 return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; 1281} 1282 1283const char *GeoIP_country_name_by_addr_v6_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl ) { 1284 int country_id; 1285 country_id = GeoIP_id_by_addr_v6_gl(gi, addr, gl); 1286 return GeoIP_country_name_by_id(gi, country_id ); 1287} 1288 1289const char *GeoIP_country_name_by_addr_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl ) { 1290 int country_id; 1291 country_id = GeoIP_id_by_addr_gl(gi, addr, gl); 1292 return GeoIP_country_name_by_id(gi, country_id ); 1293} 1294 1295const char *GeoIP_country_name_by_ipnum_gl (GeoIP* gi, unsigned long ipnum, GeoIPLookup * gl) { 1296 int country_id; 1297 country_id = GeoIP_id_by_ipnum_gl(gi, ipnum, gl); 1298 return GeoIP_country_name_by_id(gi, country_id ); 1299} 1300 1301const char *GeoIP_country_name_by_ipnum_v6_gl (GeoIP* gi, geoipv6_t ipnum, GeoIPLookup * gl) { 1302 int country_id; 1303 country_id = GeoIP_id_by_ipnum_v6_gl(gi, ipnum, gl); 1304 return GeoIP_country_name_by_id(gi, country_id ); 1305} 1306 1307const char *GeoIP_country_code_by_ipnum_gl (GeoIP* gi, unsigned long ipnum, GeoIPLookup * gl) { 1308 int country_id; 1309 country_id = GeoIP_id_by_ipnum_gl(gi, ipnum, gl); 1310 return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; 1311} 1312 1313const char *GeoIP_country_code_by_ipnum_v6_gl (GeoIP* gi, geoipv6_t ipnum, GeoIPLookup * gl) { 1314 int country_id; 1315 country_id = GeoIP_id_by_ipnum_v6_gl(gi, ipnum, gl); 1316 return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; 1317} 1318 1319const char *GeoIP_country_code3_by_ipnum_gl (GeoIP* gi, unsigned long ipnum, GeoIPLookup * gl) { 1320 int country_id; 1321 country_id = GeoIP_id_by_ipnum_gl(gi, ipnum, gl); 1322 return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; 1323} 1324 1325const char *GeoIP_country_code3_by_ipnum_v6_gl (GeoIP* gi, geoipv6_t ipnum, GeoIPLookup * gl) { 1326 int country_id; 1327 country_id = GeoIP_id_by_ipnum_v6_gl(gi, ipnum, gl); 1328 return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; 1329} 1330 1331int GeoIP_country_id_by_addr_v6_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1332 GeoIPLookup n; 1333 return GeoIP_id_by_addr_v6_gl(gi, addr, &n); 1334} 1335 1336int GeoIP_country_id_by_addr_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1337 return GeoIP_id_by_addr_gl(gi, addr, gl); 1338} 1339 1340int GeoIP_country_id_by_name_v6_gl (GeoIP* gi, const char *host, GeoIPLookup * gl) { 1341 return GeoIP_id_by_name_v6_gl(gi, host, gl); 1342} 1343 1344int GeoIP_country_id_by_name_gl (GeoIP* gi, const char *host, GeoIPLookup * gl) { 1345 return GeoIP_id_by_name_gl(gi, host, gl); 1346} 1347 1348int GeoIP_id_by_addr_v6_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1349 geoipv6_t ipnum; 1350 int ret; 1351 if (addr == NULL) { 1352 return 0; 1353 } 1354 if (gi->databaseType != GEOIP_COUNTRY_EDITION_V6 1355 && gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION_V6) { 1356 printf("Invalid database type %s, expected %s\n", 1357 get_db_description(gi->databaseType), 1358 get_db_description(GEOIP_COUNTRY_EDITION_V6)); 1359 return 0; 1360 } 1361 ipnum = _GeoIP_addr_to_num_v6(addr); 1362 ret = _GeoIP_seek_record_v6_gl(gi, ipnum, gl) - gi->databaseSegments[0]; 1363 return ret; 1364} 1365 1366 1367int GeoIP_id_by_addr_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1368 unsigned long ipnum; 1369 int ret; 1370 if (addr == NULL) { 1371 return 0; 1372 } 1373 if (gi->databaseType != GEOIP_COUNTRY_EDITION && 1374 gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION && 1375 gi->databaseType != GEOIP_PROXY_EDITION && 1376 gi->databaseType != GEOIP_NETSPEED_EDITION) { 1377 printf("Invalid database type %s, expected %s\n", 1378 get_db_description(gi->databaseType), 1379 get_db_description(GEOIP_COUNTRY_EDITION)); 1380 return 0; 1381 } 1382 ipnum = GeoIP_addr_to_num(addr); 1383 ret = _GeoIP_seek_record_gl(gi, ipnum, gl) - gi->databaseSegments[0]; 1384 return ret; 1385} 1386 1387int GeoIP_id_by_ipnum_v6_gl (GeoIP* gi, geoipv6_t ipnum, GeoIPLookup * gl) { 1388 int ret; 1389 if (gi->databaseType != GEOIP_COUNTRY_EDITION_V6 1390 && gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION_V6) { 1391 printf("Invalid database type %s, expected %s\n", 1392 get_db_description(gi->databaseType), 1393 get_db_description(GEOIP_COUNTRY_EDITION_V6)); 1394 return 0; 1395 } 1396 ret = _GeoIP_seek_record_v6_gl(gi, ipnum, gl) - gi->databaseSegments[0]; 1397 return ret; 1398} 1399 1400int GeoIP_id_by_ipnum_gl (GeoIP* gi, unsigned long ipnum, GeoIPLookup * gl) { 1401 int ret; 1402 if (ipnum == 0) { 1403 return 0; 1404 } 1405 if (gi->databaseType != GEOIP_COUNTRY_EDITION && 1406 gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION && 1407 gi->databaseType != GEOIP_PROXY_EDITION && 1408 gi->databaseType != GEOIP_NETSPEED_EDITION) { 1409 printf("Invalid database type %s, expected %s\n", 1410 get_db_description(gi->databaseType), 1411 get_db_description(GEOIP_COUNTRY_EDITION)); 1412 return 0; 1413 } 1414 ret = _GeoIP_seek_record_gl(gi, ipnum, gl) - gi->databaseSegments[0]; 1415 return ret; 1416} 1417 1418char *GeoIP_database_info (GeoIP* gi) { 1419 int i; 1420 unsigned char buf[3]; 1421 char *retval; 1422 int hasStructureInfo = 0; 1423 ssize_t silence _UNUSED; 1424 int fno; 1425 1426 if(gi == NULL) 1427 return NULL; 1428 1429 fno = fileno(gi->GeoIPDatabase); 1430 1431 _check_mtime(gi); 1432 lseek(fno, -3l, SEEK_END); 1433 1434 /* first get past the database structure information */ 1435 for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) { 1436 silence = read(fno, buf, 3 ); 1437 if (buf[0] == 255 && buf[1] == 255 && buf[2] == 255) { 1438 hasStructureInfo = 1; 1439 break; 1440 } 1441 lseek(fno, -4l, SEEK_CUR); 1442 } 1443 if (hasStructureInfo == 1) { 1444 lseek(fno, -6l, SEEK_CUR); 1445 } else { 1446 /* no structure info, must be pre Sep 2002 database, go back to end */ 1447 lseek(fno, -3l, SEEK_END); 1448 } 1449 1450 for (i = 0; i < DATABASE_INFO_MAX_SIZE; i++) { 1451 silence = read(fno, buf, 3 ); 1452 if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0) { 1453 retval = malloc(sizeof(char) * (i+1)); 1454 if (retval == NULL) { 1455 return NULL; 1456 } 1457 silence = read(fno, retval, i); 1458 retval[i] = '\0'; 1459 return retval; 1460 } 1461 lseek(fno, -4l, SEEK_CUR); 1462 } 1463 return NULL; 1464} 1465 1466/* GeoIP Region Edition functions */ 1467 1468void GeoIP_assign_region_by_inetaddr_gl(GeoIP* gi, unsigned long inetaddr, GeoIPRegion *region, GeoIPLookup * gl) { 1469 unsigned int seek_region; 1470 1471 /* This also writes in the terminating NULs (if you decide to 1472 * keep them) and clear any fields that are not set. */ 1473 memset(region, 0, sizeof(GeoIPRegion)); 1474 1475 seek_region = _GeoIP_seek_record_gl(gi, ntohl(inetaddr), gl); 1476 1477 if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { 1478 /* Region Edition, pre June 2003 */ 1479 seek_region -= STATE_BEGIN_REV0; 1480 if (seek_region >= 1000) { 1481 region->country_code[0] = 'U'; 1482 region->country_code[1] = 'S'; 1483 region->region[0] = (char) ((seek_region - 1000)/26 + 65); 1484 region->region[1] = (char) ((seek_region - 1000)%26 + 65); 1485 } else { 1486 memcpy(region->country_code, GeoIP_country_code[seek_region], 2); 1487 } 1488 } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { 1489 /* Region Edition, post June 2003 */ 1490 seek_region -= STATE_BEGIN_REV1; 1491 if (seek_region < US_OFFSET) { 1492 /* Unknown */ 1493 /* we don't need to do anything here b/c we memset region to 0 */ 1494 } else if (seek_region < CANADA_OFFSET) { 1495 /* USA State */ 1496 region->country_code[0] = 'U'; 1497 region->country_code[1] = 'S'; 1498 region->region[0] = (char) ((seek_region - US_OFFSET)/26 + 65); 1499 region->region[1] = (char) ((seek_region - US_OFFSET)%26 + 65); 1500 } else if (seek_region < WORLD_OFFSET) { 1501 /* Canada Province */ 1502 region->country_code[0] = 'C'; 1503 region->country_code[1] = 'A'; 1504 region->region[0] = (char) ((seek_region - CANADA_OFFSET)/26 + 65); 1505 region->region[1] = (char) ((seek_region - CANADA_OFFSET)%26 + 65); 1506 } else { 1507 /* Not US or Canada */ 1508 memcpy(region->country_code, GeoIP_country_code[(seek_region - WORLD_OFFSET) / FIPS_RANGE], 2); 1509 } 1510 } 1511} 1512 1513void GeoIP_assign_region_by_inetaddr_v6_gl(GeoIP* gi, geoipv6_t inetaddr, GeoIPRegion *region, GeoIPLookup * gl) { 1514 unsigned int seek_region; 1515 1516 /* This also writes in the terminating NULs (if you decide to 1517 * keep them) and clear any fields that are not set. */ 1518 memset(region, 0, sizeof(GeoIPRegion)); 1519 1520 seek_region = _GeoIP_seek_record_v6_gl(gi, inetaddr, gl); 1521 1522 if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { 1523 /* Region Edition, pre June 2003 */ 1524 seek_region -= STATE_BEGIN_REV0; 1525 if (seek_region >= 1000) { 1526 region->country_code[0] = 'U'; 1527 region->country_code[1] = 'S'; 1528 region->region[0] = (char) ((seek_region - 1000)/26 + 65); 1529 region->region[1] = (char) ((seek_region - 1000)%26 + 65); 1530 } else { 1531 memcpy(region->country_code, GeoIP_country_code[seek_region], 2); 1532 } 1533 } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { 1534 /* Region Edition, post June 2003 */ 1535 seek_region -= STATE_BEGIN_REV1; 1536 if (seek_region < US_OFFSET) { 1537 /* Unknown */ 1538 /* we don't need to do anything here b/c we memset region to 0 */ 1539 } else if (seek_region < CANADA_OFFSET) { 1540 /* USA State */ 1541 region->country_code[0] = 'U'; 1542 region->country_code[1] = 'S'; 1543 region->region[0] = (char) ((seek_region - US_OFFSET)/26 + 65); 1544 region->region[1] = (char) ((seek_region - US_OFFSET)%26 + 65); 1545 } else if (seek_region < WORLD_OFFSET) { 1546 /* Canada Province */ 1547 region->country_code[0] = 'C'; 1548 region->country_code[1] = 'A'; 1549 region->region[0] = (char) ((seek_region - CANADA_OFFSET)/26 + 65); 1550 region->region[1] = (char) ((seek_region - CANADA_OFFSET)%26 + 65); 1551 } else { 1552 /* Not US or Canada */ 1553 memcpy(region->country_code, GeoIP_country_code[(seek_region - WORLD_OFFSET) / FIPS_RANGE], 2); 1554 } 1555 } 1556} 1557 1558static 1559GeoIPRegion * _get_region_gl(GeoIP* gi, unsigned long ipnum, GeoIPLookup * gl) { 1560 GeoIPRegion * region; 1561 1562 region = malloc(sizeof(GeoIPRegion)); 1563 if (region) { 1564 GeoIP_assign_region_by_inetaddr_gl(gi, htonl(ipnum), region, gl); 1565 } 1566 return region; 1567} 1568 1569static 1570GeoIPRegion * _get_region_v6_gl(GeoIP* gi, geoipv6_t ipnum, GeoIPLookup * gl) { 1571 GeoIPRegion * region; 1572 1573 region = malloc(sizeof(GeoIPRegion)); 1574 if (region) { 1575 GeoIP_assign_region_by_inetaddr_v6_gl(gi, ipnum, region, gl); 1576 } 1577 return region; 1578} 1579 1580GeoIPRegion * GeoIP_region_by_addr_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1581 unsigned long ipnum; 1582 if (addr == NULL) { 1583 return NULL; 1584 } 1585 if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && 1586 gi->databaseType != GEOIP_REGION_EDITION_REV1) { 1587 printf("Invalid database type %s, expected %s\n", get_db_description(gi->databaseType), get_db_description(GEOIP_REGION_EDITION_REV1)); 1588 return NULL; 1589 } 1590 ipnum = GeoIP_addr_to_num(addr); 1591 return _get_region_gl(gi, ipnum, gl); 1592} 1593 1594GeoIPRegion * GeoIP_region_by_addr_v6_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1595 geoipv6_t ipnum; 1596 if (addr == NULL) { 1597 return NULL; 1598 } 1599 if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && 1600 gi->databaseType != GEOIP_REGION_EDITION_REV1) { 1601 printf("Invalid database type %s, expected %s\n", get_db_description(gi->databaseType), get_db_description(GEOIP_REGION_EDITION_REV1)); 1602 return NULL; 1603 } 1604 ipnum = _GeoIP_addr_to_num_v6(addr); 1605 return _get_region_v6_gl(gi, ipnum, gl); 1606} 1607 1608GeoIPRegion * GeoIP_region_by_name_gl (GeoIP* gi, const char *name, GeoIPLookup * gl) { 1609 unsigned long ipnum; 1610 if (name == NULL) { 1611 return NULL; 1612 } 1613 if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && 1614 gi->databaseType != GEOIP_REGION_EDITION_REV1) { 1615 printf("Invalid database type %s, expected %s\n", get_db_description(gi->databaseType), get_db_description(GEOIP_REGION_EDITION_REV1)); 1616 return NULL; 1617 } 1618 if (!(ipnum = _GeoIP_lookupaddress(name))) 1619 return NULL; 1620 return _get_region_gl(gi, ipnum, gl); 1621} 1622 1623GeoIPRegion * GeoIP_region_by_name_v6_gl (GeoIP* gi, const char *name, GeoIPLookup * gl) { 1624 geoipv6_t ipnum; 1625 if (name == NULL) { 1626 return NULL; 1627 } 1628 if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && 1629 gi->databaseType != GEOIP_REGION_EDITION_REV1) { 1630 printf("Invalid database type %s, expected %s\n", get_db_description(gi->databaseType), get_db_description(GEOIP_REGION_EDITION_REV1)); 1631 return NULL; 1632 } 1633 1634 ipnum = _GeoIP_lookupaddress_v6(name); 1635 if (__GEOIP_V6_IS_NULL(ipnum)) 1636 return NULL; 1637 return _get_region_v6_gl(gi, ipnum, gl); 1638} 1639 1640GeoIPRegion * GeoIP_region_by_ipnum_gl (GeoIP* gi, unsigned long ipnum, GeoIPLookup * gl) { 1641 if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && 1642 gi->databaseType != GEOIP_REGION_EDITION_REV1) { 1643 printf("Invalid database type %s, expected %s\n", get_db_description(gi->databaseType), get_db_description(GEOIP_REGION_EDITION_REV1)); 1644 return NULL; 1645 } 1646 return _get_region_gl(gi, ipnum, gl); 1647} 1648 1649GeoIPRegion * GeoIP_region_by_ipnum_v6_gl (GeoIP* gi, geoipv6_t ipnum, GeoIPLookup * gl) { 1650 if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && 1651 gi->databaseType != GEOIP_REGION_EDITION_REV1) { 1652 printf("Invalid database type %s, expected %s\n", get_db_description(gi->databaseType),get_db_description(GEOIP_REGION_EDITION_REV1)); 1653 return NULL; 1654 } 1655 return _get_region_v6_gl(gi, ipnum, gl); 1656} 1657 1658void GeoIPRegion_delete (GeoIPRegion *gir) { 1659 free(gir); 1660} 1661 1662/* GeoIP Organization, ISP and AS Number Edition private method */ 1663static 1664char *_get_name_gl (GeoIP* gi, unsigned long ipnum, GeoIPLookup * gl) { 1665 int seek_org; 1666 char buf[MAX_ORG_RECORD_LENGTH]; 1667 char * org_buf, * buf_pointer; 1668 int record_pointer; 1669 size_t len; 1670 ssize_t silence _UNUSED; 1671 1672 if (gi->databaseType != GEOIP_ORG_EDITION && 1673 gi->databaseType != GEOIP_ISP_EDITION && 1674 gi->databaseType != GEOIP_DOMAIN_EDITION && 1675 gi->databaseType != GEOIP_ASNUM_EDITION && 1676 gi->databaseType != GEOIP_ACCURACYRADIUS_EDITION && 1677 gi->databaseType != GEOIP_NETSPEED_EDITION_REV1 && 1678 gi->databaseType != GEOIP_USERTYPE_EDITION && 1679 gi->databaseType != GEOIP_REGISTRAR_EDITION && 1680 gi->databaseType != GEOIP_LOCATIONA_EDITION && 1681 gi->databaseType != GEOIP_CITYCONF_EDITION && 1682 gi->databaseType != GEOIP_COUNTRYCONF_EDITION && 1683 gi->databaseType != GEOIP_REGIONCONF_EDITION && 1684 gi->databaseType != GEOIP_POSTALCONF_EDITION 1685 ) { 1686 printf("Invalid database type %s, expected %s\n", get_db_description(gi->databaseType), get_db_description(GEOIP_ORG_EDITION)); 1687 return NULL; 1688 } 1689 1690 seek_org = _GeoIP_seek_record_gl(gi, ipnum, gl); 1691 if (seek_org == gi->databaseSegments[0]) 1692 return NULL; 1693 1694 record_pointer = seek_org + (2 * gi->record_length - 1) * gi->databaseSegments[0]; 1695 1696 if (gi->cache == NULL) { 1697 silence = pread(fileno(gi->GeoIPDatabase), buf, MAX_ORG_RECORD_LENGTH, record_pointer); 1698 if ( gi->charset == GEOIP_CHARSET_UTF8 ) { 1699 org_buf = _GeoIP_iso_8859_1__utf8( (const char * ) buf ); 1700 } else { 1701 len = sizeof(char) * (strlen(buf)+1); 1702 org_buf = malloc(len); 1703 strncpy(org_buf, buf, len); 1704 } 1705 } else { 1706 buf_pointer = (char *)(gi->cache + (long)record_pointer); 1707 if ( gi->charset == GEOIP_CHARSET_UTF8 ) { 1708 org_buf = _GeoIP_iso_8859_1__utf8( (const char * ) buf_pointer ); 1709 } else { 1710 len = sizeof(char) * (strlen(buf_pointer)+1); 1711 org_buf = malloc(len); 1712 strncpy(org_buf, buf_pointer, len); 1713 } 1714 } 1715 return org_buf; 1716} 1717 1718static 1719char *_get_name_v6_gl (GeoIP* gi, geoipv6_t ipnum, GeoIPLookup * gl) { 1720 int seek_org; 1721 char buf[MAX_ORG_RECORD_LENGTH]; 1722 char * org_buf, * buf_pointer; 1723 int record_pointer; 1724 size_t len; 1725 ssize_t silence _UNUSED; 1726 1727 if ( 1728 gi->databaseType != GEOIP_ORG_EDITION_V6 && 1729 gi->databaseType != GEOIP_ISP_EDITION_V6 && 1730 gi->databaseType != GEOIP_DOMAIN_EDITION_V6 && 1731 gi->databaseType != GEOIP_ASNUM_EDITION_V6 && 1732 gi->databaseType != GEOIP_ACCURACYRADIUS_EDITION_V6 && 1733 gi->databaseType != GEOIP_NETSPEED_EDITION_REV1_V6 && 1734 gi->databaseType != GEOIP_USERTYPE_EDITION_V6 && 1735 gi->databaseType != GEOIP_REGISTRAR_EDITION_V6 && 1736 gi->databaseType != GEOIP_LOCATIONA_EDITION_V6 1737 ) { 1738 printf("Invalid database type %s, expected %s\n", get_db_description(gi->databaseType), get_db_description(GEOIP_ORG_EDITION)); 1739 return NULL; 1740 } 1741 1742 seek_org = _GeoIP_seek_record_v6_gl(gi, ipnum, gl); 1743 if (seek_org == gi->databaseSegments[0]) 1744 return NULL; 1745 1746 record_pointer = seek_org + (2 * gi->record_length - 1) * gi->databaseSegments[0]; 1747 1748 if (gi->cache == NULL) { 1749 silence = pread(fileno(gi->GeoIPDatabase), buf, MAX_ORG_RECORD_LENGTH, record_pointer); 1750 if ( gi->charset == GEOIP_CHARSET_UTF8 ) { 1751 org_buf = _GeoIP_iso_8859_1__utf8( (const char * ) buf ); 1752 } else { 1753 len = sizeof(char) * (strlen(buf)+1); 1754 org_buf = malloc(len); 1755 strncpy(org_buf, buf, len); 1756 } 1757 } else { 1758 buf_pointer = (char *)(gi->cache + (long)record_pointer); 1759 if ( gi->charset == GEOIP_CHARSET_UTF8 ) { 1760 org_buf = _GeoIP_iso_8859_1__utf8( (const char * ) buf_pointer ); 1761 } else { 1762 len = sizeof(char) * (strlen(buf_pointer)+1); 1763 org_buf = malloc(len); 1764 strncpy(org_buf, buf_pointer, len); 1765 } 1766 } 1767 return org_buf; 1768} 1769 1770char * GeoIP_num_to_addr (unsigned long ipnum) { 1771 char *ret_str; 1772 char *cur_str; 1773 int octet[4]; 1774 int num_chars_written, i; 1775 1776 ret_str = malloc(sizeof(char) * 16); 1777 cur_str = ret_str; 1778 1779 for (i = 0; i<4; i++) { 1780 octet[3 - i] = ipnum % 256; 1781 ipnum >>= 8; 1782 } 1783 1784 for (i = 0; i<4; i++) { 1785 num_chars_written = sprintf(cur_str, "%d", octet[i]); 1786 cur_str += num_chars_written; 1787 1788 if (i < 3) { 1789 cur_str[0] = '.'; 1790 cur_str++; 1791 } 1792 } 1793 1794 return ret_str; 1795} 1796 1797char **GeoIP_range_by_ip_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1798 unsigned long ipnum; 1799 unsigned long left_seek; 1800 unsigned long right_seek; 1801 unsigned long mask; 1802 int orig_netmask; 1803 int target_value; 1804 char **ret; 1805 GeoIPLookup t; 1806 1807 if (addr == NULL) { 1808 return NULL; 1809 } 1810 1811 ret = malloc(sizeof(char *) * 2); 1812 1813 ipnum = GeoIP_addr_to_num(addr); 1814 target_value = _GeoIP_seek_record_gl(gi, ipnum, gl); 1815 orig_netmask = gl->netmask; 1816 mask = 0xffffffff << ( 32 - orig_netmask ); 1817 left_seek = ipnum & mask; 1818 right_seek = left_seek + ( 0xffffffff & ~mask ); 1819 1820 while (left_seek != 0 1821 && target_value == _GeoIP_seek_record_gl(gi, left_seek - 1, &t) ) { 1822 1823 /* Go to beginning of netblock defined by netmask */ 1824 mask = 0xffffffff << ( 32 - t.netmask ); 1825 left_seek = ( left_seek - 1 ) & mask; 1826 } 1827 ret[0] = GeoIP_num_to_addr(left_seek); 1828 1829 while (right_seek != 0xffffffff 1830 && target_value == _GeoIP_seek_record_gl(gi, right_seek + 1, &t) ) { 1831 1832 /* Go to end of netblock defined by netmask */ 1833 mask = 0xffffffff << ( 32 - t.netmask ); 1834 right_seek = ( right_seek + 1 ) & mask; 1835 right_seek += 0xffffffff & ~mask; 1836 } 1837 ret[1] = GeoIP_num_to_addr(right_seek); 1838 1839 gi->netmask = orig_netmask; 1840 1841 return ret; 1842} 1843void GeoIP_range_by_ip_delete( char ** ptr ){ 1844 if ( ptr ){ 1845 if ( ptr[0] ) 1846 free(ptr[0]); 1847 if ( ptr[1] ) 1848 free(ptr[1]); 1849 free(ptr); 1850 } 1851} 1852 1853char *GeoIP_name_by_ipnum_gl (GeoIP* gi, unsigned long ipnum, GeoIPLookup * gl) { 1854 return _get_name_gl(gi,ipnum, gl); 1855} 1856 1857char *GeoIP_name_by_ipnum_v6_gl (GeoIP* gi, geoipv6_t ipnum, GeoIPLookup * gl) { 1858 return _get_name_v6_gl(gi,ipnum, gl); 1859} 1860 1861char *GeoIP_name_by_addr_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1862 unsigned long ipnum; 1863 if (addr == NULL) { 1864 return NULL; 1865 } 1866 ipnum = GeoIP_addr_to_num(addr); 1867 return _get_name_gl(gi, ipnum, gl); 1868} 1869 1870char *GeoIP_name_by_addr_v6_gl (GeoIP* gi, const char *addr, GeoIPLookup * gl) { 1871 geoipv6_t ipnum; 1872 if (addr == NULL) { 1873 return NULL; 1874 } 1875 ipnum = _GeoIP_addr_to_num_v6(addr); 1876 return _get_name_v6_gl(gi, ipnum, gl); 1877} 1878 1879char *GeoIP_name_by_name_gl (GeoIP* gi, const char *name, GeoIPLookup * gl) { 1880 unsigned long ipnum; 1881 if (name == NULL) { 1882 return NULL; 1883 } 1884 if (!(ipnum = _GeoIP_lookupaddress(name))) 1885 return NULL; 1886 return _get_name_gl(gi, ipnum, gl); 1887} 1888 1889char *GeoIP_name_by_name_v6_gl (GeoIP* gi, const char *name, GeoIPLookup *gl) { 1890 geoipv6_t ipnum; 1891 if (name == NULL) { 1892 return NULL; 1893 } 1894 ipnum = _GeoIP_lookupaddress_v6(name); 1895 if (__GEOIP_V6_IS_NULL(ipnum)) 1896 return NULL; 1897 return _get_name_v6_gl(gi, ipnum, gl); 1898} 1899 1900unsigned char GeoIP_database_edition (GeoIP* gi) { 1901 return gi->databaseType; 1902} 1903 1904int GeoIP_enable_teredo(GeoIP* gi, int true_false){ 1905 unsigned int mask = ( 1U << GEOIP_TEREDO_BIT ); 1906 int b = ( gi->ext_flags & mask ) ? 1 : 0; 1907 gi->ext_flags &= ~mask ; 1908 if ( true_false ) 1909 gi->ext_flags |= true_false; 1910 return b; 1911} 1912 1913int GeoIP_teredo ( GeoIP* gi ){ 1914 unsigned int mask = ( 1U << GEOIP_TEREDO_BIT ); 1915 return ( gi->ext_flags & mask ) ? 1 : 0; 1916} 1917 1918int GeoIP_charset( GeoIP* gi){ 1919 return gi->charset; 1920} 1921 1922int GeoIP_set_charset( GeoIP* gi, int charset ){ 1923 int old_charset = gi->charset; 1924 gi->charset = charset; 1925 return old_charset; 1926} 1927 1928/** return two letter country code */ 1929const char* GeoIP_code_by_id(int id) 1930{ 1931 if (id < 0 || id >= (int) num_GeoIP_countries) 1932 return NULL; 1933 1934 return GeoIP_country_code[id]; 1935} 1936 1937/** return three letter country code */ 1938const char* GeoIP_code3_by_id(int id) 1939{ 1940 if (id < 0 || id >= (int) num_GeoIP_countries) 1941 return NULL; 1942 1943 return GeoIP_country_code3[id]; 1944} 1945 1946 1947/** return full name of country in utf8 or iso-8859-1 */ 1948const char* GeoIP_country_name_by_id(GeoIP * gi, int id) 1949{ 1950 /* return NULL also even for index 0 for backward compatibility */ 1951 if (id <= 0 || id >= (int) num_GeoIP_countries) 1952 return NULL; 1953 return ((gi->charset == GEOIP_CHARSET_UTF8) 1954 ? GeoIP_utf8_country_name[id] 1955 : GeoIP_country_name[id]); 1956} 1957 1958/** return full name of country in iso-8859-1 */ 1959const char* GeoIP_name_by_id(int id) 1960{ 1961 if (id < 0 || id >= (int) num_GeoIP_countries) 1962 return NULL; 1963 1964 return GeoIP_country_name[id]; 1965} 1966 1967/** return continent of country */ 1968const char* GeoIP_continent_by_id(int id) 1969{ 1970 if (id < 0 || id >= (int) num_GeoIP_countries) 1971 return NULL; 1972 1973 return GeoIP_country_continent[id]; 1974} 1975 1976/** return id by country code **/ 1977int GeoIP_id_by_code(const char *country) 1978{ 1979 unsigned i; 1980 1981 for ( i = 0; i < num_GeoIP_countries; ++i) 1982 { 1983 if (strcmp(country, GeoIP_country_code[i]) == 0) 1984 return i; 1985 } 1986 1987 return 0; 1988} 1989 1990unsigned GeoIP_num_countries(void) 1991{ 1992 return num_GeoIP_countries; 1993} 1994 1995const char * GeoIP_lib_version(void) 1996{ 1997 return PACKAGE_VERSION; 1998} 1999 2000int GeoIP_cleanup(void) 2001{ 2002 int i, result = 0; 2003 if (GeoIPDBFileName) { 2004 2005 for (i = 0; i < NUM_DB_TYPES; i++) { 2006 if (GeoIPDBFileName[i]) free(GeoIPDBFileName[i]); 2007 } 2008 2009 free(GeoIPDBFileName); 2010 GeoIPDBFileName = NULL; 2011 result = 1; 2012 } 2013 2014 return result; 2015} 2016 2017