GeoIP  1.6.12
About: GeoIP is a C library that enables the user to find the country that any IP address or hostname originates from (contains an initial free GeoIP Country database).
  Fossies Dox: GeoIP-1.6.12.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

GeoIP.c
Go to the documentation of this file.
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
2 /* GeoIP.c
3  *
4  * Copyright (C) 2016 MaxMind, Inc.
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 #include "GeoIP_internal.h"
23 
25 
26 #if defined(_WIN32)
27 #include <io.h>
28 
29 #ifdef _MSC_VER
30 #if _MSC_VER < 1900 // VS 2015 supports snprintf
31 #define snprintf _snprintf
32 #endif
33 #if _MSC_VER >= 1400 // VS 2005+ deprecates fileno, lseek and read
34 #define fileno _fileno
35 #define read _read
36 #define lseek _lseek
37 #endif
38 #endif
39 #else
40 #include <netdb.h>
41 #include <sys/mman.h>
42 #include <unistd.h>
43 #endif /* defined(_WIN32) */
44 
45 #include <assert.h>
46 #include <errno.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <sys/stat.h> /* for fstat */
51 #include <sys/types.h> /* for fstat */
52 
53 #ifdef HAVE_GETTIMEOFDAY
54 #include <sys/time.h> /* for gettimeofday */
55 #endif
56 
57 #ifdef HAVE_STDINT_H
58 #include <stdint.h> /* For uint32_t */
59 #endif
60 
61 #if defined(_WIN32) && !defined(__MINGW32__)
62 #include "pread.h"
63 #endif
64 
65 #ifdef _UNUSED
66 #elif defined(__GNUC__)
67 #define _UNUSED __attribute__((unused))
68 #else
69 #define _UNUSED
70 #endif
71 
72 #ifndef INADDR_NONE
73 #define INADDR_NONE -1
74 #endif
75 
76 #define COUNTRY_BEGIN 16776960
77 #define LARGE_COUNTRY_BEGIN 16515072
78 #define STATE_BEGIN_REV0 16700000
79 #define STATE_BEGIN_REV1 16000000
80 #define STRUCTURE_INFO_MAX_SIZE 20
81 #define DATABASE_INFO_MAX_SIZE 100
82 #define MAX_ORG_RECORD_LENGTH 300
83 #define US_OFFSET 1
84 #define CANADA_OFFSET 677
85 #define WORLD_OFFSET 1353
86 #define FIPS_RANGE 360
87 
88 #define DEBUG_MSGF(flags, fmt, ...) \
89  { \
90  if (((flags)&GEOIP_SILENCE) == 0) { \
91  fprintf(stderr, fmt, ##__VA_ARGS__); \
92  } \
93  }
94 
95 #ifndef HAVE_PREAD
96 #define pread(fd, buf, count, offset) \
97  (lseek(fd, offset, SEEK_SET) == offset ? read(fd, buf, count) : -1)
98 #endif /* HAVE_PREAD */
99 
100 const char GeoIP_country_code[256][3] = {
101  "--", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "CW", "AO",
102  "AQ", "AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF",
103  "BG", "BH", "BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW",
104  "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM",
105  "CN", "CO", "CR", "CU", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM",
106  "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK",
107  "FM", "FO", "FR", "SX", "GA", "GB", "GD", "GE", "GF", "GH", "GI", "GL",
108  "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM",
109  "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN", "IO", "IQ", "IR", "IS",
110  "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR",
111  "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU",
112  "LV", "LY", "MA", "MC", "MD", "MG", "MH", "MK", "ML", "MM", "MN", "MO",
113  "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA",
114  "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM",
115  "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT",
116  "PW", "PY", "QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE",
117  "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV",
118  "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO",
119  "TL", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ",
120  "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "RS",
121  "ZA", "ZM", "ME", "ZW", "A1", "A2", "O1", "AX", "GG", "IM", "JE", "BL",
122  "MF", "BQ", "SS", "O1"};
123 
124 static const unsigned num_GeoIP_countries =
125  (unsigned)(sizeof(GeoIP_country_code) / sizeof(GeoIP_country_code[0]));
126 
127 const char GeoIP_country_code3[256][4] = {
128  "--", "AP", "EU", "AND", "ARE", "AFG", "ATG", "AIA", "ALB", "ARM", "CUW",
129  "AGO", "ATA", "ARG", "ASM", "AUT", "AUS", "ABW", "AZE", "BIH", "BRB", "BGD",
130  "BEL", "BFA", "BGR", "BHR", "BDI", "BEN", "BMU", "BRN", "BOL", "BRA", "BHS",
131  "BTN", "BVT", "BWA", "BLR", "BLZ", "CAN", "CCK", "COD", "CAF", "COG", "CHE",
132  "CIV", "COK", "CHL", "CMR", "CHN", "COL", "CRI", "CUB", "CPV", "CXR", "CYP",
133  "CZE", "DEU", "DJI", "DNK", "DMA", "DOM", "DZA", "ECU", "EST", "EGY", "ESH",
134  "ERI", "ESP", "ETH", "FIN", "FJI", "FLK", "FSM", "FRO", "FRA", "SXM", "GAB",
135  "GBR", "GRD", "GEO", "GUF", "GHA", "GIB", "GRL", "GMB", "GIN", "GLP", "GNQ",
136  "GRC", "SGS", "GTM", "GUM", "GNB", "GUY", "HKG", "HMD", "HND", "HRV", "HTI",
137  "HUN", "IDN", "IRL", "ISR", "IND", "IOT", "IRQ", "IRN", "ISL", "ITA", "JAM",
138  "JOR", "JPN", "KEN", "KGZ", "KHM", "KIR", "COM", "KNA", "PRK", "KOR", "KWT",
139  "CYM", "KAZ", "LAO", "LBN", "LCA", "LIE", "LKA", "LBR", "LSO", "LTU", "LUX",
140  "LVA", "LBY", "MAR", "MCO", "MDA", "MDG", "MHL", "MKD", "MLI", "MMR", "MNG",
141  "MAC", "MNP", "MTQ", "MRT", "MSR", "MLT", "MUS", "MDV", "MWI", "MEX", "MYS",
142  "MOZ", "NAM", "NCL", "NER", "NFK", "NGA", "NIC", "NLD", "NOR", "NPL", "NRU",
143  "NIU", "NZL", "OMN", "PAN", "PER", "PYF", "PNG", "PHL", "PAK", "POL", "SPM",
144  "PCN", "PRI", "PSE", "PRT", "PLW", "PRY", "QAT", "REU", "ROU", "RUS", "RWA",
145  "SAU", "SLB", "SYC", "SDN", "SWE", "SGP", "SHN", "SVN", "SJM", "SVK", "SLE",
146  "SMR", "SEN", "SOM", "SUR", "STP", "SLV", "SYR", "SWZ", "TCA", "TCD", "ATF",
147  "TGO", "THA", "TJK", "TKL", "TKM", "TUN", "TON", "TLS", "TUR", "TTO", "TUV",
148  "TWN", "TZA", "UKR", "UGA", "UMI", "USA", "URY", "UZB", "VAT", "VCT", "VEN",
149  "VGB", "VIR", "VNM", "VUT", "WLF", "WSM", "YEM", "MYT", "SRB", "ZAF", "ZMB",
150  "MNE", "ZWE", "A1", "A2", "O1", "ALA", "GGY", "IMN", "JEY", "BLM", "MAF",
151  "BES", "SSD", "O1"};
152 
153 const char *GeoIP_utf8_country_name[256] = {
154  "N/A",
155  "Asia/Pacific Region",
156  "Europe",
157  "Andorra",
158  "United Arab Emirates",
159  "Afghanistan",
160  "Antigua and Barbuda",
161  "Anguilla",
162  "Albania",
163  "Armenia",
164  "Cura"
165  "\xc3\xa7"
166  "ao",
167  "Angola",
168  "Antarctica",
169  "Argentina",
170  "American Samoa",
171  "Austria",
172  "Australia",
173  "Aruba",
174  "Azerbaijan",
175  "Bosnia and Herzegovina",
176  "Barbados",
177  "Bangladesh",
178  "Belgium",
179  "Burkina Faso",
180  "Bulgaria",
181  "Bahrain",
182  "Burundi",
183  "Benin",
184  "Bermuda",
185  "Brunei Darussalam",
186  "Bolivia",
187  "Brazil",
188  "Bahamas",
189  "Bhutan",
190  "Bouvet Island",
191  "Botswana",
192  "Belarus",
193  "Belize",
194  "Canada",
195  "Cocos (Keeling) Islands",
196  "Congo, The Democratic Republic of the",
197  "Central African Republic",
198  "Congo",
199  "Switzerland",
200  "Cote D'Ivoire",
201  "Cook Islands",
202  "Chile",
203  "Cameroon",
204  "China",
205  "Colombia",
206  "Costa Rica",
207  "Cuba",
208  "Cape Verde",
209  "Christmas Island",
210  "Cyprus",
211  "Czech Republic",
212  "Germany",
213  "Djibouti",
214  "Denmark",
215  "Dominica",
216  "Dominican Republic",
217  "Algeria",
218  "Ecuador",
219  "Estonia",
220  "Egypt",
221  "Western Sahara",
222  "Eritrea",
223  "Spain",
224  "Ethiopia",
225  "Finland",
226  "Fiji",
227  "Falkland Islands (Malvinas)",
228  "Micronesia, Federated States of",
229  "Faroe Islands",
230  "France",
231  "Sint Maarten (Dutch part)",
232  "Gabon",
233  "United Kingdom",
234  "Grenada",
235  "Georgia",
236  "French Guiana",
237  "Ghana",
238  "Gibraltar",
239  "Greenland",
240  "Gambia",
241  "Guinea",
242  "Guadeloupe",
243  "Equatorial Guinea",
244  "Greece",
245  "South Georgia and the South Sandwich Islands",
246  "Guatemala",
247  "Guam",
248  "Guinea-Bissau",
249  "Guyana",
250  "Hong Kong",
251  "Heard Island and McDonald Islands",
252  "Honduras",
253  "Croatia",
254  "Haiti",
255  "Hungary",
256  "Indonesia",
257  "Ireland",
258  "Israel",
259  "India",
260  "British Indian Ocean Territory",
261  "Iraq",
262  "Iran, Islamic Republic of",
263  "Iceland",
264  "Italy",
265  "Jamaica",
266  "Jordan",
267  "Japan",
268  "Kenya",
269  "Kyrgyzstan",
270  "Cambodia",
271  "Kiribati",
272  "Comoros",
273  "Saint Kitts and Nevis",
274  "Korea, Democratic People's Republic of",
275  "Korea, Republic of",
276  "Kuwait",
277  "Cayman Islands",
278  "Kazakhstan",
279  "Lao People's Democratic Republic",
280  "Lebanon",
281  "Saint Lucia",
282  "Liechtenstein",
283  "Sri Lanka",
284  "Liberia",
285  "Lesotho",
286  "Lithuania",
287  "Luxembourg",
288  "Latvia",
289  "Libya",
290  "Morocco",
291  "Monaco",
292  "Moldova, Republic of",
293  "Madagascar",
294  "Marshall Islands",
295  "Macedonia",
296  "Mali",
297  "Myanmar",
298  "Mongolia",
299  "Macau",
300  "Northern Mariana Islands",
301  "Martinique",
302  "Mauritania",
303  "Montserrat",
304  "Malta",
305  "Mauritius",
306  "Maldives",
307  "Malawi",
308  "Mexico",
309  "Malaysia",
310  "Mozambique",
311  "Namibia",
312  "New Caledonia",
313  "Niger",
314  "Norfolk Island",
315  "Nigeria",
316  "Nicaragua",
317  "Netherlands",
318  "Norway",
319  "Nepal",
320  "Nauru",
321  "Niue",
322  "New Zealand",
323  "Oman",
324  "Panama",
325  "Peru",
326  "French Polynesia",
327  "Papua New Guinea",
328  "Philippines",
329  "Pakistan",
330  "Poland",
331  "Saint Pierre and Miquelon",
332  "Pitcairn Islands",
333  "Puerto Rico",
334  "Palestinian Territory",
335  "Portugal",
336  "Palau",
337  "Paraguay",
338  "Qatar",
339  "Reunion",
340  "Romania",
341  "Russian Federation",
342  "Rwanda",
343  "Saudi Arabia",
344  "Solomon Islands",
345  "Seychelles",
346  "Sudan",
347  "Sweden",
348  "Singapore",
349  "Saint Helena",
350  "Slovenia",
351  "Svalbard and Jan Mayen",
352  "Slovakia",
353  "Sierra Leone",
354  "San Marino",
355  "Senegal",
356  "Somalia",
357  "Suriname",
358  "Sao Tome and Principe",
359  "El Salvador",
360  "Syrian Arab Republic",
361  "Swaziland",
362  "Turks and Caicos Islands",
363  "Chad",
364  "French Southern Territories",
365  "Togo",
366  "Thailand",
367  "Tajikistan",
368  "Tokelau",
369  "Turkmenistan",
370  "Tunisia",
371  "Tonga",
372  "Timor-Leste",
373  "Turkey",
374  "Trinidad and Tobago",
375  "Tuvalu",
376  "Taiwan",
377  "Tanzania, United Republic of",
378  "Ukraine",
379  "Uganda",
380  "United States Minor Outlying Islands",
381  "United States",
382  "Uruguay",
383  "Uzbekistan",
384  "Holy See (Vatican City State)",
385  "Saint Vincent and the Grenadines",
386  "Venezuela",
387  "Virgin Islands, British",
388  "Virgin Islands, U.S.",
389  "Vietnam",
390  "Vanuatu",
391  "Wallis and Futuna",
392  "Samoa",
393  "Yemen",
394  "Mayotte",
395  "Serbia",
396  "South Africa",
397  "Zambia",
398  "Montenegro",
399  "Zimbabwe",
400  "Anonymous Proxy",
401  "Satellite Provider",
402  "Other",
403  "Aland Islands",
404  "Guernsey",
405  "Isle of Man",
406  "Jersey",
407  "Saint Barthelemy",
408  "Saint Martin",
409  "Bonaire, Saint Eustatius and Saba",
410  "South Sudan",
411  "Other"};
412 
413 const char *GeoIP_country_name[256] = {
414  "N/A",
415  "Asia/Pacific Region",
416  "Europe",
417  "Andorra",
418  "United Arab Emirates",
419  "Afghanistan",
420  "Antigua and Barbuda",
421  "Anguilla",
422  "Albania",
423  "Armenia",
424  "Curacao",
425  "Angola",
426  "Antarctica",
427  "Argentina",
428  "American Samoa",
429  "Austria",
430  "Australia",
431  "Aruba",
432  "Azerbaijan",
433  "Bosnia and Herzegovina",
434  "Barbados",
435  "Bangladesh",
436  "Belgium",
437  "Burkina Faso",
438  "Bulgaria",
439  "Bahrain",
440  "Burundi",
441  "Benin",
442  "Bermuda",
443  "Brunei Darussalam",
444  "Bolivia",
445  "Brazil",
446  "Bahamas",
447  "Bhutan",
448  "Bouvet Island",
449  "Botswana",
450  "Belarus",
451  "Belize",
452  "Canada",
453  "Cocos (Keeling) Islands",
454  "Congo, The Democratic Republic of the",
455  "Central African Republic",
456  "Congo",
457  "Switzerland",
458  "Cote D'Ivoire",
459  "Cook Islands",
460  "Chile",
461  "Cameroon",
462  "China",
463  "Colombia",
464  "Costa Rica",
465  "Cuba",
466  "Cape Verde",
467  "Christmas Island",
468  "Cyprus",
469  "Czech Republic",
470  "Germany",
471  "Djibouti",
472  "Denmark",
473  "Dominica",
474  "Dominican Republic",
475  "Algeria",
476  "Ecuador",
477  "Estonia",
478  "Egypt",
479  "Western Sahara",
480  "Eritrea",
481  "Spain",
482  "Ethiopia",
483  "Finland",
484  "Fiji",
485  "Falkland Islands (Malvinas)",
486  "Micronesia, Federated States of",
487  "Faroe Islands",
488  "France",
489  "Sint Maarten (Dutch part)",
490  "Gabon",
491  "United Kingdom",
492  "Grenada",
493  "Georgia",
494  "French Guiana",
495  "Ghana",
496  "Gibraltar",
497  "Greenland",
498  "Gambia",
499  "Guinea",
500  "Guadeloupe",
501  "Equatorial Guinea",
502  "Greece",
503  "South Georgia and the South Sandwich Islands",
504  "Guatemala",
505  "Guam",
506  "Guinea-Bissau",
507  "Guyana",
508  "Hong Kong",
509  "Heard Island and McDonald Islands",
510  "Honduras",
511  "Croatia",
512  "Haiti",
513  "Hungary",
514  "Indonesia",
515  "Ireland",
516  "Israel",
517  "India",
518  "British Indian Ocean Territory",
519  "Iraq",
520  "Iran, Islamic Republic of",
521  "Iceland",
522  "Italy",
523  "Jamaica",
524  "Jordan",
525  "Japan",
526  "Kenya",
527  "Kyrgyzstan",
528  "Cambodia",
529  "Kiribati",
530  "Comoros",
531  "Saint Kitts and Nevis",
532  "Korea, Democratic People's Republic of",
533  "Korea, Republic of",
534  "Kuwait",
535  "Cayman Islands",
536  "Kazakhstan",
537  "Lao People's Democratic Republic",
538  "Lebanon",
539  "Saint Lucia",
540  "Liechtenstein",
541  "Sri Lanka",
542  "Liberia",
543  "Lesotho",
544  "Lithuania",
545  "Luxembourg",
546  "Latvia",
547  "Libya",
548  "Morocco",
549  "Monaco",
550  "Moldova, Republic of",
551  "Madagascar",
552  "Marshall Islands",
553  "Macedonia",
554  "Mali",
555  "Myanmar",
556  "Mongolia",
557  "Macau",
558  "Northern Mariana Islands",
559  "Martinique",
560  "Mauritania",
561  "Montserrat",
562  "Malta",
563  "Mauritius",
564  "Maldives",
565  "Malawi",
566  "Mexico",
567  "Malaysia",
568  "Mozambique",
569  "Namibia",
570  "New Caledonia",
571  "Niger",
572  "Norfolk Island",
573  "Nigeria",
574  "Nicaragua",
575  "Netherlands",
576  "Norway",
577  "Nepal",
578  "Nauru",
579  "Niue",
580  "New Zealand",
581  "Oman",
582  "Panama",
583  "Peru",
584  "French Polynesia",
585  "Papua New Guinea",
586  "Philippines",
587  "Pakistan",
588  "Poland",
589  "Saint Pierre and Miquelon",
590  "Pitcairn Islands",
591  "Puerto Rico",
592  "Palestinian Territory",
593  "Portugal",
594  "Palau",
595  "Paraguay",
596  "Qatar",
597  "Reunion",
598  "Romania",
599  "Russian Federation",
600  "Rwanda",
601  "Saudi Arabia",
602  "Solomon Islands",
603  "Seychelles",
604  "Sudan",
605  "Sweden",
606  "Singapore",
607  "Saint Helena",
608  "Slovenia",
609  "Svalbard and Jan Mayen",
610  "Slovakia",
611  "Sierra Leone",
612  "San Marino",
613  "Senegal",
614  "Somalia",
615  "Suriname",
616  "Sao Tome and Principe",
617  "El Salvador",
618  "Syrian Arab Republic",
619  "Swaziland",
620  "Turks and Caicos Islands",
621  "Chad",
622  "French Southern Territories",
623  "Togo",
624  "Thailand",
625  "Tajikistan",
626  "Tokelau",
627  "Turkmenistan",
628  "Tunisia",
629  "Tonga",
630  "Timor-Leste",
631  "Turkey",
632  "Trinidad and Tobago",
633  "Tuvalu",
634  "Taiwan",
635  "Tanzania, United Republic of",
636  "Ukraine",
637  "Uganda",
638  "United States Minor Outlying Islands",
639  "United States",
640  "Uruguay",
641  "Uzbekistan",
642  "Holy See (Vatican City State)",
643  "Saint Vincent and the Grenadines",
644  "Venezuela",
645  "Virgin Islands, British",
646  "Virgin Islands, U.S.",
647  "Vietnam",
648  "Vanuatu",
649  "Wallis and Futuna",
650  "Samoa",
651  "Yemen",
652  "Mayotte",
653  "Serbia",
654  "South Africa",
655  "Zambia",
656  "Montenegro",
657  "Zimbabwe",
658  "Anonymous Proxy",
659  "Satellite Provider",
660  "Other",
661  "Aland Islands",
662  "Guernsey",
663  "Isle of Man",
664  "Jersey",
665  "Saint Barthelemy",
666  "Saint Martin",
667  "Bonaire, Saint Eustatius and Saba",
668  "South Sudan",
669  "Other"};
670 
671 /* Possible continent codes are AF, AS, EU, NA, OC, SA for Africa, Asia, Europe,
672  North America, Oceania
673  and South America. */
674 
675 const char GeoIP_country_continent[256][3] = {
676  "--", "AS", "EU", "EU", "AS", "AS", "NA", "NA", "EU", "AS", "NA", "AF",
677  "AN", "SA", "OC", "EU", "OC", "NA", "AS", "EU", "NA", "AS", "EU", "AF",
678  "EU", "AS", "AF", "AF", "NA", "AS", "SA", "SA", "NA", "AS", "AN", "AF",
679  "EU", "NA", "NA", "AS", "AF", "AF", "AF", "EU", "AF", "OC", "SA", "AF",
680  "AS", "SA", "NA", "NA", "AF", "AS", "AS", "EU", "EU", "AF", "EU", "NA",
681  "NA", "AF", "SA", "EU", "AF", "AF", "AF", "EU", "AF", "EU", "OC", "SA",
682  "OC", "EU", "EU", "NA", "AF", "EU", "NA", "AS", "SA", "AF", "EU", "NA",
683  "AF", "AF", "NA", "AF", "EU", "AN", "NA", "OC", "AF", "SA", "AS", "AN",
684  "NA", "EU", "NA", "EU", "AS", "EU", "AS", "AS", "AS", "AS", "AS", "EU",
685  "EU", "NA", "AS", "AS", "AF", "AS", "AS", "OC", "AF", "NA", "AS", "AS",
686  "AS", "NA", "AS", "AS", "AS", "NA", "EU", "AS", "AF", "AF", "EU", "EU",
687  "EU", "AF", "AF", "EU", "EU", "AF", "OC", "EU", "AF", "AS", "AS", "AS",
688  "OC", "NA", "AF", "NA", "EU", "AF", "AS", "AF", "NA", "AS", "AF", "AF",
689  "OC", "AF", "OC", "AF", "NA", "EU", "EU", "AS", "OC", "OC", "OC", "AS",
690  "NA", "SA", "OC", "OC", "AS", "AS", "EU", "NA", "OC", "NA", "AS", "EU",
691  "OC", "SA", "AS", "AF", "EU", "EU", "AF", "AS", "OC", "AF", "AF", "EU",
692  "AS", "AF", "EU", "EU", "EU", "AF", "EU", "AF", "AF", "SA", "AF", "NA",
693  "AS", "AF", "NA", "AF", "AN", "AF", "AS", "AS", "OC", "AS", "AF", "OC",
694  "AS", "EU", "NA", "OC", "AS", "AF", "EU", "AF", "OC", "NA", "SA", "AS",
695  "EU", "NA", "SA", "NA", "NA", "AS", "OC", "OC", "OC", "AS", "AF", "EU",
696  "AF", "AF", "EU", "AF", "--", "--", "--", "EU", "EU", "EU", "EU", "NA",
697  "NA", "NA", "AF", "--"};
698 
699 static const char *get_db_description(int dbtype) {
700  const char *ptr;
701  if (dbtype >= NUM_DB_TYPES || dbtype < 0) {
702  return "Unknown";
703  }
704  ptr = GeoIPDBDescription[dbtype];
705  return ptr == NULL ? "Unknown" : ptr;
706 }
707 
708 geoipv6_t _GeoIP_lookupaddress_v6(const char *host);
709 
710 #if defined(_WIN32)
711 /* http://www.mail-archive.com/users@ipv6.org/msg02107.html */
712 static const char *
713 _GeoIP_inet_ntop(int af, const void *src, char *dst, socklen_t cnt) {
714  if (af == AF_INET) {
715  struct sockaddr_in in;
716  memset(&in, 0, sizeof(in));
717  in.sin_family = AF_INET;
718  memcpy(&in.sin_addr, src, sizeof(struct in_addr));
719  getnameinfo((struct sockaddr *)&in,
720  sizeof(struct sockaddr_in),
721  dst,
722  cnt,
723  NULL,
724  0,
725  NI_NUMERICHOST);
726  return dst;
727  } else if (af == AF_INET6) {
728  struct sockaddr_in6 in;
729  memset(&in, 0, sizeof(in));
730  in.sin6_family = AF_INET6;
731  memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
732  getnameinfo((struct sockaddr *)&in,
733  sizeof(struct sockaddr_in6),
734  dst,
735  cnt,
736  NULL,
737  0,
738  NI_NUMERICHOST);
739  return dst;
740  }
741  return NULL;
742 }
743 
744 static int _GeoIP_inet_pton(int af, const char *src, void *dst) {
745  struct addrinfo hints, *res, *ressave;
746 
747  memset(&hints, 0, sizeof(struct addrinfo));
748  hints.ai_family = af;
749 
750  if (getaddrinfo(src, NULL, &hints, &res) != 0) {
751  return -1;
752  }
753 
754  ressave = res;
755 
756  while (res) {
757  memcpy(dst, res->ai_addr, res->ai_addrlen);
758  res = res->ai_next;
759  }
760 
761  freeaddrinfo(ressave);
762  return 0;
763 }
764 #else
765 static int _GeoIP_inet_pton(int af, const char *src, void *dst) {
766  return inet_pton(af, src, dst);
767 }
768 static const char *
769 _GeoIP_inet_ntop(int af, const void *src, char *dst, socklen_t cnt) {
770  return inet_ntop(af, src, dst, cnt);
771 }
772 #endif /* defined(_WIN32) */
773 
775  int i;
776  for (i = 0; i < 16; i++) {
777  if (v6.s6_addr[i]) {
778  return 0;
779  }
780  }
781  return 1;
782 }
783 
785  int i;
786  if ((v6->s6_addr[0]) != 0x20) {
787  return;
788  }
789  if ((v6->s6_addr[1]) != 0x01) {
790  return;
791  }
792  if ((v6->s6_addr[2]) != 0x00) {
793  return;
794  }
795  if ((v6->s6_addr[3]) != 0x00) {
796  return;
797  }
798 
799  for (i = 0; i < 12; i++) {
800  v6->s6_addr[i] = 0;
801  }
802  for (; i < 16; i++) {
803  v6->s6_addr[i] ^= 0xff;
804  }
805 }
806 
808  NULL,
809  "GeoIP Country Edition",
810  "GeoIP City Edition, Rev 1",
811  "GeoIP Region Edition, Rev 1",
812  "GeoIP ISP Edition",
813  "GeoIP Organization Edition",
814  "GeoIP City Edition, Rev 0",
815  "GeoIP Region Edition, Rev 0",
816  "GeoIP Proxy Edition",
817  "GeoIP ASNum Edition",
818  "GeoIP Netspeed Edition",
819  "GeoIP Domain Name Edition",
820  "GeoIP Country V6 Edition",
821  "GeoIP LocationID ASCII Edition",
822  "GeoIP Accuracy Radius Edition",
823  NULL,
824  NULL,
825  "GeoIP Large Country Edition",
826  "GeoIP Large Country V6 Edition",
827  NULL,
828  "GeoIP CCM Edition",
829  "GeoIP ASNum V6 Edition",
830  "GeoIP ISP V6 Edition",
831  "GeoIP Organization V6 Edition",
832  "GeoIP Domain Name V6 Edition",
833  "GeoIP LocationID ASCII V6 Edition",
834  "GeoIP Registrar Edition",
835  "GeoIP Registrar V6 Edition",
836  "GeoIP UserType Edition",
837  "GeoIP UserType V6 Edition",
838  "GeoIP City Edition V6, Rev 1",
839  "GeoIP City Edition V6, Rev 0",
840  "GeoIP Netspeed Edition, Rev 1",
841  "GeoIP Netspeed Edition V6, Rev1",
842  "GeoIP Country Confidence Edition",
843  "GeoIP City Confidence Edition",
844  "GeoIP Region Confidence Edition",
845  "GeoIP Postal Confidence Edition",
846  "GeoIP Accuracy Radius Edition V6"};
847 
849 
851 
852 char *_GeoIP_full_path_to(const char *file_name) {
853  int len;
854  char *path = malloc(sizeof(char) * 1024);
855 
856  if (GeoIP_custom_directory == NULL) {
857 #if !defined(_WIN32)
858  memset(path, 0, sizeof(char) * 1024);
859  snprintf(
860  path, sizeof(char) * 1024 - 1, "%s/%s", GEOIPDATADIR, file_name);
861 #else
862  char buf[MAX_PATH], *p, *q = NULL;
863  memset(buf, 0, sizeof(buf));
864  len = GetModuleFileNameA(GetModuleHandle(NULL), buf, sizeof(buf) - 1);
865  for (p = buf + len; p > buf; p--) {
866  if (*p == '\\') {
867  if (!q) {
868  q = p;
869  } else {
870  *p = '/';
871  }
872  }
873  }
874  *q = 0;
875  memset(path, 0, sizeof(char) * 1024);
876  snprintf(path, sizeof(char) * 1024 - 1, "%s/%s", buf, file_name);
877 #endif
878  } else {
879  len = strlen(GeoIP_custom_directory);
880  if (GeoIP_custom_directory[len - 1] != '/') {
881  snprintf(path,
882  sizeof(char) * 1024 - 1,
883  "%s/%s",
885  file_name);
886  } else {
887  snprintf(path,
888  sizeof(char) * 1024 - 1,
889  "%s%s",
891  file_name);
892  }
893  }
894  return path;
895 }
896 
897 char **GeoIPDBFileName = NULL;
898 
900  if (NULL == GeoIPDBFileName) {
901  GeoIPDBFileName = malloc(sizeof(char *) * NUM_DB_TYPES);
902  memset(GeoIPDBFileName, 0, sizeof(char *) * NUM_DB_TYPES);
903 
905  _GeoIP_full_path_to("GeoIP.dat");
907  _GeoIP_full_path_to("GeoIPRegion.dat");
909  _GeoIP_full_path_to("GeoIPRegion.dat");
911  _GeoIP_full_path_to("GeoIPCity.dat");
913  _GeoIP_full_path_to("GeoIPCity.dat");
915  _GeoIP_full_path_to("GeoIPISP.dat");
917  _GeoIP_full_path_to("GeoIPOrg.dat");
919  _GeoIP_full_path_to("GeoIPProxy.dat");
921  _GeoIP_full_path_to("GeoIPASNum.dat");
923  _GeoIP_full_path_to("GeoIPNetSpeed.dat");
925  _GeoIP_full_path_to("GeoIPDomain.dat");
927  _GeoIP_full_path_to("GeoIPv6.dat");
929  _GeoIP_full_path_to("GeoIPLocA.dat");
931  _GeoIP_full_path_to("GeoIPDistance.dat");
933  _GeoIP_full_path_to("GeoIP.dat");
935  _GeoIP_full_path_to("GeoIPv6.dat");
937  _GeoIP_full_path_to("GeoIPASNumv6.dat");
939  _GeoIP_full_path_to("GeoIPISPv6.dat");
941  _GeoIP_full_path_to("GeoIPOrgv6.dat");
943  _GeoIP_full_path_to("GeoIPDomainv6.dat");
945  _GeoIP_full_path_to("GeoIPLocAv6.dat");
947  _GeoIP_full_path_to("GeoIPRegistrar.dat");
949  _GeoIP_full_path_to("GeoIPRegistrarv6.dat");
951  _GeoIP_full_path_to("GeoIPUserType.dat");
953  _GeoIP_full_path_to("GeoIPUserTypev6.dat");
955  _GeoIP_full_path_to("GeoIPCityv6.dat");
957  _GeoIP_full_path_to("GeoIPCityv6.dat");
959  _GeoIP_full_path_to("GeoIPNetSpeedCell.dat");
961  _GeoIP_full_path_to("GeoIPNetSpeedCellv6.dat");
963  _GeoIP_full_path_to("GeoIPCountryConf.dat");
965  _GeoIP_full_path_to("GeoIPCityConf.dat");
967  _GeoIP_full_path_to("GeoIPRegionConf.dat");
969  _GeoIP_full_path_to("GeoIPPostalConf.dat");
971  _GeoIP_full_path_to("GeoIPDistancev6.dat");
972  }
973 }
974 
975 static int _file_exists(const char *file_name) {
976  struct stat file_stat;
977  return (stat(file_name, &file_stat) == 0) ? 1 : 0;
978 }
979 
980 char *_GeoIP_iso_8859_1__utf8(const char *iso) {
981  signed char c;
982  char k;
983  char *p;
984  char *t = (char *)iso;
985  int len = 0;
986  while ((c = *t++)) {
987  if (c < 0) {
988  len++;
989  }
990  }
991  len += t - iso;
992  t = p = malloc(len);
993 
994  if (p) {
995  while ((c = *iso++)) {
996  if (c < 0) {
997  k = (char)0xc2;
998  if (c >= -64) {
999  k++;
1000  }
1001  *t++ = k;
1002  c &= ~0x40;
1003  }
1004  *t++ = c;
1005  }
1006  *t++ = 0x00;
1007  }
1008  return p;
1009 }
1010 
1011 int GeoIP_is_private_ipnum_v4(unsigned long ipnum) {
1012  return ((ipnum >= 167772160U && ipnum <= 184549375U) ||
1013  (ipnum >= 2851995648U && ipnum <= 2852061183U) ||
1014  (ipnum >= 2886729728U && ipnum <= 2887778303U) ||
1015  (ipnum >= 3232235520U && ipnum <= 3232301055U) ||
1016  (ipnum >= 2130706432U && ipnum <= 2147483647U))
1017  ? 1
1018  : 0;
1019 }
1020 
1021 int GeoIP_is_private_v4(const char *addr) {
1022  unsigned long ipnum = GeoIP_addr_to_num(addr);
1023  return GeoIP_is_private_ipnum_v4(ipnum);
1024 }
1025 
1026 int GeoIP_db_avail(int type) {
1027  const char *filePath;
1028  if (type < 0 || type >= NUM_DB_TYPES) {
1029  return 0;
1030  }
1032  filePath = GeoIPDBFileName[type];
1033  if (NULL == filePath) {
1034  return 0;
1035  }
1036  return _file_exists(filePath);
1037 }
1038 
1039 static int _database_has_content(int database_type) {
1040  return (database_type != GEOIP_COUNTRY_EDITION &&
1041  database_type != GEOIP_PROXY_EDITION &&
1042  database_type != GEOIP_NETSPEED_EDITION &&
1043  database_type != GEOIP_COUNTRY_EDITION_V6 &&
1044  database_type != GEOIP_LARGE_COUNTRY_EDITION &&
1045  database_type != GEOIP_LARGE_COUNTRY_EDITION_V6 &&
1046  database_type != GEOIP_REGION_EDITION_REV0 &&
1047  database_type != GEOIP_REGION_EDITION_REV1)
1048  ? 1
1049  : 0;
1050 }
1051 
1052 static ssize_t get_index_size(GeoIP *gi, struct stat *buf) {
1053  ssize_t index_size;
1054  unsigned int segment;
1055 
1056  if (!_database_has_content(gi->databaseType)) {
1057  return buf->st_size;
1058  }
1059 
1060  segment = gi->databaseSegments[0];
1061  index_size = segment * (ssize_t)gi->record_length * 2;
1062 
1063  /* check for overflow in multiplication */
1064  if (segment != 0 &&
1065  index_size / segment != (ssize_t)gi->record_length * 2) {
1066  return -1;
1067  }
1068 
1069  /* Index size should never exceed the size of the file */
1070  if (index_size > buf->st_size) {
1071  return -1;
1072  }
1073 
1074  return index_size;
1075 }
1076 
1077 static void _setup_segments(GeoIP *gi) {
1078  int i, j, segment_record_length;
1079  unsigned char delim[3];
1080  unsigned char buf[LARGE_SEGMENT_RECORD_LENGTH];
1081  off_t offset = gi->size - 3;
1082  int fno = fileno(gi->GeoIPDatabase);
1083 
1084  gi->databaseSegments = NULL;
1085 
1086  /* default to GeoIP Country Edition */
1089 
1090  for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) {
1091  if (pread(fno, delim, 3, offset) != 3) {
1092  return;
1093  }
1094  offset += 3;
1095  if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) {
1096  if (pread(fno, &gi->databaseType, 1, offset) != 1) {
1097  return;
1098  }
1099  offset++;
1100  if (gi->databaseType >= 106) {
1101  /* backwards compatibility with databases from April 2003 and
1102  * earlier */
1103  gi->databaseType -= 105;
1104  }
1105 
1107  /* Region Edition, pre June 2003 */
1108  gi->databaseSegments = malloc(sizeof(unsigned int));
1109  if (gi->databaseSegments == NULL) {
1110  return;
1111  }
1113  } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) {
1114  /* Region Edition, post June 2003 */
1115  gi->databaseSegments = malloc(sizeof(unsigned int));
1116  if (gi->databaseSegments == NULL) {
1117  return;
1118  }
1120  } else if (gi->databaseType == GEOIP_CITY_EDITION_REV0 ||
1145  /* City/Org Editions have two segments, read offset of second
1146  * segment */
1147  gi->databaseSegments = malloc(sizeof(unsigned int));
1148  if (gi->databaseSegments == NULL) {
1149  return;
1150  }
1151  gi->databaseSegments[0] = 0;
1152  segment_record_length = SEGMENT_RECORD_LENGTH;
1153 
1154  if (pread(fno, buf, segment_record_length, offset) !=
1155  segment_record_length) {
1156  free(gi->databaseSegments);
1157  gi->databaseSegments = NULL;
1158  return;
1159  }
1160 
1161  for (j = 0; j < segment_record_length; j++) {
1162  gi->databaseSegments[0] += (buf[j] << (j * 8));
1163  }
1164 
1165  /* the record_length must be correct from here on */
1166  if (gi->databaseType == GEOIP_ORG_EDITION ||
1173  }
1174  }
1175  break;
1176  } else {
1177  offset -= 4;
1178  if (offset < 0) {
1179  gi->databaseSegments = NULL;
1180  return;
1181  }
1182  }
1183  }
1184  if (gi->databaseType == GEOIP_COUNTRY_EDITION ||
1188  gi->databaseSegments = malloc(sizeof(unsigned int));
1189  if (gi->databaseSegments == NULL) {
1190  return;
1191  }
1193  } else if (gi->databaseType == GEOIP_LARGE_COUNTRY_EDITION ||
1195  gi->databaseSegments = malloc(sizeof(unsigned int));
1196  if (gi->databaseSegments == NULL) {
1197  return;
1198  }
1200  }
1201 }
1202 
1203 static void _check_mtime(GeoIP *gi) {
1204  struct stat buf;
1205  ssize_t idx_size;
1206 
1207 #if !defined(_WIN32)
1208  struct timeval t;
1209 #else /* !defined(_WIN32) */
1210  FILETIME ft;
1211  ULONGLONG t;
1212 #endif /* !defined(_WIN32) */
1213 
1214  if (gi->flags & GEOIP_CHECK_CACHE) {
1215 
1216 #if !defined(_WIN32)
1217  /* stat only has second granularity, so don't
1218  * call it more than once a second */
1219  if (0 != gettimeofday(&t, NULL)) {
1220  DEBUG_MSGF(
1221  gi->flags, "Error calling gettimeofday: %s\n", strerror(errno));
1222  return;
1223  }
1224 
1225  if (t.tv_sec == gi->last_mtime_check) {
1226  return;
1227  }
1228  gi->last_mtime_check = t.tv_sec;
1229 
1230 #else /* !defined(_WIN32) */
1231 
1232  /* stat only has second granularity, so don't
1233  call it more than once a second */
1234  GetSystemTimeAsFileTime(&ft);
1235  t = FILETIME_TO_USEC(ft) / 1000 / 1000;
1236  if (t == gi->last_mtime_check) {
1237  return;
1238  }
1239  gi->last_mtime_check = t;
1240 
1241 #endif /* !defined(_WIN32) */
1242 
1243  if (stat(gi->file_path, &buf) != -1) {
1244  /* make sure that the database file is at least 60
1245  * seconds untouched. Otherwise we might load the
1246  * database only partly and crash
1247  */
1248  if (buf.st_mtime != gi->mtime &&
1249  (buf.st_mtime + 60 < gi->last_mtime_check)) {
1250  /* GeoIP Database file updated */
1251  if (gi->flags & (GEOIP_MEMORY_CACHE | GEOIP_MMAP_CACHE)) {
1252  if (gi->cache && (gi->flags & GEOIP_MMAP_CACHE)) {
1253 #if !defined(_WIN32)
1254  /* MMAP is only avail on UNIX */
1255  munmap(gi->cache, gi->size);
1256  gi->cache = NULL;
1257 #endif
1258  } else {
1259  /* reload database into memory cache */
1260  if ((gi->cache = (unsigned char *)realloc(
1261  gi->cache, buf.st_size)) == NULL) {
1262  DEBUG_MSGF(gi->flags,
1263  "Out of memory when reloading %s\n",
1264  gi->file_path);
1265  return;
1266  }
1267  }
1268  }
1269  /* refresh filehandle */
1270  fclose(gi->GeoIPDatabase);
1271  gi->GeoIPDatabase = fopen(gi->file_path, "rb");
1272  if (gi->GeoIPDatabase == NULL) {
1273  DEBUG_MSGF(gi->flags,
1274  "Error Opening file %s when reloading\n",
1275  gi->file_path);
1276  return;
1277  }
1278  gi->mtime = buf.st_mtime;
1279  gi->size = buf.st_size;
1280 
1281  if (gi->flags & GEOIP_MMAP_CACHE) {
1282 #if defined(_WIN32)
1283  DEBUG_MSGF(gi->flags,
1284  "GEOIP_MMAP_CACHE is not supported on WIN32\n");
1285  gi->cache = 0;
1286  return;
1287 #else
1288  gi->cache = mmap(NULL,
1289  buf.st_size,
1290  PROT_READ,
1291  MAP_PRIVATE,
1292  fileno(gi->GeoIPDatabase),
1293  0);
1294  if (gi->cache == MAP_FAILED) {
1295 
1296  DEBUG_MSGF(gi->flags,
1297  "Error remapping file %s when reloading\n",
1298  gi->file_path);
1299 
1300  gi->cache = NULL;
1301  return;
1302  }
1303 #endif
1304  } else if (gi->flags & GEOIP_MEMORY_CACHE) {
1305  if (pread(fileno(gi->GeoIPDatabase),
1306  gi->cache,
1307  buf.st_size,
1308  0) != (ssize_t)buf.st_size) {
1309  DEBUG_MSGF(gi->flags,
1310  "Error reading file %s when reloading\n",
1311  gi->file_path);
1312  return;
1313  }
1314  }
1315 
1316  if (gi->databaseSegments != NULL) {
1317  free(gi->databaseSegments);
1318  gi->databaseSegments = NULL;
1319  }
1320  _setup_segments(gi);
1321  if (gi->databaseSegments == NULL) {
1322  DEBUG_MSGF(gi->flags,
1323  "Error reading file %s -- corrupt\n",
1324  gi->file_path);
1325  return;
1326  }
1327 
1328  idx_size = get_index_size(gi, &buf);
1329  if (idx_size < 0) {
1330  DEBUG_MSGF(
1331  gi->flags, "Error file %s -- corrupt\n", gi->file_path);
1332  return;
1333  }
1334 
1335  if (gi->flags & GEOIP_INDEX_CACHE) {
1336  gi->index_cache = (unsigned char *)realloc(
1337  gi->index_cache, sizeof(unsigned char) * idx_size);
1338  if (gi->index_cache != NULL) {
1339  if (pread(fileno(gi->GeoIPDatabase),
1340  gi->index_cache,
1341  idx_size,
1342  0) != idx_size) {
1343  DEBUG_MSGF(
1344  gi->flags,
1345  "Error reading file %s where reloading\n",
1346  gi->file_path);
1347  return;
1348  }
1349  }
1350  }
1351  }
1352  }
1353  }
1354  return;
1355 }
1356 
1357 #define ADDR_STR_LEN (8 * 4 + 7 + 1)
1358 unsigned int
1360  int depth;
1361  char paddr[ADDR_STR_LEN];
1362  unsigned int x;
1363  unsigned char stack_buffer[2 * MAX_RECORD_LENGTH];
1364  const unsigned char *buf = (gi->cache == NULL) ? stack_buffer : NULL;
1365  unsigned int offset = 0;
1366 
1367  const unsigned char *p;
1368  int j;
1369  int fno = fileno(gi->GeoIPDatabase);
1370 
1371  unsigned int record_pair_length = gi->record_length * 2;
1372 
1373  _check_mtime(gi);
1374  if (GeoIP_teredo(gi)) {
1375  __GEOIP_PREPARE_TEREDO(&ipnum);
1376  }
1377  for (depth = 127; depth >= 0; depth--) {
1378  unsigned int byte_offset = record_pair_length * offset;
1379  if (byte_offset > gi->size - record_pair_length) {
1380  /* The pointer is invalid */
1381  break;
1382  }
1383  if (gi->cache == NULL && gi->index_cache == NULL) {
1384  /* read from disk */
1385  if (pread(
1386  fno, stack_buffer, record_pair_length, (long)byte_offset) !=
1387  record_pair_length) {
1388  break;
1389  }
1390  } else if (gi->index_cache == NULL) {
1391  /* simply point to record in memory */
1392  buf = gi->cache + (long)byte_offset;
1393  } else {
1394  buf = gi->index_cache + (long)byte_offset;
1395  }
1396 
1397  if (GEOIP_CHKBIT_V6(depth, ipnum.s6_addr)) {
1398  /* Take the right-hand branch */
1399  if (gi->record_length == 3) {
1400  /* Most common case is completely unrolled and uses constants.
1401  */
1402  x = (buf[3 * 1 + 0] << (0 * 8)) + (buf[3 * 1 + 1] << (1 * 8)) +
1403  (buf[3 * 1 + 2] << (2 * 8));
1404 
1405  } else {
1406  /* General case */
1407  j = gi->record_length;
1408  p = &buf[2 * j];
1409  x = 0;
1410  do {
1411  x <<= 8;
1412  x += *(--p);
1413  } while (--j);
1414  }
1415 
1416  } else {
1417  /* Take the left-hand branch */
1418  if (gi->record_length == 3) {
1419  /* Most common case is completely unrolled and uses constants.
1420  */
1421  x = (buf[3 * 0 + 0] << (0 * 8)) + (buf[3 * 0 + 1] << (1 * 8)) +
1422  (buf[3 * 0 + 2] << (2 * 8));
1423  } else {
1424  /* General case */
1425  j = gi->record_length;
1426  p = &buf[1 * j];
1427  x = 0;
1428  do {
1429  x <<= 8;
1430  x += *(--p);
1431  } while (--j);
1432  }
1433  }
1434 
1435  if (x >= gi->databaseSegments[0]) {
1436  gi->netmask = gl->netmask = 128 - depth;
1437  return x;
1438  }
1439  offset = x;
1440  }
1441 
1442  /* shouldn't reach here */
1443  _GeoIP_inet_ntop(AF_INET6, &ipnum.s6_addr[0], paddr, ADDR_STR_LEN);
1444  DEBUG_MSGF(gi->flags,
1445  "Error Traversing Database for ipnum = %s - Perhaps database is "
1446  "corrupt?\n",
1447  paddr);
1448  return 0;
1449 }
1450 
1452  geoipv6_t ipnum;
1453  if (1 == _GeoIP_inet_pton(AF_INET6, addr, &ipnum.s6_addr[0])) {
1454  return ipnum;
1455  }
1456  return IPV6_NULL;
1457 }
1458 
1459 unsigned int
1460 _GeoIP_seek_record_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) {
1461  int depth;
1462  unsigned int x;
1463  unsigned char stack_buffer[2 * MAX_RECORD_LENGTH];
1464  const unsigned char *buf = (gi->cache == NULL) ? stack_buffer : NULL;
1465  unsigned int offset = 0;
1466 
1467  const unsigned char *p;
1468  int j;
1469  int fno = fileno(gi->GeoIPDatabase);
1470 
1471  unsigned int record_pair_length = gi->record_length * 2;
1472 
1473  _check_mtime(gi);
1474  for (depth = 31; depth >= 0; depth--) {
1475  unsigned int byte_offset = record_pair_length * offset;
1476  if (byte_offset > gi->size - record_pair_length) {
1477  /* The pointer is invalid */
1478  break;
1479  }
1480  if (gi->cache == NULL && gi->index_cache == NULL) {
1481  /* read from disk */
1482  if (pread(fno, stack_buffer, record_pair_length, byte_offset) !=
1483  record_pair_length) {
1484  break;
1485  }
1486  } else if (gi->index_cache == NULL) {
1487  /* simply point to record in memory */
1488  buf = gi->cache + (long)byte_offset;
1489  } else {
1490  buf = gi->index_cache + (long)byte_offset;
1491  }
1492 
1493  if (ipnum & (1 << depth)) {
1494  /* Take the right-hand branch */
1495  if (gi->record_length == 3) {
1496  /* Most common case is completely unrolled and uses constants.
1497  */
1498  x = (buf[3 * 1 + 0] << (0 * 8)) + (buf[3 * 1 + 1] << (1 * 8)) +
1499  (buf[3 * 1 + 2] << (2 * 8));
1500 
1501  } else {
1502  /* General case */
1503  j = gi->record_length;
1504  p = &buf[2 * j];
1505  x = 0;
1506  do {
1507  x <<= 8;
1508  x += *(--p);
1509  } while (--j);
1510  }
1511 
1512  } else {
1513  /* Take the left-hand branch */
1514  if (gi->record_length == 3) {
1515  /* Most common case is completely unrolled and uses constants.
1516  */
1517  x = (buf[3 * 0 + 0] << (0 * 8)) + (buf[3 * 0 + 1] << (1 * 8)) +
1518  (buf[3 * 0 + 2] << (2 * 8));
1519  } else {
1520  /* General case */
1521  j = gi->record_length;
1522  p = &buf[1 * j];
1523  x = 0;
1524  do {
1525  x <<= 8;
1526  x += *(--p);
1527  } while (--j);
1528  }
1529  }
1530 
1531  if (x >= gi->databaseSegments[0]) {
1532  gi->netmask = gl->netmask = 32 - depth;
1533  return x;
1534  }
1535  offset = x;
1536  }
1537  /* shouldn't reach here */
1538  DEBUG_MSGF(gi->flags,
1539  "Error Traversing Database for ipnum = %lu - Perhaps database "
1540  "is corrupt?\n",
1541  ipnum);
1542  return 0;
1543 }
1544 
1545 unsigned long GeoIP_addr_to_num(const char *addr) {
1546  unsigned int c, octet, t;
1547  unsigned long ipnum;
1548  int i = 3;
1549 
1550  octet = ipnum = 0;
1551  while ((c = *addr++)) {
1552  if (c == '.') {
1553  if (octet > 255) {
1554  return 0;
1555  }
1556  ipnum <<= 8;
1557  ipnum += octet;
1558  i--;
1559  octet = 0;
1560  } else {
1561  t = octet;
1562  octet <<= 3;
1563  octet += t;
1564  octet += t;
1565  c -= '0';
1566  if (c > 9) {
1567  return 0;
1568  }
1569  octet += c;
1570  }
1571  }
1572  if ((octet > 255) || (i != 0)) {
1573  return 0;
1574  }
1575  ipnum <<= 8;
1576  return ipnum + octet;
1577 }
1578 
1579 GeoIP *GeoIP_open_type(int type, int flags) {
1580  GeoIP *gi;
1581  const char *filePath;
1582  if (type < 0 || type >= NUM_DB_TYPES) {
1583  printf("Invalid database type %d\n", type);
1584  return NULL;
1585  }
1587  filePath = GeoIPDBFileName[type];
1588  if (filePath == NULL) {
1589  printf("Invalid database type %d\n", type);
1590  return NULL;
1591  }
1592  gi = GeoIP_open(filePath, flags);
1593 
1594  if (gi) {
1595  /* make sure this is the requested database type */
1596  int database_type = gi->databaseType;
1597  if (database_type > 105) {
1598  database_type -= 105;
1599  }
1600  /* type must match, but we accept org and asnum,
1601  * since domain and *conf database have always the wrong type
1602  * for historical reason. Maybe we fix it at some point.
1603  */
1604  if (database_type == type || database_type == GEOIP_ASNUM_EDITION ||
1605  database_type == GEOIP_ORG_EDITION) {
1606  return gi;
1607  }
1608  GeoIP_delete(gi);
1609  }
1610 
1611  return NULL;
1612 }
1613 
1614 GeoIP *GeoIP_new(int flags) {
1615  GeoIP *gi;
1618  return gi;
1619 }
1620 
1621 GeoIP *GeoIP_open(const char *filename, int flags) {
1622  struct stat buf;
1623  ssize_t idx_size;
1624  GeoIP *gi;
1625  size_t len;
1626 
1627  gi = (GeoIP *)calloc(1, sizeof(GeoIP));
1628  if (gi == NULL) {
1629  return NULL;
1630  }
1631  len = sizeof(char) * (strlen(filename) + 1);
1632  gi->file_path = malloc(len);
1633  if (gi->file_path == NULL) {
1634  free(gi);
1635  return NULL;
1636  }
1637  strncpy(gi->file_path, filename, len);
1638  gi->GeoIPDatabase = fopen(filename, "rb");
1639  if (gi->GeoIPDatabase == NULL) {
1640  DEBUG_MSGF(flags, "Error Opening file %s\n", filename);
1641  GeoIP_delete(gi);
1642  return NULL;
1643  }
1644 
1645  if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) {
1646  DEBUG_MSGF(flags, "Error stating file %s\n", filename);
1647  GeoIP_delete(gi);
1648  return NULL;
1649  }
1650 
1651  gi->size = buf.st_size;
1652  if (flags & (GEOIP_MEMORY_CACHE | GEOIP_MMAP_CACHE)) {
1653  gi->mtime = buf.st_mtime;
1654 
1655  /* MMAP added my Peter Shipley */
1656  if (flags & GEOIP_MMAP_CACHE) {
1657 #if !defined(_WIN32)
1658  gi->cache = mmap(NULL,
1659  buf.st_size,
1660  PROT_READ,
1661  MAP_PRIVATE,
1662  fileno(gi->GeoIPDatabase),
1663  0);
1664  if (gi->cache == MAP_FAILED) {
1665  DEBUG_MSGF(flags, "Error mmaping file %s\n", filename);
1666  GeoIP_delete(gi);
1667  return NULL;
1668  }
1669 #endif
1670  } else {
1671  gi->cache =
1672  (unsigned char *)malloc(sizeof(unsigned char) * buf.st_size);
1673 
1674  if (gi->cache != NULL) {
1675  if (pread(
1676  fileno(gi->GeoIPDatabase), gi->cache, buf.st_size, 0) !=
1677  (ssize_t)buf.st_size) {
1678  DEBUG_MSGF(flags, "Error reading file %s\n", filename);
1679  GeoIP_delete(gi);
1680  return NULL;
1681  }
1682  }
1683  }
1684  } else {
1685  if (flags & GEOIP_CHECK_CACHE) {
1686  if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) {
1687  DEBUG_MSGF(flags, "Error stating file %s\n", filename);
1688  GeoIP_delete(gi);
1689  return NULL;
1690  }
1691  gi->mtime = buf.st_mtime;
1692  }
1693  gi->cache = NULL;
1694  }
1695  gi->flags = flags;
1697  gi->ext_flags = 1U << GEOIP_TEREDO_BIT;
1698  _setup_segments(gi);
1699  if (gi->databaseSegments == NULL) {
1700  DEBUG_MSGF(
1701  gi->flags, "Error reading file %s -- corrupt\n", gi->file_path);
1702  GeoIP_delete(gi);
1703  return NULL;
1704  }
1705 
1706  idx_size = get_index_size(gi, &buf);
1707 
1708  if (idx_size < 0) {
1709  DEBUG_MSGF(gi->flags, "Error file %s -- corrupt\n", gi->file_path);
1710  GeoIP_delete(gi);
1711  return NULL;
1712  }
1713 
1714  if (flags & GEOIP_INDEX_CACHE) {
1715  gi->index_cache =
1716  (unsigned char *)malloc(sizeof(unsigned char) * idx_size);
1717  if (gi->index_cache != NULL) {
1718  if (pread(
1719  fileno(gi->GeoIPDatabase), gi->index_cache, idx_size, 0) !=
1720  idx_size) {
1721  DEBUG_MSGF(gi->flags, "Error reading file %s\n", filename);
1722  GeoIP_delete(gi);
1723  return NULL;
1724  }
1725  }
1726  } else {
1727  gi->index_cache = NULL;
1728  }
1729 
1730  gi->last_mtime_check = 0;
1731 
1732  return gi;
1733 }
1734 
1735 void GeoIP_delete(GeoIP *gi) {
1736  if (gi == NULL) {
1737  return;
1738  }
1739  if (gi->GeoIPDatabase != NULL) {
1740  fclose(gi->GeoIPDatabase);
1741  }
1742  if (gi->cache != NULL) {
1743  if (gi->flags & GEOIP_MMAP_CACHE) {
1744 #if !defined(_WIN32)
1745  if (gi->cache) {
1746  munmap(gi->cache, gi->size);
1747  }
1748 #endif
1749  } else {
1750  free(gi->cache);
1751  }
1752  gi->cache = NULL;
1753  }
1754  free(gi->index_cache);
1755  free(gi->file_path);
1756  free(gi->databaseSegments);
1757  free(gi);
1758 }
1759 
1760 const char *
1762  int country_id;
1763  country_id = GeoIP_id_by_name_v6_gl(gi, name, gl);
1764  return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL;
1765 }
1766 
1767 const char *
1768 GeoIP_country_code_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) {
1769  int country_id;
1770  country_id = GeoIP_id_by_name_gl(gi, name, gl);
1771  return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL;
1772 }
1773 
1775  const char *name,
1776  GeoIPLookup *gl) {
1777  int country_id;
1778  country_id = GeoIP_id_by_name_v6_gl(gi, name, gl);
1779  return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL;
1780 }
1781 
1782 const char *
1783 GeoIP_country_code3_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) {
1784  int country_id;
1785  country_id = GeoIP_id_by_name_gl(gi, name, gl);
1786  return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL;
1787 }
1788 
1789 const char *
1791  int country_id;
1792  country_id = GeoIP_id_by_name_v6_gl(gi, name, gl);
1793  return GeoIP_country_name_by_id(gi, country_id);
1794 }
1795 
1796 const char *
1797 GeoIP_country_name_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) {
1798  int country_id;
1799  country_id = GeoIP_id_by_name_gl(gi, name, gl);
1800  return GeoIP_country_name_by_id(gi, country_id);
1801 }
1802 
1803 unsigned long _GeoIP_lookupaddress(const char *host) {
1804  unsigned long addr = inet_addr(host);
1805  struct hostent phe2;
1806  struct hostent *phe = &phe2;
1807  char *buf = NULL;
1808 #ifdef HAVE_GETHOSTBYNAME_R
1809  int buflength = 16384;
1810  int herr = 0;
1811 #endif
1812  int result = 0;
1813 #ifdef HAVE_GETHOSTBYNAME_R
1814  buf = malloc(buflength);
1815 #endif
1816  if (addr == INADDR_NONE) {
1817 #ifdef HAVE_GETHOSTBYNAME_R
1818  while (1) {
1819 /* we use gethostbyname_r here because it is thread-safe and gethostbyname is
1820  * not */
1821 #ifdef GETHOSTBYNAME_R_RETURNS_INT
1822  result = gethostbyname_r(host, &phe2, buf, buflength, &phe, &herr);
1823 #else
1824  phe = gethostbyname_r(host, &phe2, buf, buflength, &herr);
1825 #endif
1826  if (herr != ERANGE) {
1827  break;
1828  }
1829  if (result == 0) {
1830  break;
1831  }
1832  /* double the buffer if the buffer is too small */
1833  buflength = buflength * 2;
1834  buf = realloc(buf, buflength);
1835  }
1836 #else
1837  /* Some systems do not support gethostbyname_r, such as Mac OS X */
1838  phe = gethostbyname(host);
1839 #endif
1840  if (!phe || result != 0) {
1841  free(buf);
1842  return 0;
1843  }
1844 #if !defined(_WIN32)
1845  addr = *((in_addr_t *)phe->h_addr_list[0]);
1846 #else
1847  addr = ((IN_ADDR *)phe->h_addr_list[0])->S_un.S_addr;
1848 #endif
1849  }
1850 #ifdef HAVE_GETHOSTBYNAME_R
1851  free(buf);
1852 #endif
1853  return ntohl(addr);
1854 }
1855 
1857  geoipv6_t ipnum;
1858  int gaierr;
1859  struct addrinfo hints, *aifirst;
1860 
1861  memset(&hints, 0, sizeof(hints));
1862  hints.ai_family = AF_INET6;
1863  /* hints.ai_flags = AI_V4MAPPED; */
1864  hints.ai_socktype = SOCK_STREAM;
1865 
1866  if ((gaierr = getaddrinfo(host, NULL, &hints, &aifirst)) != 0) {
1867  /* DEBUG_MSGF("Err: %s (%d %s)\n", host, gaierr, gai_strerror(gaierr));
1868  */
1869  return IPV6_NULL;
1870  }
1871  memcpy(ipnum.s6_addr,
1872  ((struct sockaddr_in6 *)aifirst->ai_addr)->sin6_addr.s6_addr,
1873  sizeof(geoipv6_t));
1874  freeaddrinfo(aifirst);
1875  /* inet_pton(AF_INET6, host, ipnum.s6_addr); */
1876 
1877  return ipnum;
1878 }
1879 
1880 int GeoIP_id_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) {
1881  unsigned long ipnum;
1882  int ret;
1883  if (name == NULL) {
1884  return 0;
1885  }
1890  printf("Invalid database type %s, expected %s\n",
1893  return 0;
1894  }
1895  if (!(ipnum = _GeoIP_lookupaddress(name))) {
1896  return 0;
1897  }
1898  ret = _GeoIP_seek_record_gl(gi, ipnum, gl) - gi->databaseSegments[0];
1899  return ret;
1900 }
1901 
1902 int GeoIP_id_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) {
1903  geoipv6_t ipnum;
1904  int ret;
1905  if (name == NULL) {
1906  return 0;
1907  }
1910  printf("Invalid database type %s, expected %s\n",
1913  return 0;
1914  }
1915  ipnum = _GeoIP_lookupaddress_v6(name);
1916  if (__GEOIP_V6_IS_NULL(ipnum)) {
1917  return 0;
1918  }
1919 
1920  ret = _GeoIP_seek_record_v6_gl(gi, ipnum, gl) - gi->databaseSegments[0];
1921  return ret;
1922 }
1923 
1924 const char *
1926  int country_id;
1927  country_id = GeoIP_id_by_addr_v6_gl(gi, addr, gl);
1928  return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL;
1929 }
1930 
1931 const char *
1932 GeoIP_country_code_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) {
1933  int country_id;
1934  country_id = GeoIP_id_by_addr_gl(gi, addr, gl);
1935  return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL;
1936 }
1938  const char *addr,
1939  GeoIPLookup *gl) {
1940  int country_id;
1941  country_id = GeoIP_id_by_addr_v6_gl(gi, addr, gl);
1942  return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL;
1943 }
1944 
1945 const char *
1946 GeoIP_country_code3_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) {
1947  int country_id;
1948  country_id = GeoIP_id_by_addr_gl(gi, addr, gl);
1949  return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL;
1950 }
1951 
1952 const char *
1954  int country_id;
1955  country_id = GeoIP_id_by_addr_v6_gl(gi, addr, gl);
1956  return GeoIP_country_name_by_id(gi, country_id);
1957 }
1958 
1959 const char *
1960 GeoIP_country_name_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) {
1961  int country_id;
1962  country_id = GeoIP_id_by_addr_gl(gi, addr, gl);
1963  return GeoIP_country_name_by_id(gi, country_id);
1964 }
1965 
1967  unsigned long ipnum,
1968  GeoIPLookup *gl) {
1969  int country_id;
1970  country_id = GeoIP_id_by_ipnum_gl(gi, ipnum, gl);
1971  return GeoIP_country_name_by_id(gi, country_id);
1972 }
1973 
1974 const char *
1976  int country_id;
1977  country_id = GeoIP_id_by_ipnum_v6_gl(gi, ipnum, gl);
1978  return GeoIP_country_name_by_id(gi, country_id);
1979 }
1980 
1982  unsigned long ipnum,
1983  GeoIPLookup *gl) {
1984  int country_id;
1985  country_id = GeoIP_id_by_ipnum_gl(gi, ipnum, gl);
1986  return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL;
1987 }
1988 
1989 const char *
1991  int country_id;
1992  country_id = GeoIP_id_by_ipnum_v6_gl(gi, ipnum, gl);
1993  return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL;
1994 }
1995 
1997  unsigned long ipnum,
1998  GeoIPLookup *gl) {
1999  int country_id;
2000  country_id = GeoIP_id_by_ipnum_gl(gi, ipnum, gl);
2001  return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL;
2002 }
2003 
2005  geoipv6_t ipnum,
2006  GeoIPLookup *gl) {
2007  int country_id;
2008  country_id = GeoIP_id_by_ipnum_v6_gl(gi, ipnum, gl);
2009  return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL;
2010 }
2011 
2013  const char *addr,
2014  GeoIPLookup *gl) {
2015  return GeoIP_id_by_addr_v6_gl(gi, addr, gl);
2016 }
2017 
2018 int GeoIP_country_id_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) {
2019  return GeoIP_id_by_addr_gl(gi, addr, gl);
2020 }
2021 
2023  const char *host,
2024  GeoIPLookup *gl) {
2025  return GeoIP_id_by_name_v6_gl(gi, host, gl);
2026 }
2027 
2028 int GeoIP_country_id_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl) {
2029  return GeoIP_id_by_name_gl(gi, host, gl);
2030 }
2031 
2032 int GeoIP_id_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) {
2033  geoipv6_t ipnum;
2034  int ret;
2035  if (addr == NULL) {
2036  return 0;
2037  }
2040  printf("Invalid database type %s, expected %s\n",
2043  return 0;
2044  }
2045  ipnum = _GeoIP_addr_to_num_v6(addr);
2046  ret = _GeoIP_seek_record_v6_gl(gi, ipnum, gl) - gi->databaseSegments[0];
2047  return ret;
2048 }
2049 
2050 int GeoIP_id_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) {
2051  unsigned long ipnum;
2052  int ret;
2053  if (addr == NULL) {
2054  return 0;
2055  }
2056  if (gi->databaseType != GEOIP_COUNTRY_EDITION &&
2060  printf("Invalid database type %s, expected %s\n",
2063  return 0;
2064  }
2065  ipnum = GeoIP_addr_to_num(addr);
2066  ret = _GeoIP_seek_record_gl(gi, ipnum, gl) - gi->databaseSegments[0];
2067  return ret;
2068 }
2069 
2071  int ret;
2074  printf("Invalid database type %s, expected %s\n",
2077  return 0;
2078  }
2079  ret = _GeoIP_seek_record_v6_gl(gi, ipnum, gl) - gi->databaseSegments[0];
2080  return ret;
2081 }
2082 
2083 int GeoIP_id_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) {
2084  int ret;
2085  if (ipnum == 0) {
2086  return 0;
2087  }
2088  if (gi->databaseType != GEOIP_COUNTRY_EDITION &&
2092  printf("Invalid database type %s, expected %s\n",
2095  return 0;
2096  }
2097  ret = _GeoIP_seek_record_gl(gi, ipnum, gl) - gi->databaseSegments[0];
2098  return ret;
2099 }
2100 
2102  int i;
2103  unsigned char buf[3];
2104  char *retval;
2105  int has_structure_info = 0;
2106  off_t offset = gi->size - 3;
2107  int fno;
2108 
2109  if (gi == NULL) {
2110  return NULL;
2111  }
2112 
2113  fno = fileno(gi->GeoIPDatabase);
2114 
2115  _check_mtime(gi);
2116 
2117  /* first get past the database structure information */
2118  for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) {
2119  if (pread(fno, buf, 3, offset) != 3) {
2120  return NULL;
2121  }
2122  offset += 3;
2123  if (buf[0] == 255 && buf[1] == 255 && buf[2] == 255) {
2124  has_structure_info = 1;
2125  break;
2126  }
2127  offset -= 4;
2128  if (offset < 0) {
2129  return NULL;
2130  }
2131  }
2132  if (has_structure_info) {
2133  offset -= 6;
2134  if (offset < 0) {
2135  return NULL;
2136  }
2137  } else {
2138  /* no structure info, must be pre Sep 2002 database, go back to end */
2139  offset = gi->size - 3;
2140  if (offset < 0) {
2141  return NULL;
2142  }
2143  }
2144 
2145  for (i = 0; i < DATABASE_INFO_MAX_SIZE; i++) {
2146  if (pread(fno, buf, 3, offset) != 3) {
2147  return NULL;
2148  }
2149  offset += 3;
2150  if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0) {
2151  retval = malloc(sizeof(char) * (i + 1));
2152  if (retval == NULL) {
2153  return NULL;
2154  }
2155  if (pread(fno, retval, i, offset) != i) {
2156  return NULL;
2157  }
2158  retval[i] = '\0';
2159  return retval;
2160  }
2161  offset -= 4;
2162  if (offset < 0) {
2163  return NULL;
2164  }
2165  }
2166  return NULL;
2167 }
2168 
2169 /* GeoIP Region Edition functions */
2170 
2172  unsigned long inetaddr,
2173  GeoIPRegion *region,
2174  GeoIPLookup *gl) {
2175  unsigned int seek_region;
2176 
2177  /* This also writes in the terminating NULs (if you decide to
2178  * keep them) and clear any fields that are not set. */
2179  memset(region, 0, sizeof(GeoIPRegion));
2180 
2181  seek_region = _GeoIP_seek_record_gl(gi, ntohl(inetaddr), gl);
2182 
2184  /* Region Edition, pre June 2003 */
2185  seek_region -= STATE_BEGIN_REV0;
2186  if (seek_region >= 1000) {
2187  region->country_code[0] = 'U';
2188  region->country_code[1] = 'S';
2189  region->region[0] = (char)((seek_region - 1000) / 26 + 65);
2190  region->region[1] = (char)((seek_region - 1000) % 26 + 65);
2191  } else {
2192  const char *code = GeoIP_code_by_id(seek_region);
2193  if (code != NULL) {
2194  memcpy(region->country_code, code, 2);
2195  }
2196  }
2197  } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) {
2198  /* Region Edition, post June 2003 */
2199  seek_region -= STATE_BEGIN_REV1;
2200  if (seek_region < US_OFFSET) {
2201  /* Unknown */
2202  /* we don't need to do anything here b/c we memset region to 0 */
2203  } else if (seek_region < CANADA_OFFSET) {
2204  /* USA State */
2205  region->country_code[0] = 'U';
2206  region->country_code[1] = 'S';
2207  region->region[0] = (char)((seek_region - US_OFFSET) / 26 + 65);
2208  region->region[1] = (char)((seek_region - US_OFFSET) % 26 + 65);
2209  } else if (seek_region < WORLD_OFFSET) {
2210  /* Canada Province */
2211  region->country_code[0] = 'C';
2212  region->country_code[1] = 'A';
2213  region->region[0] = (char)((seek_region - CANADA_OFFSET) / 26 + 65);
2214  region->region[1] = (char)((seek_region - CANADA_OFFSET) % 26 + 65);
2215  } else {
2216  /* Not US or Canada ( cc_id is always cc_id * FIPS_RANGE ) */
2217  const char *code =
2218  GeoIP_code_by_id((seek_region - WORLD_OFFSET) / FIPS_RANGE);
2219  if (code != NULL) {
2220  /* coverity[dont_call] */
2221  memcpy(region->country_code, code, 2);
2222  }
2223  }
2224  }
2225 }
2226 
2228  geoipv6_t inetaddr,
2229  GeoIPRegion *region,
2230  GeoIPLookup *gl) {
2231  unsigned int seek_region;
2232 
2233  /* This also writes in the terminating NULs (if you decide to
2234  * keep them) and clear any fields that are not set. */
2235  memset(region, 0, sizeof(GeoIPRegion));
2236 
2237  seek_region = _GeoIP_seek_record_v6_gl(gi, inetaddr, gl);
2238 
2240  /* Region Edition, pre June 2003 */
2241  seek_region -= STATE_BEGIN_REV0;
2242  if (seek_region >= 1000) {
2243  region->country_code[0] = 'U';
2244  region->country_code[1] = 'S';
2245  region->region[0] = (char)((seek_region - 1000) / 26 + 65);
2246  region->region[1] = (char)((seek_region - 1000) % 26 + 65);
2247  } else {
2248  const char *code = GeoIP_code_by_id(seek_region);
2249  if (code != NULL) {
2250  /* coverity[dont_call] */
2251  memcpy(region->country_code, code, 2);
2252  }
2253  }
2254  } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) {
2255  /* Region Edition, post June 2003 */
2256  seek_region -= STATE_BEGIN_REV1;
2257  if (seek_region < US_OFFSET) {
2258  /* Unknown */
2259  /* we don't need to do anything here b/c we memset region to 0 */
2260  } else if (seek_region < CANADA_OFFSET) {
2261  /* USA State */
2262  region->country_code[0] = 'U';
2263  region->country_code[1] = 'S';
2264  region->region[0] = (char)((seek_region - US_OFFSET) / 26 + 65);
2265  region->region[1] = (char)((seek_region - US_OFFSET) % 26 + 65);
2266  } else if (seek_region < WORLD_OFFSET) {
2267  /* Canada Province */
2268  region->country_code[0] = 'C';
2269  region->country_code[1] = 'A';
2270  region->region[0] = (char)((seek_region - CANADA_OFFSET) / 26 + 65);
2271  region->region[1] = (char)((seek_region - CANADA_OFFSET) % 26 + 65);
2272  } else {
2273  /* Not US or Canada ( cc_id is always cc_id * FIPS_RANGE ) */
2274  const char *code =
2275  GeoIP_code_by_id((seek_region - WORLD_OFFSET) / FIPS_RANGE);
2276  if (code != NULL) {
2277  /* coverity[dont_call] */
2278  memcpy(region->country_code, code, 2);
2279  }
2280  }
2281  }
2282 }
2283 
2284 static GeoIPRegion *
2285 _get_region_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) {
2286  GeoIPRegion *region;
2287 
2288  region = malloc(sizeof(GeoIPRegion));
2289  if (region) {
2290  GeoIP_assign_region_by_inetaddr_gl(gi, htonl(ipnum), region, gl);
2291  }
2292  return region;
2293 }
2294 
2295 static GeoIPRegion *
2297  GeoIPRegion *region;
2298 
2299  region = malloc(sizeof(GeoIPRegion));
2300  if (region) {
2301  GeoIP_assign_region_by_inetaddr_v6_gl(gi, ipnum, region, gl);
2302  }
2303  return region;
2304 }
2305 
2306 GeoIPRegion *
2307 GeoIP_region_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) {
2308  unsigned long ipnum;
2309  if (addr == NULL) {
2310  return NULL;
2311  }
2314  printf("Invalid database type %s, expected %s\n",
2317  return NULL;
2318  }
2319  ipnum = GeoIP_addr_to_num(addr);
2320  return _get_region_gl(gi, ipnum, gl);
2321 }
2322 
2323 GeoIPRegion *
2324 GeoIP_region_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) {
2325  geoipv6_t ipnum;
2326  if (addr == NULL) {
2327  return NULL;
2328  }
2331  printf("Invalid database type %s, expected %s\n",
2334  return NULL;
2335  }
2336  ipnum = _GeoIP_addr_to_num_v6(addr);
2337  return _get_region_v6_gl(gi, ipnum, gl);
2338 }
2339 
2340 GeoIPRegion *
2341 GeoIP_region_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) {
2342  unsigned long ipnum;
2343  if (name == NULL) {
2344  return NULL;
2345  }
2348  printf("Invalid database type %s, expected %s\n",
2351  return NULL;
2352  }
2353  if (!(ipnum = _GeoIP_lookupaddress(name))) {
2354  return NULL;
2355  }
2356  return _get_region_gl(gi, ipnum, gl);
2357 }
2358 
2359 GeoIPRegion *
2360 GeoIP_region_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) {
2361  geoipv6_t ipnum;
2362  if (name == NULL) {
2363  return NULL;
2364  }
2367  printf("Invalid database type %s, expected %s\n",
2370  return NULL;
2371  }
2372 
2373  ipnum = _GeoIP_lookupaddress_v6(name);
2374  if (__GEOIP_V6_IS_NULL(ipnum)) {
2375  return NULL;
2376  }
2377  return _get_region_v6_gl(gi, ipnum, gl);
2378 }
2379 
2380 GeoIPRegion *
2381 GeoIP_region_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) {
2384  printf("Invalid database type %s, expected %s\n",
2387  return NULL;
2388  }
2389  return _get_region_gl(gi, ipnum, gl);
2390 }
2391 
2392 GeoIPRegion *
2396  printf("Invalid database type %s, expected %s\n",
2399  return NULL;
2400  }
2401  return _get_region_v6_gl(gi, ipnum, gl);
2402 }
2403 
2404 void GeoIPRegion_delete(GeoIPRegion *gir) { free(gir); }
2405 
2406 /* GeoIP Organization, ISP and AS Number Edition private method */
2407 static char *_get_name_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) {
2408  unsigned int seek_org;
2409  char buf[MAX_ORG_RECORD_LENGTH];
2410  char *org_buf, *buf_pointer;
2411  int record_pointer;
2412  size_t len;
2413 
2414  if (gi->databaseType != GEOIP_ORG_EDITION &&
2427  printf("Invalid database type %s, expected %s\n",
2430  return NULL;
2431  }
2432 
2433  seek_org = _GeoIP_seek_record_gl(gi, ipnum, gl);
2434  if (seek_org == gi->databaseSegments[0]) {
2435  return NULL;
2436  }
2437 
2438  record_pointer =
2439  seek_org + (2 * gi->record_length - 1) * gi->databaseSegments[0];
2440 
2441  if (gi->cache == NULL) {
2442  if (pread(fileno(gi->GeoIPDatabase),
2443  buf,
2445  record_pointer) == -1) {
2446  return NULL;
2447  }
2448  if (gi->charset == GEOIP_CHARSET_UTF8) {
2449  org_buf = _GeoIP_iso_8859_1__utf8((const char *)buf);
2450  } else {
2451  len = sizeof(char) * (strlen(buf) + 1);
2452  org_buf = malloc(len);
2453  strncpy(org_buf, buf, len);
2454  }
2455  } else {
2456  buf_pointer = (char *)(gi->cache + (long)record_pointer);
2457  if (gi->charset == GEOIP_CHARSET_UTF8) {
2458  org_buf = _GeoIP_iso_8859_1__utf8((const char *)buf_pointer);
2459  } else {
2460  len = sizeof(char) * (strlen(buf_pointer) + 1);
2461  org_buf = malloc(len);
2462  strncpy(org_buf, buf_pointer, len);
2463  }
2464  }
2465  return org_buf;
2466 }
2467 
2468 static char *_get_name_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) {
2469  unsigned int seek_org;
2470  char buf[MAX_ORG_RECORD_LENGTH + 1];
2471  char *org_buf, *buf_pointer;
2472  int record_pointer;
2473  size_t len;
2474 
2475  if (gi->databaseType != GEOIP_ORG_EDITION_V6 &&
2484  printf("Invalid database type %s, expected %s\n",
2487  return NULL;
2488  }
2489 
2490  seek_org = _GeoIP_seek_record_v6_gl(gi, ipnum, gl);
2491  if (seek_org == gi->databaseSegments[0]) {
2492  return NULL;
2493  }
2494 
2495  record_pointer =
2496  seek_org + (2 * gi->record_length - 1) * gi->databaseSegments[0];
2497 
2498  if (gi->cache == NULL) {
2499  if (pread(fileno(gi->GeoIPDatabase),
2500  buf,
2502  record_pointer) == -1) {
2503  return NULL;
2504  }
2505  buf[MAX_ORG_RECORD_LENGTH] = 0;
2506  if (gi->charset == GEOIP_CHARSET_UTF8) {
2507  org_buf = _GeoIP_iso_8859_1__utf8((const char *)buf);
2508  } else {
2509  len = sizeof(char) * (strlen(buf) + 1);
2510  org_buf = malloc(len);
2511  strncpy(org_buf, buf, len);
2512  }
2513  } else {
2514  buf_pointer = (char *)(gi->cache + (long)record_pointer);
2515  if (gi->charset == GEOIP_CHARSET_UTF8) {
2516  org_buf = _GeoIP_iso_8859_1__utf8((const char *)buf_pointer);
2517  } else {
2518  len = sizeof(char) * (strlen(buf_pointer) + 1);
2519  org_buf = malloc(len);
2520  strncpy(org_buf, buf_pointer, len);
2521  }
2522  }
2523  return org_buf;
2524 }
2525 
2526 char *GeoIP_num_to_addr(unsigned long ipnum) {
2527  char *ret_str;
2528  char *cur_str;
2529  int octet[4];
2530  int num_chars_written, i;
2531 
2532  ret_str = malloc(sizeof(char) * 16);
2533  cur_str = ret_str;
2534 
2535  for (i = 0; i < 4; i++) {
2536  octet[3 - i] = ipnum % 256;
2537  ipnum >>= 8;
2538  }
2539 
2540  for (i = 0; i < 4; i++) {
2541  num_chars_written = sprintf(cur_str, "%d", octet[i]);
2542  cur_str += num_chars_written;
2543 
2544  if (i < 3) {
2545  cur_str[0] = '.';
2546  cur_str++;
2547  }
2548  }
2549 
2550  return ret_str;
2551 }
2552 
2553 char **GeoIP_range_by_ip_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) {
2554  unsigned long ipnum;
2555  unsigned long left_seek;
2556  unsigned long right_seek;
2557  unsigned long mask;
2558  int orig_netmask;
2559  unsigned int target_value;
2560  char **ret;
2561  GeoIPLookup t;
2562 
2563  if (addr == NULL) {
2564  return NULL;
2565  }
2566 
2567  ret = malloc(sizeof(char *) * 2);
2568 
2569  ipnum = GeoIP_addr_to_num(addr);
2570  target_value = _GeoIP_seek_record_gl(gi, ipnum, gl);
2571  orig_netmask = gl->netmask;
2572  mask = 0xffffffff << (32 - orig_netmask);
2573  left_seek = ipnum & mask;
2574  right_seek = left_seek + (0xffffffff & ~mask);
2575 
2576  while (left_seek != 0 &&
2577  target_value == _GeoIP_seek_record_gl(gi, left_seek - 1, &t)) {
2578 
2579  /* Go to beginning of netblock defined by netmask */
2580  mask = 0xffffffff << (32 - t.netmask);
2581  left_seek = (left_seek - 1) & mask;
2582  }
2583  ret[0] = GeoIP_num_to_addr(left_seek);
2584 
2585  while (right_seek != 0xffffffff &&
2586  target_value == _GeoIP_seek_record_gl(gi, right_seek + 1, &t)) {
2587 
2588  /* Go to end of netblock defined by netmask */
2589  mask = 0xffffffff << (32 - t.netmask);
2590  right_seek = (right_seek + 1) & mask;
2591  right_seek += 0xffffffff & ~mask;
2592  }
2593  ret[1] = GeoIP_num_to_addr(right_seek);
2594 
2595  gi->netmask = orig_netmask;
2596 
2597  return ret;
2598 }
2599 void GeoIP_range_by_ip_delete(char **ptr) {
2600  if (ptr) {
2601  if (ptr[0]) {
2602  free(ptr[0]);
2603  }
2604  if (ptr[1]) {
2605  free(ptr[1]);
2606  }
2607  free(ptr);
2608  }
2609 }
2610 
2611 char *GeoIP_name_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) {
2612  return _get_name_gl(gi, ipnum, gl);
2613 }
2614 
2616  return _get_name_v6_gl(gi, ipnum, gl);
2617 }
2618 
2619 char *GeoIP_name_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) {
2620  unsigned long ipnum;
2621  if (addr == NULL) {
2622  return NULL;
2623  }
2624  ipnum = GeoIP_addr_to_num(addr);
2625  return _get_name_gl(gi, ipnum, gl);
2626 }
2627 
2628 char *GeoIP_name_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) {
2629  geoipv6_t ipnum;
2630  if (addr == NULL) {
2631  return NULL;
2632  }
2633  ipnum = _GeoIP_addr_to_num_v6(addr);
2634  return _get_name_v6_gl(gi, ipnum, gl);
2635 }
2636 
2637 char *GeoIP_name_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) {
2638  unsigned long ipnum;
2639  if (name == NULL) {
2640  return NULL;
2641  }
2642  if (!(ipnum = _GeoIP_lookupaddress(name))) {
2643  return NULL;
2644  }
2645  return _get_name_gl(gi, ipnum, gl);
2646 }
2647 
2648 char *GeoIP_name_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) {
2649  geoipv6_t ipnum;
2650  if (name == NULL) {
2651  return NULL;
2652  }
2653  ipnum = _GeoIP_lookupaddress_v6(name);
2654  if (__GEOIP_V6_IS_NULL(ipnum)) {
2655  return NULL;
2656  }
2657  return _get_name_v6_gl(gi, ipnum, gl);
2658 }
2659 
2660 unsigned char GeoIP_database_edition(GeoIP *gi) { return gi->databaseType; }
2661 
2662 int GeoIP_enable_teredo(GeoIP *gi, int true_false) {
2663  unsigned int mask = (1U << GEOIP_TEREDO_BIT);
2664  int b = (gi->ext_flags & mask) ? 1 : 0;
2665  gi->ext_flags &= ~mask;
2666  if (true_false) {
2667  gi->ext_flags |= true_false;
2668  }
2669  return b;
2670 }
2671 
2673  unsigned int mask = (1U << GEOIP_TEREDO_BIT);
2674  return (gi->ext_flags & mask) ? 1 : 0;
2675 }
2676 
2677 int GeoIP_charset(GeoIP *gi) { return gi->charset; }
2678 
2679 int GeoIP_set_charset(GeoIP *gi, int charset) {
2680  int old_charset = gi->charset;
2681  gi->charset = charset;
2682  return old_charset;
2683 }
2684 
2686 const char *GeoIP_code_by_id(int id) {
2687  if (id < 0 || id >= (int)num_GeoIP_countries) {
2688  return NULL;
2689  }
2690 
2691  return GeoIP_country_code[id];
2692 }
2693 
2695 const char *GeoIP_code3_by_id(int id) {
2696  if (id < 0 || id >= (int)num_GeoIP_countries) {
2697  return NULL;
2698  }
2699 
2700  return GeoIP_country_code3[id];
2701 }
2702 
2704 const char *GeoIP_country_name_by_id(GeoIP *gi, int id) {
2705  /* return NULL also even for index 0 for backward compatibility */
2706  if (id <= 0 || id >= (int)num_GeoIP_countries) {
2707  return NULL;
2708  }
2709  return (gi->charset == GEOIP_CHARSET_UTF8) ? GeoIP_utf8_country_name[id]
2710  : GeoIP_country_name[id];
2711 }
2712 
2714 const char *GeoIP_name_by_id(int id) {
2715  if (id < 0 || id >= (int)num_GeoIP_countries) {
2716  return NULL;
2717  }
2718 
2719  return GeoIP_country_name[id];
2720 }
2721 
2723 const char *GeoIP_continent_by_id(int id) {
2724  if (id < 0 || id >= (int)num_GeoIP_countries) {
2725  return NULL;
2726  }
2727 
2728  return GeoIP_country_continent[id];
2729 }
2730 
2732 int GeoIP_id_by_code(const char *country) {
2733  unsigned i;
2734 
2735  for (i = 0; i < num_GeoIP_countries; ++i) {
2736  if (strcmp(country, GeoIP_country_code[i]) == 0) {
2737  return i;
2738  }
2739  }
2740 
2741  return 0;
2742 }
2743 
2744 unsigned GeoIP_num_countries(void) { return num_GeoIP_countries; }
2745 
2746 const char *GeoIP_lib_version(void) { return PACKAGE_VERSION; }
2747 
2748 int GeoIP_cleanup(void) {
2749  int i, result = 0;
2750  char **tmpGeoIPDBFileName = GeoIPDBFileName;
2751 
2752  GeoIPDBFileName = NULL;
2753 
2754  if (tmpGeoIPDBFileName) {
2755  for (i = 0; i < NUM_DB_TYPES; i++) {
2756  if (tmpGeoIPDBFileName[i]) {
2757  free(tmpGeoIPDBFileName[i]);
2758  }
2759  }
2760 
2761  free(tmpGeoIPDBFileName);
2762  result = 1;
2763  }
2764 
2765  return result;
2766 }
GeoIPTag::databaseSegments
unsigned int * databaseSegments
Definition: GeoIP.h:64
GEOIP_USERTYPE_EDITION
Definition: GeoIP.h:131
GeoIP_country_name
const char * GeoIP_country_name[256]
Definition: GeoIP.c:413
GeoIP_assign_region_by_inetaddr_gl
void GeoIP_assign_region_by_inetaddr_gl(GeoIP *gi, unsigned long inetaddr, GeoIPRegion *region, GeoIPLookup *gl)
Definition: GeoIP.c:2171
num_GeoIP_countries
static const unsigned num_GeoIP_countries
Definition: GeoIP.c:124
GeoIPTag::flags
int flags
Definition: GeoIP.h:67
US_OFFSET
#define US_OFFSET
Definition: GeoIP.c:83
GEOIP_COUNTRYCONF_EDITION
Definition: GeoIP.h:137
GEOIP_CHECK_CACHE
Definition: GeoIP.h:96
MAX_ORG_RECORD_LENGTH
#define MAX_ORG_RECORD_LENGTH
Definition: GeoIP.c:82
GeoIP_code_by_id
const char * GeoIP_code_by_id(int id)
Definition: GeoIP.c:2686
GeoIP_country_name_by_addr_v6_gl
const char * GeoIP_country_name_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:1953
GeoIP_country_continent
const char GeoIP_country_continent[256][3]
Definition: GeoIP.c:675
GEOIP_MMAP_CACHE
Definition: GeoIP.h:98
GeoIP_country_id_by_name_v6_gl
int GeoIP_country_id_by_name_v6_gl(GeoIP *gi, const char *host, GeoIPLookup *gl)
Definition: GeoIP.c:2022
GeoIPTag::last_mtime_check
time_t last_mtime_check
Definition: GeoIP.h:74
STRUCTURE_INFO_MAX_SIZE
#define STRUCTURE_INFO_MAX_SIZE
Definition: GeoIP.c:80
GEOIP_ACCURACYRADIUS_EDITION_V6
Definition: GeoIP.h:141
GeoIP_name_by_ipnum_gl
char * GeoIP_name_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:2611
GEOIP_DOMAIN_EDITION
Definition: GeoIP.h:113
GEOIP_REGION_EDITION_REV1
Definition: GeoIP.h:109
__GEOIP_PREPARE_TEREDO
void __GEOIP_PREPARE_TEREDO(geoipv6_t *v6)
Definition: GeoIP.c:784
GeoIP_country_code_by_name_v6_gl
const char * GeoIP_country_code_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl)
Definition: GeoIP.c:1761
GeoIP_id_by_addr_v6_gl
int GeoIP_id_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:2032
GeoIP_region_by_name_v6_gl
GeoIPRegion * GeoIP_region_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl)
Definition: GeoIP.c:2360
GeoIP_continent_by_id
const char * GeoIP_continent_by_id(int id)
Definition: GeoIP.c:2723
STANDARD_RECORD_LENGTH
#define STANDARD_RECORD_LENGTH
Definition: GeoIP.h:48
__GEOIP_V6_IS_NULL
int __GEOIP_V6_IS_NULL(geoipv6_t v6)
Definition: GeoIP.c:774
GeoIP_country_code_by_name_gl
const char * GeoIP_country_code_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl)
Definition: GeoIP.c:1768
GeoIP_region_by_name_gl
GeoIPRegion * GeoIP_region_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl)
Definition: GeoIP.c:2341
DATABASE_INFO_MAX_SIZE
#define DATABASE_INFO_MAX_SIZE
Definition: GeoIP.c:81
FIPS_RANGE
#define FIPS_RANGE
Definition: GeoIP.c:86
_file_exists
static int _file_exists(const char *file_name)
Definition: GeoIP.c:975
GEOIP_TEREDO_BIT
Definition: GeoIP.h:81
GeoIP_country_name_by_name_v6_gl
const char * GeoIP_country_name_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl)
Definition: GeoIP.c:1790
_get_name_gl
static char * _get_name_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:2407
GEOIP_ISP_EDITION
Definition: GeoIP.h:107
GeoIP_cleanup
int GeoIP_cleanup(void)
Definition: GeoIP.c:2748
GeoIP_region_by_addr_gl
GeoIPRegion * GeoIP_region_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:2307
GEOIP_NETSPEED_EDITION_REV1_V6
Definition: GeoIP.h:136
GeoIPRegionTag
Definition: GeoIP.h:88
GeoIPTag::record_length
char record_length
Definition: GeoIP.h:69
DEBUG_MSGF
#define DEBUG_MSGF(flags, fmt,...)
Definition: GeoIP.c:88
GeoIP_range_by_ip_gl
char ** GeoIP_range_by_ip_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:2553
GeoIP_teredo
int GeoIP_teredo(GeoIP *gi)
Definition: GeoIP.c:2672
GeoIP_country_name_by_ipnum_gl
const char * GeoIP_country_name_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:1966
GeoIP_country_code_by_addr_v6_gl
const char * GeoIP_country_code_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:1925
GEOIP_REGIONCONF_EDITION
Definition: GeoIP.h:139
GEOIP_CITY_EDITION_REV0_V6
Definition: GeoIP.h:134
GeoIP_lib_version
const char * GeoIP_lib_version(void)
Definition: GeoIP.c:2746
_GeoIP_inet_ntop
static const char * _GeoIP_inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
Definition: GeoIP.c:769
GeoIP_country_id_by_name_gl
int GeoIP_country_id_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl)
Definition: GeoIP.c:2028
GeoIP_id_by_name_v6_gl
int GeoIP_id_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl)
Definition: GeoIP.c:1902
get_db_description
static const char * get_db_description(int dbtype)
Definition: GeoIP.c:699
LARGE_SEGMENT_RECORD_LENGTH
#define LARGE_SEGMENT_RECORD_LENGTH
Definition: GeoIP.h:47
COUNTRY_BEGIN
#define COUNTRY_BEGIN
Definition: GeoIP.c:76
GeoIP_database_edition
unsigned char GeoIP_database_edition(GeoIP *gi)
Definition: GeoIP.c:2660
INADDR_NONE
#define INADDR_NONE
Definition: GeoIP.c:73
GeoIP.h
GeoIP_internal.h
GeoIP_charset
int GeoIP_charset(GeoIP *gi)
Definition: GeoIP.c:2677
_GeoIP_lookupaddress
unsigned long _GeoIP_lookupaddress(const char *host)
Definition: GeoIP.c:1803
GeoIP_region_by_ipnum_gl
GeoIPRegion * GeoIP_region_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:2381
GeoIP_new
GeoIP * GeoIP_new(int flags)
Definition: GeoIP.c:1614
GeoIPTag::ext_flags
unsigned int ext_flags
Definition: GeoIP.h:76
CANADA_OFFSET
#define CANADA_OFFSET
Definition: GeoIP.c:84
GeoIPLookup::netmask
int netmask
Definition: GeoIP.h:79
GeoIP_id_by_addr_gl
int GeoIP_id_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:2050
GEOIP_LOCATIONA_EDITION_V6
Definition: GeoIP.h:128
GEOIP_REGISTRAR_EDITION_V6
Definition: GeoIP.h:130
GEOIP_ACCURACYRADIUS_EDITION
Definition: GeoIP.h:116
GeoIPRegionTag::region
char region[3]
Definition: GeoIP.h:90
GeoIP_country_code3_by_addr_gl
const char * GeoIP_country_code3_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:1946
GEOIP_LOCATIONA_EDITION
Definition: GeoIP.h:115
GEOIP_INDEX_CACHE
Definition: GeoIP.h:97
_GeoIP_lookupaddress_v6
geoipv6_t _GeoIP_lookupaddress_v6(const char *host)
Definition: GeoIP.c:1856
GeoIPTag::index_cache
unsigned char * index_cache
Definition: GeoIP.h:63
GEOIP_CITY_EDITION_REV1_V6
Definition: GeoIP.h:133
GeoIP_country_code_by_ipnum_gl
const char * GeoIP_country_code_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:1981
GeoIP_country_code
const char GeoIP_country_code[256][3]
Definition: GeoIP.c:100
_GeoIP_addr_to_num_v6
geoipv6_t _GeoIP_addr_to_num_v6(const char *addr)
Definition: GeoIP.c:1451
GEOIP_ASNUM_EDITION
Definition: GeoIP.h:111
GeoIPDBDescription
const char * GeoIPDBDescription[(38+1)]
Definition: GeoIP.c:807
GeoIP_addr_to_num
unsigned long GeoIP_addr_to_num(const char *addr)
Definition: GeoIP.c:1545
NUM_DB_TYPES
#define NUM_DB_TYPES
Definition: GeoIP.h:51
GEOIP_NETSPEED_EDITION_REV1
Definition: GeoIP.h:135
GeoIPTag
Definition: GeoIP.h:59
GeoIP_id_by_code
int GeoIP_id_by_code(const char *country)
Definition: GeoIP.c:2732
GeoIP_is_private_v4
int GeoIP_is_private_v4(const char *addr)
Definition: GeoIP.c:1021
GeoIP_name_by_addr_gl
char * GeoIP_name_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:2619
GEOIP_LARGE_COUNTRY_EDITION_V6
Definition: GeoIP.h:120
GeoIP_country_id_by_addr_gl
int GeoIP_country_id_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:2018
GEOIP_DOMAIN_EDITION_V6
Definition: GeoIP.h:127
GeoIP_country_code3_by_addr_v6_gl
const char * GeoIP_country_code3_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:1937
pread.h
GeoIPTag::file_path
char * file_path
Definition: GeoIP.h:61
GeoIP_country_code_by_ipnum_v6_gl
const char * GeoIP_country_code_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:1990
ADDR_STR_LEN
#define ADDR_STR_LEN
Definition: GeoIP.c:1357
GeoIP_name_by_ipnum_v6_gl
char * GeoIP_name_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:2615
GeoIP_country_name_by_addr_gl
const char * GeoIP_country_name_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:1960
GeoIP_id_by_name_gl
int GeoIP_id_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl)
Definition: GeoIP.c:1880
GeoIP_utf8_country_name
const char * GeoIP_utf8_country_name[256]
Definition: GeoIP.c:153
GeoIP_name_by_name_gl
char * GeoIP_name_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl)
Definition: GeoIP.c:2637
_GeoIP_inet_pton
static int _GeoIP_inet_pton(int af, const char *src, void *dst)
Definition: GeoIP.c:765
GEOIP_CITY_EDITION_REV0
Definition: GeoIP.h:105
GeoIPTag::cache
unsigned char * cache
Definition: GeoIP.h:62
GeoIPRegionTag::country_code
char country_code[3]
Definition: GeoIP.h:89
GeoIP_country_code3_by_name_v6_gl
const char * GeoIP_country_code3_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl)
Definition: GeoIP.c:1774
GeoIP_name_by_addr_v6_gl
char * GeoIP_name_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:2628
GeoIP_name_by_id
const char * GeoIP_name_by_id(int id)
Definition: GeoIP.c:2714
GeoIP_num_to_addr
char * GeoIP_num_to_addr(unsigned long ipnum)
Definition: GeoIP.c:2526
GeoIP_db_avail
int GeoIP_db_avail(int type)
Definition: GeoIP.c:1026
LARGE_COUNTRY_BEGIN
#define LARGE_COUNTRY_BEGIN
Definition: GeoIP.c:77
GeoIPTag::mtime
time_t mtime
Definition: GeoIP.h:66
GeoIP_code3_by_id
const char * GeoIP_code3_by_id(int id)
Definition: GeoIP.c:2695
GeoIP_region_by_ipnum_v6_gl
GeoIPRegion * GeoIP_region_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:2393
_GeoIP_setup_dbfilename
void _GeoIP_setup_dbfilename(void)
Definition: GeoIP.c:899
_GeoIP_full_path_to
char * _GeoIP_full_path_to(const char *file_name)
Definition: GeoIP.c:852
get_index_size
static ssize_t get_index_size(GeoIP *gi, struct stat *buf)
Definition: GeoIP.c:1052
MAX_RECORD_LENGTH
#define MAX_RECORD_LENGTH
Definition: GeoIP.h:50
GEOIP_ORG_EDITION_V6
Definition: GeoIP.h:126
GeoIP_open
GeoIP * GeoIP_open(const char *filename, int flags)
Definition: GeoIP.c:1621
_check_mtime
static void _check_mtime(GeoIP *gi)
Definition: GeoIP.c:1203
GeoIP_delete
void GeoIP_delete(GeoIP *gi)
Definition: GeoIP.c:1735
STATE_BEGIN_REV1
#define STATE_BEGIN_REV1
Definition: GeoIP.c:79
_get_region_v6_gl
static GeoIPRegion * _get_region_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:2296
GeoIP_country_name_by_name_gl
const char * GeoIP_country_name_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl)
Definition: GeoIP.c:1797
GEOIP_CHARSET_ISO_8859_1
Definition: GeoIP.h:84
_GeoIP_iso_8859_1__utf8
char * _GeoIP_iso_8859_1__utf8(const char *iso)
Definition: GeoIP.c:980
GeoIP_open_type
GeoIP * GeoIP_open_type(int type, int flags)
Definition: GeoIP.c:1579
_GeoIP_seek_record_gl
unsigned int _GeoIP_seek_record_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:1460
_get_name_v6_gl
static char * _get_name_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:2468
GeoIP_region_by_addr_v6_gl
GeoIPRegion * GeoIP_region_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:2324
GEOIP_CHKBIT_V6
#define GEOIP_CHKBIT_V6(bit, ptr)
Definition: GeoIP.h:56
STATE_BEGIN_REV0
#define STATE_BEGIN_REV0
Definition: GeoIP.c:78
_database_has_content
static int _database_has_content(int database_type)
Definition: GeoIP.c:1039
GeoIP_country_code3_by_name_gl
const char * GeoIP_country_code3_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl)
Definition: GeoIP.c:1783
GEOIP_POSTALCONF_EDITION
Definition: GeoIP.h:140
GEOIP_ORG_EDITION
Definition: GeoIP.h:106
GeoIP_name_by_name_v6_gl
char * GeoIP_name_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl)
Definition: GeoIP.c:2648
GeoIPTag::charset
int charset
Definition: GeoIP.h:70
GEOIP_CITY_EDITION_REV1
Definition: GeoIP.h:108
pread
#define pread(fd, buf, count, offset)
Definition: GeoIP.c:96
GeoIP_is_private_ipnum_v4
int GeoIP_is_private_ipnum_v4(unsigned long ipnum)
Definition: GeoIP.c:1011
GeoIP_assign_region_by_inetaddr_v6_gl
void GeoIP_assign_region_by_inetaddr_v6_gl(GeoIP *gi, geoipv6_t inetaddr, GeoIPRegion *region, GeoIPLookup *gl)
Definition: GeoIP.c:2227
GeoIPLookup
Definition: GeoIP.h:79
GeoIPTag::size
off_t size
Definition: GeoIP.h:68
GeoIP_id_by_ipnum_gl
int GeoIP_id_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:2083
GEOIP_COUNTRY_EDITION
Definition: GeoIP.h:103
_get_region_gl
static GeoIPRegion * _get_region_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:2285
WORLD_OFFSET
#define WORLD_OFFSET
Definition: GeoIP.c:85
SEGMENT_RECORD_LENGTH
#define SEGMENT_RECORD_LENGTH
Definition: GeoIP.h:46
GEOIP_MEMORY_CACHE
Definition: GeoIP.h:95
GEOIP_LARGE_COUNTRY_EDITION
Definition: GeoIP.h:119
GEOIP_NETSPEED_EDITION
Definition: GeoIP.h:112
GEOIP_CHARSET_UTF8
Definition: GeoIP.h:85
GeoIP_set_charset
int GeoIP_set_charset(GeoIP *gi, int charset)
Definition: GeoIP.c:2679
ORG_RECORD_LENGTH
#define ORG_RECORD_LENGTH
Definition: GeoIP.h:49
GeoIP_country_code3_by_ipnum_gl
const char * GeoIP_country_code3_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:1996
GeoIP_country_code_by_addr_gl
const char * GeoIP_country_code_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:1932
GeoIPTag::databaseType
char databaseType
Definition: GeoIP.h:65
GeoIP_country_code3
const char GeoIP_country_code3[256][4]
Definition: GeoIP.c:127
_setup_segments
static void _setup_segments(GeoIP *gi)
Definition: GeoIP.c:1077
GeoIP_id_by_ipnum_v6_gl
int GeoIP_id_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:2070
GeoIP_range_by_ip_delete
void GeoIP_range_by_ip_delete(char **ptr)
Definition: GeoIP.c:2599
GEOIP_ISP_EDITION_V6
Definition: GeoIP.h:125
GEOIP_CITYCONF_EDITION
Definition: GeoIP.h:138
GeoIPDBFileName
char ** GeoIPDBFileName
Definition: GeoIP.c:897
GeoIP_custom_directory
char * GeoIP_custom_directory
Definition: GeoIP.c:848
GeoIP_enable_teredo
int GeoIP_enable_teredo(GeoIP *gi, int true_false)
Definition: GeoIP.c:2662
GEOIP_PROXY_EDITION
Definition: GeoIP.h:110
GeoIP_database_info
char * GeoIP_database_info(GeoIP *gi)
Definition: GeoIP.c:2101
GeoIP_num_countries
unsigned GeoIP_num_countries(void)
Definition: GeoIP.c:2744
geoipv6_t
struct in6_addr geoipv6_t
Definition: GeoIP.h:54
ssize_t
int ssize_t
Definition: pread.h:22
GEOIP_ASNUM_EDITION_V6
Definition: GeoIP.h:124
GEOIP_COUNTRY_EDITION_V6
Definition: GeoIP.h:114
GEOIP_REGISTRAR_EDITION
Definition: GeoIP.h:129
GEOIP_REGION_EDITION_REV0
Definition: GeoIP.h:104
GeoIP_setup_custom_directory
void GeoIP_setup_custom_directory(char *dir)
Definition: GeoIP.c:850
GEOIP_USERTYPE_EDITION_V6
Definition: GeoIP.h:132
GeoIP_country_name_by_id
const char * GeoIP_country_name_by_id(GeoIP *gi, int id)
Definition: GeoIP.c:2704
IPV6_NULL
static geoipv6_t IPV6_NULL
Definition: GeoIP.c:24
GeoIP_country_code3_by_ipnum_v6_gl
const char * GeoIP_country_code3_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:2004
GeoIPTag::GeoIPDatabase
FILE * GeoIPDatabase
Definition: GeoIP.h:60
GeoIP_country_id_by_addr_v6_gl
int GeoIP_country_id_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl)
Definition: GeoIP.c:2012
GeoIPTag::netmask
int netmask
Definition: GeoIP.h:72
GeoIP_country_name_by_ipnum_v6_gl
const char * GeoIP_country_name_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:1975
_GeoIP_seek_record_v6_gl
unsigned int _GeoIP_seek_record_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl)
Definition: GeoIP.c:1359
GeoIPRegion_delete
void GeoIPRegion_delete(GeoIPRegion *gir)
Definition: GeoIP.c:2404